xref: /openbsd-src/sys/dev/ic/athnvar.h (revision d2dd70ac0a5fe22ca102dd594dce32a1fe581c76)
1*d2dd70acSstsp /*	$OpenBSD: athnvar.h,v 1.42 2021/04/15 18:25:43 stsp Exp $	*/
2498e8a28Sdamien 
3498e8a28Sdamien /*-
4498e8a28Sdamien  * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
5498e8a28Sdamien  *
6498e8a28Sdamien  * Permission to use, copy, modify, and distribute this software for any
7498e8a28Sdamien  * purpose with or without fee is hereby granted, provided that the above
8498e8a28Sdamien  * copyright notice and this permission notice appear in all copies.
9498e8a28Sdamien  *
10498e8a28Sdamien  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11498e8a28Sdamien  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12498e8a28Sdamien  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13498e8a28Sdamien  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14498e8a28Sdamien  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15498e8a28Sdamien  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16498e8a28Sdamien  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17498e8a28Sdamien  */
18498e8a28Sdamien 
19c0a11cf8Sdamien #ifdef notyet
20c0a11cf8Sdamien #define ATHN_BT_COEXISTENCE	1
21c0a11cf8Sdamien #endif
22498e8a28Sdamien 
23498e8a28Sdamien #ifdef ATHN_DEBUG
24498e8a28Sdamien #define DPRINTF(x)	do { if (athn_debug > 0) printf x; } while (0)
25498e8a28Sdamien #define DPRINTFN(n, x)	do { if (athn_debug >= (n)) printf x; } while (0)
26498e8a28Sdamien extern int athn_debug;
27498e8a28Sdamien #else
28498e8a28Sdamien #define DPRINTF(x)
29498e8a28Sdamien #define DPRINTFN(n, x)
30498e8a28Sdamien #endif
31498e8a28Sdamien 
326c0255d5Sdamien #define LE_READ_4(p)	((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24)
336c0255d5Sdamien #define LE_READ_2(p)	((p)[0] | (p)[1] << 8)
346c0255d5Sdamien 
35498e8a28Sdamien #define ATHN_RXBUFSZ	3872
36498e8a28Sdamien #define ATHN_TXBUFSZ	4096
37498e8a28Sdamien 
38498e8a28Sdamien #define ATHN_NRXBUFS	64
39498e8a28Sdamien #define ATHN_NTXBUFS	64	/* Shared between all Tx queues. */
40498e8a28Sdamien 
41498e8a28Sdamien struct athn_rx_radiotap_header {
42498e8a28Sdamien 	struct ieee80211_radiotap_header wr_ihdr;
43498e8a28Sdamien 	uint64_t	wr_tsft;
44498e8a28Sdamien 	uint8_t		wr_flags;
45498e8a28Sdamien 	uint8_t		wr_rate;
46498e8a28Sdamien 	uint16_t	wr_chan_freq;
47498e8a28Sdamien 	uint16_t	wr_chan_flags;
48498e8a28Sdamien 	int8_t		wr_dbm_antsignal;
49498e8a28Sdamien 	uint8_t		wr_antenna;
50498e8a28Sdamien } __packed;
51498e8a28Sdamien 
52498e8a28Sdamien #define ATHN_RX_RADIOTAP_PRESENT						\
53498e8a28Sdamien 	(1 << IEEE80211_RADIOTAP_TSFT |					\
54498e8a28Sdamien 	 1 << IEEE80211_RADIOTAP_FLAGS |				\
55498e8a28Sdamien 	 1 << IEEE80211_RADIOTAP_RATE |					\
56498e8a28Sdamien 	 1 << IEEE80211_RADIOTAP_CHANNEL |				\
57498e8a28Sdamien 	 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL |			\
58498e8a28Sdamien 	 1 << IEEE80211_RADIOTAP_ANTENNA)
59498e8a28Sdamien 
60498e8a28Sdamien struct athn_tx_radiotap_header {
61498e8a28Sdamien 	struct ieee80211_radiotap_header wt_ihdr;
62498e8a28Sdamien 	uint8_t		wt_flags;
63498e8a28Sdamien 	uint8_t		wt_rate;
64498e8a28Sdamien 	uint16_t	wt_chan_freq;
65498e8a28Sdamien 	uint16_t	wt_chan_flags;
66498e8a28Sdamien } __packed;
67498e8a28Sdamien 
68498e8a28Sdamien #define ATHN_TX_RADIOTAP_PRESENT						\
69498e8a28Sdamien 	(1 << IEEE80211_RADIOTAP_FLAGS |				\
70498e8a28Sdamien 	 1 << IEEE80211_RADIOTAP_RATE |					\
71eb1adcecSmpi 	 1 << IEEE80211_RADIOTAP_CHANNEL)
72498e8a28Sdamien 
73498e8a28Sdamien struct athn_tx_buf {
74498e8a28Sdamien 	SIMPLEQ_ENTRY(athn_tx_buf)	bf_list;
75498e8a28Sdamien 
76bd6ea91dSdamien 	void				*bf_descs;
77498e8a28Sdamien 	bus_dmamap_t			bf_map;
78498e8a28Sdamien 	bus_addr_t			bf_daddr;
79498e8a28Sdamien 
80498e8a28Sdamien 	struct mbuf			*bf_m;
81498e8a28Sdamien 	struct ieee80211_node		*bf_ni;
82*d2dd70acSstsp 	int				bf_txmcs;
83436170c5Sdamien 	int				bf_txflags;
84df31d9afSdamien #define ATHN_TXFLAG_PAPRD	(1 << 0)
855dde5fe4Skettenis #define ATHN_TXFLAG_CAB		(1 << 1)
86498e8a28Sdamien };
87498e8a28Sdamien 
88498e8a28Sdamien struct athn_txq {
89498e8a28Sdamien 	SIMPLEQ_HEAD(, athn_tx_buf)	head;
90bd6ea91dSdamien 	void				*lastds;
916c0255d5Sdamien 	struct athn_tx_buf		*wait;
926c0255d5Sdamien 	int				queued;
93498e8a28Sdamien };
94498e8a28Sdamien 
95498e8a28Sdamien struct athn_rx_buf {
96498e8a28Sdamien 	SIMPLEQ_ENTRY(athn_rx_buf)	bf_list;
97498e8a28Sdamien 
98bd6ea91dSdamien 	void				*bf_desc;
99498e8a28Sdamien 	bus_dmamap_t			bf_map;
100498e8a28Sdamien 
101498e8a28Sdamien 	struct mbuf			*bf_m;
102498e8a28Sdamien 	bus_addr_t			bf_daddr;
103498e8a28Sdamien };
104498e8a28Sdamien 
105498e8a28Sdamien struct athn_rxq {
106bd6ea91dSdamien 	struct athn_rx_buf		*bf;
107498e8a28Sdamien 
108bd6ea91dSdamien 	void				*descs;
109bd6ea91dSdamien 	void				*lastds;
110498e8a28Sdamien 	bus_dmamap_t			map;
111498e8a28Sdamien 	bus_dma_segment_t		seg;
112bd6ea91dSdamien 	int				count;
113498e8a28Sdamien 
114498e8a28Sdamien 	SIMPLEQ_HEAD(, athn_rx_buf)	head;
115498e8a28Sdamien };
116498e8a28Sdamien 
117498e8a28Sdamien /* Software rate indexes. */
118498e8a28Sdamien #define ATHN_RIDX_CCK1	0
1198f9a2877Sdamien #define ATHN_RIDX_CCK2	1
120498e8a28Sdamien #define ATHN_RIDX_OFDM6	4
121498e8a28Sdamien #define ATHN_RIDX_MCS0	12
1227363c99eSstsp #define ATHN_RIDX_MCS8	(ATHN_RIDX_MCS0 + 8)
123498e8a28Sdamien #define ATHN_RIDX_MCS15	27
124498e8a28Sdamien #define ATHN_RIDX_MAX	27
1257363c99eSstsp #define ATHN_MCS_MAX	15
1267363c99eSstsp #define ATHN_NUM_MCS	(ATHN_MCS_MAX + 1)
127498e8a28Sdamien #define ATHN_IS_HT_RIDX(ridx)	((ridx) >= ATHN_RIDX_MCS0)
1287363c99eSstsp #define ATHN_IS_MIMO_RIDX(ridx)	((ridx) >= ATHN_RIDX_MCS8)
129498e8a28Sdamien 
130498e8a28Sdamien static const struct athn_rate {
1317363c99eSstsp 	uint16_t	rate;		/* Rate in 500Kbps unit. */
132498e8a28Sdamien 	uint8_t		hwrate;		/* HW representation. */
1338f9a2877Sdamien 	uint8_t		rspridx;	/* Control Response Frame rate index. */
134498e8a28Sdamien 	enum	ieee80211_phytype phy;
135498e8a28Sdamien } athn_rates[] = {
1368f9a2877Sdamien 	{    2, 0x1b, 0, IEEE80211_T_DS },
1378f9a2877Sdamien 	{    4, 0x1a, 1, IEEE80211_T_DS },
1388f9a2877Sdamien 	{   11, 0x19, 1, IEEE80211_T_DS },
1398f9a2877Sdamien 	{   22, 0x18, 1, IEEE80211_T_DS },
1408f9a2877Sdamien 	{   12, 0x0b, 4, IEEE80211_T_OFDM },
1418f9a2877Sdamien 	{   18, 0x0f, 4, IEEE80211_T_OFDM },
1428f9a2877Sdamien 	{   24, 0x0a, 6, IEEE80211_T_OFDM },
1438f9a2877Sdamien 	{   36, 0x0e, 6, IEEE80211_T_OFDM },
1448f9a2877Sdamien 	{   48, 0x09, 8, IEEE80211_T_OFDM },
1458f9a2877Sdamien 	{   72, 0x0d, 8, IEEE80211_T_OFDM },
1468f9a2877Sdamien 	{   96, 0x08, 8, IEEE80211_T_OFDM },
1478f9a2877Sdamien 	{  108, 0x0c, 8, IEEE80211_T_OFDM },
1487363c99eSstsp 	{   13, 0x80, 4, IEEE80211_T_OFDM },
1497363c99eSstsp 	{   26, 0x81, 6, IEEE80211_T_OFDM },
1507363c99eSstsp 	{   39, 0x82, 6, IEEE80211_T_OFDM },
1517363c99eSstsp 	{   52, 0x83, 8, IEEE80211_T_OFDM },
1527363c99eSstsp 	{   78, 0x84, 8, IEEE80211_T_OFDM },
1537363c99eSstsp 	{  104, 0x85, 8, IEEE80211_T_OFDM },
1547363c99eSstsp 	{  117, 0x86, 8, IEEE80211_T_OFDM },
1557363c99eSstsp 	{  130, 0x87, 8, IEEE80211_T_OFDM },
1567363c99eSstsp 	{   26, 0x88, 4, IEEE80211_T_OFDM },
1577363c99eSstsp 	{   52, 0x89, 6, IEEE80211_T_OFDM },
1587363c99eSstsp 	{   78, 0x8a, 8, IEEE80211_T_OFDM },
1597363c99eSstsp 	{  104, 0x8b, 8, IEEE80211_T_OFDM },
1607363c99eSstsp 	{  156, 0x8c, 8, IEEE80211_T_OFDM },
1617363c99eSstsp 	{  208, 0x8d, 8, IEEE80211_T_OFDM },
1627363c99eSstsp 	{  234, 0x8e, 8, IEEE80211_T_OFDM },
1637363c99eSstsp 	{  260, 0x8f, 8, IEEE80211_T_OFDM }
164498e8a28Sdamien };
165498e8a28Sdamien 
166498e8a28Sdamien struct athn_series {
167498e8a28Sdamien 	uint16_t	dur;
1686b118bcdSdamien 	uint8_t		hwrate;
169498e8a28Sdamien };
170498e8a28Sdamien 
171498e8a28Sdamien struct athn_pier {
172498e8a28Sdamien 	uint8_t		fbin;
173498e8a28Sdamien 	const uint8_t	*pwr[AR_PD_GAINS_IN_MASK];
174498e8a28Sdamien 	const uint8_t	*vpd[AR_PD_GAINS_IN_MASK];
175498e8a28Sdamien };
176498e8a28Sdamien 
177498e8a28Sdamien /*
178498e8a28Sdamien  * Structures used to store initialization values.
179498e8a28Sdamien  */
180498e8a28Sdamien struct athn_ini {
181498e8a28Sdamien 	int		nregs;
182498e8a28Sdamien 	const uint16_t	*regs;
183498e8a28Sdamien 	const uint32_t	*vals_5g20;
184498e8a28Sdamien 	const uint32_t	*vals_5g40;
185498e8a28Sdamien 	const uint32_t	*vals_2g40;
186498e8a28Sdamien 	const uint32_t	*vals_2g20;
187498e8a28Sdamien 	int		ncmregs;
188498e8a28Sdamien 	const uint16_t	*cmregs;
189498e8a28Sdamien 	const uint32_t	*cmvals;
19097bf8fdcSdamien 	int		nfastregs;
19197bf8fdcSdamien 	const uint16_t	*fastregs;
19297bf8fdcSdamien 	const uint32_t	*fastvals_5g20;
19397bf8fdcSdamien 	const uint32_t	*fastvals_5g40;
194498e8a28Sdamien };
195498e8a28Sdamien 
196498e8a28Sdamien struct athn_gain {
197498e8a28Sdamien 	int		nregs;
198498e8a28Sdamien 	const uint16_t	*regs;
199498e8a28Sdamien 	const uint32_t	*vals_5g;
200498e8a28Sdamien 	const uint32_t	*vals_2g;
201498e8a28Sdamien };
202498e8a28Sdamien 
203498e8a28Sdamien struct athn_addac {
204498e8a28Sdamien 	int		nvals;
205498e8a28Sdamien 	const uint32_t	*vals;
206498e8a28Sdamien };
207498e8a28Sdamien 
208328b15b2Skettenis struct athn_serdes {
209328b15b2Skettenis 	int		nvals;
210c8971d2aSstsp 	const uint32_t	*regs;
211328b15b2Skettenis 	const uint32_t	*vals;
212328b15b2Skettenis };
213328b15b2Skettenis 
214bd6ea91dSdamien /* Rx queue software indexes. */
215bd6ea91dSdamien #define ATHN_QID_LP		0
21617ac1014Sstsp #define ATHN_QID_HP		1
217bd6ea91dSdamien 
218498e8a28Sdamien /* Tx queue software indexes. */
219498e8a28Sdamien #define ATHN_QID_AC_BE		0
220498e8a28Sdamien #define ATHN_QID_PSPOLL		1
221498e8a28Sdamien #define ATHN_QID_AC_BK		2
222498e8a28Sdamien #define ATHN_QID_AC_VI		3
223498e8a28Sdamien #define ATHN_QID_AC_VO		4
224498e8a28Sdamien #define ATHN_QID_UAPSD		5
225498e8a28Sdamien #define ATHN_QID_CAB		6
226498e8a28Sdamien #define ATHN_QID_BEACON		7
227498e8a28Sdamien #define ATHN_QID_COUNT		8
228498e8a28Sdamien 
229498e8a28Sdamien /* Map Access Category to Tx queue Id. */
230498e8a28Sdamien static const uint8_t athn_ac2qid[EDCA_NUM_AC] = {
231498e8a28Sdamien 	ATHN_QID_AC_BE,	/* EDCA_AC_BE */
232498e8a28Sdamien 	ATHN_QID_AC_BK,	/* EDCA_AC_BK */
233498e8a28Sdamien 	ATHN_QID_AC_VI,	/* EDCA_AC_VI */
234498e8a28Sdamien 	ATHN_QID_AC_VO	/* EDCA_AC_VO */
235498e8a28Sdamien };
236498e8a28Sdamien 
237498e8a28Sdamien static const uint8_t athn_5ghz_chans[] = {
238498e8a28Sdamien 	/* UNII 1. */
239498e8a28Sdamien 	36, 40, 44, 48,
240498e8a28Sdamien 	/* UNII 2. */
241498e8a28Sdamien 	52, 56, 60, 64,
242498e8a28Sdamien 	/* Middle band. */
243498e8a28Sdamien 	100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
244498e8a28Sdamien 	/* UNII 3. */
245498e8a28Sdamien 	149, 153, 157, 161, 165
246498e8a28Sdamien };
247498e8a28Sdamien 
248498e8a28Sdamien /* Number of data bits per OFDM symbol for MCS[0-15]. */
249498e8a28Sdamien /* See tables 20-29, 20-30, 20-33, 20-34. */
250498e8a28Sdamien static const uint16_t ar_mcs_ndbps[][2] = {
251498e8a28Sdamien 	/* 20MHz  40MHz */
252498e8a28Sdamien 	{     26,    54 },	/* MCS0 */
253498e8a28Sdamien 	{     52,   108 },	/* MCS1 */
254498e8a28Sdamien 	{     78,   162 },	/* MCS2 */
255498e8a28Sdamien 	{    104,   216 },	/* MCS3 */
256498e8a28Sdamien 	{    156,   324 },	/* MCS4 */
257498e8a28Sdamien 	{    208,   432 },	/* MCS5 */
258498e8a28Sdamien 	{    234,   486 },	/* MCS6 */
259498e8a28Sdamien 	{    260,   540 },	/* MCS7 */
260498e8a28Sdamien 	{     26,   108 },	/* MCS8 */
261498e8a28Sdamien 	{     52,   216 },	/* MCS9 */
262498e8a28Sdamien 	{     78,   324 },	/* MCS10 */
263498e8a28Sdamien 	{    104,   432 },	/* MCS11 */
264498e8a28Sdamien 	{    156,   648 },	/* MCS12 */
265498e8a28Sdamien 	{    208,   864 },	/* MCS13 */
266498e8a28Sdamien 	{    234,   972 },	/* MCS14 */
267498e8a28Sdamien 	{    260,  1080 }	/* MCS15 */
268498e8a28Sdamien };
269498e8a28Sdamien 
270498e8a28Sdamien #define ATHN_POWER_OFDM6	0
271498e8a28Sdamien #define ATHN_POWER_OFDM9	1
272498e8a28Sdamien #define ATHN_POWER_OFDM12	2
273498e8a28Sdamien #define ATHN_POWER_OFDM18	3
274498e8a28Sdamien #define ATHN_POWER_OFDM24	4
275498e8a28Sdamien #define ATHN_POWER_OFDM36	5
276498e8a28Sdamien #define ATHN_POWER_OFDM48	6
277498e8a28Sdamien #define ATHN_POWER_OFDM54	7
278498e8a28Sdamien #define ATHN_POWER_CCK1_LP	8
279498e8a28Sdamien #define ATHN_POWER_CCK2_LP	9
280498e8a28Sdamien #define ATHN_POWER_CCK2_SP	10
281498e8a28Sdamien #define ATHN_POWER_CCK55_LP	11
282498e8a28Sdamien #define ATHN_POWER_CCK55_SP	12
283498e8a28Sdamien #define ATHN_POWER_CCK11_LP	13
284498e8a28Sdamien #define ATHN_POWER_CCK11_SP	14
285498e8a28Sdamien #define ATHN_POWER_XR		15
286498e8a28Sdamien #define ATHN_POWER_HT20(mcs)	(16 + (mcs))
287bd6ea91dSdamien #define ATHN_POWER_HT40(mcs)	(40 + (mcs))
288bd6ea91dSdamien #define ATHN_POWER_CCK_DUP	64
289bd6ea91dSdamien #define ATHN_POWER_OFDM_DUP	65
290bd6ea91dSdamien #define ATHN_POWER_CCK_EXT	66
291bd6ea91dSdamien #define ATHN_POWER_OFDM_EXT	67
292bd6ea91dSdamien #define ATHN_POWER_COUNT	68
293498e8a28Sdamien 
2947363c99eSstsp #define ATHN_NUM_LEGACY_RATES	IEEE80211_RATE_MAXSIZE
2957363c99eSstsp #define ATHN_NUM_RATES		(ATHN_NUM_LEGACY_RATES + ATHN_NUM_MCS)
296498e8a28Sdamien struct athn_node {
297498e8a28Sdamien 	struct ieee80211_node		ni;
298498e8a28Sdamien 	struct ieee80211_amrr_node	amn;
299*d2dd70acSstsp 	struct ieee80211_ra_node	rn;
3007363c99eSstsp 	uint8_t				ridx[ATHN_NUM_RATES];
3017363c99eSstsp 	uint8_t				fallback[ATHN_NUM_RATES];
30213236e8dSdamien 	uint8_t				sta_index;
303498e8a28Sdamien };
304498e8a28Sdamien 
305bd6ea91dSdamien /*
306bd6ea91dSdamien  * Adaptive noise immunity state.
307bd6ea91dSdamien  */
308498e8a28Sdamien #define ATHN_ANI_PERIOD		100
309498e8a28Sdamien #define ATHN_ANI_RSSI_THR_HIGH	40
310498e8a28Sdamien #define ATHN_ANI_RSSI_THR_LOW	7
311498e8a28Sdamien struct athn_ani {
312498e8a28Sdamien 	uint8_t		noise_immunity_level;
313498e8a28Sdamien 	uint8_t		spur_immunity_level;
314498e8a28Sdamien 	uint8_t		firstep_level;
315498e8a28Sdamien 	uint8_t		ofdm_weak_signal;
316498e8a28Sdamien 	uint8_t		cck_weak_signal;
317498e8a28Sdamien 
318498e8a28Sdamien 	uint32_t	listen_time;
319498e8a28Sdamien 
320498e8a28Sdamien 	uint32_t	ofdm_trig_high;
321498e8a28Sdamien 	uint32_t	ofdm_trig_low;
322498e8a28Sdamien 
323498e8a28Sdamien 	int32_t		cck_trig_high;
324498e8a28Sdamien 	int32_t		cck_trig_low;
325498e8a28Sdamien 
326498e8a28Sdamien 	uint32_t	ofdm_phy_err_base;
327498e8a28Sdamien 	uint32_t	cck_phy_err_base;
328498e8a28Sdamien 	uint32_t	ofdm_phy_err_count;
329498e8a28Sdamien 	uint32_t	cck_phy_err_count;
330498e8a28Sdamien 
331498e8a28Sdamien 	uint32_t	cyccnt;
332498e8a28Sdamien 	uint32_t	txfcnt;
333498e8a28Sdamien 	uint32_t	rxfcnt;
334498e8a28Sdamien };
335498e8a28Sdamien 
336498e8a28Sdamien struct athn_iq_cal {
337498e8a28Sdamien 	uint32_t	pwr_meas_i;
338498e8a28Sdamien 	uint32_t	pwr_meas_q;
339498e8a28Sdamien 	int32_t		iq_corr_meas;
340498e8a28Sdamien };
341498e8a28Sdamien 
342498e8a28Sdamien struct athn_adc_cal {
343498e8a28Sdamien 	uint32_t	pwr_meas_odd_i;
344498e8a28Sdamien 	uint32_t	pwr_meas_even_i;
345498e8a28Sdamien 	uint32_t	pwr_meas_odd_q;
346498e8a28Sdamien 	uint32_t	pwr_meas_even_q;
347498e8a28Sdamien };
348498e8a28Sdamien 
349498e8a28Sdamien struct athn_calib {
350498e8a28Sdamien 	int			nsamples;
351498e8a28Sdamien 	struct athn_iq_cal	iq[AR_MAX_CHAINS];
352498e8a28Sdamien 	struct athn_adc_cal	adc_gain[AR_MAX_CHAINS];
353498e8a28Sdamien 	struct athn_adc_cal	adc_dc_offset[AR_MAX_CHAINS];
354498e8a28Sdamien };
355498e8a28Sdamien 
356498e8a28Sdamien #define ATHN_NF_CAL_HIST_MAX	5
357498e8a28Sdamien 
358498e8a28Sdamien struct athn_softc;
359498e8a28Sdamien 
360498e8a28Sdamien struct athn_ops {
361c0a11cf8Sdamien 	/* Bus callbacks. */
362c0a11cf8Sdamien 	uint32_t	(*read)(struct athn_softc *, uint32_t);
363c0a11cf8Sdamien 	void		(*write)(struct athn_softc *, uint32_t, uint32_t);
364c0a11cf8Sdamien 	void		(*write_barrier)(struct athn_softc *);
365c0a11cf8Sdamien 
366498e8a28Sdamien 	void	(*setup)(struct athn_softc *);
367498e8a28Sdamien 	void	(*set_txpower)(struct athn_softc *, struct ieee80211_channel *,
368498e8a28Sdamien 		    struct ieee80211_channel *);
369498e8a28Sdamien 	void	(*spur_mitigate)(struct athn_softc *,
370498e8a28Sdamien 		    struct ieee80211_channel *, struct ieee80211_channel *);
371bd6ea91dSdamien 	const struct ar_spur_chan *
372bd6ea91dSdamien 		(*get_spur_chans)(struct athn_softc *, int);
373498e8a28Sdamien 	void	(*init_from_rom)(struct athn_softc *,
374498e8a28Sdamien 		    struct ieee80211_channel *, struct ieee80211_channel *);
375498e8a28Sdamien 	int	(*set_synth)(struct athn_softc *, struct ieee80211_channel *,
376498e8a28Sdamien 		    struct ieee80211_channel *);
3773a686414Sdamien 	int	(*read_rom_data)(struct athn_softc *, uint32_t, void *, int);
378e7e15635Sdamien 	const uint8_t *
379e7e15635Sdamien 		(*get_rom_template)(struct athn_softc *, uint8_t);
380498e8a28Sdamien 	void	(*swap_rom)(struct athn_softc *);
381498e8a28Sdamien 	void	(*olpc_init)(struct athn_softc *);
382b46f6896Sdamien 	void	(*olpc_temp_compensation)(struct athn_softc *);
383bd6ea91dSdamien 	/* GPIO callbacks. */
384bd6ea91dSdamien 	int	(*gpio_read)(struct athn_softc *, int);
385bd6ea91dSdamien 	void	(*gpio_write)(struct athn_softc *, int, int);
386bd6ea91dSdamien 	void	(*gpio_config_input)(struct athn_softc *, int);
387bd6ea91dSdamien 	void	(*gpio_config_output)(struct athn_softc *, int, int);
388bd6ea91dSdamien 	void	(*rfsilent_init)(struct athn_softc *);
389bd6ea91dSdamien 	/* DMA callbacks. */
390bd6ea91dSdamien 	int	(*dma_alloc)(struct athn_softc *);
391bd6ea91dSdamien 	void	(*dma_free)(struct athn_softc *);
392bd6ea91dSdamien 	void	(*rx_enable)(struct athn_softc *);
393bd6ea91dSdamien 	int	(*intr)(struct athn_softc *);
394bd6ea91dSdamien 	int	(*tx)(struct athn_softc *, struct mbuf *,
395436170c5Sdamien 		    struct ieee80211_node *, int);
396bd6ea91dSdamien 	/* PHY callbacks. */
397bd6ea91dSdamien 	void	(*set_rf_mode)(struct athn_softc *,
398bd6ea91dSdamien 		    struct ieee80211_channel *);
399bd6ea91dSdamien 	int	(*rf_bus_request)(struct athn_softc *);
400bd6ea91dSdamien 	void	(*rf_bus_release)(struct athn_softc *);
401bd6ea91dSdamien 	void	(*set_phy)(struct athn_softc *, struct ieee80211_channel *,
402bd6ea91dSdamien 		    struct ieee80211_channel *);
403bd6ea91dSdamien 	void	(*set_delta_slope)(struct athn_softc *,
404bd6ea91dSdamien 		    struct ieee80211_channel *, struct ieee80211_channel *);
405bd6ea91dSdamien 	void	(*enable_antenna_diversity)(struct athn_softc *);
406bd6ea91dSdamien 	void	(*init_baseband)(struct athn_softc *);
407bd6ea91dSdamien 	void	(*disable_phy)(struct athn_softc *);
408bd6ea91dSdamien 	void	(*set_rxchains)(struct athn_softc *);
409bd6ea91dSdamien 	void	(*noisefloor_calib)(struct athn_softc *);
4109d1f2812Sstsp 	void	(*init_noisefloor_calib)(struct athn_softc *);
4119d1f2812Sstsp 	int	(*get_noisefloor)(struct athn_softc *);
4129d1f2812Sstsp 	void	(*apply_noisefloor)(struct athn_softc *);
413bd6ea91dSdamien 	void	(*do_calib)(struct athn_softc *);
414bd6ea91dSdamien 	void	(*next_calib)(struct athn_softc *);
415bd6ea91dSdamien 	void	(*hw_init)(struct athn_softc *, struct ieee80211_channel *,
416bd6ea91dSdamien 		    struct ieee80211_channel *);
417df31d9afSdamien 	void	(*get_paprd_masks)(struct athn_softc *sc,
418df31d9afSdamien 		    struct ieee80211_channel *, uint32_t *, uint32_t *);
419bd6ea91dSdamien 	/* ANI callbacks. */
420bd6ea91dSdamien 	void	(*set_noise_immunity_level)(struct athn_softc *, int);
421bd6ea91dSdamien 	void	(*enable_ofdm_weak_signal)(struct athn_softc *);
422bd6ea91dSdamien 	void	(*disable_ofdm_weak_signal)(struct athn_softc *);
423bd6ea91dSdamien 	void	(*set_cck_weak_signal)(struct athn_softc *, int);
424bd6ea91dSdamien 	void	(*set_firstep_level)(struct athn_softc *, int);
425bd6ea91dSdamien 	void	(*set_spur_immunity_level)(struct athn_softc *, int);
426498e8a28Sdamien };
427498e8a28Sdamien 
428498e8a28Sdamien struct athn_softc {
429498e8a28Sdamien 	struct device			sc_dev;
430498e8a28Sdamien 	struct ieee80211com		sc_ic;
431498e8a28Sdamien 
432498e8a28Sdamien 	int				(*sc_enable)(struct athn_softc *);
433498e8a28Sdamien 	void				(*sc_disable)(struct athn_softc *);
434498e8a28Sdamien 	void				(*sc_power)(struct athn_softc *, int);
435498e8a28Sdamien 	void				(*sc_disable_aspm)(struct athn_softc *);
43644176b8eSdamien 	void				(*sc_enable_extsynch)(
43744176b8eSdamien 					    struct athn_softc *);
438498e8a28Sdamien 
439498e8a28Sdamien 	int				(*sc_newstate)(struct ieee80211com *,
440498e8a28Sdamien 					    enum ieee80211_state, int);
441498e8a28Sdamien 
442498e8a28Sdamien 	bus_dma_tag_t			sc_dmat;
443498e8a28Sdamien 
444498e8a28Sdamien 	struct timeout			scan_to;
445498e8a28Sdamien 	struct timeout			calib_to;
446498e8a28Sdamien 	struct ieee80211_amrr		amrr;
447498e8a28Sdamien 
448498e8a28Sdamien 	u_int				flags;
449498e8a28Sdamien #define ATHN_FLAG_PCIE			(1 << 0)
450c0a11cf8Sdamien #define ATHN_FLAG_USB			(1 << 1)
451c0a11cf8Sdamien #define ATHN_FLAG_OLPC			(1 << 2)
452c0a11cf8Sdamien #define ATHN_FLAG_PAPRD			(1 << 3)
453c0a11cf8Sdamien #define ATHN_FLAG_FAST_PLL_CLOCK	(1 << 4)
454c0a11cf8Sdamien #define ATHN_FLAG_RFSILENT		(1 << 5)
455c0a11cf8Sdamien #define ATHN_FLAG_RFSILENT_REVERSED	(1 << 6)
456c0a11cf8Sdamien #define ATHN_FLAG_BTCOEX2WIRE		(1 << 7)
457c0a11cf8Sdamien #define ATHN_FLAG_BTCOEX3WIRE		(1 << 8)
458498e8a28Sdamien /* Shortcut. */
459498e8a28Sdamien #define ATHN_FLAG_BTCOEX	(ATHN_FLAG_BTCOEX2WIRE | ATHN_FLAG_BTCOEX3WIRE)
460c0a11cf8Sdamien #define ATHN_FLAG_11A			(1 << 9)
461c0a11cf8Sdamien #define ATHN_FLAG_11G			(1 << 10)
462c0a11cf8Sdamien #define ATHN_FLAG_11N			(1 << 11)
463c0a11cf8Sdamien #define ATHN_FLAG_AN_TOP2_FIXUP		(1 << 12)
464c0a11cf8Sdamien #define ATHN_FLAG_NON_ENTERPRISE	(1 << 13)
46544176b8eSdamien #define ATHN_FLAG_3TREDUCE_CHAIN	(1 << 14)
466498e8a28Sdamien 
467498e8a28Sdamien 	uint8_t				ngpiopins;
4689feb3d58Sdamien 	int				led_pin;
469498e8a28Sdamien 	int				rfsilent_pin;
4705632af28Sdamien 	int				led_state;
4717f0116d0Sdamien 	uint32_t			isync;
4727f0116d0Sdamien 	uint32_t			imask;
473498e8a28Sdamien 
474498e8a28Sdamien 	uint16_t			mac_ver;
475498e8a28Sdamien 	uint8_t				mac_rev;
476498e8a28Sdamien 	uint8_t				rf_rev;
477498e8a28Sdamien 	uint16_t			eep_rev;
478498e8a28Sdamien 
479498e8a28Sdamien 	uint8_t				txchainmask;
480498e8a28Sdamien 	uint8_t				rxchainmask;
481498e8a28Sdamien 	uint8_t				ntxchains;
482498e8a28Sdamien 	uint8_t				nrxchains;
483498e8a28Sdamien 
48426bcd0d6Sdamien 	uint8_t				sup_calib_mask;
48526bcd0d6Sdamien 	uint8_t				cur_calib_mask;
486498e8a28Sdamien #define ATHN_CAL_IQ		(1 << 0)
487498e8a28Sdamien #define ATHN_CAL_ADC_GAIN	(1 << 1)
488498e8a28Sdamien #define ATHN_CAL_ADC_DC		(1 << 2)
489bd6ea91dSdamien #define ATHN_CAL_TEMP		(1 << 3)
490498e8a28Sdamien 
491aca706e9Sdamien 	struct ieee80211_channel	*curchan;
492aca706e9Sdamien 	struct ieee80211_channel	*curchanext;
493aca706e9Sdamien 
494498e8a28Sdamien 	/* Open Loop Power Control. */
495498e8a28Sdamien 	int8_t				tx_gain_tbl[AR9280_TX_GAIN_TABLE_SIZE];
496498e8a28Sdamien 	int8_t				pdadc;
497498e8a28Sdamien 	int8_t				tcomp;
498b46f6896Sdamien 	int				olpc_ticks;
499cc6e2d0bSstsp 	int				iqcal_ticks;
500498e8a28Sdamien 
501df31d9afSdamien 	/* PA predistortion. */
502df31d9afSdamien 	uint16_t			gain1[AR_MAX_CHAINS];
503df31d9afSdamien 	uint32_t			txgain[AR9003_TX_GAIN_TABLE_SIZE];
50449841013Sdamien 	int16_t				pa_in[AR_MAX_CHAINS]
50549841013Sdamien 					     [AR9003_PAPRD_MEM_TAB_SIZE];
50649841013Sdamien 	int16_t				angle[AR_MAX_CHAINS]
507df31d9afSdamien 					     [AR9003_PAPRD_MEM_TAB_SIZE];
508df31d9afSdamien 	int32_t				trainpow;
509df31d9afSdamien 	uint8_t				paprd_curchain;
510df31d9afSdamien 
511498e8a28Sdamien 	uint32_t			rwbuf[64];
512498e8a28Sdamien 
513498e8a28Sdamien 	int				kc_entries;
514498e8a28Sdamien 
515498e8a28Sdamien 	void				*eep;
516bd6ea91dSdamien 	const void			*eep_def;
517498e8a28Sdamien 	uint32_t			eep_base;
518498e8a28Sdamien 	uint32_t			eep_size;
519498e8a28Sdamien 
520bd6ea91dSdamien 	struct athn_rxq			rxq[2];
521bd6ea91dSdamien 	struct athn_txq			txq[31];
522498e8a28Sdamien 
523bd6ea91dSdamien 	void				*descs;
524498e8a28Sdamien 	bus_dmamap_t			map;
525498e8a28Sdamien 	bus_dma_segment_t		seg;
526498e8a28Sdamien 	SIMPLEQ_HEAD(, athn_tx_buf)	txbufs;
527eff5798eSdamien 	struct athn_tx_buf		*bcnbuf;
528498e8a28Sdamien 	struct athn_tx_buf		txpool[ATHN_NTXBUFS];
529498e8a28Sdamien 
530bd6ea91dSdamien 	bus_dmamap_t			txsmap;
531bd6ea91dSdamien 	bus_dma_segment_t		txsseg;
532bd6ea91dSdamien 	void				*txsring;
533bd6ea91dSdamien 	int				txscur;
534bd6ea91dSdamien 
535277846c0Sdamien 	int				sc_if_flags;
536498e8a28Sdamien 	int				sc_tx_timer;
537498e8a28Sdamien 
538498e8a28Sdamien 	const struct athn_ini		*ini;
539498e8a28Sdamien 	const struct athn_gain		*rx_gain;
540498e8a28Sdamien 	const struct athn_gain		*tx_gain;
541498e8a28Sdamien 	const struct athn_addac		*addac;
542328b15b2Skettenis 	const struct athn_serdes	*serdes;
543498e8a28Sdamien 	uint32_t			workaround;
544bd6ea91dSdamien 	uint32_t			obs_off;
545bd6ea91dSdamien 	uint32_t			gpio_input_en_off;
546498e8a28Sdamien 
547498e8a28Sdamien 	struct athn_ops			ops;
548498e8a28Sdamien 
549498e8a28Sdamien 	int				fixed_ridx;
550498e8a28Sdamien 
551bd6ea91dSdamien 	int16_t				cca_min_2g;
552bd6ea91dSdamien 	int16_t				cca_max_2g;
553bd6ea91dSdamien 	int16_t				cca_min_5g;
554bd6ea91dSdamien 	int16_t				cca_max_5g;
555498e8a28Sdamien 	struct {
556498e8a28Sdamien 		int16_t	nf[AR_MAX_CHAINS];
557498e8a28Sdamien 		int16_t	nf_ext[AR_MAX_CHAINS];
558498e8a28Sdamien 	}				nf_hist[ATHN_NF_CAL_HIST_MAX];
559498e8a28Sdamien 	int				nf_hist_cur;
5609d1f2812Sstsp 	int				nf_hist_nvalid;
561498e8a28Sdamien 	int16_t				nf_priv[AR_MAX_CHAINS];
562498e8a28Sdamien 	int16_t				nf_ext_priv[AR_MAX_CHAINS];
5639d1f2812Sstsp 	int				nf_calib_pending;
5649d1f2812Sstsp 	int				nf_calib_ticks;
5654116fd83Sdamien 	int				pa_calib_ticks;
566498e8a28Sdamien 
567498e8a28Sdamien 	struct athn_calib		calib;
568498e8a28Sdamien 	struct athn_ani			ani;
569498e8a28Sdamien 
570498e8a28Sdamien #if NBPFILTER > 0
571498e8a28Sdamien 	caddr_t				sc_drvbpf;
572498e8a28Sdamien 
573498e8a28Sdamien 	union {
574498e8a28Sdamien 		struct athn_rx_radiotap_header th;
575498e8a28Sdamien 		uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
576498e8a28Sdamien 	} sc_rxtapu;
577498e8a28Sdamien #define sc_rxtap			sc_rxtapu.th
578498e8a28Sdamien 	int				sc_rxtap_len;
579498e8a28Sdamien 
580498e8a28Sdamien 	union {
581498e8a28Sdamien 		struct athn_tx_radiotap_header th;
582498e8a28Sdamien 		uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
583498e8a28Sdamien 	} sc_txtapu;
584498e8a28Sdamien #define sc_txtap			sc_txtapu.th
585498e8a28Sdamien 	int				sc_txtap_len;
586498e8a28Sdamien #endif
587498e8a28Sdamien };
588498e8a28Sdamien 
589498e8a28Sdamien extern int	athn_attach(struct athn_softc *);
590498e8a28Sdamien extern void	athn_detach(struct athn_softc *);
59195d74b5fSkettenis extern void	athn_suspend(struct athn_softc *);
59237ecb596Sderaadt extern void	athn_wakeup(struct athn_softc *);
593498e8a28Sdamien extern int	athn_intr(void *);
594