1203945Sweongyo/*-
2203945Sweongyo * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
3203945Sweongyo * All rights reserved.
4203945Sweongyo *
5203945Sweongyo * Redistribution and use in source and binary forms, with or without
6203945Sweongyo * modification, are permitted provided that the following conditions
7203945Sweongyo * are met:
8203945Sweongyo * 1. Redistributions of source code must retain the above copyright
9203945Sweongyo *    notice, this list of conditions and the following disclaimer,
10203945Sweongyo *    without modification.
11203945Sweongyo * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12203945Sweongyo *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13203945Sweongyo *    redistribution must be conditioned upon including a substantially
14203945Sweongyo *    similar Disclaimer requirement for further binary redistribution.
15203945Sweongyo *
16203945Sweongyo * NO WARRANTY
17203945Sweongyo * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18203945Sweongyo * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19203945Sweongyo * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20203945Sweongyo * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21203945Sweongyo * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22203945Sweongyo * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23203945Sweongyo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24203945Sweongyo * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25203945Sweongyo * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26203945Sweongyo * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27203945Sweongyo * THE POSSIBILITY OF SUCH DAMAGES.
28203945Sweongyo *
29203945Sweongyo * $FreeBSD: stable/11/sys/dev/bwn/if_bwnvar.h 355454 2019-12-06 18:15:27Z brooks $
30203945Sweongyo */
31203945Sweongyo
32203945Sweongyo#ifndef _IF_BWNVAR_H
33203945Sweongyo#define	_IF_BWNVAR_H
34203945Sweongyo
35203945Sweongyostruct siba_dev_softc;
36203945Sweongyostruct bwn_softc;
37203945Sweongyostruct bwn_mac;
38203945Sweongyo
39203945Sweongyo#define	N(a)			(sizeof(a) / sizeof(a[0]))
40203945Sweongyo#define	BWN_ALIGN			0x1000
41203945Sweongyo#define	BWN_BUS_SPACE_MAXADDR_30BIT	0x3fffffff
42203945Sweongyo#define	BWN_RETRY_SHORT			7
43203945Sweongyo#define	BWN_RETRY_LONG			4
44203945Sweongyo#define	BWN_STAID_MAX			64
45203945Sweongyo#define	BWN_TXPWR_IGNORE_TIME		(1 << 0)
46203945Sweongyo#define	BWN_TXPWR_IGNORE_TSSI		(1 << 1)
47203945Sweongyo#define	BWN_HAS_TXMAG(phy)						\
48203945Sweongyo	(((phy)->rev >= 2) && ((phy)->rf_ver == 0x2050) &&		\
49203945Sweongyo	 ((phy)->rf_rev == 8))
50203945Sweongyo#define	BWN_HAS_LOOPBACK(phy)						\
51203945Sweongyo	(((phy)->rev > 1) || ((phy)->gmode))
52203945Sweongyo#define	BWN_TXERROR_MAX			1000
53203945Sweongyo#define	BWN_GETTIME(v)	do {						\
54203945Sweongyo	struct timespec ts;						\
55203945Sweongyo	nanouptime(&ts);						\
56203945Sweongyo	(v) = ts.tv_nsec / 1000000 + ts.tv_sec * 1000;			\
57203945Sweongyo} while (0)
58203945Sweongyo#define	BWN_ISOLDFMT(mac)		((mac)->mac_fw.rev <= 351)
59203945Sweongyo#define	BWN_TSSI2DBM(num, den)						\
60203945Sweongyo	((int32_t)((num < 0) ? num / den : (num + den / 2) / den))
61299790Sadrian#define	BWN_HDRSIZE(mac)	bwn_tx_hdrsize(mac)
62300075Sadrian#define	BWN_MAXTXHDRSIZE	(112 + (sizeof(struct bwn_plcp6)))
63299790Sadrian
64203945Sweongyo#define	BWN_PIO_COOKIE(tq, tp)						\
65203945Sweongyo	((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index))
66203945Sweongyo#define	BWN_DMA_COOKIE(dr, slot)					\
67203945Sweongyo	((uint16_t)(((uint16_t)dr->dr_index + 1) << 12) | (uint16_t)slot)
68204922Sweongyo#define	BWN_READ_2(mac, o)		(siba_read_2(mac->mac_sc->sc_dev, o))
69204922Sweongyo#define	BWN_READ_4(mac, o)		(siba_read_4(mac->mac_sc->sc_dev, o))
70204922Sweongyo#define	BWN_WRITE_2(mac, o, v)						\
71204922Sweongyo	(siba_write_2(mac->mac_sc->sc_dev, o, v))
72299790Sadrian#define	BWN_WRITE_2_F(mac, o, v) do { \
73299790Sadrian	(BWN_WRITE_2(mac, o, v)); \
74299790Sadrian	BWN_READ_2(mac, o); \
75299790Sadrian} while(0)
76299790Sadrian#define	BWN_WRITE_SETMASK2(mac, offset, mask, set)			\
77299790Sadrian	BWN_WRITE_2(mac, offset, (BWN_READ_2(mac, offset) & mask) | set)
78204922Sweongyo#define	BWN_WRITE_4(mac, o, v)						\
79204922Sweongyo	(siba_write_4(mac->mac_sc->sc_dev, o, v))
80299790Sadrian#define	BWN_WRITE_SETMASK4(mac, offset, mask, set)			\
81299790Sadrian	BWN_WRITE_4(mac, offset, (BWN_READ_4(mac, offset) & mask) | set)
82203945Sweongyo#define	BWN_PIO_TXQOFFSET(mac)						\
83204922Sweongyo	((siba_get_revid(mac->mac_sc->sc_dev) >= 11) ? 0x18 : 0)
84203945Sweongyo#define	BWN_PIO_RXQOFFSET(mac)						\
85204922Sweongyo	((siba_get_revid(mac->mac_sc->sc_dev) >= 11) ? 0x38 : 8)
86203945Sweongyo#define	BWN_SEC_NEWAPI(mac)		(mac->mac_fw.rev >= 351)
87203945Sweongyo#define	BWN_SEC_KEY2FW(mac, idx)					\
88203945Sweongyo	(BWN_SEC_NEWAPI(mac) ? idx : ((idx >= 4) ? idx - 4 : idx))
89203945Sweongyo#define	BWN_RF_READ(mac, r)		(mac->mac_phy.rf_read(mac, r))
90203945Sweongyo#define	BWN_RF_WRITE(mac, r, v)		(mac->mac_phy.rf_write(mac, r, v))
91203945Sweongyo#define	BWN_RF_MASK(mac, o, m)						\
92203945Sweongyo	BWN_RF_WRITE(mac, o, BWN_RF_READ(mac, o) & m)
93203945Sweongyo#define	BWN_RF_SETMASK(mac, offset, mask, set)				\
94203945Sweongyo	BWN_RF_WRITE(mac, offset, (BWN_RF_READ(mac, offset) & mask) | set)
95203945Sweongyo#define	BWN_RF_SET(mac, offset, set)					\
96203945Sweongyo	BWN_RF_WRITE(mac, offset, BWN_RF_READ(mac, offset) | set)
97203945Sweongyo#define	BWN_PHY_READ(mac, r)		(mac->mac_phy.phy_read(mac, r))
98203945Sweongyo#define	BWN_PHY_WRITE(mac, r, v)					\
99203945Sweongyo	(mac->mac_phy.phy_write(mac, r, v))
100203945Sweongyo#define	BWN_PHY_SET(mac, offset, set)	do {				\
101203945Sweongyo	if (mac->mac_phy.phy_maskset != NULL) {				\
102203945Sweongyo		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
103203945Sweongyo		    mac->mac_suspended > 0,				\
104203945Sweongyo		    ("dont access PHY or RF registers after turning on MAC")); \
105203945Sweongyo		mac->mac_phy.phy_maskset(mac, offset, 0xffff, set);	\
106203945Sweongyo	} else								\
107203945Sweongyo		BWN_PHY_WRITE(mac, offset,				\
108203945Sweongyo		    BWN_PHY_READ(mac, offset) | (set));			\
109203945Sweongyo} while (0)
110203945Sweongyo#define	BWN_PHY_SETMASK(mac, offset, mask, set)	do {			\
111203945Sweongyo	if (mac->mac_phy.phy_maskset != NULL) {				\
112203945Sweongyo		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
113203945Sweongyo		    mac->mac_suspended > 0,				\
114203945Sweongyo		    ("dont access PHY or RF registers after turning on MAC")); \
115203945Sweongyo		mac->mac_phy.phy_maskset(mac, offset, mask, set);	\
116203945Sweongyo	} else								\
117203945Sweongyo		BWN_PHY_WRITE(mac, offset,				\
118203945Sweongyo		    (BWN_PHY_READ(mac, offset) & (mask)) | (set));	\
119203945Sweongyo} while (0)
120203945Sweongyo#define	BWN_PHY_MASK(mac, offset, mask)	do {				\
121203945Sweongyo	if (mac->mac_phy.phy_maskset != NULL) {				\
122203945Sweongyo		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
123203945Sweongyo		    mac->mac_suspended > 0,				\
124203945Sweongyo		    ("dont access PHY or RF registers after turning on MAC")); \
125203945Sweongyo		mac->mac_phy.phy_maskset(mac, offset, mask, 0);		\
126203945Sweongyo	} else								\
127203945Sweongyo		BWN_PHY_WRITE(mac, offset,				\
128355454Sbrooks		    BWN_PHY_READ(mac, offset) & (mask));		\
129203945Sweongyo} while (0)
130203945Sweongyo#define	BWN_PHY_COPY(mac, dst, src)	do {				\
131203945Sweongyo	KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||		\
132203945Sweongyo	    mac->mac_suspended > 0,					\
133203945Sweongyo	    ("dont access PHY or RF registers after turning on MAC"));	\
134203945Sweongyo	BWN_PHY_WRITE(mac, dst, BWN_PHY_READ(mac, src));		\
135203945Sweongyo} while (0)
136203945Sweongyo#define BWN_LO_CALIB_EXPIRE		(1000 * (30 - 2))
137203945Sweongyo#define BWN_LO_PWRVEC_EXPIRE		(1000 * (30 - 2))
138203945Sweongyo#define BWN_LO_TXCTL_EXPIRE		(1000 * (180 - 4))
139203945Sweongyo#define	BWN_DMA_BIT_MASK(n)		(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
140203945Sweongyo#define BWN_LPD(L, P, D)		(((L) << 2) | ((P) << 1) | ((D) << 0))
141203945Sweongyo#define BWN_BITREV4(tmp)		(BWN_BITREV8(tmp) >> 4)
142203945Sweongyo#define	BWN_BITREV8(byte)		(bwn_bitrev_table[byte])
143203945Sweongyo#define	BWN_BBATTCMP(a, b)		((a)->att == (b)->att)
144203945Sweongyo#define	BWN_RFATTCMP(a, b)						\
145203945Sweongyo	(((a)->att == (b)->att) && ((a)->padmix == (b)->padmix))
146203945Sweongyo#define	BWN_PIO_WRITE_2(mac, tq, offset, value)				\
147203945Sweongyo	BWN_WRITE_2(mac, (tq)->tq_base + offset, value)
148203945Sweongyo#define	BWN_PIO_READ_4(mac, tq, offset)					\
149203945Sweongyo	BWN_READ_4(mac, tq->tq_base + offset)
150203945Sweongyo#define	BWN_ISCCKRATE(rate)						\
151203945Sweongyo	(rate == BWN_CCK_RATE_1MB || rate == BWN_CCK_RATE_2MB ||	\
152203945Sweongyo	 rate == BWN_CCK_RATE_5MB || rate == BWN_CCK_RATE_11MB)
153203945Sweongyo#define	BWN_ISOFDMRATE(rate)		(!BWN_ISCCKRATE(rate))
154204922Sweongyo#define	BWN_BARRIER(mac, flags)		siba_barrier(mac->mac_sc->sc_dev, flags)
155203945Sweongyo#define	BWN_DMA_READ(dr, offset)				\
156203945Sweongyo	(BWN_READ_4(dr->dr_mac, dr->dr_base + offset))
157203945Sweongyo#define	BWN_DMA_WRITE(dr, offset, value)			\
158203945Sweongyo	(BWN_WRITE_4(dr->dr_mac, dr->dr_base + offset, value))
159203945Sweongyo
160299790Sadrian
161299790Sadriantypedef enum {
162299790Sadrian	BWN_PHY_BAND_2G = 0,
163299790Sadrian	BWN_PHY_BAND_5G_LO = 1,
164299790Sadrian	BWN_PHY_BAND_5G_MI = 2,
165299790Sadrian	BWN_PHY_BAND_5G_HI = 3
166299790Sadrian} bwn_phy_band_t;
167299790Sadrian
168299790Sadriantypedef enum {
169299790Sadrian	BWN_BAND_2G,
170299790Sadrian	BWN_BAND_5G,
171299790Sadrian} bwn_band_t;
172299790Sadrian
173299790Sadriantypedef enum {
174299790Sadrian	BWN_CHAN_TYPE_20,
175299790Sadrian	BWN_CHAN_TYPE_20_HT,
176299790Sadrian	BWN_CHAN_TYPE_40_HT_U,
177299790Sadrian	BWN_CHAN_TYPE_40_HT_D,
178299790Sadrian} bwn_chan_type_t;
179299790Sadrian
180203945Sweongyostruct bwn_rate {
181203945Sweongyo	uint16_t			rateid;
182203945Sweongyo	uint32_t			flags;
183203945Sweongyo};
184203945Sweongyo
185203945Sweongyo#define	BWN_ANT0			0
186203945Sweongyo#define	BWN_ANT1			1
187203945Sweongyo#define	BWN_ANTAUTO0			2
188203945Sweongyo#define	BWN_ANTAUTO1			3
189203945Sweongyo#define	BWN_ANT2			4
190203945Sweongyo#define	BWN_ANT3			8
191203945Sweongyo#define	BWN_ANTAUTO			BWN_ANTAUTO0
192203945Sweongyo#define	BWN_ANT_DEFAULT			BWN_ANTAUTO
193203945Sweongyo#define	BWN_TX_SLOTS_PER_FRAME		2
194203945Sweongyo
195203945Sweongyostruct bwn_channel {
196203945Sweongyo	unsigned			freq;
197203945Sweongyo	unsigned			ieee;
198203945Sweongyo	unsigned			maxTxPow;
199203945Sweongyo};
200203945Sweongyo
201203945Sweongyostruct bwn_channelinfo {
202203945Sweongyo	struct bwn_channel		channels[IEEE80211_CHAN_MAX];
203203945Sweongyo	unsigned			nchannels;
204203945Sweongyo};
205203945Sweongyo
206203945Sweongyostruct bwn_bbatt {
207203945Sweongyo	uint8_t				att;
208203945Sweongyo};
209203945Sweongyo
210203945Sweongyostruct bwn_bbatt_list {
211203945Sweongyo	const struct bwn_bbatt		*array;
212203945Sweongyo	uint8_t				len;
213203945Sweongyo	uint8_t				min;
214203945Sweongyo	uint8_t				max;
215203945Sweongyo};
216203945Sweongyo
217203945Sweongyostruct bwn_rfatt {
218203945Sweongyo	uint8_t				att;
219203945Sweongyo	int				padmix;
220203945Sweongyo};
221203945Sweongyo
222203945Sweongyostruct bwn_rfatt_list {
223203945Sweongyo	const struct bwn_rfatt		*array;
224203945Sweongyo	uint8_t				len;
225203945Sweongyo	uint8_t				min;
226203945Sweongyo	uint8_t				max;
227203945Sweongyo};
228203945Sweongyo
229203945Sweongyo#define	BWN_DC_LT_SIZE			32
230203945Sweongyo
231203945Sweongyostruct bwn_loctl {
232203945Sweongyo	int8_t				i;
233203945Sweongyo	int8_t				q;
234203945Sweongyo};
235203945Sweongyo
236299790Sadriantypedef enum {
237299790Sadrian	BWN_TXPWR_RES_NEED_ADJUST,
238299790Sadrian	BWN_TXPWR_RES_DONE,
239299790Sadrian} bwn_txpwr_result_t;
240299790Sadrian
241203945Sweongyostruct bwn_lo_calib {
242203945Sweongyo	struct bwn_bbatt		bbatt;
243203945Sweongyo	struct bwn_rfatt		rfatt;
244203945Sweongyo	struct bwn_loctl		ctl;
245203945Sweongyo	unsigned long			calib_time;
246203945Sweongyo	TAILQ_ENTRY(bwn_lo_calib)	list;
247203945Sweongyo};
248203945Sweongyo
249203945Sweongyostruct bwn_rxhdr4 {
250203945Sweongyo	uint16_t			frame_len;
251203945Sweongyo	uint8_t				pad1[2];
252203945Sweongyo	uint16_t			phy_status0;
253203945Sweongyo	union {
254203945Sweongyo		struct {
255203945Sweongyo			uint8_t		rssi;
256203945Sweongyo			uint8_t		sig_qual;
257203945Sweongyo		} __packed abg;
258203945Sweongyo		struct {
259203945Sweongyo			int8_t		power0;
260203945Sweongyo			int8_t		power1;
261203945Sweongyo		} __packed n;
262203945Sweongyo	} __packed phy;
263299790Sadrian	union {
264299790Sadrian		struct {
265299790Sadrian			int8_t		power2;
266299790Sadrian			uint8_t		pad;
267299790Sadrian		} __packed n;
268299790Sadrian		struct {
269299790Sadrian			uint8_t		pad;
270299790Sadrian			int8_t		ht_power0;
271299790Sadrian		} __packed ht;
272299790Sadrian		uint16_t		phy_status2;
273299790Sadrian	} __packed ps2;
274300114Sadrian	union {
275300114Sadrian		struct {
276300114Sadrian			uint16_t	phy_status3;
277300114Sadrian		} __packed lp;
278300114Sadrian		struct {
279300114Sadrian			int8_t		phy_ht_power1;
280300114Sadrian			int8_t		phy_ht_power2;
281300114Sadrian		} __packed ht;
282300114Sadrian	} __packed ps3;
283300114Sadrian	union {
284300114Sadrian		struct {
285300114Sadrian			uint32_t	mac_status;
286300114Sadrian			uint16_t	mac_time;
287300114Sadrian			uint16_t	channel;
288300114Sadrian		} __packed r351;
289300114Sadrian		struct {
290300114Sadrian			uint16_t	phy_status4;
291300114Sadrian			uint16_t	phy_status5;
292300114Sadrian			uint32_t	mac_status;
293300114Sadrian			uint16_t	mac_time;
294300114Sadrian			uint16_t	channel;
295300114Sadrian		} __packed r598;
296300114Sadrian	} __packed ps4;
297203945Sweongyo} __packed;
298203945Sweongyo
299203945Sweongyostruct bwn_txstatus {
300203945Sweongyo	uint16_t			cookie;
301203945Sweongyo	uint16_t			seq;
302203945Sweongyo	uint8_t				phy_stat;
303203945Sweongyo	uint8_t				framecnt;
304203945Sweongyo	uint8_t				rtscnt;
305203945Sweongyo	uint8_t				sreason;
306203945Sweongyo	uint8_t				pm;
307203945Sweongyo	uint8_t				im;
308203945Sweongyo	uint8_t				ampdu;
309203945Sweongyo	uint8_t				ack;
310203945Sweongyo};
311203945Sweongyo
312203945Sweongyo#define	BWN_TXCTL_PA3DB			0x40
313203945Sweongyo#define	BWN_TXCTL_PA2DB			0x20
314203945Sweongyo#define	BWN_TXCTL_TXMIX			0x10
315203945Sweongyo
316203945Sweongyostruct bwn_txpwr_loctl {
317203945Sweongyo	struct bwn_rfatt_list		rfatt;
318203945Sweongyo	struct bwn_bbatt_list		bbatt;
319203945Sweongyo	uint16_t			dc_lt[BWN_DC_LT_SIZE];
320203945Sweongyo	TAILQ_HEAD(, bwn_lo_calib)	calib_list;
321203945Sweongyo	unsigned long			pwr_vec_read_time;
322203945Sweongyo	unsigned long			txctl_measured_time;
323203945Sweongyo	uint8_t				tx_bias;
324203945Sweongyo	uint8_t				tx_magn;
325203945Sweongyo	uint64_t			power_vector;
326203945Sweongyo};
327203945Sweongyo
328203945Sweongyo#define	BWN_OFDMTAB_DIR_UNKNOWN		0
329203945Sweongyo#define	BWN_OFDMTAB_DIR_READ		1
330203945Sweongyo#define	BWN_OFDMTAB_DIR_WRITE		2
331203945Sweongyo
332203945Sweongyostruct bwn_phy_g {
333203945Sweongyo	unsigned			pg_flags;
334203945Sweongyo#define	BWN_PHY_G_FLAG_TSSITABLE_ALLOC	(1 << 0)
335203945Sweongyo#define	BWN_PHY_G_FLAG_RADIOCTX_VALID	(1 << 1)
336203945Sweongyo	int				pg_aci_enable;
337203945Sweongyo	int				pg_aci_wlan_automatic;
338203945Sweongyo	int				pg_aci_hw_rssi;
339203945Sweongyo	int				pg_rf_on;
340203945Sweongyo	uint16_t			pg_radioctx_over;
341203945Sweongyo	uint16_t			pg_radioctx_overval;
342203945Sweongyo	uint16_t			pg_minlowsig[2];
343203945Sweongyo	uint16_t			pg_minlowsigpos[2];
344203945Sweongyo	int8_t				*pg_tssi2dbm;
345203945Sweongyo	int				pg_idletssi;
346203945Sweongyo	int				pg_curtssi;
347203945Sweongyo	uint8_t				pg_avgtssi;
348203945Sweongyo	struct bwn_bbatt		pg_bbatt;
349203945Sweongyo	struct bwn_rfatt		pg_rfatt;
350203945Sweongyo	uint8_t				pg_txctl;
351203945Sweongyo	int				pg_bbatt_delta;
352203945Sweongyo	int				pg_rfatt_delta;
353203945Sweongyo
354203945Sweongyo	struct bwn_txpwr_loctl		pg_loctl;
355203945Sweongyo	int16_t				pg_max_lb_gain;
356203945Sweongyo	int16_t				pg_trsw_rx_gain;
357203945Sweongyo	int16_t				pg_lna_lod_gain;
358203945Sweongyo	int16_t				pg_lna_gain;
359203945Sweongyo	int16_t				pg_pga_gain;
360203945Sweongyo	int				pg_immode;
361203945Sweongyo#define	BWN_INTERFSTACK_SIZE	26
362203945Sweongyo	uint32_t			pg_interfstack[BWN_INTERFSTACK_SIZE];
363203945Sweongyo
364203945Sweongyo	int16_t				pg_nrssi[2];
365203945Sweongyo	int32_t				pg_nrssi_slope;
366203945Sweongyo	int8_t				pg_nrssi_lt[64];
367203945Sweongyo
368203945Sweongyo	uint16_t			pg_lofcal;
369203945Sweongyo
370203945Sweongyo	uint16_t			pg_initval;
371203945Sweongyo	uint16_t			pg_ofdmtab_addr;
372203945Sweongyo	unsigned			pg_ofdmtab_dir;
373203945Sweongyo};
374203945Sweongyo
375203945Sweongyo#define	BWN_IMMODE_NONE			0
376203945Sweongyo#define	BWN_IMMODE_NONWLAN		1
377203945Sweongyo#define	BWN_IMMODE_MANUAL		2
378203945Sweongyo#define	BWN_IMMODE_AUTO			3
379203945Sweongyo
380203945Sweongyo#define	BWN_PHYLP_TXPCTL_UNKNOWN	0
381203945Sweongyo#define	BWN_PHYLP_TXPCTL_OFF		1
382203945Sweongyo#define	BWN_PHYLP_TXPCTL_ON_SW		2
383203945Sweongyo#define	BWN_PHYLP_TXPCTL_ON_HW		3
384203945Sweongyo
385203945Sweongyostruct bwn_phy_lp {
386203945Sweongyo	uint8_t				plp_chan;
387203945Sweongyo	uint8_t				plp_chanfullcal;
388203945Sweongyo	int32_t				plp_antenna;
389203945Sweongyo	uint8_t				plp_txpctlmode;
390203945Sweongyo	uint8_t				plp_txisoband_h;
391203945Sweongyo	uint8_t				plp_txisoband_m;
392203945Sweongyo	uint8_t				plp_txisoband_l;
393203945Sweongyo	uint8_t				plp_rxpwroffset;
394203945Sweongyo	int8_t				plp_txpwridx;
395203945Sweongyo	uint16_t			plp_tssiidx;
396203945Sweongyo	uint16_t			plp_tssinpt;
397203945Sweongyo	uint8_t				plp_rssivf;
398203945Sweongyo	uint8_t				plp_rssivc;
399203945Sweongyo	uint8_t				plp_rssigs;
400203945Sweongyo	uint8_t				plp_rccap;
401203945Sweongyo	uint8_t				plp_bxarch;
402203945Sweongyo	uint8_t				plp_crsusr_off;
403203945Sweongyo	uint8_t				plp_crssys_off;
404203945Sweongyo	uint32_t			plp_div;
405203945Sweongyo	int32_t				plp_tonefreq;
406203945Sweongyo	uint16_t			plp_digfilt[9];
407203945Sweongyo};
408203945Sweongyo
409203945Sweongyo/* for LP */
410203945Sweongyostruct bwn_txgain {
411203945Sweongyo	uint16_t			tg_gm;
412203945Sweongyo	uint16_t			tg_pga;
413203945Sweongyo	uint16_t			tg_pad;
414203945Sweongyo	uint16_t			tg_dac;
415203945Sweongyo};
416203945Sweongyo
417203945Sweongyostruct bwn_rxcompco {
418203945Sweongyo	uint8_t				rc_chan;
419203945Sweongyo	int8_t				rc_c1;
420203945Sweongyo	int8_t				rc_c0;
421203945Sweongyo};
422203945Sweongyo
423203945Sweongyostruct bwn_phy_lp_iq_est {
424203945Sweongyo	uint32_t			ie_iqprod;
425203945Sweongyo	uint32_t			ie_ipwr;
426203945Sweongyo	uint32_t			ie_qpwr;
427203945Sweongyo};
428203945Sweongyo
429203945Sweongyostruct bwn_txgain_entry {
430203945Sweongyo	uint8_t				te_gm;
431203945Sweongyo	uint8_t				te_pga;
432203945Sweongyo	uint8_t				te_pad;
433203945Sweongyo	uint8_t				te_dac;
434203945Sweongyo	uint8_t				te_bbmult;
435203945Sweongyo};
436203945Sweongyo
437203945Sweongyo/* only for LP PHY */
438203945Sweongyostruct bwn_stxtable {
439203945Sweongyo	uint16_t			st_phyoffset;
440203945Sweongyo	uint16_t			st_physhift;
441203945Sweongyo	uint16_t			st_rfaddr;
442203945Sweongyo	uint16_t			st_rfshift;
443203945Sweongyo	uint16_t			st_mask;
444203945Sweongyo};
445203945Sweongyo
446203945Sweongyostruct bwn_b206x_chan {
447203945Sweongyo	uint8_t				bc_chan;
448203945Sweongyo	uint16_t			bc_freq;
449203945Sweongyo	const uint8_t			*bc_data;
450203945Sweongyo};
451203945Sweongyo
452203945Sweongyostruct bwn_b206x_rfinit_entry {
453203945Sweongyo	uint16_t			br_offset;
454203945Sweongyo	uint16_t			br_valuea;
455203945Sweongyo	uint16_t			br_valueg;
456203945Sweongyo	uint8_t				br_flags;
457203945Sweongyo};
458203945Sweongyo
459299790Sadrianstruct bwn_phy_n;
460299790Sadrian
461203945Sweongyostruct bwn_phy {
462203945Sweongyo	uint8_t				type;
463203945Sweongyo	uint8_t				rev;
464203945Sweongyo	uint8_t				analog;
465203945Sweongyo
466203945Sweongyo	int				supports_2ghz;
467203945Sweongyo	int				supports_5ghz;
468203945Sweongyo
469203945Sweongyo	int				gmode;
470203945Sweongyo	struct bwn_phy_g		phy_g;
471203945Sweongyo	struct bwn_phy_lp		phy_lp;
472203945Sweongyo
473299790Sadrian	/*
474299790Sadrian	 * I'd like the newer PHY code to not hide in the top-level
475299790Sadrian	 * structs..
476299790Sadrian	 */
477299790Sadrian	struct bwn_phy_n		*phy_n;
478299790Sadrian
479203945Sweongyo	uint16_t			rf_manuf;
480203945Sweongyo	uint16_t			rf_ver;
481203945Sweongyo	uint8_t				rf_rev;
482203945Sweongyo	int				rf_on;
483299790Sadrian	int				phy_do_full_init;
484203945Sweongyo
485203945Sweongyo	int				txpower;
486203945Sweongyo	int				hwpctl;
487203945Sweongyo	unsigned long			nexttime;
488203945Sweongyo	unsigned int			chan;
489203945Sweongyo	int				txerrors;
490203945Sweongyo
491203945Sweongyo	int				(*attach)(struct bwn_mac *);
492203945Sweongyo	void				(*detach)(struct bwn_mac *);
493203945Sweongyo	int				(*prepare_hw)(struct bwn_mac *);
494203945Sweongyo	void				(*init_pre)(struct bwn_mac *);
495203945Sweongyo	int				(*init)(struct bwn_mac *);
496203945Sweongyo	void				(*exit)(struct bwn_mac *);
497203945Sweongyo	uint16_t			(*phy_read)(struct bwn_mac *, uint16_t);
498203945Sweongyo	void				(*phy_write)(struct bwn_mac *, uint16_t,
499203945Sweongyo					    uint16_t);
500203945Sweongyo	void				(*phy_maskset)(struct bwn_mac *,
501203945Sweongyo					    uint16_t, uint16_t, uint16_t);
502203945Sweongyo	uint16_t			(*rf_read)(struct bwn_mac *, uint16_t);
503203945Sweongyo	void				(*rf_write)(struct bwn_mac *, uint16_t,
504203945Sweongyo					    uint16_t);
505203945Sweongyo	int				(*use_hwpctl)(struct bwn_mac *);
506203945Sweongyo	void				(*rf_onoff)(struct bwn_mac *, int);
507203945Sweongyo	void				(*switch_analog)(struct bwn_mac *, int);
508203945Sweongyo	int				(*switch_channel)(struct bwn_mac *,
509203945Sweongyo					    unsigned int);
510203945Sweongyo	uint32_t			(*get_default_chan)(struct bwn_mac *);
511203945Sweongyo	void				(*set_antenna)(struct bwn_mac *, int);
512203945Sweongyo	int				(*set_im)(struct bwn_mac *, int);
513299790Sadrian	bwn_txpwr_result_t		(*recalc_txpwr)(struct bwn_mac *, int);
514203945Sweongyo	void				(*set_txpwr)(struct bwn_mac *);
515203945Sweongyo	void				(*task_15s)(struct bwn_mac *);
516203945Sweongyo	void				(*task_60s)(struct bwn_mac *);
517203945Sweongyo};
518203945Sweongyo
519203945Sweongyostruct bwn_chan_band {
520203945Sweongyo	uint32_t			flags;
521203945Sweongyo	uint8_t				nchan;
522203945Sweongyo#define	BWN_MAX_CHAN_PER_BAND		14
523203945Sweongyo	uint8_t				chan[BWN_MAX_CHAN_PER_BAND];
524203945Sweongyo};
525203945Sweongyo
526203945Sweongyo#define	BWN_NR_WMEPARAMS		16
527203945Sweongyoenum {
528203945Sweongyo	BWN_WMEPARAM_TXOP = 0,
529203945Sweongyo	BWN_WMEPARAM_CWMIN,
530203945Sweongyo	BWN_WMEPARAM_CWMAX,
531203945Sweongyo	BWN_WMEPARAM_CWCUR,
532203945Sweongyo	BWN_WMEPARAM_AIFS,
533203945Sweongyo	BWN_WMEPARAM_BSLOTS,
534203945Sweongyo	BWN_WMEPARAM_REGGAP,
535203945Sweongyo	BWN_WMEPARAM_STATUS,
536203945Sweongyo};
537203945Sweongyo
538203945Sweongyo#define	BWN_WME_PARAMS(queue)	\
539203945Sweongyo	(BWN_SHARED_EDCFQ + (BWN_NR_WMEPARAMS * sizeof(uint16_t) * (queue)))
540203945Sweongyo#define	BWN_WME_BACKGROUND	BWN_WME_PARAMS(0)
541203945Sweongyo#define	BWN_WME_BESTEFFORT	BWN_WME_PARAMS(1)
542203945Sweongyo#define	BWN_WME_VIDEO		BWN_WME_PARAMS(2)
543203945Sweongyo#define	BWN_WME_VOICE		BWN_WME_PARAMS(3)
544203945Sweongyo
545203945Sweongyo/*
546203945Sweongyo * Radio capture format.
547203945Sweongyo */
548203945Sweongyo#define	BWN_RX_RADIOTAP_PRESENT (		\
549203945Sweongyo	(1 << IEEE80211_RADIOTAP_TSFT)		| \
550203945Sweongyo	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
551203945Sweongyo	(1 << IEEE80211_RADIOTAP_RATE)		| \
552203945Sweongyo	(1 << IEEE80211_RADIOTAP_CHANNEL)	| \
553203945Sweongyo	(1 << IEEE80211_RADIOTAP_ANTENNA)	| \
554203945Sweongyo	(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)	| \
555203945Sweongyo	(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)	| \
556203945Sweongyo	0)
557203945Sweongyo
558203945Sweongyostruct bwn_rx_radiotap_header {
559203945Sweongyo	struct ieee80211_radiotap_header wr_ihdr;
560203945Sweongyo	uint64_t			wr_tsf;
561203945Sweongyo	u_int8_t			wr_flags;
562203945Sweongyo	u_int8_t			wr_rate;
563203945Sweongyo	u_int16_t			wr_chan_freq;
564203945Sweongyo	u_int16_t			wr_chan_flags;
565203945Sweongyo	int8_t				wr_antsignal;
566203945Sweongyo	int8_t				wr_antnoise;
567203945Sweongyo	u_int8_t			wr_antenna;
568345636Savos} __packed __aligned(8);
569203945Sweongyo
570203945Sweongyo#define	BWN_TX_RADIOTAP_PRESENT (		\
571203945Sweongyo	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
572203945Sweongyo	(1 << IEEE80211_RADIOTAP_RATE)		| \
573203945Sweongyo	(1 << IEEE80211_RADIOTAP_CHANNEL)	| \
574203945Sweongyo	(1 << IEEE80211_RADIOTAP_DBM_TX_POWER)	| \
575203945Sweongyo	(1 << IEEE80211_RADIOTAP_ANTENNA)	| \
576203945Sweongyo	0)
577203945Sweongyo
578203945Sweongyostruct bwn_tx_radiotap_header {
579203945Sweongyo	struct ieee80211_radiotap_header wt_ihdr;
580203945Sweongyo	u_int8_t			wt_flags;
581203945Sweongyo	u_int8_t			wt_rate;
582203945Sweongyo	u_int16_t			wt_chan_freq;
583203945Sweongyo	u_int16_t			wt_chan_flags;
584203945Sweongyo	u_int8_t			wt_txpower;
585203945Sweongyo	u_int8_t			wt_antenna;
586345636Savos} __packed;
587203945Sweongyo
588203945Sweongyostruct bwn_stats {
589204257Sweongyo	int32_t				rtsfail;
590204257Sweongyo	int32_t				rts;
591203945Sweongyo	int32_t				link_noise;
592203945Sweongyo};
593203945Sweongyo
594203945Sweongyo/* Noise Calculation (Link Quality) */
595203945Sweongyostruct bwn_noise {
596203945Sweongyo	uint8_t				noi_running;
597203945Sweongyo	uint8_t				noi_nsamples;
598203945Sweongyo	int8_t				noi_samples[8][4];
599203945Sweongyo};
600203945Sweongyo
601203945Sweongyo#define	BWN_DMA_30BIT			30
602203945Sweongyo#define	BWN_DMA_32BIT			32
603203945Sweongyo#define	BWN_DMA_64BIT			64
604203945Sweongyo
605203945Sweongyostruct bwn_dmadesc_meta {
606203945Sweongyo	bus_dmamap_t			mt_dmap;
607203945Sweongyo	bus_addr_t			mt_paddr;
608203945Sweongyo	struct mbuf			*mt_m;
609203945Sweongyo	struct ieee80211_node		*mt_ni;
610203945Sweongyo	uint8_t				mt_txtype;
611203945Sweongyo#define	BWN_DMADESC_METATYPE_HEADER	0
612203945Sweongyo#define	BWN_DMADESC_METATYPE_BODY	1
613203945Sweongyo	uint8_t				mt_islast;
614203945Sweongyo};
615203945Sweongyo
616203945Sweongyo#define	BWN_DMAINTR_FATALMASK	\
617203945Sweongyo	((1 << 10) | (1 << 11) | (1 << 12) | (1 << 14) | (1 << 15))
618203945Sweongyo#define	BWN_DMAINTR_NONFATALMASK	(1 << 13)
619203945Sweongyo#define	BWN_DMAINTR_RX_DONE		(1 << 16)
620203945Sweongyo
621203945Sweongyo#define	BWN_DMA32_DCTL_BYTECNT		0x00001fff
622203945Sweongyo#define	BWN_DMA32_DCTL_ADDREXT_MASK	0x00030000
623203945Sweongyo#define	BWN_DMA32_DCTL_ADDREXT_SHIFT	16
624203945Sweongyo#define	BWN_DMA32_DCTL_DTABLEEND	0x10000000
625203945Sweongyo#define	BWN_DMA32_DCTL_IRQ		0x20000000
626203945Sweongyo#define	BWN_DMA32_DCTL_FRAMEEND		0x40000000
627203945Sweongyo#define	BWN_DMA32_DCTL_FRAMESTART	0x80000000
628203945Sweongyostruct bwn_dmadesc32 {
629203945Sweongyo	uint32_t			control;
630203945Sweongyo	uint32_t			address;
631203945Sweongyo} __packed;
632203945Sweongyo
633203945Sweongyo#define	BWN_DMA64_DCTL0_DTABLEEND	0x10000000
634203945Sweongyo#define	BWN_DMA64_DCTL0_IRQ		0x20000000
635203945Sweongyo#define	BWN_DMA64_DCTL0_FRAMEEND	0x40000000
636203945Sweongyo#define	BWN_DMA64_DCTL0_FRAMESTART	0x80000000
637203945Sweongyo#define	BWN_DMA64_DCTL1_BYTECNT		0x00001fff
638203945Sweongyo#define	BWN_DMA64_DCTL1_ADDREXT_MASK	0x00030000
639203945Sweongyo#define	BWN_DMA64_DCTL1_ADDREXT_SHIFT	16
640203945Sweongyostruct bwn_dmadesc64 {
641203945Sweongyo	uint32_t			control0;
642203945Sweongyo	uint32_t			control1;
643203945Sweongyo	uint32_t			address_low;
644203945Sweongyo	uint32_t			address_high;
645203945Sweongyo} __packed;
646203945Sweongyo
647203945Sweongyostruct bwn_dmadesc_generic {
648203945Sweongyo	union {
649203945Sweongyo		struct bwn_dmadesc32 dma32;
650203945Sweongyo		struct bwn_dmadesc64 dma64;
651203945Sweongyo	} __packed dma;
652203945Sweongyo} __packed;
653203945Sweongyo
654203945Sweongyostruct bwn_dma_ring;
655203945Sweongyo
656203945Sweongyostruct bwn_dma_ring {
657203945Sweongyo	struct bwn_mac			*dr_mac;
658203945Sweongyo	const struct bwn_dma_ops	*dr_ops;
659203945Sweongyo	struct bwn_dmadesc_meta		*dr_meta;
660203945Sweongyo	void				*dr_txhdr_cache;
661203945Sweongyo	bus_dma_tag_t			dr_ring_dtag;
662203945Sweongyo	bus_dma_tag_t			dr_txring_dtag;
663203945Sweongyo	bus_dmamap_t			dr_spare_dmap; /* only for RX */
664203945Sweongyo	bus_dmamap_t			dr_ring_dmap;
665203945Sweongyo	bus_addr_t			dr_txring_paddr;
666203945Sweongyo	void				*dr_ring_descbase;
667203945Sweongyo	bus_addr_t			dr_ring_dmabase;
668203945Sweongyo	int				dr_numslots;
669203945Sweongyo	int				dr_usedslot;
670203945Sweongyo	int				dr_curslot;
671203945Sweongyo	uint32_t			dr_frameoffset;
672203945Sweongyo	uint16_t			dr_rx_bufsize;
673203945Sweongyo	uint16_t			dr_base;
674203945Sweongyo	int				dr_index;
675203945Sweongyo	uint8_t				dr_tx;
676203945Sweongyo	uint8_t				dr_stop;
677203945Sweongyo	int				dr_type;
678203945Sweongyo
679203945Sweongyo	void				(*getdesc)(struct bwn_dma_ring *,
680203945Sweongyo					    int, struct bwn_dmadesc_generic **,
681203945Sweongyo					    struct bwn_dmadesc_meta **);
682203945Sweongyo	void				(*setdesc)(struct bwn_dma_ring *,
683203945Sweongyo					    struct bwn_dmadesc_generic *,
684203945Sweongyo					    bus_addr_t, uint16_t, int, int,
685203945Sweongyo					    int);
686203945Sweongyo	void				(*start_transfer)(struct bwn_dma_ring *,
687203945Sweongyo					    int);
688203945Sweongyo	void				(*suspend)(struct bwn_dma_ring *);
689203945Sweongyo	void				(*resume)(struct bwn_dma_ring *);
690203945Sweongyo	int				(*get_curslot)(struct bwn_dma_ring *);
691203945Sweongyo	void				(*set_curslot)(struct bwn_dma_ring *,
692203945Sweongyo					    int);
693203945Sweongyo};
694203945Sweongyo
695203945Sweongyostruct bwn_dma {
696203945Sweongyo	int				dmatype;
697203945Sweongyo	bus_dma_tag_t			parent_dtag;
698203945Sweongyo	bus_dma_tag_t			rxbuf_dtag;
699203945Sweongyo	bus_dma_tag_t			txbuf_dtag;
700203945Sweongyo
701203945Sweongyo	struct bwn_dma_ring		*wme[5];
702203945Sweongyo	struct bwn_dma_ring		*mcast;
703203945Sweongyo	struct bwn_dma_ring		*rx;
704203945Sweongyo	uint64_t			lastseq;	/* XXX FIXME */
705203945Sweongyo};
706203945Sweongyo
707203945Sweongyostruct bwn_pio_rxqueue {
708203945Sweongyo	struct bwn_mac			*prq_mac;
709203945Sweongyo	uint16_t			prq_base;
710203945Sweongyo	uint8_t				prq_rev;
711203945Sweongyo};
712203945Sweongyo
713203945Sweongyostruct bwn_pio_txqueue;
714203945Sweongyostruct bwn_pio_txpkt {
715203945Sweongyo	struct bwn_pio_txqueue		*tp_queue;
716203945Sweongyo	struct ieee80211_node		*tp_ni;
717203945Sweongyo	struct mbuf			*tp_m;
718203945Sweongyo	uint8_t				tp_index;
719203945Sweongyo	TAILQ_ENTRY(bwn_pio_txpkt)	tp_list;
720203945Sweongyo};
721203945Sweongyo
722203945Sweongyo#define	BWN_PIO_MAX_TXPACKETS		32
723203945Sweongyostruct bwn_pio_txqueue {
724203945Sweongyo	uint16_t			tq_base;
725203945Sweongyo	uint16_t			tq_size;
726203945Sweongyo	uint16_t			tq_used;
727203945Sweongyo	uint16_t			tq_free;
728203945Sweongyo	uint8_t				tq_index;
729203945Sweongyo	struct bwn_pio_txpkt		tq_pkts[BWN_PIO_MAX_TXPACKETS];
730203945Sweongyo	TAILQ_HEAD(, bwn_pio_txpkt)	tq_pktlist;
731203945Sweongyo};
732203945Sweongyo
733203945Sweongyostruct bwn_pio {
734203945Sweongyo	struct bwn_pio_txqueue		wme[5];
735203945Sweongyo	struct bwn_pio_txqueue		mcast;
736203945Sweongyo	struct bwn_pio_rxqueue		rx;
737203945Sweongyo};
738203945Sweongyo
739203945Sweongyostruct bwn_plcp4 {
740203945Sweongyo	union {
741203945Sweongyo		uint32_t		data;
742203945Sweongyo		uint8_t			raw[4];
743203945Sweongyo	} __packed o;
744203945Sweongyo} __packed;
745203945Sweongyo
746203945Sweongyostruct bwn_plcp6 {
747203945Sweongyo	union {
748203945Sweongyo		uint32_t		data;
749203945Sweongyo		uint8_t			raw[6];
750203945Sweongyo	} __packed o;
751203945Sweongyo} __packed;
752203945Sweongyo
753203945Sweongyostruct bwn_txhdr {
754203945Sweongyo	uint32_t			macctl;
755203945Sweongyo	uint8_t				macfc[2];
756203945Sweongyo	uint16_t			tx_festime;
757203945Sweongyo	uint16_t			phyctl;
758203945Sweongyo	uint16_t			phyctl_1;
759203945Sweongyo	uint16_t			phyctl_1fb;
760203945Sweongyo	uint16_t			phyctl_1rts;
761203945Sweongyo	uint16_t			phyctl_1rtsfb;
762203945Sweongyo	uint8_t				phyrate;
763203945Sweongyo	uint8_t				phyrate_rts;
764203945Sweongyo	uint8_t				eftypes;	/* extra frame types */
765203945Sweongyo	uint8_t				chan;
766203945Sweongyo	uint8_t				iv[16];
767203945Sweongyo	uint8_t				addr1[IEEE80211_ADDR_LEN];
768203945Sweongyo	uint16_t			tx_festime_fb;
769203945Sweongyo	struct bwn_plcp6		rts_plcp_fb;
770203945Sweongyo	uint16_t			rts_dur_fb;
771203945Sweongyo	struct bwn_plcp6		plcp_fb;
772203945Sweongyo	uint16_t			dur_fb;
773203945Sweongyo	uint16_t			mimo_modelen;
774203945Sweongyo	uint16_t			mimo_ratelen_fb;
775203945Sweongyo	uint32_t			timeout;
776203945Sweongyo
777203945Sweongyo	union {
778203945Sweongyo		/* format <= r351 */
779203945Sweongyo		struct {
780203945Sweongyo			uint8_t		pad0[2];
781203945Sweongyo			uint16_t	cookie;
782203945Sweongyo			uint16_t	tx_status;
783203945Sweongyo			struct bwn_plcp6	rts_plcp;
784203945Sweongyo			uint8_t		rts_frame[16];
785228399Seadler			uint8_t		pad1[2];
786203945Sweongyo			struct bwn_plcp6	plcp;
787300114Sadrian		} __packed r351;
788300114Sadrian		/* format > r410 < r598 */
789203945Sweongyo		struct {
790203945Sweongyo			uint16_t	mimo_antenna;
791203945Sweongyo			uint16_t	preload_size;
792203945Sweongyo			uint8_t		pad0[2];
793203945Sweongyo			uint16_t	cookie;
794203945Sweongyo			uint16_t	tx_status;
795203945Sweongyo			struct bwn_plcp6	rts_plcp;
796203945Sweongyo			uint8_t		rts_frame[16];
797203945Sweongyo			uint8_t		pad1[2];
798203945Sweongyo			struct bwn_plcp6	plcp;
799300114Sadrian		} __packed r410;
800300114Sadrian		struct {
801300114Sadrian			uint16_t	mimo_antenna;
802300114Sadrian			uint16_t	preload_size;
803300114Sadrian			uint8_t		pad0[2];
804300114Sadrian			uint16_t	cookie;
805300114Sadrian			uint16_t	tx_status;
806300114Sadrian			uint16_t	max_n_mpdus;
807300114Sadrian			uint16_t	max_a_bytes_mrt;
808300114Sadrian			uint16_t	max_a_bytes_fbr;
809300114Sadrian			uint16_t	min_m_bytes;
810300114Sadrian			struct bwn_plcp6	rts_plcp;
811300114Sadrian			uint8_t		rts_frame[16];
812300114Sadrian			uint8_t		pad1[2];
813300114Sadrian			struct bwn_plcp6	plcp;
814300114Sadrian		} __packed r598;
815203945Sweongyo	} __packed body;
816203945Sweongyo} __packed;
817203945Sweongyo
818203945Sweongyo#define	BWN_FWTYPE_UCODE		'u'
819203945Sweongyo#define	BWN_FWTYPE_PCM			'p'
820203945Sweongyo#define	BWN_FWTYPE_IV			'i'
821203945Sweongyostruct bwn_fwhdr {
822203945Sweongyo	uint8_t				type;
823203945Sweongyo	uint8_t				ver;
824203945Sweongyo	uint8_t				pad[2];
825203945Sweongyo	uint32_t			size;
826203945Sweongyo} __packed;
827203945Sweongyo
828203945Sweongyo#define	BWN_FWINITVALS_OFFSET_MASK	0x7fff
829203945Sweongyo#define	BWN_FWINITVALS_32BIT		0x8000
830203945Sweongyostruct bwn_fwinitvals {
831203945Sweongyo	uint16_t			offset_size;
832203945Sweongyo	union {
833203945Sweongyo		uint16_t		d16;
834203945Sweongyo		uint32_t		d32;
835203945Sweongyo	} __packed data;
836203945Sweongyo} __packed;
837203945Sweongyo
838299110Sadrianenum bwn_fw_hdr_format {
839299110Sadrian	BWN_FW_HDR_598,
840299110Sadrian	BWN_FW_HDR_410,
841299110Sadrian	BWN_FW_HDR_351,
842299110Sadrian};
843299110Sadrian
844203945Sweongyoenum bwn_fwtype {
845203945Sweongyo	BWN_FWTYPE_DEFAULT,
846203945Sweongyo	BWN_FWTYPE_OPENSOURCE,
847203945Sweongyo	BWN_NR_FWTYPES,
848203945Sweongyo};
849203945Sweongyo
850203945Sweongyostruct bwn_fwfile {
851203945Sweongyo	const char			*filename;
852203945Sweongyo	const struct firmware		*fw;
853203945Sweongyo	enum bwn_fwtype			type;
854203945Sweongyo};
855203945Sweongyo
856203945Sweongyostruct bwn_key {
857203945Sweongyo	void				*keyconf;
858203945Sweongyo	uint8_t				algorithm;
859203945Sweongyo};
860203945Sweongyo
861203945Sweongyostruct bwn_fw {
862203945Sweongyo	struct bwn_fwfile		ucode;
863203945Sweongyo	struct bwn_fwfile		pcm;
864203945Sweongyo	struct bwn_fwfile		initvals;
865203945Sweongyo	struct bwn_fwfile		initvals_band;
866299110Sadrian	enum bwn_fw_hdr_format		fw_hdr_format;
867203945Sweongyo
868203945Sweongyo	uint16_t			rev;
869203945Sweongyo	uint16_t			patch;
870203945Sweongyo	uint8_t				opensource;
871203945Sweongyo	uint8_t				no_pcmfile;
872203945Sweongyo};
873203945Sweongyo
874203945Sweongyostruct bwn_lo_g_sm {
875203945Sweongyo	int				curstate;
876203945Sweongyo	int				nmeasure;
877203945Sweongyo	int				multipler;
878203945Sweongyo	uint16_t			feedth;
879203945Sweongyo	struct bwn_loctl		loctl;
880203945Sweongyo};
881203945Sweongyo
882203945Sweongyostruct bwn_lo_g_value {
883203945Sweongyo	uint8_t				old_channel;
884203945Sweongyo	uint16_t			phy_lomask;
885203945Sweongyo	uint16_t			phy_extg;
886203945Sweongyo	uint16_t			phy_dacctl_hwpctl;
887203945Sweongyo	uint16_t			phy_dacctl;
888203945Sweongyo	uint16_t			phy_hpwr_tssictl;
889203945Sweongyo	uint16_t			phy_analogover;
890203945Sweongyo	uint16_t			phy_analogoverval;
891203945Sweongyo	uint16_t			phy_rfover;
892203945Sweongyo	uint16_t			phy_rfoverval;
893203945Sweongyo	uint16_t			phy_classctl;
894203945Sweongyo	uint16_t			phy_crs0;
895203945Sweongyo	uint16_t			phy_pgactl;
896203945Sweongyo	uint16_t			phy_syncctl;
897203945Sweongyo	uint16_t			phy_cck0;
898203945Sweongyo	uint16_t			phy_cck1;
899203945Sweongyo	uint16_t			phy_cck2;
900203945Sweongyo	uint16_t			phy_cck3;
901203945Sweongyo	uint16_t			phy_cck4;
902203945Sweongyo	uint16_t			reg0;
903203945Sweongyo	uint16_t			reg1;
904203945Sweongyo	uint16_t			rf0;
905203945Sweongyo	uint16_t			rf1;
906203945Sweongyo	uint16_t			rf2;
907203945Sweongyo};
908203945Sweongyo
909203945Sweongyo#define	BWN_LED_MAX			4
910203945Sweongyo
911203945Sweongyo#define	BWN_LED_EVENT_NONE		-1
912203945Sweongyo#define	BWN_LED_EVENT_POLL		0
913203945Sweongyo#define	BWN_LED_EVENT_TX		1
914203945Sweongyo#define	BWN_LED_EVENT_RX		2
915203945Sweongyo#define	BWN_LED_SLOWDOWN(dur)		(dur) = (((dur) * 3) / 2)
916203945Sweongyo
917203945Sweongyostruct bwn_led {
918203945Sweongyo	uint8_t				led_flags;	/* BWN_LED_F_ */
919203945Sweongyo	uint8_t				led_act;	/* BWN_LED_ACT_ */
920203945Sweongyo	uint8_t				led_mask;
921203945Sweongyo};
922203945Sweongyo
923203945Sweongyo#define	BWN_LED_F_ACTLOW		0x1
924203945Sweongyo#define	BWN_LED_F_BLINK			0x2
925203945Sweongyo#define	BWN_LED_F_POLLABLE		0x4
926203945Sweongyo#define	BWN_LED_F_SLOW			0x8
927203945Sweongyo
928203945Sweongyostruct bwn_mac {
929203945Sweongyo	struct bwn_softc		*mac_sc;
930203945Sweongyo	unsigned			mac_status;
931203945Sweongyo#define	BWN_MAC_STATUS_UNINIT		0
932203945Sweongyo#define	BWN_MAC_STATUS_INITED		1
933203945Sweongyo#define	BWN_MAC_STATUS_STARTED		2
934203945Sweongyo	unsigned			mac_flags;
935203945Sweongyo	/* use "Bad Frames Preemption" */
936203945Sweongyo#define	BWN_MAC_FLAG_BADFRAME_PREEMP	(1 << 0)
937203945Sweongyo#define	BWN_MAC_FLAG_DFQVALID		(1 << 1)
938203945Sweongyo#define	BWN_MAC_FLAG_RADIO_ON		(1 << 2)
939203945Sweongyo#define	BWN_MAC_FLAG_DMA		(1 << 3)
940203945Sweongyo#define	BWN_MAC_FLAG_WME		(1 << 4)
941203945Sweongyo#define	BWN_MAC_FLAG_HWCRYPTO		(1 << 5)
942203945Sweongyo
943203945Sweongyo	struct resource_spec		*mac_intr_spec;
944203945Sweongyo#define	BWN_MSI_MESSAGES		1
945203945Sweongyo	struct resource			*mac_res_irq[BWN_MSI_MESSAGES];
946203945Sweongyo	void				*mac_intrhand[BWN_MSI_MESSAGES];
947203945Sweongyo	int				mac_msi;
948203945Sweongyo
949203945Sweongyo	struct bwn_noise		mac_noise;
950203945Sweongyo	struct bwn_phy			mac_phy;
951203945Sweongyo	struct bwn_stats		mac_stats;
952203945Sweongyo	uint32_t			mac_reason_intr;
953203945Sweongyo	uint32_t			mac_reason[6];
954203945Sweongyo	uint32_t			mac_intr_mask;
955203945Sweongyo	int				mac_suspended;
956203945Sweongyo
957203945Sweongyo	struct bwn_fw			mac_fw;
958203945Sweongyo
959203945Sweongyo	union {
960203945Sweongyo		struct bwn_dma		dma;
961203945Sweongyo		struct bwn_pio		pio;
962203945Sweongyo	} mac_method;
963203945Sweongyo
964203945Sweongyo	uint16_t			mac_ktp;	/* Key table pointer */
965203945Sweongyo	uint8_t				mac_max_nr_keys;
966203945Sweongyo	struct bwn_key			mac_key[58];
967203945Sweongyo
968203945Sweongyo	unsigned int			mac_task_state;
969203945Sweongyo	struct task			mac_intrtask;
970203945Sweongyo	struct task			mac_hwreset;
971203945Sweongyo	struct task			mac_txpower;
972203945Sweongyo
973203945Sweongyo	TAILQ_ENTRY(bwn_mac)	mac_list;
974203945Sweongyo};
975203945Sweongyo
976299790Sadrianstatic inline int
977299790Sadrianbwn_tx_hdrsize(struct bwn_mac *mac)
978299790Sadrian{
979299790Sadrian	switch (mac->mac_fw.fw_hdr_format) {
980299790Sadrian	case BWN_FW_HDR_598:
981299790Sadrian		return (112 + (sizeof(struct bwn_plcp6)));
982299790Sadrian	case BWN_FW_HDR_410:
983299790Sadrian		return (104 + (sizeof(struct bwn_plcp6)));
984299790Sadrian	case BWN_FW_HDR_351:
985299790Sadrian		return (100 + (sizeof(struct bwn_plcp6)));
986299790Sadrian	default:
987299790Sadrian		printf("%s: unknown header format (%d)\n", __func__,
988299790Sadrian		    mac->mac_fw.fw_hdr_format);
989299790Sadrian		return (112 + (sizeof(struct bwn_plcp6)));
990299790Sadrian	}
991299790Sadrian}
992299790Sadrian
993203945Sweongyo/*
994203945Sweongyo * Driver-specific vap state.
995203945Sweongyo */
996203945Sweongyostruct bwn_vap {
997203945Sweongyo	struct ieee80211vap		bv_vap;	/* base class */
998203945Sweongyo	int				(*bv_newstate)(struct ieee80211vap *,
999203945Sweongyo					    enum ieee80211_state, int);
1000203945Sweongyo};
1001203945Sweongyo#define	BWN_VAP(vap)			((struct bwn_vap *)(vap))
1002203945Sweongyo#define	BWN_VAP_CONST(vap)		((const struct mwl_vap *)(vap))
1003203945Sweongyo
1004203945Sweongyostruct bwn_softc {
1005203945Sweongyo	device_t			sc_dev;
1006203945Sweongyo	struct mtx			sc_mtx;
1007287197Sglebius	struct ieee80211com		sc_ic;
1008287197Sglebius	struct mbufq			sc_snd;
1009203945Sweongyo	unsigned			sc_flags;
1010203945Sweongyo#define	BWN_FLAG_ATTACHED		(1 << 0)
1011203945Sweongyo#define	BWN_FLAG_INVALID		(1 << 1)
1012203945Sweongyo#define	BWN_FLAG_NEED_BEACON_TP		(1 << 2)
1013287197Sglebius#define	BWN_FLAG_RUNNING		(1 << 3)
1014203945Sweongyo	unsigned			sc_debug;
1015203945Sweongyo
1016203945Sweongyo	struct bwn_mac		*sc_curmac;
1017203945Sweongyo	TAILQ_HEAD(, bwn_mac)	sc_maclist;
1018203945Sweongyo
1019203945Sweongyo	uint8_t				sc_bssid[IEEE80211_ADDR_LEN];
1020203945Sweongyo	unsigned int			sc_filters;
1021203945Sweongyo	uint8_t				sc_beacons[2];
1022203945Sweongyo	uint8_t				sc_rf_enabled;
1023203945Sweongyo
1024203945Sweongyo	struct wmeParams		sc_wmeParams[4];
1025203945Sweongyo
1026203945Sweongyo	struct callout			sc_rfswitch_ch;	/* for laptop */
1027203945Sweongyo	struct callout			sc_task_ch;
1028203945Sweongyo	struct callout			sc_watchdog_ch;
1029203945Sweongyo	int				sc_watchdog_timer;
1030203945Sweongyo	struct taskqueue		*sc_tq;	/* private task queue */
1031203945Sweongyo	int				(*sc_newstate)(struct ieee80211com *,
1032203945Sweongyo					    enum ieee80211_state, int);
1033203945Sweongyo	void				(*sc_node_cleanup)(
1034203945Sweongyo					    struct ieee80211_node *);
1035203945Sweongyo
1036203945Sweongyo	int				sc_rx_rate;
1037203945Sweongyo	int				sc_tx_rate;
1038203945Sweongyo
1039203945Sweongyo	int				sc_led_blinking;
1040203945Sweongyo	int				sc_led_ticks;
1041203945Sweongyo	struct bwn_led			*sc_blink_led;
1042203945Sweongyo	struct callout			sc_led_blink_ch;
1043203945Sweongyo	int				sc_led_blink_offdur;
1044203945Sweongyo	struct bwn_led			sc_leds[BWN_LED_MAX];
1045203945Sweongyo	int				sc_led_idle;
1046203945Sweongyo	int				sc_led_blink;
1047203945Sweongyo
1048203945Sweongyo	struct bwn_tx_radiotap_header	sc_tx_th;
1049203945Sweongyo	struct bwn_rx_radiotap_header	sc_rx_th;
1050203945Sweongyo};
1051203945Sweongyo
1052203945Sweongyo#define	BWN_LOCK_INIT(sc) \
1053203945Sweongyo	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \
1054203945Sweongyo	    MTX_NETWORK_LOCK, MTX_DEF)
1055203945Sweongyo#define	BWN_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
1056203945Sweongyo#define	BWN_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
1057203945Sweongyo#define	BWN_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
1058203945Sweongyo#define	BWN_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)
1059203945Sweongyo
1060299790Sadrianstatic inline bwn_band_t
1061299790Sadrianbwn_channel_band(struct bwn_mac *mac, struct ieee80211_channel *c)
1062299790Sadrian{
1063299790Sadrian	if (IEEE80211_IS_CHAN_5GHZ(c))
1064299790Sadrian		return BWN_BAND_5G;
1065299790Sadrian	/* XXX check 2g, log error if not 2g or 5g? */
1066299790Sadrian	return BWN_BAND_2G;
1067299790Sadrian}
1068299790Sadrian
1069299790Sadrianstatic inline bwn_band_t
1070299790Sadrianbwn_current_band(struct bwn_mac *mac)
1071299790Sadrian{
1072299790Sadrian	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1073299790Sadrian	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
1074299790Sadrian		return BWN_BAND_5G;
1075299790Sadrian	/* XXX check 2g, log error if not 2g or 5g? */
1076299790Sadrian	return BWN_BAND_2G;
1077299790Sadrian}
1078299790Sadrian
1079299790Sadrianstatic inline bool
1080299790Sadrianbwn_is_40mhz(struct bwn_mac *mac)
1081299790Sadrian{
1082299790Sadrian	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1083299790Sadrian
1084299790Sadrian	return !! (IEEE80211_IS_CHAN_HT40(ic->ic_curchan));
1085299790Sadrian}
1086299790Sadrian
1087299790Sadrianstatic inline int
1088299790Sadrianbwn_get_centre_freq(struct bwn_mac *mac)
1089299790Sadrian{
1090299790Sadrian
1091299790Sadrian	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1092299790Sadrian	/* XXX TODO: calculate correctly for HT40 mode */
1093299790Sadrian	return ic->ic_curchan->ic_freq;
1094299790Sadrian}
1095299790Sadrian
1096299790Sadrianstatic inline int
1097299790Sadrianbwn_get_chan_centre_freq(struct bwn_mac *mac, struct ieee80211_channel *chan)
1098299790Sadrian{
1099299790Sadrian
1100299790Sadrian	/* XXX TODO: calculate correctly for HT40 mode */
1101299790Sadrian	return chan->ic_freq;
1102299790Sadrian}
1103299790Sadrian
1104299790Sadrianstatic inline int
1105299790Sadrianbwn_get_chan(struct bwn_mac *mac)
1106299790Sadrian{
1107299790Sadrian
1108299790Sadrian	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1109299790Sadrian	/* XXX TODO: calculate correctly for HT40 mode */
1110299790Sadrian	return ic->ic_curchan->ic_ieee;
1111299790Sadrian}
1112299790Sadrian
1113299790Sadrianstatic inline struct ieee80211_channel *
1114299790Sadrianbwn_get_channel(struct bwn_mac *mac)
1115299790Sadrian{
1116299790Sadrian
1117299790Sadrian	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1118299790Sadrian	return ic->ic_curchan;
1119299790Sadrian}
1120299790Sadrian
1121299790Sadrianstatic inline bool
1122299790Sadrianbwn_is_chan_passive(struct bwn_mac *mac)
1123299790Sadrian{
1124299790Sadrian
1125299790Sadrian	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1126299790Sadrian	return !! IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan);
1127299790Sadrian}
1128299790Sadrian
1129299790Sadrianstatic inline bwn_chan_type_t
1130299790Sadrianbwn_get_chan_type(struct bwn_mac *mac, struct ieee80211_channel *c)
1131299790Sadrian{
1132299790Sadrian	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1133299790Sadrian	if (c == NULL)
1134299790Sadrian		c = ic->ic_curchan;
1135299790Sadrian	if (IEEE80211_IS_CHAN_HT40U(c))
1136299790Sadrian		return BWN_CHAN_TYPE_40_HT_U;
1137299790Sadrian	else if (IEEE80211_IS_CHAN_HT40D(c))
1138299790Sadrian		return BWN_CHAN_TYPE_40_HT_D;
1139299790Sadrian	else if (IEEE80211_IS_CHAN_HT20(c))
1140299790Sadrian		return BWN_CHAN_TYPE_20_HT;
1141299790Sadrian	else
1142299790Sadrian		return BWN_CHAN_TYPE_20;
1143299790Sadrian}
1144299790Sadrian
1145299790Sadrianstatic inline int
1146299790Sadrianbwn_get_chan_power(struct bwn_mac *mac, struct ieee80211_channel *c)
1147299790Sadrian{
1148299790Sadrian
1149299790Sadrian	/* return in dbm */
1150299790Sadrian	return c->ic_maxpower / 2;
1151299790Sadrian}
1152299790Sadrian
1153299790Sadrian/*
1154299790Sadrian * For now there's no bhnd bus support.  Places where it matters
1155299790Sadrian * should call this routine so we can start logging things.
1156299790Sadrian */
1157299790Sadrianstatic inline int
1158299790Sadrianbwn_is_bus_siba(struct bwn_mac *mac)
1159299790Sadrian{
1160299790Sadrian
1161299790Sadrian	return 1;
1162299790Sadrian}
1163203945Sweongyo#endif	/* !_IF_BWNVAR_H */
1164