xref: /freebsd-src/sys/dev/bwn/if_bwnvar.h (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
145d9abdbSWeongyo Jeong /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni  *
445d9abdbSWeongyo Jeong  * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
545d9abdbSWeongyo Jeong  * All rights reserved.
645d9abdbSWeongyo Jeong  *
745d9abdbSWeongyo Jeong  * Redistribution and use in source and binary forms, with or without
845d9abdbSWeongyo Jeong  * modification, are permitted provided that the following conditions
945d9abdbSWeongyo Jeong  * are met:
1045d9abdbSWeongyo Jeong  * 1. Redistributions of source code must retain the above copyright
1145d9abdbSWeongyo Jeong  *    notice, this list of conditions and the following disclaimer,
1245d9abdbSWeongyo Jeong  *    without modification.
1345d9abdbSWeongyo Jeong  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1445d9abdbSWeongyo Jeong  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
1545d9abdbSWeongyo Jeong  *    redistribution must be conditioned upon including a substantially
1645d9abdbSWeongyo Jeong  *    similar Disclaimer requirement for further binary redistribution.
1745d9abdbSWeongyo Jeong  *
1845d9abdbSWeongyo Jeong  * NO WARRANTY
1945d9abdbSWeongyo Jeong  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2045d9abdbSWeongyo Jeong  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2145d9abdbSWeongyo Jeong  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
2245d9abdbSWeongyo Jeong  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
2345d9abdbSWeongyo Jeong  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
2445d9abdbSWeongyo Jeong  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2545d9abdbSWeongyo Jeong  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2645d9abdbSWeongyo Jeong  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2745d9abdbSWeongyo Jeong  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2845d9abdbSWeongyo Jeong  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2945d9abdbSWeongyo Jeong  * THE POSSIBILITY OF SUCH DAMAGES.
3045d9abdbSWeongyo Jeong  */
3145d9abdbSWeongyo Jeong 
3245d9abdbSWeongyo Jeong #ifndef _IF_BWNVAR_H
3345d9abdbSWeongyo Jeong #define	_IF_BWNVAR_H
3445d9abdbSWeongyo Jeong 
35d177c199SLandon J. Fuller #include <dev/bhnd/bhnd.h>
368d14ca9cSLandon J. Fuller 
3745d9abdbSWeongyo Jeong struct bwn_softc;
3845d9abdbSWeongyo Jeong struct bwn_mac;
3945d9abdbSWeongyo Jeong 
4045d9abdbSWeongyo Jeong #define	N(a)			(sizeof(a) / sizeof(a[0]))
4145d9abdbSWeongyo Jeong #define	BWN_ALIGN			0x1000
4245d9abdbSWeongyo Jeong #define	BWN_RETRY_SHORT			7
4345d9abdbSWeongyo Jeong #define	BWN_RETRY_LONG			4
4445d9abdbSWeongyo Jeong #define	BWN_STAID_MAX			64
4545d9abdbSWeongyo Jeong #define	BWN_TXPWR_IGNORE_TIME		(1 << 0)
4645d9abdbSWeongyo Jeong #define	BWN_TXPWR_IGNORE_TSSI		(1 << 1)
4745d9abdbSWeongyo Jeong #define	BWN_HAS_TXMAG(phy)						\
4845d9abdbSWeongyo Jeong 	(((phy)->rev >= 2) && ((phy)->rf_ver == 0x2050) &&		\
4945d9abdbSWeongyo Jeong 	 ((phy)->rf_rev == 8))
5045d9abdbSWeongyo Jeong #define	BWN_HAS_LOOPBACK(phy)						\
5145d9abdbSWeongyo Jeong 	(((phy)->rev > 1) || ((phy)->gmode))
5245d9abdbSWeongyo Jeong #define	BWN_TXERROR_MAX			1000
5345d9abdbSWeongyo Jeong #define	BWN_GETTIME(v)	do {						\
5445d9abdbSWeongyo Jeong 	struct timespec ts;						\
5545d9abdbSWeongyo Jeong 	nanouptime(&ts);						\
5645d9abdbSWeongyo Jeong 	(v) = ts.tv_nsec / 1000000 + ts.tv_sec * 1000;			\
5745d9abdbSWeongyo Jeong } while (0)
5845d9abdbSWeongyo Jeong #define	BWN_ISOLDFMT(mac)		((mac)->mac_fw.rev <= 351)
5945d9abdbSWeongyo Jeong #define	BWN_TSSI2DBM(num, den)						\
6045d9abdbSWeongyo Jeong 	((int32_t)((num < 0) ? num / den : (num + den / 2) / den))
611ea96818SAdrian Chadd #define	BWN_HDRSIZE(mac)	bwn_tx_hdrsize(mac)
62f629a238SAdrian Chadd #define	BWN_MAXTXHDRSIZE	(112 + (sizeof(struct bwn_plcp6)))
631ea96818SAdrian Chadd 
6445d9abdbSWeongyo Jeong #define	BWN_PIO_COOKIE(tq, tp)						\
6545d9abdbSWeongyo Jeong 	((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index))
6645d9abdbSWeongyo Jeong #define	BWN_DMA_COOKIE(dr, slot)					\
6745d9abdbSWeongyo Jeong 	((uint16_t)(((uint16_t)dr->dr_index + 1) << 12) | (uint16_t)slot)
68d177c199SLandon J. Fuller #define	BWN_READ_2(mac, o)						\
69d177c199SLandon J. Fuller 	(bus_read_2((mac)->mac_sc->sc_mem_res, (o)))
70d177c199SLandon J. Fuller #define	BWN_READ_4(mac, o)						\
71d177c199SLandon J. Fuller 	(bus_read_4((mac)->mac_sc->sc_mem_res, (o)))
72b9b64aa5SWeongyo Jeong #define	BWN_WRITE_2(mac, o, v)						\
73d177c199SLandon J. Fuller 	(bus_write_2((mac)->mac_sc->sc_mem_res, (o), (v)))
741ea96818SAdrian Chadd #define	BWN_WRITE_2_F(mac, o, v) do { \
751ea96818SAdrian Chadd 	(BWN_WRITE_2(mac, o, v)); \
761ea96818SAdrian Chadd 	BWN_READ_2(mac, o); \
771ea96818SAdrian Chadd } while(0)
781ea96818SAdrian Chadd #define	BWN_WRITE_SETMASK2(mac, offset, mask, set)			\
791ea96818SAdrian Chadd 	BWN_WRITE_2(mac, offset, (BWN_READ_2(mac, offset) & mask) | set)
80b9b64aa5SWeongyo Jeong #define	BWN_WRITE_4(mac, o, v)						\
81d177c199SLandon J. Fuller 	(bus_write_4((mac)->mac_sc->sc_mem_res, (o), (v)))
821ea96818SAdrian Chadd #define	BWN_WRITE_SETMASK4(mac, offset, mask, set)			\
831ea96818SAdrian Chadd 	BWN_WRITE_4(mac, offset, (BWN_READ_4(mac, offset) & mask) | set)
8445d9abdbSWeongyo Jeong #define	BWN_PIO_TXQOFFSET(mac)						\
85d177c199SLandon J. Fuller 	((bhnd_get_hwrev(mac->mac_sc->sc_dev) >= 11) ? 0x18 : 0)
8645d9abdbSWeongyo Jeong #define	BWN_PIO_RXQOFFSET(mac)						\
87d177c199SLandon J. Fuller 	((bhnd_get_hwrev(mac->mac_sc->sc_dev) >= 11) ? 0x38 : 8)
8845d9abdbSWeongyo Jeong #define	BWN_SEC_NEWAPI(mac)		(mac->mac_fw.rev >= 351)
8945d9abdbSWeongyo Jeong #define	BWN_SEC_KEY2FW(mac, idx)					\
9045d9abdbSWeongyo Jeong 	(BWN_SEC_NEWAPI(mac) ? idx : ((idx >= 4) ? idx - 4 : idx))
9145d9abdbSWeongyo Jeong #define	BWN_RF_READ(mac, r)		(mac->mac_phy.rf_read(mac, r))
9245d9abdbSWeongyo Jeong #define	BWN_RF_WRITE(mac, r, v)		(mac->mac_phy.rf_write(mac, r, v))
9345d9abdbSWeongyo Jeong #define	BWN_RF_MASK(mac, o, m)						\
9445d9abdbSWeongyo Jeong 	BWN_RF_WRITE(mac, o, BWN_RF_READ(mac, o) & m)
9545d9abdbSWeongyo Jeong #define	BWN_RF_SETMASK(mac, offset, mask, set)				\
9645d9abdbSWeongyo Jeong 	BWN_RF_WRITE(mac, offset, (BWN_RF_READ(mac, offset) & mask) | set)
9745d9abdbSWeongyo Jeong #define	BWN_RF_SET(mac, offset, set)					\
9845d9abdbSWeongyo Jeong 	BWN_RF_WRITE(mac, offset, BWN_RF_READ(mac, offset) | set)
9945d9abdbSWeongyo Jeong #define	BWN_PHY_READ(mac, r)		(mac->mac_phy.phy_read(mac, r))
10045d9abdbSWeongyo Jeong #define	BWN_PHY_WRITE(mac, r, v)					\
10145d9abdbSWeongyo Jeong 	(mac->mac_phy.phy_write(mac, r, v))
10245d9abdbSWeongyo Jeong #define	BWN_PHY_SET(mac, offset, set)	do {				\
10345d9abdbSWeongyo Jeong 	if (mac->mac_phy.phy_maskset != NULL) {				\
10445d9abdbSWeongyo Jeong 		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
10545d9abdbSWeongyo Jeong 		    mac->mac_suspended > 0,				\
10645d9abdbSWeongyo Jeong 		    ("dont access PHY or RF registers after turning on MAC")); \
10745d9abdbSWeongyo Jeong 		mac->mac_phy.phy_maskset(mac, offset, 0xffff, set);	\
10845d9abdbSWeongyo Jeong 	} else								\
10945d9abdbSWeongyo Jeong 		BWN_PHY_WRITE(mac, offset,				\
11045d9abdbSWeongyo Jeong 		    BWN_PHY_READ(mac, offset) | (set));			\
11145d9abdbSWeongyo Jeong } while (0)
11245d9abdbSWeongyo Jeong #define	BWN_PHY_SETMASK(mac, offset, mask, set)	do {			\
11345d9abdbSWeongyo Jeong 	if (mac->mac_phy.phy_maskset != NULL) {				\
11445d9abdbSWeongyo Jeong 		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
11545d9abdbSWeongyo Jeong 		    mac->mac_suspended > 0,				\
11645d9abdbSWeongyo Jeong 		    ("dont access PHY or RF registers after turning on MAC")); \
11745d9abdbSWeongyo Jeong 		mac->mac_phy.phy_maskset(mac, offset, mask, set);	\
11845d9abdbSWeongyo Jeong 	} else								\
11945d9abdbSWeongyo Jeong 		BWN_PHY_WRITE(mac, offset,				\
12045d9abdbSWeongyo Jeong 		    (BWN_PHY_READ(mac, offset) & (mask)) | (set));	\
12145d9abdbSWeongyo Jeong } while (0)
12245d9abdbSWeongyo Jeong #define	BWN_PHY_MASK(mac, offset, mask)	do {				\
12345d9abdbSWeongyo Jeong 	if (mac->mac_phy.phy_maskset != NULL) {				\
12445d9abdbSWeongyo Jeong 		KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||	\
12545d9abdbSWeongyo Jeong 		    mac->mac_suspended > 0,				\
12645d9abdbSWeongyo Jeong 		    ("dont access PHY or RF registers after turning on MAC")); \
12745d9abdbSWeongyo Jeong 		mac->mac_phy.phy_maskset(mac, offset, mask, 0);		\
12845d9abdbSWeongyo Jeong 	} else								\
12945d9abdbSWeongyo Jeong 		BWN_PHY_WRITE(mac, offset,				\
1309005a5a0SBrooks Davis 		    BWN_PHY_READ(mac, offset) & (mask));		\
13145d9abdbSWeongyo Jeong } while (0)
13245d9abdbSWeongyo Jeong #define	BWN_PHY_COPY(mac, dst, src)	do {				\
13345d9abdbSWeongyo Jeong 	KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED ||		\
13445d9abdbSWeongyo Jeong 	    mac->mac_suspended > 0,					\
13545d9abdbSWeongyo Jeong 	    ("dont access PHY or RF registers after turning on MAC"));	\
13645d9abdbSWeongyo Jeong 	BWN_PHY_WRITE(mac, dst, BWN_PHY_READ(mac, src));		\
13745d9abdbSWeongyo Jeong } while (0)
13845d9abdbSWeongyo Jeong #define BWN_LO_CALIB_EXPIRE		(1000 * (30 - 2))
13945d9abdbSWeongyo Jeong #define BWN_LO_PWRVEC_EXPIRE		(1000 * (30 - 2))
14045d9abdbSWeongyo Jeong #define BWN_LO_TXCTL_EXPIRE		(1000 * (180 - 4))
14145d9abdbSWeongyo Jeong #define BWN_LPD(L, P, D)		(((L) << 2) | ((P) << 1) | ((D) << 0))
14245d9abdbSWeongyo Jeong #define BWN_BITREV4(tmp)		(BWN_BITREV8(tmp) >> 4)
14345d9abdbSWeongyo Jeong #define	BWN_BITREV8(byte)		(bwn_bitrev_table[byte])
14445d9abdbSWeongyo Jeong #define	BWN_BBATTCMP(a, b)		((a)->att == (b)->att)
14545d9abdbSWeongyo Jeong #define	BWN_RFATTCMP(a, b)						\
14645d9abdbSWeongyo Jeong 	(((a)->att == (b)->att) && ((a)->padmix == (b)->padmix))
14745d9abdbSWeongyo Jeong #define	BWN_PIO_WRITE_2(mac, tq, offset, value)				\
14845d9abdbSWeongyo Jeong 	BWN_WRITE_2(mac, (tq)->tq_base + offset, value)
14945d9abdbSWeongyo Jeong #define	BWN_PIO_READ_4(mac, tq, offset)					\
15045d9abdbSWeongyo Jeong 	BWN_READ_4(mac, tq->tq_base + offset)
15145d9abdbSWeongyo Jeong #define	BWN_ISCCKRATE(rate)						\
15245d9abdbSWeongyo Jeong 	(rate == BWN_CCK_RATE_1MB || rate == BWN_CCK_RATE_2MB ||	\
15345d9abdbSWeongyo Jeong 	 rate == BWN_CCK_RATE_5MB || rate == BWN_CCK_RATE_11MB)
15445d9abdbSWeongyo Jeong #define	BWN_ISOFDMRATE(rate)		(!BWN_ISCCKRATE(rate))
155d177c199SLandon J. Fuller #define	BWN_BARRIER(mac, offset, length, flags)			\
156d177c199SLandon J. Fuller 	bus_barrier((mac)->mac_sc->sc_mem_res, (offset), (length), (flags))
15745d9abdbSWeongyo Jeong #define	BWN_DMA_READ(dr, offset)				\
15845d9abdbSWeongyo Jeong 	(BWN_READ_4(dr->dr_mac, dr->dr_base + offset))
15945d9abdbSWeongyo Jeong #define	BWN_DMA_WRITE(dr, offset, value)			\
16045d9abdbSWeongyo Jeong 	(BWN_WRITE_4(dr->dr_mac, dr->dr_base + offset, value))
16145d9abdbSWeongyo Jeong 
1621ea96818SAdrian Chadd typedef enum {
1631ea96818SAdrian Chadd 	BWN_PHY_BAND_2G = 0,
1641ea96818SAdrian Chadd 	BWN_PHY_BAND_5G_LO = 1,
1651ea96818SAdrian Chadd 	BWN_PHY_BAND_5G_MI = 2,
1661ea96818SAdrian Chadd 	BWN_PHY_BAND_5G_HI = 3
1671ea96818SAdrian Chadd } bwn_phy_band_t;
1681ea96818SAdrian Chadd 
1691ea96818SAdrian Chadd typedef enum {
1701ea96818SAdrian Chadd 	BWN_BAND_2G,
1711ea96818SAdrian Chadd 	BWN_BAND_5G,
1721ea96818SAdrian Chadd } bwn_band_t;
1731ea96818SAdrian Chadd 
1741ea96818SAdrian Chadd typedef enum {
1751ea96818SAdrian Chadd 	BWN_CHAN_TYPE_20,
1761ea96818SAdrian Chadd 	BWN_CHAN_TYPE_20_HT,
1771ea96818SAdrian Chadd 	BWN_CHAN_TYPE_40_HT_U,
1781ea96818SAdrian Chadd 	BWN_CHAN_TYPE_40_HT_D,
1791ea96818SAdrian Chadd } bwn_chan_type_t;
1801ea96818SAdrian Chadd 
18145d9abdbSWeongyo Jeong struct bwn_rate {
18245d9abdbSWeongyo Jeong 	uint16_t			rateid;
18345d9abdbSWeongyo Jeong 	uint32_t			flags;
18445d9abdbSWeongyo Jeong };
18545d9abdbSWeongyo Jeong 
18645d9abdbSWeongyo Jeong #define	BWN_ANT0			0
18745d9abdbSWeongyo Jeong #define	BWN_ANT1			1
18845d9abdbSWeongyo Jeong #define	BWN_ANTAUTO0			2
18945d9abdbSWeongyo Jeong #define	BWN_ANTAUTO1			3
19045d9abdbSWeongyo Jeong #define	BWN_ANT2			4
19145d9abdbSWeongyo Jeong #define	BWN_ANT3			8
19245d9abdbSWeongyo Jeong #define	BWN_ANTAUTO			BWN_ANTAUTO0
19345d9abdbSWeongyo Jeong #define	BWN_ANT_DEFAULT			BWN_ANTAUTO
19445d9abdbSWeongyo Jeong #define	BWN_TX_SLOTS_PER_FRAME		2
19545d9abdbSWeongyo Jeong 
19645d9abdbSWeongyo Jeong struct bwn_channel {
19745d9abdbSWeongyo Jeong 	unsigned			freq;
19845d9abdbSWeongyo Jeong 	unsigned			ieee;
19945d9abdbSWeongyo Jeong 	unsigned			maxTxPow;
20045d9abdbSWeongyo Jeong };
20145d9abdbSWeongyo Jeong 
20245d9abdbSWeongyo Jeong struct bwn_channelinfo {
20345d9abdbSWeongyo Jeong 	struct bwn_channel		channels[IEEE80211_CHAN_MAX];
20445d9abdbSWeongyo Jeong 	unsigned			nchannels;
20545d9abdbSWeongyo Jeong };
20645d9abdbSWeongyo Jeong 
20745d9abdbSWeongyo Jeong struct bwn_bbatt {
20845d9abdbSWeongyo Jeong 	uint8_t				att;
20945d9abdbSWeongyo Jeong };
21045d9abdbSWeongyo Jeong 
21145d9abdbSWeongyo Jeong struct bwn_bbatt_list {
21245d9abdbSWeongyo Jeong 	const struct bwn_bbatt		*array;
21345d9abdbSWeongyo Jeong 	uint8_t				len;
21445d9abdbSWeongyo Jeong 	uint8_t				min;
21545d9abdbSWeongyo Jeong 	uint8_t				max;
21645d9abdbSWeongyo Jeong };
21745d9abdbSWeongyo Jeong 
21845d9abdbSWeongyo Jeong struct bwn_rfatt {
21945d9abdbSWeongyo Jeong 	uint8_t				att;
22045d9abdbSWeongyo Jeong 	int				padmix;
22145d9abdbSWeongyo Jeong };
22245d9abdbSWeongyo Jeong 
22345d9abdbSWeongyo Jeong struct bwn_rfatt_list {
22445d9abdbSWeongyo Jeong 	const struct bwn_rfatt		*array;
22545d9abdbSWeongyo Jeong 	uint8_t				len;
22645d9abdbSWeongyo Jeong 	uint8_t				min;
22745d9abdbSWeongyo Jeong 	uint8_t				max;
22845d9abdbSWeongyo Jeong };
22945d9abdbSWeongyo Jeong 
23045d9abdbSWeongyo Jeong #define	BWN_DC_LT_SIZE			32
23145d9abdbSWeongyo Jeong 
23245d9abdbSWeongyo Jeong struct bwn_loctl {
23345d9abdbSWeongyo Jeong 	int8_t				i;
23445d9abdbSWeongyo Jeong 	int8_t				q;
23545d9abdbSWeongyo Jeong };
23645d9abdbSWeongyo Jeong 
2371ea96818SAdrian Chadd typedef enum {
2381ea96818SAdrian Chadd 	BWN_TXPWR_RES_NEED_ADJUST,
2391ea96818SAdrian Chadd 	BWN_TXPWR_RES_DONE,
2401ea96818SAdrian Chadd } bwn_txpwr_result_t;
2411ea96818SAdrian Chadd 
24245d9abdbSWeongyo Jeong struct bwn_lo_calib {
24345d9abdbSWeongyo Jeong 	struct bwn_bbatt		bbatt;
24445d9abdbSWeongyo Jeong 	struct bwn_rfatt		rfatt;
24545d9abdbSWeongyo Jeong 	struct bwn_loctl		ctl;
24645d9abdbSWeongyo Jeong 	unsigned long			calib_time;
24745d9abdbSWeongyo Jeong 	TAILQ_ENTRY(bwn_lo_calib)	list;
24845d9abdbSWeongyo Jeong };
24945d9abdbSWeongyo Jeong 
25045d9abdbSWeongyo Jeong struct bwn_rxhdr4 {
25145d9abdbSWeongyo Jeong 	uint16_t			frame_len;
25245d9abdbSWeongyo Jeong 	uint8_t				pad1[2];
25345d9abdbSWeongyo Jeong 	uint16_t			phy_status0;
25445d9abdbSWeongyo Jeong 	union {
25545d9abdbSWeongyo Jeong 		struct {
25645d9abdbSWeongyo Jeong 			uint8_t		rssi;
25745d9abdbSWeongyo Jeong 			uint8_t		sig_qual;
25845d9abdbSWeongyo Jeong 		} __packed abg;
25945d9abdbSWeongyo Jeong 		struct {
26045d9abdbSWeongyo Jeong 			int8_t		power0;
26145d9abdbSWeongyo Jeong 			int8_t		power1;
26245d9abdbSWeongyo Jeong 		} __packed n;
26345d9abdbSWeongyo Jeong 	} __packed phy;
2641ea96818SAdrian Chadd 	union {
2651ea96818SAdrian Chadd 		struct {
2661ea96818SAdrian Chadd 			int8_t		power2;
2671ea96818SAdrian Chadd 			uint8_t		pad;
2681ea96818SAdrian Chadd 		} __packed n;
2691ea96818SAdrian Chadd 		struct {
2701ea96818SAdrian Chadd 			uint8_t		pad;
2711ea96818SAdrian Chadd 			int8_t		ht_power0;
2721ea96818SAdrian Chadd 		} __packed ht;
27345d9abdbSWeongyo Jeong 		uint16_t		phy_status2;
2741ea96818SAdrian Chadd 	} __packed ps2;
275a74bf020SAdrian Chadd 	union {
276a74bf020SAdrian Chadd 		struct {
27745d9abdbSWeongyo Jeong 			uint16_t	phy_status3;
278a74bf020SAdrian Chadd 		} __packed lp;
279a74bf020SAdrian Chadd 		struct {
280a74bf020SAdrian Chadd 			int8_t		phy_ht_power1;
281a74bf020SAdrian Chadd 			int8_t		phy_ht_power2;
282a74bf020SAdrian Chadd 		} __packed ht;
283a74bf020SAdrian Chadd 	} __packed ps3;
284a74bf020SAdrian Chadd 	union {
285a74bf020SAdrian Chadd 		struct {
28645d9abdbSWeongyo Jeong 			uint32_t	mac_status;
28745d9abdbSWeongyo Jeong 			uint16_t	mac_time;
28845d9abdbSWeongyo Jeong 			uint16_t	channel;
289a74bf020SAdrian Chadd 		} __packed r351;
290a74bf020SAdrian Chadd 		struct {
291a74bf020SAdrian Chadd 			uint16_t	phy_status4;
292a74bf020SAdrian Chadd 			uint16_t	phy_status5;
293a74bf020SAdrian Chadd 			uint32_t	mac_status;
294a74bf020SAdrian Chadd 			uint16_t	mac_time;
295a74bf020SAdrian Chadd 			uint16_t	channel;
296a74bf020SAdrian Chadd 		} __packed r598;
297a74bf020SAdrian Chadd 	} __packed ps4;
29845d9abdbSWeongyo Jeong } __packed;
29945d9abdbSWeongyo Jeong 
30045d9abdbSWeongyo Jeong struct bwn_txstatus {
30145d9abdbSWeongyo Jeong 	uint16_t			cookie;
30245d9abdbSWeongyo Jeong 	uint16_t			seq;
30345d9abdbSWeongyo Jeong 	uint8_t				phy_stat;
30445d9abdbSWeongyo Jeong 	uint8_t				framecnt;
30545d9abdbSWeongyo Jeong 	uint8_t				rtscnt;
30645d9abdbSWeongyo Jeong 	uint8_t				sreason;
30745d9abdbSWeongyo Jeong 	uint8_t				pm;
30845d9abdbSWeongyo Jeong 	uint8_t				im;
30945d9abdbSWeongyo Jeong 	uint8_t				ampdu;
31045d9abdbSWeongyo Jeong 	uint8_t				ack;
31145d9abdbSWeongyo Jeong };
31245d9abdbSWeongyo Jeong 
31345d9abdbSWeongyo Jeong #define	BWN_TXCTL_PA3DB			0x40
31445d9abdbSWeongyo Jeong #define	BWN_TXCTL_PA2DB			0x20
31545d9abdbSWeongyo Jeong #define	BWN_TXCTL_TXMIX			0x10
31645d9abdbSWeongyo Jeong 
31745d9abdbSWeongyo Jeong struct bwn_txpwr_loctl {
31845d9abdbSWeongyo Jeong 	struct bwn_rfatt_list		rfatt;
31945d9abdbSWeongyo Jeong 	struct bwn_bbatt_list		bbatt;
32045d9abdbSWeongyo Jeong 	uint16_t			dc_lt[BWN_DC_LT_SIZE];
32145d9abdbSWeongyo Jeong 	TAILQ_HEAD(, bwn_lo_calib)	calib_list;
32245d9abdbSWeongyo Jeong 	unsigned long			pwr_vec_read_time;
32345d9abdbSWeongyo Jeong 	unsigned long			txctl_measured_time;
32445d9abdbSWeongyo Jeong 	uint8_t				tx_bias;
32545d9abdbSWeongyo Jeong 	uint8_t				tx_magn;
32645d9abdbSWeongyo Jeong 	uint64_t			power_vector;
32745d9abdbSWeongyo Jeong };
32845d9abdbSWeongyo Jeong 
32945d9abdbSWeongyo Jeong #define	BWN_OFDMTAB_DIR_UNKNOWN		0
33045d9abdbSWeongyo Jeong #define	BWN_OFDMTAB_DIR_READ		1
33145d9abdbSWeongyo Jeong #define	BWN_OFDMTAB_DIR_WRITE		2
33245d9abdbSWeongyo Jeong 
33345d9abdbSWeongyo Jeong struct bwn_phy_g {
33445d9abdbSWeongyo Jeong 	unsigned			pg_flags;
33545d9abdbSWeongyo Jeong #define	BWN_PHY_G_FLAG_TSSITABLE_ALLOC	(1 << 0)
33645d9abdbSWeongyo Jeong #define	BWN_PHY_G_FLAG_RADIOCTX_VALID	(1 << 1)
33745d9abdbSWeongyo Jeong 	int				pg_aci_enable;
33845d9abdbSWeongyo Jeong 	int				pg_aci_wlan_automatic;
33945d9abdbSWeongyo Jeong 	int				pg_aci_hw_rssi;
34045d9abdbSWeongyo Jeong 	int				pg_rf_on;
34145d9abdbSWeongyo Jeong 	uint16_t			pg_radioctx_over;
34245d9abdbSWeongyo Jeong 	uint16_t			pg_radioctx_overval;
34345d9abdbSWeongyo Jeong 	uint16_t			pg_minlowsig[2];
34445d9abdbSWeongyo Jeong 	uint16_t			pg_minlowsigpos[2];
345d177c199SLandon J. Fuller 	uint16_t			pg_pa0maxpwr;
34645d9abdbSWeongyo Jeong 	int8_t				*pg_tssi2dbm;
34745d9abdbSWeongyo Jeong 	int				pg_idletssi;
34845d9abdbSWeongyo Jeong 	int				pg_curtssi;
34945d9abdbSWeongyo Jeong 	uint8_t				pg_avgtssi;
35045d9abdbSWeongyo Jeong 	struct bwn_bbatt		pg_bbatt;
35145d9abdbSWeongyo Jeong 	struct bwn_rfatt		pg_rfatt;
35245d9abdbSWeongyo Jeong 	uint8_t				pg_txctl;
35345d9abdbSWeongyo Jeong 	int				pg_bbatt_delta;
35445d9abdbSWeongyo Jeong 	int				pg_rfatt_delta;
35545d9abdbSWeongyo Jeong 
35645d9abdbSWeongyo Jeong 	struct bwn_txpwr_loctl		pg_loctl;
35745d9abdbSWeongyo Jeong 	int16_t				pg_max_lb_gain;
35845d9abdbSWeongyo Jeong 	int16_t				pg_trsw_rx_gain;
35945d9abdbSWeongyo Jeong 	int16_t				pg_lna_lod_gain;
36045d9abdbSWeongyo Jeong 	int16_t				pg_lna_gain;
36145d9abdbSWeongyo Jeong 	int16_t				pg_pga_gain;
36245d9abdbSWeongyo Jeong 	int				pg_immode;
36345d9abdbSWeongyo Jeong #define	BWN_INTERFSTACK_SIZE	26
36445d9abdbSWeongyo Jeong 	uint32_t			pg_interfstack[BWN_INTERFSTACK_SIZE];
36545d9abdbSWeongyo Jeong 
36645d9abdbSWeongyo Jeong 	int16_t				pg_nrssi[2];
36745d9abdbSWeongyo Jeong 	int32_t				pg_nrssi_slope;
36845d9abdbSWeongyo Jeong 	int8_t				pg_nrssi_lt[64];
36945d9abdbSWeongyo Jeong 
37045d9abdbSWeongyo Jeong 	uint16_t			pg_lofcal;
37145d9abdbSWeongyo Jeong 
37245d9abdbSWeongyo Jeong 	uint16_t			pg_initval;
37345d9abdbSWeongyo Jeong 	uint16_t			pg_ofdmtab_addr;
37445d9abdbSWeongyo Jeong 	unsigned			pg_ofdmtab_dir;
37545d9abdbSWeongyo Jeong };
37645d9abdbSWeongyo Jeong 
37745d9abdbSWeongyo Jeong #define	BWN_IMMODE_NONE			0
37845d9abdbSWeongyo Jeong #define	BWN_IMMODE_NONWLAN		1
37945d9abdbSWeongyo Jeong #define	BWN_IMMODE_MANUAL		2
38045d9abdbSWeongyo Jeong #define	BWN_IMMODE_AUTO			3
38145d9abdbSWeongyo Jeong 
38245d9abdbSWeongyo Jeong #define	BWN_PHYLP_TXPCTL_UNKNOWN	0
38345d9abdbSWeongyo Jeong #define	BWN_PHYLP_TXPCTL_OFF		1
38445d9abdbSWeongyo Jeong #define	BWN_PHYLP_TXPCTL_ON_SW		2
38545d9abdbSWeongyo Jeong #define	BWN_PHYLP_TXPCTL_ON_HW		3
38645d9abdbSWeongyo Jeong 
38745d9abdbSWeongyo Jeong struct bwn_phy_lp {
38845d9abdbSWeongyo Jeong 	uint8_t				plp_chan;
38945d9abdbSWeongyo Jeong 	uint8_t				plp_chanfullcal;
39045d9abdbSWeongyo Jeong 	int32_t				plp_antenna;
39145d9abdbSWeongyo Jeong 	uint8_t				plp_txpctlmode;
39245d9abdbSWeongyo Jeong 	uint8_t				plp_txisoband_h;
39345d9abdbSWeongyo Jeong 	uint8_t				plp_txisoband_m;
39445d9abdbSWeongyo Jeong 	uint8_t				plp_txisoband_l;
39545d9abdbSWeongyo Jeong 	uint8_t				plp_rxpwroffset;
39645d9abdbSWeongyo Jeong 	int8_t				plp_txpwridx;
39745d9abdbSWeongyo Jeong 	uint16_t			plp_tssiidx;
39845d9abdbSWeongyo Jeong 	uint16_t			plp_tssinpt;
39945d9abdbSWeongyo Jeong 	uint8_t				plp_rssivf;
40045d9abdbSWeongyo Jeong 	uint8_t				plp_rssivc;
40145d9abdbSWeongyo Jeong 	uint8_t				plp_rssigs;
40245d9abdbSWeongyo Jeong 	uint8_t				plp_rccap;
40345d9abdbSWeongyo Jeong 	uint8_t				plp_bxarch;
40445d9abdbSWeongyo Jeong 	uint8_t				plp_crsusr_off;
40545d9abdbSWeongyo Jeong 	uint8_t				plp_crssys_off;
40645d9abdbSWeongyo Jeong 	uint32_t			plp_div;
40745d9abdbSWeongyo Jeong 	int32_t				plp_tonefreq;
40845d9abdbSWeongyo Jeong 	uint16_t			plp_digfilt[9];
40945d9abdbSWeongyo Jeong };
41045d9abdbSWeongyo Jeong 
41145d9abdbSWeongyo Jeong /* for LP */
41245d9abdbSWeongyo Jeong struct bwn_txgain {
41345d9abdbSWeongyo Jeong 	uint16_t			tg_gm;
41445d9abdbSWeongyo Jeong 	uint16_t			tg_pga;
41545d9abdbSWeongyo Jeong 	uint16_t			tg_pad;
41645d9abdbSWeongyo Jeong 	uint16_t			tg_dac;
41745d9abdbSWeongyo Jeong };
41845d9abdbSWeongyo Jeong 
41945d9abdbSWeongyo Jeong struct bwn_rxcompco {
42045d9abdbSWeongyo Jeong 	uint8_t				rc_chan;
42145d9abdbSWeongyo Jeong 	int8_t				rc_c1;
42245d9abdbSWeongyo Jeong 	int8_t				rc_c0;
42345d9abdbSWeongyo Jeong };
42445d9abdbSWeongyo Jeong 
42545d9abdbSWeongyo Jeong struct bwn_phy_lp_iq_est {
42645d9abdbSWeongyo Jeong 	uint32_t			ie_iqprod;
42745d9abdbSWeongyo Jeong 	uint32_t			ie_ipwr;
42845d9abdbSWeongyo Jeong 	uint32_t			ie_qpwr;
42945d9abdbSWeongyo Jeong };
43045d9abdbSWeongyo Jeong 
43145d9abdbSWeongyo Jeong struct bwn_txgain_entry {
43245d9abdbSWeongyo Jeong 	uint8_t				te_gm;
43345d9abdbSWeongyo Jeong 	uint8_t				te_pga;
43445d9abdbSWeongyo Jeong 	uint8_t				te_pad;
43545d9abdbSWeongyo Jeong 	uint8_t				te_dac;
43645d9abdbSWeongyo Jeong 	uint8_t				te_bbmult;
43745d9abdbSWeongyo Jeong };
43845d9abdbSWeongyo Jeong 
43945d9abdbSWeongyo Jeong /* only for LP PHY */
44045d9abdbSWeongyo Jeong struct bwn_stxtable {
44145d9abdbSWeongyo Jeong 	uint16_t			st_phyoffset;
44245d9abdbSWeongyo Jeong 	uint16_t			st_physhift;
44345d9abdbSWeongyo Jeong 	uint16_t			st_rfaddr;
44445d9abdbSWeongyo Jeong 	uint16_t			st_rfshift;
44545d9abdbSWeongyo Jeong 	uint16_t			st_mask;
44645d9abdbSWeongyo Jeong };
44745d9abdbSWeongyo Jeong 
44845d9abdbSWeongyo Jeong struct bwn_b206x_chan {
44945d9abdbSWeongyo Jeong 	uint8_t				bc_chan;
45045d9abdbSWeongyo Jeong 	uint16_t			bc_freq;
45145d9abdbSWeongyo Jeong 	const uint8_t			*bc_data;
45245d9abdbSWeongyo Jeong };
45345d9abdbSWeongyo Jeong 
45445d9abdbSWeongyo Jeong struct bwn_b206x_rfinit_entry {
45545d9abdbSWeongyo Jeong 	uint16_t			br_offset;
45645d9abdbSWeongyo Jeong 	uint16_t			br_valuea;
45745d9abdbSWeongyo Jeong 	uint16_t			br_valueg;
45845d9abdbSWeongyo Jeong 	uint8_t				br_flags;
45945d9abdbSWeongyo Jeong };
46045d9abdbSWeongyo Jeong 
4611ea96818SAdrian Chadd struct bwn_phy_n;
4621ea96818SAdrian Chadd 
46345d9abdbSWeongyo Jeong struct bwn_phy {
46445d9abdbSWeongyo Jeong 	uint8_t				type;
46545d9abdbSWeongyo Jeong 	uint8_t				rev;
46645d9abdbSWeongyo Jeong 	uint8_t				analog;
46745d9abdbSWeongyo Jeong 
46845d9abdbSWeongyo Jeong 	int				supports_2ghz;
46945d9abdbSWeongyo Jeong 	int				supports_5ghz;
47045d9abdbSWeongyo Jeong 
47145d9abdbSWeongyo Jeong 	int				gmode;
47245d9abdbSWeongyo Jeong 	struct bwn_phy_g		phy_g;
47345d9abdbSWeongyo Jeong 	struct bwn_phy_lp		phy_lp;
47445d9abdbSWeongyo Jeong 
4751ea96818SAdrian Chadd 	/*
4761ea96818SAdrian Chadd 	 * I'd like the newer PHY code to not hide in the top-level
4771ea96818SAdrian Chadd 	 * structs..
4781ea96818SAdrian Chadd 	 */
4791ea96818SAdrian Chadd 	struct bwn_phy_n		*phy_n;
4801ea96818SAdrian Chadd 
48145d9abdbSWeongyo Jeong 	uint16_t			rf_manuf;
48245d9abdbSWeongyo Jeong 	uint16_t			rf_ver;
48345d9abdbSWeongyo Jeong 	uint8_t				rf_rev;
48445d9abdbSWeongyo Jeong 	int				rf_on;
4851ea96818SAdrian Chadd 	int				phy_do_full_init;
48645d9abdbSWeongyo Jeong 
48745d9abdbSWeongyo Jeong 	int				txpower;
48845d9abdbSWeongyo Jeong 	int				hwpctl;
48945d9abdbSWeongyo Jeong 	unsigned long			nexttime;
49045d9abdbSWeongyo Jeong 	unsigned int			chan;
49145d9abdbSWeongyo Jeong 	int				txerrors;
49245d9abdbSWeongyo Jeong 
49345d9abdbSWeongyo Jeong 	int				(*attach)(struct bwn_mac *);
49445d9abdbSWeongyo Jeong 	void				(*detach)(struct bwn_mac *);
49545d9abdbSWeongyo Jeong 	int				(*prepare_hw)(struct bwn_mac *);
49645d9abdbSWeongyo Jeong 	void				(*init_pre)(struct bwn_mac *);
49745d9abdbSWeongyo Jeong 	int				(*init)(struct bwn_mac *);
49845d9abdbSWeongyo Jeong 	void				(*exit)(struct bwn_mac *);
49945d9abdbSWeongyo Jeong 	uint16_t			(*phy_read)(struct bwn_mac *, uint16_t);
50045d9abdbSWeongyo Jeong 	void				(*phy_write)(struct bwn_mac *, uint16_t,
50145d9abdbSWeongyo Jeong 					    uint16_t);
50245d9abdbSWeongyo Jeong 	void				(*phy_maskset)(struct bwn_mac *,
50345d9abdbSWeongyo Jeong 					    uint16_t, uint16_t, uint16_t);
50445d9abdbSWeongyo Jeong 	uint16_t			(*rf_read)(struct bwn_mac *, uint16_t);
50545d9abdbSWeongyo Jeong 	void				(*rf_write)(struct bwn_mac *, uint16_t,
50645d9abdbSWeongyo Jeong 					    uint16_t);
50745d9abdbSWeongyo Jeong 	int				(*use_hwpctl)(struct bwn_mac *);
50845d9abdbSWeongyo Jeong 	void				(*rf_onoff)(struct bwn_mac *, int);
50945d9abdbSWeongyo Jeong 	void				(*switch_analog)(struct bwn_mac *, int);
51045d9abdbSWeongyo Jeong 	int				(*switch_channel)(struct bwn_mac *,
51145d9abdbSWeongyo Jeong 					    unsigned int);
51245d9abdbSWeongyo Jeong 	uint32_t			(*get_default_chan)(struct bwn_mac *);
51345d9abdbSWeongyo Jeong 	void				(*set_antenna)(struct bwn_mac *, int);
51445d9abdbSWeongyo Jeong 	int				(*set_im)(struct bwn_mac *, int);
5151ea96818SAdrian Chadd 	bwn_txpwr_result_t		(*recalc_txpwr)(struct bwn_mac *, int);
51645d9abdbSWeongyo Jeong 	void				(*set_txpwr)(struct bwn_mac *);
51745d9abdbSWeongyo Jeong 	void				(*task_15s)(struct bwn_mac *);
51845d9abdbSWeongyo Jeong 	void				(*task_60s)(struct bwn_mac *);
51945d9abdbSWeongyo Jeong };
52045d9abdbSWeongyo Jeong 
52145d9abdbSWeongyo Jeong struct bwn_chan_band {
52245d9abdbSWeongyo Jeong 	uint32_t			flags;
52345d9abdbSWeongyo Jeong 	uint8_t				nchan;
52445d9abdbSWeongyo Jeong #define	BWN_MAX_CHAN_PER_BAND		14
52545d9abdbSWeongyo Jeong 	uint8_t				chan[BWN_MAX_CHAN_PER_BAND];
52645d9abdbSWeongyo Jeong };
52745d9abdbSWeongyo Jeong 
52845d9abdbSWeongyo Jeong #define	BWN_NR_WMEPARAMS		16
52945d9abdbSWeongyo Jeong enum {
53045d9abdbSWeongyo Jeong 	BWN_WMEPARAM_TXOP = 0,
53145d9abdbSWeongyo Jeong 	BWN_WMEPARAM_CWMIN,
53245d9abdbSWeongyo Jeong 	BWN_WMEPARAM_CWMAX,
53345d9abdbSWeongyo Jeong 	BWN_WMEPARAM_CWCUR,
53445d9abdbSWeongyo Jeong 	BWN_WMEPARAM_AIFS,
53545d9abdbSWeongyo Jeong 	BWN_WMEPARAM_BSLOTS,
53645d9abdbSWeongyo Jeong 	BWN_WMEPARAM_REGGAP,
53745d9abdbSWeongyo Jeong 	BWN_WMEPARAM_STATUS,
53845d9abdbSWeongyo Jeong };
53945d9abdbSWeongyo Jeong 
54045d9abdbSWeongyo Jeong #define	BWN_WME_PARAMS(queue)	\
54145d9abdbSWeongyo Jeong 	(BWN_SHARED_EDCFQ + (BWN_NR_WMEPARAMS * sizeof(uint16_t) * (queue)))
54245d9abdbSWeongyo Jeong #define	BWN_WME_BACKGROUND	BWN_WME_PARAMS(0)
54345d9abdbSWeongyo Jeong #define	BWN_WME_BESTEFFORT	BWN_WME_PARAMS(1)
54445d9abdbSWeongyo Jeong #define	BWN_WME_VIDEO		BWN_WME_PARAMS(2)
54545d9abdbSWeongyo Jeong #define	BWN_WME_VOICE		BWN_WME_PARAMS(3)
54645d9abdbSWeongyo Jeong 
54745d9abdbSWeongyo Jeong /*
54845d9abdbSWeongyo Jeong  * Radio capture format.
54945d9abdbSWeongyo Jeong  */
55045d9abdbSWeongyo Jeong #define	BWN_RX_RADIOTAP_PRESENT (		\
55145d9abdbSWeongyo Jeong 	(1 << IEEE80211_RADIOTAP_TSFT)		| \
55245d9abdbSWeongyo Jeong 	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
55345d9abdbSWeongyo Jeong 	(1 << IEEE80211_RADIOTAP_RATE)		| \
55445d9abdbSWeongyo Jeong 	(1 << IEEE80211_RADIOTAP_CHANNEL)	| \
55545d9abdbSWeongyo Jeong 	(1 << IEEE80211_RADIOTAP_ANTENNA)	| \
55645d9abdbSWeongyo Jeong 	(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)	| \
55745d9abdbSWeongyo Jeong 	(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)	| \
55845d9abdbSWeongyo Jeong 	0)
55945d9abdbSWeongyo Jeong 
56045d9abdbSWeongyo Jeong struct bwn_rx_radiotap_header {
56145d9abdbSWeongyo Jeong 	struct ieee80211_radiotap_header wr_ihdr;
56245d9abdbSWeongyo Jeong 	uint64_t			wr_tsf;
56345d9abdbSWeongyo Jeong 	u_int8_t			wr_flags;
56445d9abdbSWeongyo Jeong 	u_int8_t			wr_rate;
56545d9abdbSWeongyo Jeong 	u_int16_t			wr_chan_freq;
56645d9abdbSWeongyo Jeong 	u_int16_t			wr_chan_flags;
56745d9abdbSWeongyo Jeong 	int8_t				wr_antsignal;
56845d9abdbSWeongyo Jeong 	int8_t				wr_antnoise;
56945d9abdbSWeongyo Jeong 	u_int8_t			wr_antenna;
570786ac703SAndriy Voskoboinyk } __packed __aligned(8);
57145d9abdbSWeongyo Jeong 
57245d9abdbSWeongyo Jeong #define	BWN_TX_RADIOTAP_PRESENT (		\
57345d9abdbSWeongyo Jeong 	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
57445d9abdbSWeongyo Jeong 	(1 << IEEE80211_RADIOTAP_RATE)		| \
57545d9abdbSWeongyo Jeong 	(1 << IEEE80211_RADIOTAP_CHANNEL)	| \
57645d9abdbSWeongyo Jeong 	(1 << IEEE80211_RADIOTAP_DBM_TX_POWER)	| \
57745d9abdbSWeongyo Jeong 	(1 << IEEE80211_RADIOTAP_ANTENNA)	| \
57845d9abdbSWeongyo Jeong 	0)
57945d9abdbSWeongyo Jeong 
58045d9abdbSWeongyo Jeong struct bwn_tx_radiotap_header {
58145d9abdbSWeongyo Jeong 	struct ieee80211_radiotap_header wt_ihdr;
58245d9abdbSWeongyo Jeong 	u_int8_t			wt_flags;
58345d9abdbSWeongyo Jeong 	u_int8_t			wt_rate;
58445d9abdbSWeongyo Jeong 	u_int16_t			wt_chan_freq;
58545d9abdbSWeongyo Jeong 	u_int16_t			wt_chan_flags;
58645d9abdbSWeongyo Jeong 	u_int8_t			wt_txpower;
58745d9abdbSWeongyo Jeong 	u_int8_t			wt_antenna;
588786ac703SAndriy Voskoboinyk } __packed;
58945d9abdbSWeongyo Jeong 
59045d9abdbSWeongyo Jeong struct bwn_stats {
591d2ee7771SWeongyo Jeong 	int32_t				rtsfail;
592d2ee7771SWeongyo Jeong 	int32_t				rts;
59345d9abdbSWeongyo Jeong 	int32_t				link_noise;
59445d9abdbSWeongyo Jeong };
59545d9abdbSWeongyo Jeong 
59645d9abdbSWeongyo Jeong /* Noise Calculation (Link Quality) */
59745d9abdbSWeongyo Jeong struct bwn_noise {
59845d9abdbSWeongyo Jeong 	uint8_t				noi_running;
59945d9abdbSWeongyo Jeong 	uint8_t				noi_nsamples;
60045d9abdbSWeongyo Jeong 	int8_t				noi_samples[8][4];
60145d9abdbSWeongyo Jeong };
60245d9abdbSWeongyo Jeong 
60345d9abdbSWeongyo Jeong struct bwn_dmadesc_meta {
60445d9abdbSWeongyo Jeong 	bus_dmamap_t			mt_dmap;
60545d9abdbSWeongyo Jeong 	bus_addr_t			mt_paddr;
60645d9abdbSWeongyo Jeong 	struct mbuf			*mt_m;
60745d9abdbSWeongyo Jeong 	struct ieee80211_node		*mt_ni;
60845d9abdbSWeongyo Jeong 	uint8_t				mt_txtype;
60945d9abdbSWeongyo Jeong #define	BWN_DMADESC_METATYPE_HEADER	0
61045d9abdbSWeongyo Jeong #define	BWN_DMADESC_METATYPE_BODY	1
61145d9abdbSWeongyo Jeong 	uint8_t				mt_islast;
61245d9abdbSWeongyo Jeong };
61345d9abdbSWeongyo Jeong 
61445d9abdbSWeongyo Jeong #define	BWN_DMAINTR_FATALMASK	\
61545d9abdbSWeongyo Jeong 	((1 << 10) | (1 << 11) | (1 << 12) | (1 << 14) | (1 << 15))
61645d9abdbSWeongyo Jeong #define	BWN_DMAINTR_NONFATALMASK	(1 << 13)
61745d9abdbSWeongyo Jeong #define	BWN_DMAINTR_RX_DONE		(1 << 16)
61845d9abdbSWeongyo Jeong 
61945d9abdbSWeongyo Jeong #define	BWN_DMA32_DCTL_BYTECNT		0x00001fff
62045d9abdbSWeongyo Jeong #define	BWN_DMA32_DCTL_ADDREXT_MASK	0x00030000
62145d9abdbSWeongyo Jeong #define	BWN_DMA32_DCTL_ADDREXT_SHIFT	16
62245d9abdbSWeongyo Jeong #define	BWN_DMA32_DCTL_DTABLEEND	0x10000000
62345d9abdbSWeongyo Jeong #define	BWN_DMA32_DCTL_IRQ		0x20000000
62445d9abdbSWeongyo Jeong #define	BWN_DMA32_DCTL_FRAMEEND		0x40000000
62545d9abdbSWeongyo Jeong #define	BWN_DMA32_DCTL_FRAMESTART	0x80000000
62645d9abdbSWeongyo Jeong struct bwn_dmadesc32 {
62745d9abdbSWeongyo Jeong 	uint32_t			control;
62845d9abdbSWeongyo Jeong 	uint32_t			address;
62945d9abdbSWeongyo Jeong } __packed;
63045d9abdbSWeongyo Jeong 
63145d9abdbSWeongyo Jeong #define	BWN_DMA64_DCTL0_DTABLEEND	0x10000000
63245d9abdbSWeongyo Jeong #define	BWN_DMA64_DCTL0_IRQ		0x20000000
63345d9abdbSWeongyo Jeong #define	BWN_DMA64_DCTL0_FRAMEEND	0x40000000
63445d9abdbSWeongyo Jeong #define	BWN_DMA64_DCTL0_FRAMESTART	0x80000000
63545d9abdbSWeongyo Jeong #define	BWN_DMA64_DCTL1_BYTECNT		0x00001fff
63645d9abdbSWeongyo Jeong #define	BWN_DMA64_DCTL1_ADDREXT_MASK	0x00030000
63745d9abdbSWeongyo Jeong #define	BWN_DMA64_DCTL1_ADDREXT_SHIFT	16
63845d9abdbSWeongyo Jeong struct bwn_dmadesc64 {
63945d9abdbSWeongyo Jeong 	uint32_t			control0;
64045d9abdbSWeongyo Jeong 	uint32_t			control1;
64145d9abdbSWeongyo Jeong 	uint32_t			address_low;
64245d9abdbSWeongyo Jeong 	uint32_t			address_high;
64345d9abdbSWeongyo Jeong } __packed;
64445d9abdbSWeongyo Jeong 
64545d9abdbSWeongyo Jeong struct bwn_dmadesc_generic {
64645d9abdbSWeongyo Jeong 	union {
64745d9abdbSWeongyo Jeong 		struct bwn_dmadesc32 dma32;
64845d9abdbSWeongyo Jeong 		struct bwn_dmadesc64 dma64;
64945d9abdbSWeongyo Jeong 	} __packed dma;
65045d9abdbSWeongyo Jeong } __packed;
65145d9abdbSWeongyo Jeong 
65245d9abdbSWeongyo Jeong struct bwn_dma_ring;
65345d9abdbSWeongyo Jeong 
65445d9abdbSWeongyo Jeong struct bwn_dma_ring {
65545d9abdbSWeongyo Jeong 	struct bwn_mac			*dr_mac;
65645d9abdbSWeongyo Jeong 	const struct bwn_dma_ops	*dr_ops;
65745d9abdbSWeongyo Jeong 	struct bwn_dmadesc_meta		*dr_meta;
65845d9abdbSWeongyo Jeong 	void				*dr_txhdr_cache;
65945d9abdbSWeongyo Jeong 	bus_dma_tag_t			dr_ring_dtag;
66045d9abdbSWeongyo Jeong 	bus_dma_tag_t			dr_txring_dtag;
66145d9abdbSWeongyo Jeong 	bus_dmamap_t			dr_spare_dmap; /* only for RX */
66245d9abdbSWeongyo Jeong 	bus_dmamap_t			dr_ring_dmap;
66345d9abdbSWeongyo Jeong 	bus_addr_t			dr_txring_paddr;
66445d9abdbSWeongyo Jeong 	void				*dr_ring_descbase;
66545d9abdbSWeongyo Jeong 	bus_addr_t			dr_ring_dmabase;
66645d9abdbSWeongyo Jeong 	int				dr_numslots;
66745d9abdbSWeongyo Jeong 	int				dr_usedslot;
66845d9abdbSWeongyo Jeong 	int				dr_curslot;
66945d9abdbSWeongyo Jeong 	uint32_t			dr_frameoffset;
67045d9abdbSWeongyo Jeong 	uint16_t			dr_rx_bufsize;
67145d9abdbSWeongyo Jeong 	uint16_t			dr_base;
67245d9abdbSWeongyo Jeong 	int				dr_index;
67345d9abdbSWeongyo Jeong 	uint8_t				dr_tx;
67445d9abdbSWeongyo Jeong 	uint8_t				dr_stop;
67545d9abdbSWeongyo Jeong 	int				dr_type;
67645d9abdbSWeongyo Jeong 
67745d9abdbSWeongyo Jeong 	void				(*getdesc)(struct bwn_dma_ring *,
67845d9abdbSWeongyo Jeong 					    int, struct bwn_dmadesc_generic **,
67945d9abdbSWeongyo Jeong 					    struct bwn_dmadesc_meta **);
68045d9abdbSWeongyo Jeong 	void				(*setdesc)(struct bwn_dma_ring *,
68145d9abdbSWeongyo Jeong 					    struct bwn_dmadesc_generic *,
68245d9abdbSWeongyo Jeong 					    bus_addr_t, uint16_t, int, int,
68345d9abdbSWeongyo Jeong 					    int);
68445d9abdbSWeongyo Jeong 	void				(*start_transfer)(struct bwn_dma_ring *,
68545d9abdbSWeongyo Jeong 					    int);
68645d9abdbSWeongyo Jeong 	void				(*suspend)(struct bwn_dma_ring *);
68745d9abdbSWeongyo Jeong 	void				(*resume)(struct bwn_dma_ring *);
68845d9abdbSWeongyo Jeong 	int				(*get_curslot)(struct bwn_dma_ring *);
68945d9abdbSWeongyo Jeong 	void				(*set_curslot)(struct bwn_dma_ring *,
69045d9abdbSWeongyo Jeong 					    int);
69145d9abdbSWeongyo Jeong };
69245d9abdbSWeongyo Jeong 
69345d9abdbSWeongyo Jeong struct bwn_dma {
69445d9abdbSWeongyo Jeong 	bus_dma_tag_t			parent_dtag;
69545d9abdbSWeongyo Jeong 	bus_dma_tag_t			rxbuf_dtag;
69645d9abdbSWeongyo Jeong 	bus_dma_tag_t			txbuf_dtag;
697d177c199SLandon J. Fuller 	struct bhnd_dma_translation	translation;
698d177c199SLandon J. Fuller 	u_int				addrext_shift;
69945d9abdbSWeongyo Jeong 
70045d9abdbSWeongyo Jeong 	struct bwn_dma_ring		*wme[5];
70145d9abdbSWeongyo Jeong 	struct bwn_dma_ring		*mcast;
70245d9abdbSWeongyo Jeong 	struct bwn_dma_ring		*rx;
70345d9abdbSWeongyo Jeong 	uint64_t			lastseq;	/* XXX FIXME */
70445d9abdbSWeongyo Jeong };
70545d9abdbSWeongyo Jeong 
70645d9abdbSWeongyo Jeong struct bwn_pio_rxqueue {
70745d9abdbSWeongyo Jeong 	struct bwn_mac			*prq_mac;
70845d9abdbSWeongyo Jeong 	uint16_t			prq_base;
70945d9abdbSWeongyo Jeong 	uint8_t				prq_rev;
71045d9abdbSWeongyo Jeong };
71145d9abdbSWeongyo Jeong 
71245d9abdbSWeongyo Jeong struct bwn_pio_txqueue;
71345d9abdbSWeongyo Jeong struct bwn_pio_txpkt {
71445d9abdbSWeongyo Jeong 	struct bwn_pio_txqueue		*tp_queue;
71545d9abdbSWeongyo Jeong 	struct ieee80211_node		*tp_ni;
71645d9abdbSWeongyo Jeong 	struct mbuf			*tp_m;
71745d9abdbSWeongyo Jeong 	uint8_t				tp_index;
71845d9abdbSWeongyo Jeong 	TAILQ_ENTRY(bwn_pio_txpkt)	tp_list;
71945d9abdbSWeongyo Jeong };
72045d9abdbSWeongyo Jeong 
72145d9abdbSWeongyo Jeong #define	BWN_PIO_MAX_TXPACKETS		32
72245d9abdbSWeongyo Jeong struct bwn_pio_txqueue {
72345d9abdbSWeongyo Jeong 	uint16_t			tq_base;
72445d9abdbSWeongyo Jeong 	uint16_t			tq_size;
72545d9abdbSWeongyo Jeong 	uint16_t			tq_used;
72645d9abdbSWeongyo Jeong 	uint16_t			tq_free;
72745d9abdbSWeongyo Jeong 	uint8_t				tq_index;
72845d9abdbSWeongyo Jeong 	struct bwn_pio_txpkt		tq_pkts[BWN_PIO_MAX_TXPACKETS];
72945d9abdbSWeongyo Jeong 	TAILQ_HEAD(, bwn_pio_txpkt)	tq_pktlist;
73045d9abdbSWeongyo Jeong };
73145d9abdbSWeongyo Jeong 
73245d9abdbSWeongyo Jeong struct bwn_pio {
73345d9abdbSWeongyo Jeong 	struct bwn_pio_txqueue		wme[5];
73445d9abdbSWeongyo Jeong 	struct bwn_pio_txqueue		mcast;
73545d9abdbSWeongyo Jeong 	struct bwn_pio_rxqueue		rx;
73645d9abdbSWeongyo Jeong };
73745d9abdbSWeongyo Jeong 
73845d9abdbSWeongyo Jeong struct bwn_plcp4 {
73945d9abdbSWeongyo Jeong 	union {
74045d9abdbSWeongyo Jeong 		uint32_t		data;
74145d9abdbSWeongyo Jeong 		uint8_t			raw[4];
74245d9abdbSWeongyo Jeong 	} __packed o;
74345d9abdbSWeongyo Jeong } __packed;
74445d9abdbSWeongyo Jeong 
74545d9abdbSWeongyo Jeong struct bwn_plcp6 {
74645d9abdbSWeongyo Jeong 	union {
74745d9abdbSWeongyo Jeong 		uint32_t		data;
74845d9abdbSWeongyo Jeong 		uint8_t			raw[6];
74945d9abdbSWeongyo Jeong 	} __packed o;
75045d9abdbSWeongyo Jeong } __packed;
75145d9abdbSWeongyo Jeong 
75245d9abdbSWeongyo Jeong struct bwn_txhdr {
75345d9abdbSWeongyo Jeong 	uint32_t			macctl;
75445d9abdbSWeongyo Jeong 	uint8_t				macfc[2];
75545d9abdbSWeongyo Jeong 	uint16_t			tx_festime;
75645d9abdbSWeongyo Jeong 	uint16_t			phyctl;
75745d9abdbSWeongyo Jeong 	uint16_t			phyctl_1;
75845d9abdbSWeongyo Jeong 	uint16_t			phyctl_1fb;
75945d9abdbSWeongyo Jeong 	uint16_t			phyctl_1rts;
76045d9abdbSWeongyo Jeong 	uint16_t			phyctl_1rtsfb;
76145d9abdbSWeongyo Jeong 	uint8_t				phyrate;
76245d9abdbSWeongyo Jeong 	uint8_t				phyrate_rts;
76345d9abdbSWeongyo Jeong 	uint8_t				eftypes;	/* extra frame types */
76445d9abdbSWeongyo Jeong 	uint8_t				chan;
76545d9abdbSWeongyo Jeong 	uint8_t				iv[16];
76645d9abdbSWeongyo Jeong 	uint8_t				addr1[IEEE80211_ADDR_LEN];
76745d9abdbSWeongyo Jeong 	uint16_t			tx_festime_fb;
76845d9abdbSWeongyo Jeong 	struct bwn_plcp6		rts_plcp_fb;
76945d9abdbSWeongyo Jeong 	uint16_t			rts_dur_fb;
77045d9abdbSWeongyo Jeong 	struct bwn_plcp6		plcp_fb;
77145d9abdbSWeongyo Jeong 	uint16_t			dur_fb;
77245d9abdbSWeongyo Jeong 	uint16_t			mimo_modelen;
77345d9abdbSWeongyo Jeong 	uint16_t			mimo_ratelen_fb;
77445d9abdbSWeongyo Jeong 	uint32_t			timeout;
77545d9abdbSWeongyo Jeong 
77645d9abdbSWeongyo Jeong 	union {
77745d9abdbSWeongyo Jeong 		/* format <= r351 */
77845d9abdbSWeongyo Jeong 		struct {
77945d9abdbSWeongyo Jeong 			uint8_t		pad0[2];
78045d9abdbSWeongyo Jeong 			uint16_t	cookie;
78145d9abdbSWeongyo Jeong 			uint16_t	tx_status;
78245d9abdbSWeongyo Jeong 			struct bwn_plcp6	rts_plcp;
78345d9abdbSWeongyo Jeong 			uint8_t		rts_frame[16];
784a506169aSEitan Adler 			uint8_t		pad1[2];
78545d9abdbSWeongyo Jeong 			struct bwn_plcp6	plcp;
786a74bf020SAdrian Chadd 		} __packed r351;
787a74bf020SAdrian Chadd 		/* format > r410 < r598 */
78845d9abdbSWeongyo Jeong 		struct {
78945d9abdbSWeongyo Jeong 			uint16_t	mimo_antenna;
79045d9abdbSWeongyo Jeong 			uint16_t	preload_size;
79145d9abdbSWeongyo Jeong 			uint8_t		pad0[2];
79245d9abdbSWeongyo Jeong 			uint16_t	cookie;
79345d9abdbSWeongyo Jeong 			uint16_t	tx_status;
79445d9abdbSWeongyo Jeong 			struct bwn_plcp6	rts_plcp;
79545d9abdbSWeongyo Jeong 			uint8_t		rts_frame[16];
79645d9abdbSWeongyo Jeong 			uint8_t		pad1[2];
79745d9abdbSWeongyo Jeong 			struct bwn_plcp6	plcp;
798a74bf020SAdrian Chadd 		} __packed r410;
799a74bf020SAdrian Chadd 		struct {
800a74bf020SAdrian Chadd 			uint16_t	mimo_antenna;
801a74bf020SAdrian Chadd 			uint16_t	preload_size;
802a74bf020SAdrian Chadd 			uint8_t		pad0[2];
803a74bf020SAdrian Chadd 			uint16_t	cookie;
804a74bf020SAdrian Chadd 			uint16_t	tx_status;
805a74bf020SAdrian Chadd 			uint16_t	max_n_mpdus;
806a74bf020SAdrian Chadd 			uint16_t	max_a_bytes_mrt;
807a74bf020SAdrian Chadd 			uint16_t	max_a_bytes_fbr;
808a74bf020SAdrian Chadd 			uint16_t	min_m_bytes;
809a74bf020SAdrian Chadd 			struct bwn_plcp6	rts_plcp;
810a74bf020SAdrian Chadd 			uint8_t		rts_frame[16];
811a74bf020SAdrian Chadd 			uint8_t		pad1[2];
812a74bf020SAdrian Chadd 			struct bwn_plcp6	plcp;
813a74bf020SAdrian Chadd 		} __packed r598;
81445d9abdbSWeongyo Jeong 	} __packed body;
81545d9abdbSWeongyo Jeong } __packed;
81645d9abdbSWeongyo Jeong 
81745d9abdbSWeongyo Jeong #define	BWN_FWTYPE_UCODE		'u'
81845d9abdbSWeongyo Jeong #define	BWN_FWTYPE_PCM			'p'
81945d9abdbSWeongyo Jeong #define	BWN_FWTYPE_IV			'i'
82045d9abdbSWeongyo Jeong struct bwn_fwhdr {
82145d9abdbSWeongyo Jeong 	uint8_t				type;
82245d9abdbSWeongyo Jeong 	uint8_t				ver;
82345d9abdbSWeongyo Jeong 	uint8_t				pad[2];
82445d9abdbSWeongyo Jeong 	uint32_t			size;
82545d9abdbSWeongyo Jeong } __packed;
82645d9abdbSWeongyo Jeong 
82745d9abdbSWeongyo Jeong #define	BWN_FWINITVALS_OFFSET_MASK	0x7fff
82845d9abdbSWeongyo Jeong #define	BWN_FWINITVALS_32BIT		0x8000
82945d9abdbSWeongyo Jeong struct bwn_fwinitvals {
83045d9abdbSWeongyo Jeong 	uint16_t			offset_size;
83145d9abdbSWeongyo Jeong 	union {
83245d9abdbSWeongyo Jeong 		uint16_t		d16;
83345d9abdbSWeongyo Jeong 		uint32_t		d32;
83445d9abdbSWeongyo Jeong 	} __packed data;
83545d9abdbSWeongyo Jeong } __packed;
83645d9abdbSWeongyo Jeong 
837af4ae173SAdrian Chadd enum bwn_fw_hdr_format {
838af4ae173SAdrian Chadd 	BWN_FW_HDR_598,
839af4ae173SAdrian Chadd 	BWN_FW_HDR_410,
840af4ae173SAdrian Chadd 	BWN_FW_HDR_351,
841af4ae173SAdrian Chadd };
842af4ae173SAdrian Chadd 
84345d9abdbSWeongyo Jeong enum bwn_fwtype {
84445d9abdbSWeongyo Jeong 	BWN_FWTYPE_DEFAULT,
84545d9abdbSWeongyo Jeong 	BWN_FWTYPE_OPENSOURCE,
84645d9abdbSWeongyo Jeong 	BWN_NR_FWTYPES,
84745d9abdbSWeongyo Jeong };
84845d9abdbSWeongyo Jeong 
84945d9abdbSWeongyo Jeong struct bwn_fwfile {
85045d9abdbSWeongyo Jeong 	const char			*filename;
85145d9abdbSWeongyo Jeong 	const struct firmware		*fw;
85245d9abdbSWeongyo Jeong 	enum bwn_fwtype			type;
85345d9abdbSWeongyo Jeong };
85445d9abdbSWeongyo Jeong 
85545d9abdbSWeongyo Jeong struct bwn_key {
85645d9abdbSWeongyo Jeong 	void				*keyconf;
85745d9abdbSWeongyo Jeong 	uint8_t				algorithm;
85845d9abdbSWeongyo Jeong };
85945d9abdbSWeongyo Jeong 
86045d9abdbSWeongyo Jeong struct bwn_fw {
86145d9abdbSWeongyo Jeong 	struct bwn_fwfile		ucode;
86245d9abdbSWeongyo Jeong 	struct bwn_fwfile		pcm;
86345d9abdbSWeongyo Jeong 	struct bwn_fwfile		initvals;
86445d9abdbSWeongyo Jeong 	struct bwn_fwfile		initvals_band;
865af4ae173SAdrian Chadd 	enum bwn_fw_hdr_format		fw_hdr_format;
86645d9abdbSWeongyo Jeong 
86745d9abdbSWeongyo Jeong 	uint16_t			rev;
86845d9abdbSWeongyo Jeong 	uint16_t			patch;
86945d9abdbSWeongyo Jeong 	uint8_t				opensource;
87045d9abdbSWeongyo Jeong 	uint8_t				no_pcmfile;
87145d9abdbSWeongyo Jeong };
87245d9abdbSWeongyo Jeong 
87345d9abdbSWeongyo Jeong struct bwn_lo_g_sm {
87445d9abdbSWeongyo Jeong 	int				curstate;
87545d9abdbSWeongyo Jeong 	int				nmeasure;
87645d9abdbSWeongyo Jeong 	int				multipler;
87745d9abdbSWeongyo Jeong 	uint16_t			feedth;
87845d9abdbSWeongyo Jeong 	struct bwn_loctl		loctl;
87945d9abdbSWeongyo Jeong };
88045d9abdbSWeongyo Jeong 
88145d9abdbSWeongyo Jeong struct bwn_lo_g_value {
88245d9abdbSWeongyo Jeong 	uint8_t				old_channel;
88345d9abdbSWeongyo Jeong 	uint16_t			phy_lomask;
88445d9abdbSWeongyo Jeong 	uint16_t			phy_extg;
88545d9abdbSWeongyo Jeong 	uint16_t			phy_dacctl_hwpctl;
88645d9abdbSWeongyo Jeong 	uint16_t			phy_dacctl;
88745d9abdbSWeongyo Jeong 	uint16_t			phy_hpwr_tssictl;
88845d9abdbSWeongyo Jeong 	uint16_t			phy_analogover;
88945d9abdbSWeongyo Jeong 	uint16_t			phy_analogoverval;
89045d9abdbSWeongyo Jeong 	uint16_t			phy_rfover;
89145d9abdbSWeongyo Jeong 	uint16_t			phy_rfoverval;
89245d9abdbSWeongyo Jeong 	uint16_t			phy_classctl;
89345d9abdbSWeongyo Jeong 	uint16_t			phy_crs0;
89445d9abdbSWeongyo Jeong 	uint16_t			phy_pgactl;
89545d9abdbSWeongyo Jeong 	uint16_t			phy_syncctl;
89645d9abdbSWeongyo Jeong 	uint16_t			phy_cck0;
89745d9abdbSWeongyo Jeong 	uint16_t			phy_cck1;
89845d9abdbSWeongyo Jeong 	uint16_t			phy_cck2;
89945d9abdbSWeongyo Jeong 	uint16_t			phy_cck3;
90045d9abdbSWeongyo Jeong 	uint16_t			phy_cck4;
90145d9abdbSWeongyo Jeong 	uint16_t			reg0;
90245d9abdbSWeongyo Jeong 	uint16_t			reg1;
90345d9abdbSWeongyo Jeong 	uint16_t			rf0;
90445d9abdbSWeongyo Jeong 	uint16_t			rf1;
90545d9abdbSWeongyo Jeong 	uint16_t			rf2;
90645d9abdbSWeongyo Jeong };
90745d9abdbSWeongyo Jeong 
90845d9abdbSWeongyo Jeong #define	BWN_LED_MAX			4
90945d9abdbSWeongyo Jeong 
91045d9abdbSWeongyo Jeong #define	BWN_LED_EVENT_NONE		-1
91145d9abdbSWeongyo Jeong #define	BWN_LED_EVENT_POLL		0
91245d9abdbSWeongyo Jeong #define	BWN_LED_EVENT_TX		1
91345d9abdbSWeongyo Jeong #define	BWN_LED_EVENT_RX		2
91445d9abdbSWeongyo Jeong #define	BWN_LED_SLOWDOWN(dur)		(dur) = (((dur) * 3) / 2)
91545d9abdbSWeongyo Jeong 
91645d9abdbSWeongyo Jeong struct bwn_led {
91745d9abdbSWeongyo Jeong 	uint8_t				led_flags;	/* BWN_LED_F_ */
91845d9abdbSWeongyo Jeong 	uint8_t				led_act;	/* BWN_LED_ACT_ */
91945d9abdbSWeongyo Jeong 	uint8_t				led_mask;
92045d9abdbSWeongyo Jeong };
92145d9abdbSWeongyo Jeong 
92245d9abdbSWeongyo Jeong #define	BWN_LED_F_ACTLOW		0x1
92345d9abdbSWeongyo Jeong #define	BWN_LED_F_BLINK			0x2
92445d9abdbSWeongyo Jeong #define	BWN_LED_F_POLLABLE		0x4
92545d9abdbSWeongyo Jeong #define	BWN_LED_F_SLOW			0x8
92645d9abdbSWeongyo Jeong 
92745d9abdbSWeongyo Jeong struct bwn_mac {
92845d9abdbSWeongyo Jeong 	struct bwn_softc		*mac_sc;
92945d9abdbSWeongyo Jeong 	unsigned			mac_status;
93045d9abdbSWeongyo Jeong #define	BWN_MAC_STATUS_UNINIT		0
93145d9abdbSWeongyo Jeong #define	BWN_MAC_STATUS_INITED		1
93245d9abdbSWeongyo Jeong #define	BWN_MAC_STATUS_STARTED		2
93345d9abdbSWeongyo Jeong 	unsigned			mac_flags;
93445d9abdbSWeongyo Jeong 	/* use "Bad Frames Preemption" */
93545d9abdbSWeongyo Jeong #define	BWN_MAC_FLAG_BADFRAME_PREEMP	(1 << 0)
93645d9abdbSWeongyo Jeong #define	BWN_MAC_FLAG_DFQVALID		(1 << 1)
93745d9abdbSWeongyo Jeong #define	BWN_MAC_FLAG_RADIO_ON		(1 << 2)
93845d9abdbSWeongyo Jeong #define	BWN_MAC_FLAG_DMA		(1 << 3)
93945d9abdbSWeongyo Jeong #define	BWN_MAC_FLAG_WME		(1 << 4)
94045d9abdbSWeongyo Jeong #define	BWN_MAC_FLAG_HWCRYPTO		(1 << 5)
94145d9abdbSWeongyo Jeong 
942d177c199SLandon J. Fuller 	struct resource			*mac_res_irq;
943d177c199SLandon J. Fuller 	int				 mac_rid_irq;
944d177c199SLandon J. Fuller 	void				*mac_intrhand;
94545d9abdbSWeongyo Jeong 
94645d9abdbSWeongyo Jeong 	struct bwn_noise		mac_noise;
94745d9abdbSWeongyo Jeong 	struct bwn_phy			mac_phy;
94845d9abdbSWeongyo Jeong 	struct bwn_stats		mac_stats;
94945d9abdbSWeongyo Jeong 	uint32_t			mac_reason_intr;
95045d9abdbSWeongyo Jeong 	uint32_t			mac_reason[6];
95145d9abdbSWeongyo Jeong 	uint32_t			mac_intr_mask;
95245d9abdbSWeongyo Jeong 	int				mac_suspended;
95345d9abdbSWeongyo Jeong 
95445d9abdbSWeongyo Jeong 	struct bwn_fw			mac_fw;
95545d9abdbSWeongyo Jeong 
956d177c199SLandon J. Fuller 	int				mac_dmatype;
95745d9abdbSWeongyo Jeong 	union {
95845d9abdbSWeongyo Jeong 		struct bwn_dma		dma;
95945d9abdbSWeongyo Jeong 		struct bwn_pio		pio;
96045d9abdbSWeongyo Jeong 	} mac_method;
96145d9abdbSWeongyo Jeong 
96245d9abdbSWeongyo Jeong 	uint16_t			mac_ktp;	/* Key table pointer */
96345d9abdbSWeongyo Jeong 	uint8_t				mac_max_nr_keys;
96445d9abdbSWeongyo Jeong 	struct bwn_key			mac_key[58];
96545d9abdbSWeongyo Jeong 
96645d9abdbSWeongyo Jeong 	unsigned int			mac_task_state;
96745d9abdbSWeongyo Jeong 	struct task			mac_intrtask;
96845d9abdbSWeongyo Jeong 	struct task			mac_hwreset;
96945d9abdbSWeongyo Jeong 	struct task			mac_txpower;
97045d9abdbSWeongyo Jeong 
97145d9abdbSWeongyo Jeong 	TAILQ_ENTRY(bwn_mac)	mac_list;
97245d9abdbSWeongyo Jeong };
97345d9abdbSWeongyo Jeong 
9741ea96818SAdrian Chadd static inline int
bwn_tx_hdrsize(struct bwn_mac * mac)9751ea96818SAdrian Chadd bwn_tx_hdrsize(struct bwn_mac *mac)
9761ea96818SAdrian Chadd {
9771ea96818SAdrian Chadd 	switch (mac->mac_fw.fw_hdr_format) {
9781ea96818SAdrian Chadd 	case BWN_FW_HDR_598:
9791ea96818SAdrian Chadd 		return (112 + (sizeof(struct bwn_plcp6)));
9801ea96818SAdrian Chadd 	case BWN_FW_HDR_410:
9811ea96818SAdrian Chadd 		return (104 + (sizeof(struct bwn_plcp6)));
9821ea96818SAdrian Chadd 	case BWN_FW_HDR_351:
9831ea96818SAdrian Chadd 		return (100 + (sizeof(struct bwn_plcp6)));
9841ea96818SAdrian Chadd 	default:
9851ea96818SAdrian Chadd 		printf("%s: unknown header format (%d)\n", __func__,
9861ea96818SAdrian Chadd 		    mac->mac_fw.fw_hdr_format);
9871ea96818SAdrian Chadd 		return (112 + (sizeof(struct bwn_plcp6)));
9881ea96818SAdrian Chadd 	}
9891ea96818SAdrian Chadd }
9901ea96818SAdrian Chadd 
99145d9abdbSWeongyo Jeong /*
99245d9abdbSWeongyo Jeong  * Driver-specific vap state.
99345d9abdbSWeongyo Jeong  */
99445d9abdbSWeongyo Jeong struct bwn_vap {
99545d9abdbSWeongyo Jeong 	struct ieee80211vap		bv_vap;	/* base class */
99645d9abdbSWeongyo Jeong 	int				(*bv_newstate)(struct ieee80211vap *,
99745d9abdbSWeongyo Jeong 					    enum ieee80211_state, int);
99845d9abdbSWeongyo Jeong };
99945d9abdbSWeongyo Jeong #define	BWN_VAP(vap)			((struct bwn_vap *)(vap))
100045d9abdbSWeongyo Jeong #define	BWN_VAP_CONST(vap)		((const struct mwl_vap *)(vap))
100145d9abdbSWeongyo Jeong 
1002d177c199SLandon J. Fuller enum bwn_quirk {
1003d177c199SLandon J. Fuller 	/**
1004d177c199SLandon J. Fuller 	 * The ucode PCI slowclock workaround is required on this device.
1005d177c199SLandon J. Fuller 	 * @see BWN_HF_PCI_SLOWCLOCK_WORKAROUND.
1006d177c199SLandon J. Fuller 	 */
1007d177c199SLandon J. Fuller 	BWN_QUIRK_UCODE_SLOWCLOCK_WAR	= (1<<0),
1008d177c199SLandon J. Fuller 
1009d177c199SLandon J. Fuller 	/**
1010d177c199SLandon J. Fuller 	 * DMA is unsupported on this device; PIO should be used instead.
1011d177c199SLandon J. Fuller 	 */
1012d177c199SLandon J. Fuller 	BWN_QUIRK_NODMA			= (1<<1),
1013d177c199SLandon J. Fuller };
1014d177c199SLandon J. Fuller 
101545d9abdbSWeongyo Jeong struct bwn_softc {
101645d9abdbSWeongyo Jeong 	device_t			sc_dev;
1017d177c199SLandon J. Fuller 	struct bhnd_board_info		sc_board_info;
1018d177c199SLandon J. Fuller 	struct bhnd_chipid		sc_cid;
1019d177c199SLandon J. Fuller 	uint32_t			sc_quirks;	/**< @see bwn_quirk */
1020d177c199SLandon J. Fuller 	struct resource			*sc_mem_res;
10218d14ca9cSLandon J. Fuller 	int				sc_mem_rid;
1022d177c199SLandon J. Fuller 
1023d177c199SLandon J. Fuller 	device_t			sc_chipc;	/**< ChipCommon device */
1024d177c199SLandon J. Fuller 	device_t			sc_gpio;	/**< GPIO device */
1025d177c199SLandon J. Fuller 	device_t			sc_pmu;		/**< PMU device, or NULL if unsupported */
1026d177c199SLandon J. Fuller 
102745d9abdbSWeongyo Jeong 	struct mtx			sc_mtx;
10287a79cebfSGleb Smirnoff 	struct ieee80211com		sc_ic;
10297a79cebfSGleb Smirnoff 	struct mbufq			sc_snd;
103045d9abdbSWeongyo Jeong 	unsigned			sc_flags;
103145d9abdbSWeongyo Jeong #define	BWN_FLAG_ATTACHED		(1 << 0)
103245d9abdbSWeongyo Jeong #define	BWN_FLAG_INVALID		(1 << 1)
103345d9abdbSWeongyo Jeong #define	BWN_FLAG_NEED_BEACON_TP		(1 << 2)
10347a79cebfSGleb Smirnoff #define	BWN_FLAG_RUNNING		(1 << 3)
103545d9abdbSWeongyo Jeong 	unsigned			sc_debug;
103645d9abdbSWeongyo Jeong 
103745d9abdbSWeongyo Jeong 	struct bwn_mac		*sc_curmac;
103845d9abdbSWeongyo Jeong 	TAILQ_HEAD(, bwn_mac)	sc_maclist;
103945d9abdbSWeongyo Jeong 
104045d9abdbSWeongyo Jeong 	uint8_t				sc_bssid[IEEE80211_ADDR_LEN];
104145d9abdbSWeongyo Jeong 	unsigned int			sc_filters;
104245d9abdbSWeongyo Jeong 	uint8_t				sc_beacons[2];
104345d9abdbSWeongyo Jeong 	uint8_t				sc_rf_enabled;
104445d9abdbSWeongyo Jeong 
104545d9abdbSWeongyo Jeong 	struct wmeParams		sc_wmeParams[4];
104645d9abdbSWeongyo Jeong 
104745d9abdbSWeongyo Jeong 	struct callout			sc_rfswitch_ch;	/* for laptop */
104845d9abdbSWeongyo Jeong 	struct callout			sc_task_ch;
104945d9abdbSWeongyo Jeong 	struct callout			sc_watchdog_ch;
105045d9abdbSWeongyo Jeong 	int				sc_watchdog_timer;
105145d9abdbSWeongyo Jeong 	struct taskqueue		*sc_tq;	/* private task queue */
105245d9abdbSWeongyo Jeong 	int				(*sc_newstate)(struct ieee80211com *,
105345d9abdbSWeongyo Jeong 					    enum ieee80211_state, int);
105445d9abdbSWeongyo Jeong 	void				(*sc_node_cleanup)(
105545d9abdbSWeongyo Jeong 					    struct ieee80211_node *);
105645d9abdbSWeongyo Jeong 
105745d9abdbSWeongyo Jeong 	int				sc_rx_rate;
105845d9abdbSWeongyo Jeong 	int				sc_tx_rate;
105945d9abdbSWeongyo Jeong 
106045d9abdbSWeongyo Jeong 	int				sc_led_blinking;
106145d9abdbSWeongyo Jeong 	int				sc_led_ticks;
106245d9abdbSWeongyo Jeong 	struct bwn_led			*sc_blink_led;
106345d9abdbSWeongyo Jeong 	struct callout			sc_led_blink_ch;
106445d9abdbSWeongyo Jeong 	int				sc_led_blink_offdur;
106545d9abdbSWeongyo Jeong 	struct bwn_led			sc_leds[BWN_LED_MAX];
106645d9abdbSWeongyo Jeong 	int				sc_led_idle;
106745d9abdbSWeongyo Jeong 	int				sc_led_blink;
106845d9abdbSWeongyo Jeong 
1069d177c199SLandon J. Fuller 	uint8_t				sc_ant2g;	/**< available 2GHz antennas */
1070d177c199SLandon J. Fuller 	uint8_t				sc_ant5g;	/**< available 5GHz antennas */
1071d177c199SLandon J. Fuller 
107245d9abdbSWeongyo Jeong 	struct bwn_tx_radiotap_header	sc_tx_th;
107345d9abdbSWeongyo Jeong 	struct bwn_rx_radiotap_header	sc_rx_th;
107445d9abdbSWeongyo Jeong };
107545d9abdbSWeongyo Jeong 
107645d9abdbSWeongyo Jeong #define	BWN_LOCK_INIT(sc) \
107745d9abdbSWeongyo Jeong 	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \
107845d9abdbSWeongyo Jeong 	    MTX_NETWORK_LOCK, MTX_DEF)
107945d9abdbSWeongyo Jeong #define	BWN_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
108045d9abdbSWeongyo Jeong #define	BWN_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
108145d9abdbSWeongyo Jeong #define	BWN_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
108245d9abdbSWeongyo Jeong #define	BWN_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)
108345d9abdbSWeongyo Jeong 
10841ea96818SAdrian Chadd static inline bwn_band_t
bwn_channel_band(struct bwn_mac * mac,struct ieee80211_channel * c)10851ea96818SAdrian Chadd bwn_channel_band(struct bwn_mac *mac, struct ieee80211_channel *c)
10861ea96818SAdrian Chadd {
10871ea96818SAdrian Chadd 	if (IEEE80211_IS_CHAN_5GHZ(c))
10881ea96818SAdrian Chadd 		return BWN_BAND_5G;
10891ea96818SAdrian Chadd 	/* XXX check 2g, log error if not 2g or 5g? */
10901ea96818SAdrian Chadd 	return BWN_BAND_2G;
10911ea96818SAdrian Chadd }
10921ea96818SAdrian Chadd 
10931ea96818SAdrian Chadd static inline bwn_band_t
bwn_current_band(struct bwn_mac * mac)10941ea96818SAdrian Chadd bwn_current_band(struct bwn_mac *mac)
10951ea96818SAdrian Chadd {
10961ea96818SAdrian Chadd 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
10971ea96818SAdrian Chadd 	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
10981ea96818SAdrian Chadd 		return BWN_BAND_5G;
10991ea96818SAdrian Chadd 	/* XXX check 2g, log error if not 2g or 5g? */
11001ea96818SAdrian Chadd 	return BWN_BAND_2G;
11011ea96818SAdrian Chadd }
11021ea96818SAdrian Chadd 
11031ea96818SAdrian Chadd static inline bool
bwn_is_40mhz(struct bwn_mac * mac)11041ea96818SAdrian Chadd bwn_is_40mhz(struct bwn_mac *mac)
11051ea96818SAdrian Chadd {
11061ea96818SAdrian Chadd 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
11071ea96818SAdrian Chadd 
11081ea96818SAdrian Chadd 	return !! (IEEE80211_IS_CHAN_HT40(ic->ic_curchan));
11091ea96818SAdrian Chadd }
11101ea96818SAdrian Chadd 
11111ea96818SAdrian Chadd static inline int
bwn_get_centre_freq(struct bwn_mac * mac)11121ea96818SAdrian Chadd bwn_get_centre_freq(struct bwn_mac *mac)
11131ea96818SAdrian Chadd {
11141ea96818SAdrian Chadd 
11151ea96818SAdrian Chadd 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
11161ea96818SAdrian Chadd 	/* XXX TODO: calculate correctly for HT40 mode */
11171ea96818SAdrian Chadd 	return ic->ic_curchan->ic_freq;
11181ea96818SAdrian Chadd }
11191ea96818SAdrian Chadd 
11201ea96818SAdrian Chadd static inline int
bwn_get_chan_centre_freq(struct bwn_mac * mac,struct ieee80211_channel * chan)11211ea96818SAdrian Chadd bwn_get_chan_centre_freq(struct bwn_mac *mac, struct ieee80211_channel *chan)
11221ea96818SAdrian Chadd {
11231ea96818SAdrian Chadd 
11241ea96818SAdrian Chadd 	/* XXX TODO: calculate correctly for HT40 mode */
11251ea96818SAdrian Chadd 	return chan->ic_freq;
11261ea96818SAdrian Chadd }
11271ea96818SAdrian Chadd 
11281ea96818SAdrian Chadd static inline int
bwn_get_chan(struct bwn_mac * mac)11291ea96818SAdrian Chadd bwn_get_chan(struct bwn_mac *mac)
11301ea96818SAdrian Chadd {
11311ea96818SAdrian Chadd 
11321ea96818SAdrian Chadd 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
11331ea96818SAdrian Chadd 	/* XXX TODO: calculate correctly for HT40 mode */
11341ea96818SAdrian Chadd 	return ic->ic_curchan->ic_ieee;
11351ea96818SAdrian Chadd }
11361ea96818SAdrian Chadd 
11371ea96818SAdrian Chadd static inline struct ieee80211_channel *
bwn_get_channel(struct bwn_mac * mac)11381ea96818SAdrian Chadd bwn_get_channel(struct bwn_mac *mac)
11391ea96818SAdrian Chadd {
11401ea96818SAdrian Chadd 
11411ea96818SAdrian Chadd 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
11421ea96818SAdrian Chadd 	return ic->ic_curchan;
11431ea96818SAdrian Chadd }
11441ea96818SAdrian Chadd 
11451ea96818SAdrian Chadd static inline bool
bwn_is_chan_passive(struct bwn_mac * mac)11461ea96818SAdrian Chadd bwn_is_chan_passive(struct bwn_mac *mac)
11471ea96818SAdrian Chadd {
11481ea96818SAdrian Chadd 
11491ea96818SAdrian Chadd 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
11501ea96818SAdrian Chadd 	return !! IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan);
11511ea96818SAdrian Chadd }
11521ea96818SAdrian Chadd 
11531ea96818SAdrian Chadd static inline bwn_chan_type_t
bwn_get_chan_type(struct bwn_mac * mac,struct ieee80211_channel * c)11541ea96818SAdrian Chadd bwn_get_chan_type(struct bwn_mac *mac, struct ieee80211_channel *c)
11551ea96818SAdrian Chadd {
11561ea96818SAdrian Chadd 	struct ieee80211com *ic = &mac->mac_sc->sc_ic;
11571ea96818SAdrian Chadd 	if (c == NULL)
11581ea96818SAdrian Chadd 		c = ic->ic_curchan;
11591ea96818SAdrian Chadd 	if (IEEE80211_IS_CHAN_HT40U(c))
11601ea96818SAdrian Chadd 		return BWN_CHAN_TYPE_40_HT_U;
11611ea96818SAdrian Chadd 	else if (IEEE80211_IS_CHAN_HT40D(c))
11621ea96818SAdrian Chadd 		return BWN_CHAN_TYPE_40_HT_D;
11631ea96818SAdrian Chadd 	else if (IEEE80211_IS_CHAN_HT20(c))
11641ea96818SAdrian Chadd 		return BWN_CHAN_TYPE_20_HT;
11651ea96818SAdrian Chadd 	else
11661ea96818SAdrian Chadd 		return BWN_CHAN_TYPE_20;
11671ea96818SAdrian Chadd }
11681ea96818SAdrian Chadd 
11691ea96818SAdrian Chadd static inline int
bwn_get_chan_power(struct bwn_mac * mac,struct ieee80211_channel * c)11701ea96818SAdrian Chadd bwn_get_chan_power(struct bwn_mac *mac, struct ieee80211_channel *c)
11711ea96818SAdrian Chadd {
11721ea96818SAdrian Chadd 
11731ea96818SAdrian Chadd 	/* return in dbm */
11741ea96818SAdrian Chadd 	return c->ic_maxpower / 2;
11751ea96818SAdrian Chadd }
11761ea96818SAdrian Chadd 
117745d9abdbSWeongyo Jeong #endif	/* !_IF_BWNVAR_H */
1178