/*	$NetBSD: athnvar.h,v 1.6 2017/02/02 10:05:35 nonaka Exp $	*/
/*	$OpenBSD: athnvar.h,v 1.34 2013/10/21 16:13:49 stsp Exp $	*/

/*-
 * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef _ATHNVAR_H_
#define _ATHNVAR_H_

#ifdef	_KERNEL_OPT
#include "opt_athn.h"
#endif

#define PUBLIC

#define IEEE80211_NO_HT		/* XXX: porting artifact */

#ifdef notyet
#define ATHN_BT_COEXISTENCE	1
#endif

#define ATHN_SOFTC(sc)		((struct athn_softc *)(sc))
#define ATHN_NODE(ni)		((struct athn_node *)(ni))

#ifdef ATHN_DEBUG
#define	DBG_INIT	__BIT(0)
#define	DBG_FN		__BIT(1)
#define	DBG_TX		__BIT(2)
#define	DBG_RX		__BIT(3)
#define	DBG_STM		__BIT(4)
#define	DBG_RF		__BIT(5)
#define	DBG_NODES	__BIT(6)
#define	DBG_INTR	__BIT(7)
#define	DBG_ALL		0xffffffffU
#define DPRINTFN(n, s, ...) do { \
	if (athn_debug & (n)) { \
		printf("%s: %s: ", \
			device_xname(ATHN_SOFTC(s)->sc_dev), __func__); \
		printf(__VA_ARGS__); \
	} \
} while (0)
extern int athn_debug;
#else /* ATHN_DEBUG */
#define DPRINTFN(n, s, ...)
#endif /* ATHN_DEBUG */

#define LE_READ_4(p)	((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24)
#define LE_READ_2(p)	((p)[0] | (p)[1] << 8)

#define ATHN_RXBUFSZ	3872
#define ATHN_TXBUFSZ	4096

#define ATHN_NRXBUFS	64
#define ATHN_NTXBUFS	64	/* Shared between all Tx queues. */

struct athn_rx_radiotap_header {
	struct ieee80211_radiotap_header wr_ihdr;
	uint64_t	wr_tsft;
	uint8_t		wr_flags;
	uint8_t		wr_rate;
	uint16_t	wr_chan_freq;
	uint16_t	wr_chan_flags;
	int8_t		wr_dbm_antsignal;
	uint8_t		wr_antenna;
} __packed;

#define ATHN_RX_RADIOTAP_PRESENT					\
	(1 << IEEE80211_RADIOTAP_TSFT |					\
	 1 << IEEE80211_RADIOTAP_FLAGS |				\
	 1 << IEEE80211_RADIOTAP_RATE |					\
	 1 << IEEE80211_RADIOTAP_CHANNEL |				\
	 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL |			\
	 1 << IEEE80211_RADIOTAP_ANTENNA)

struct athn_tx_radiotap_header {
	struct ieee80211_radiotap_header wt_ihdr;
	uint8_t		wt_flags;
	uint8_t		wt_rate;
	uint16_t	wt_chan_freq;
	uint16_t	wt_chan_flags;
} __packed;

#define ATHN_TX_RADIOTAP_PRESENT					\
	(1 << IEEE80211_RADIOTAP_FLAGS |				\
	 1 << IEEE80211_RADIOTAP_RATE |					\
	 1 << IEEE80211_RADIOTAP_CHANNEL)

struct athn_tx_buf {
	SIMPLEQ_ENTRY(athn_tx_buf)	bf_list;

	void				*bf_descs;
	bus_dmamap_t			bf_map;
	bus_addr_t			bf_daddr;

	struct mbuf			*bf_m;
	struct ieee80211_node		*bf_ni;
	int				bf_txflags;
#define ATHN_TXFLAG_PAPRD	(1 << 0)
#define ATHN_TXFLAG_CAB		(1 << 1)
};

struct athn_txq {
	SIMPLEQ_HEAD(, athn_tx_buf)	head;
	void				*lastds;
	struct athn_tx_buf		*wait;
	int				queued;
};

struct athn_rx_buf {
	SIMPLEQ_ENTRY(athn_rx_buf)	bf_list;

	void				*bf_desc;
	bus_dmamap_t			bf_map;

	struct mbuf			*bf_m;
	bus_addr_t			bf_daddr;
};

struct athn_rxq {
	struct athn_rx_buf		*bf;

	void				*descs;
	void				*lastds;
	bus_dmamap_t			map;
	bus_dma_segment_t		seg;
	int				count;

	SIMPLEQ_HEAD(, athn_rx_buf)	head;
};

/* Software rate indexes. */
#define ATHN_RIDX_CCK1	0
#define ATHN_RIDX_CCK2	1
#define ATHN_RIDX_OFDM6	4
#define ATHN_RIDX_MCS0	12
#define ATHN_RIDX_MCS15	27
#define ATHN_RIDX_MAX	27
#define ATHN_IS_HT_RIDX(ridx)	((ridx) >= ATHN_RIDX_MCS0)

static const struct athn_rate {
	uint8_t	rate;		/* Rate in 500Kbps unit or MCS if 0x80. */
	uint8_t	hwrate;		/* HW representation. */
	uint8_t	rspridx;	/* Control Response Frame rate index. */
	enum	ieee80211_phytype phy;
} athn_rates[] = {
	{    2, 0x1b, 0, IEEE80211_T_DS },
	{    4, 0x1a, 1, IEEE80211_T_DS },
	{   11, 0x19, 1, IEEE80211_T_DS },
	{   22, 0x18, 1, IEEE80211_T_DS },
	{   12, 0x0b, 4, IEEE80211_T_OFDM },
	{   18, 0x0f, 4, IEEE80211_T_OFDM },
	{   24, 0x0a, 6, IEEE80211_T_OFDM },
	{   36, 0x0e, 6, IEEE80211_T_OFDM },
	{   48, 0x09, 8, IEEE80211_T_OFDM },
	{   72, 0x0d, 8, IEEE80211_T_OFDM },
	{   96, 0x08, 8, IEEE80211_T_OFDM },
	{  108, 0x0c, 8, IEEE80211_T_OFDM },
	{ 0x80, 0x80, 8, IEEE80211_T_OFDM },
	{ 0x81, 0x81, 8, IEEE80211_T_OFDM },
	{ 0x82, 0x82, 8, IEEE80211_T_OFDM },
	{ 0x83, 0x83, 8, IEEE80211_T_OFDM },
	{ 0x84, 0x84, 8, IEEE80211_T_OFDM },
	{ 0x85, 0x85, 8, IEEE80211_T_OFDM },
	{ 0x86, 0x86, 8, IEEE80211_T_OFDM },
	{ 0x87, 0x87, 8, IEEE80211_T_OFDM },
	{ 0x88, 0x88, 8, IEEE80211_T_OFDM },
	{ 0x89, 0x89, 8, IEEE80211_T_OFDM },
	{ 0x8a, 0x8a, 8, IEEE80211_T_OFDM },
	{ 0x8b, 0x8b, 8, IEEE80211_T_OFDM },
	{ 0x8c, 0x8c, 8, IEEE80211_T_OFDM },
	{ 0x8d, 0x8d, 8, IEEE80211_T_OFDM },
	{ 0x8e, 0x8e, 8, IEEE80211_T_OFDM },
	{ 0x8f, 0x8f, 8, IEEE80211_T_OFDM }
};

struct athn_series {
	uint16_t	dur;
	uint8_t		hwrate;
};

struct athn_pier {
	uint8_t		fbin;
	const uint8_t	*pwr[AR_PD_GAINS_IN_MASK];
	const uint8_t	*vpd[AR_PD_GAINS_IN_MASK];
};

/*
 * Structures used to store initialization values.
 */
struct athn_ini {
	int		nregs;
	const uint16_t	*regs;
	const uint32_t	*vals_5g20;
#ifndef IEEE80211_NO_HT
	const uint32_t	*vals_5g40;
	const uint32_t	*vals_2g40;
#endif
	const uint32_t	*vals_2g20;
	int		ncmregs;
	const uint16_t	*cmregs;
	const uint32_t	*cmvals;
	int		nfastregs;
	const uint16_t	*fastregs;
	const uint32_t	*fastvals_5g20;
#ifndef IEEE80211_NO_HT
	const uint32_t	*fastvals_5g40;
#endif
};

struct athn_gain {
	int		nregs;
	const uint16_t	*regs;
	const uint32_t	*vals_5g;
	const uint32_t	*vals_2g;
};

struct athn_addac {
	int		nvals;
	const uint32_t	*vals;
};

struct athn_serdes {
	int		nvals;
	const uint32_t	*regs;
	const uint32_t	*vals;
};

/* Rx queue software indexes. */
#define ATHN_QID_LP		0
#define ATHN_QID_HP		1

/* Tx queue software indexes. */
#define ATHN_QID_AC_BE		0
#define ATHN_QID_PSPOLL		1
#define ATHN_QID_AC_BK		2
#define ATHN_QID_AC_VI		3
#define ATHN_QID_AC_VO		4
#define ATHN_QID_UAPSD		5
#define ATHN_QID_CAB		6
#define ATHN_QID_BEACON		7
#define ATHN_QID_COUNT		8

/* Map Access Category to Tx queue Id. */
static const uint8_t athn_ac2qid[WME_NUM_AC] = {
	ATHN_QID_AC_BE,	/* WME_AC_BE */
	ATHN_QID_AC_BK,	/* WME_AC_BK */
	ATHN_QID_AC_VI,	/* WME_AC_VI */
	ATHN_QID_AC_VO	/* WME_AC_VO */
};

static const uint8_t athn_5ghz_chans[] = {
	/* UNII 1. */
	36, 40, 44, 48,
	/* UNII 2. */
	52, 56, 60, 64,
	/* Middle band. */
	100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
	/* UNII 3. */
	149, 153, 157, 161, 165
};

/* Number of data bits per OFDM symbol for MCS[0-15]. */
/* See tables 20-29, 20-30, 20-33, 20-34. */
static const uint16_t ar_mcs_ndbps[][2] = {
	/* 20MHz  40MHz */
	{     26,    54 },	/* MCS0 */
	{     52,   108 },	/* MCS1 */
	{     78,   162 },	/* MCS2 */
	{    104,   216 },	/* MCS3 */
	{    156,   324 },	/* MCS4 */
	{    208,   432 },	/* MCS5 */
	{    234,   486 },	/* MCS6 */
	{    260,   540 },	/* MCS7 */
	{     26,   108 },	/* MCS8 */
	{     52,   216 },	/* MCS9 */
	{     78,   324 },	/* MCS10 */
	{    104,   432 },	/* MCS11 */
	{    156,   648 },	/* MCS12 */
	{    208,   864 },	/* MCS13 */
	{    234,   972 },	/* MCS14 */
	{    260,  1080 }	/* MCS15 */
};

#define ATHN_POWER_OFDM6	0
#define ATHN_POWER_OFDM9	1
#define ATHN_POWER_OFDM12	2
#define ATHN_POWER_OFDM18	3
#define ATHN_POWER_OFDM24	4
#define ATHN_POWER_OFDM36	5
#define ATHN_POWER_OFDM48	6
#define ATHN_POWER_OFDM54	7
#define ATHN_POWER_CCK1_LP	8
#define ATHN_POWER_CCK2_LP	9
#define ATHN_POWER_CCK2_SP	10
#define ATHN_POWER_CCK55_LP	11
#define ATHN_POWER_CCK55_SP	12
#define ATHN_POWER_CCK11_LP	13
#define ATHN_POWER_CCK11_SP	14
#define ATHN_POWER_XR		15
#define ATHN_POWER_HT20(mcs)	(16 + (mcs))
#define ATHN_POWER_HT40(mcs)	(40 + (mcs))
#define ATHN_POWER_CCK_DUP	64
#define ATHN_POWER_OFDM_DUP	65
#define ATHN_POWER_CCK_EXT	66
#define ATHN_POWER_OFDM_EXT	67
#define ATHN_POWER_COUNT	68

struct athn_node {
	struct ieee80211_node		ni;
	struct ieee80211_amrr_node	amn;
	uint8_t				ridx[IEEE80211_RATE_MAXSIZE];
	uint8_t				fallback[IEEE80211_RATE_MAXSIZE];
	uint8_t				sta_index;
};

/*
 * Adaptive noise immunity state.
 */
#define ATHN_ANI_PERIOD		100
#define ATHN_ANI_RSSI_THR_HIGH	40
#define ATHN_ANI_RSSI_THR_LOW	7
struct athn_ani {
	uint8_t		noise_immunity_level;
	uint8_t		spur_immunity_level;
	uint8_t		firstep_level;
	uint8_t		ofdm_weak_signal;
	uint8_t		cck_weak_signal;

	uint32_t	listen_time;

	uint32_t	ofdm_trig_high;
	uint32_t	ofdm_trig_low;

	int32_t		cck_trig_high;
	int32_t		cck_trig_low;

	uint32_t	ofdm_phy_err_base;
	uint32_t	cck_phy_err_base;
	uint32_t	ofdm_phy_err_count;
	uint32_t	cck_phy_err_count;

	uint32_t	cyccnt;
	uint32_t	txfcnt;
	uint32_t	rxfcnt;
};

struct athn_iq_cal {
	uint32_t	pwr_meas_i;
	uint32_t	pwr_meas_q;
	int32_t		iq_corr_meas;
};

struct athn_adc_cal {
	uint32_t	pwr_meas_odd_i;
	uint32_t	pwr_meas_even_i;
	uint32_t	pwr_meas_odd_q;
	uint32_t	pwr_meas_even_q;
};

struct athn_calib {
	int			nsamples;
	struct athn_iq_cal	iq[AR_MAX_CHAINS];
	struct athn_adc_cal	adc_gain[AR_MAX_CHAINS];
	struct athn_adc_cal	adc_dc_offset[AR_MAX_CHAINS];
};

#define ATHN_NF_CAL_HIST_MAX	5

struct athn_softc;

struct athn_ops {
	/* Bus callbacks. */
	uint32_t	(*read)(struct athn_softc *, uint32_t);
	void		(*write)(struct athn_softc *, uint32_t, uint32_t);
	void		(*write_barrier)(struct athn_softc *);

	void	(*setup)(struct athn_softc *);
	void	(*set_txpower)(struct athn_softc *, struct ieee80211_channel *,
		    struct ieee80211_channel *);
	void	(*spur_mitigate)(struct athn_softc *,
		    struct ieee80211_channel *, struct ieee80211_channel *);
	const struct ar_spur_chan *
		(*get_spur_chans)(struct athn_softc *, int);
	void	(*init_from_rom)(struct athn_softc *,
		    struct ieee80211_channel *, struct ieee80211_channel *);
	int	(*set_synth)(struct athn_softc *, struct ieee80211_channel *,
		    struct ieee80211_channel *);
	int	(*read_rom_data)(struct athn_softc *, uint32_t, void *, int);
	const uint8_t *
		(*get_rom_template)(struct athn_softc *, uint8_t);
	void	(*swap_rom)(struct athn_softc *);
	void	(*olpc_init)(struct athn_softc *);
	void	(*olpc_temp_compensation)(struct athn_softc *);

	/* GPIO callbacks. */
	int	(*gpio_read)(struct athn_softc *, int);
	void	(*gpio_write)(struct athn_softc *, int, int);
	void	(*gpio_config_input)(struct athn_softc *, int);
	void	(*gpio_config_output)(struct athn_softc *, int, int);
	void	(*rfsilent_init)(struct athn_softc *);

	/* DMA callbacks. */
	int	(*dma_alloc)(struct athn_softc *);
	void	(*dma_free)(struct athn_softc *);
	void	(*rx_enable)(struct athn_softc *);
	int	(*intr_status)(struct athn_softc *);
	int	(*intr)(struct athn_softc *);
	int	(*tx)(struct athn_softc *, struct mbuf *,
		    struct ieee80211_node *, int);

	/* PHY callbacks. */
	void	(*set_rf_mode)(struct athn_softc *,
		    struct ieee80211_channel *);
	int	(*rf_bus_request)(struct athn_softc *);
	void	(*rf_bus_release)(struct athn_softc *);
	void	(*set_phy)(struct athn_softc *, struct ieee80211_channel *,
		    struct ieee80211_channel *);
	void	(*set_delta_slope)(struct athn_softc *,
		    struct ieee80211_channel *, struct ieee80211_channel *);
	void	(*enable_antenna_diversity)(struct athn_softc *);
	void	(*init_baseband)(struct athn_softc *);
	void	(*disable_phy)(struct athn_softc *);
	void	(*set_rxchains)(struct athn_softc *);
	void	(*noisefloor_calib)(struct athn_softc *);
	void	(*do_calib)(struct athn_softc *);
	void	(*next_calib)(struct athn_softc *);
	void	(*hw_init)(struct athn_softc *, struct ieee80211_channel *,
		    struct ieee80211_channel *);
	void	(*get_paprd_masks)(struct athn_softc *sc,
		    struct ieee80211_channel *, uint32_t *, uint32_t *);

	/* ANI callbacks. */
	void	(*set_noise_immunity_level)(struct athn_softc *, int);
	void	(*enable_ofdm_weak_signal)(struct athn_softc *);
	void	(*disable_ofdm_weak_signal)(struct athn_softc *);
	void	(*set_cck_weak_signal)(struct athn_softc *, int);
	void	(*set_firstep_level)(struct athn_softc *, int);
	void	(*set_spur_immunity_level)(struct athn_softc *, int);
};

struct athn_softc {
	device_t			sc_dev;
	device_suspensor_t		sc_suspensor;
	pmf_qual_t			sc_qual;
	struct ieee80211com		sc_ic;
	struct ethercom			sc_ec;
#define sc_if	sc_ec.ec_if
	void				*sc_soft_ih;

#if 0
	int				(*sc_enable)(struct athn_softc *);
	void				(*sc_disable)(struct athn_softc *);
	void				(*sc_power)(struct athn_softc *, int);
#endif
	void				(*sc_disable_aspm)(struct athn_softc *);
	void				(*sc_enable_extsynch)(
					    struct athn_softc *);

	int				(*sc_newstate)(struct ieee80211com *,
					    enum ieee80211_state, int);

	bus_dma_tag_t			sc_dmat;

	callout_t			sc_scan_to;
	callout_t			sc_calib_to;
	struct ieee80211_amrr		sc_amrr;

	u_int				sc_flags;
#define ATHN_FLAG_PCIE			(1 << 0)
#define ATHN_FLAG_USB			(1 << 1)
#define ATHN_FLAG_OLPC			(1 << 2)
#define ATHN_FLAG_PAPRD			(1 << 3)
#define ATHN_FLAG_FAST_PLL_CLOCK	(1 << 4)
#define ATHN_FLAG_RFSILENT		(1 << 5)
#define ATHN_FLAG_RFSILENT_REVERSED	(1 << 6)
#define ATHN_FLAG_BTCOEX2WIRE		(1 << 7)
#define ATHN_FLAG_BTCOEX3WIRE		(1 << 8)
/* Shortcut. */
#define ATHN_FLAG_BTCOEX	(ATHN_FLAG_BTCOEX2WIRE | ATHN_FLAG_BTCOEX3WIRE)
#define ATHN_FLAG_11A			(1 << 9)
#define ATHN_FLAG_11G			(1 << 10)
#define ATHN_FLAG_11N			(1 << 11)
#define ATHN_FLAG_AN_TOP2_FIXUP		(1 << 12)
#define ATHN_FLAG_NON_ENTERPRISE	(1 << 13)
#define ATHN_FLAG_3TREDUCE_CHAIN	(1 << 14)

	uint8_t				sc_ngpiopins;
	int				sc_led_pin;
	int				sc_rfsilent_pin;
	int				sc_led_state;
	uint32_t			sc_isync;
	uint32_t			sc_imask;

	uint16_t			sc_mac_ver;
	uint8_t				sc_mac_rev;
	uint8_t				sc_rf_rev;
	uint16_t			sc_eep_rev;

	uint8_t				sc_txchainmask;
	uint8_t				sc_rxchainmask;
	uint8_t				sc_ntxchains;
	uint8_t				sc_nrxchains;

	uint8_t				sc_sup_calib_mask;
	uint8_t				sc_cur_calib_mask;
#define ATHN_CAL_IQ		(1 << 0)
#define ATHN_CAL_ADC_GAIN	(1 << 1)
#define ATHN_CAL_ADC_DC		(1 << 2)
#define ATHN_CAL_TEMP		(1 << 3)

	struct ieee80211_channel	*sc_curchan;
	struct ieee80211_channel	*sc_curchanext;

	/* Open Loop Power Control. */
	int8_t				sc_tx_gain_tbl[AR9280_TX_GAIN_TABLE_SIZE];
	int8_t				sc_pdadc;
	int8_t				sc_tcomp;
	int				sc_olpc_ticks;

	/* PA predistortion. */
	uint16_t			sc_gain1[AR_MAX_CHAINS];
	uint32_t			sc_txgain[AR9003_TX_GAIN_TABLE_SIZE];
	int16_t				sc_pa_in[AR_MAX_CHAINS]
					     [AR9003_PAPRD_MEM_TAB_SIZE];
	int16_t				sc_angle[AR_MAX_CHAINS]
					     [AR9003_PAPRD_MEM_TAB_SIZE];
	int32_t				sc_trainpow;
	uint8_t				sc_paprd_curchain;

	uint32_t			sc_rwbuf[64];

	size_t				sc_kc_entries;

	void				*sc_eep;
	const void			*sc_eep_def;
	uint32_t			sc_eep_base;
	uint32_t			sc_eep_size;

	struct athn_rxq			sc_rxq[2];
	struct athn_txq			sc_txq[31];

	void				*sc_descs;
	bus_dmamap_t			sc_map;
	bus_dma_segment_t		sc_seg;
	SIMPLEQ_HEAD(, athn_tx_buf)	sc_txbufs;
	struct athn_tx_buf		*sc_bcnbuf;
	struct athn_tx_buf		sc_txpool[ATHN_NTXBUFS];

	bus_dmamap_t			sc_txsmap;
	bus_dma_segment_t		sc_txsseg;
	void				*sc_txsring;
	int				sc_txscur;

	int				sc_if_flags;
	int				sc_tx_timer;

	const struct athn_ini		*sc_ini;
	const struct athn_gain		*sc_rx_gain;
	const struct athn_gain		*sc_tx_gain;
	const struct athn_addac		*sc_addac;
	const struct athn_serdes	*sc_serdes;
	uint32_t			sc_workaround;
	uint32_t			sc_obs_off;
	uint32_t			sc_gpio_input_en_off;

	struct athn_ops			sc_ops;

	int				sc_fixed_ridx;

	int16_t				sc_cca_min_2g;
	int16_t				sc_cca_max_2g;
	int16_t				sc_cca_min_5g;
	int16_t				sc_cca_max_5g;
	int16_t				sc_def_nf;
	struct {
		int16_t	nf[AR_MAX_CHAINS];
		int16_t	nf_ext[AR_MAX_CHAINS];
	}				sc_nf_hist[ATHN_NF_CAL_HIST_MAX];
	int				sc_nf_hist_cur;
	int16_t				sc_nf_priv[AR_MAX_CHAINS];
	int16_t				sc_nf_ext_priv[AR_MAX_CHAINS];
	int				sc_pa_calib_ticks;

	struct athn_calib		sc_calib;
	struct athn_ani			sc_ani;

	struct bpf_if *			sc_drvbpf;

	union {
		struct athn_rx_radiotap_header th;
		uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
	} sc_rxtapu;
#define sc_rxtap			sc_rxtapu.th
	int				sc_rxtap_len;

	union {
		struct athn_tx_radiotap_header th;
		uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
	} sc_txtapu;
#define sc_txtap			sc_txtapu.th
	int				sc_txtap_len;

	/*
	 * Attach overrides.  Set before calling athn_attach().
	 */
	int				sc_max_aid;
	int				(*sc_media_change)(struct ifnet *);
};

int	athn_attach(struct athn_softc *);
void	athn_detach(struct athn_softc *);
void	athn_suspend(struct athn_softc *);
bool	athn_resume(struct athn_softc *);
int	athn_intr(void *);

/* used by if_athn_usb.c */
void	athn_btcoex_init(struct athn_softc *);
int	athn_hw_reset(struct athn_softc *, struct ieee80211_channel *,
	    struct ieee80211_channel *, int);
void	athn_init_pll(struct athn_softc *, const struct ieee80211_channel *);
void	athn_led_init(struct athn_softc *);
int	athn_reset(struct athn_softc *, int);
void	athn_reset_key(struct athn_softc *, int);
void	athn_rx_start(struct athn_softc *);
void	athn_set_bss(struct athn_softc *, struct ieee80211_node *);
int	athn_set_chan(struct athn_softc *, struct ieee80211_channel *,
	    struct ieee80211_channel *);
void	athn_set_hostap_timers(struct athn_softc *);
void	athn_set_led(struct athn_softc *, int);
void	athn_set_opmode(struct athn_softc *);
int	athn_set_power_awake(struct athn_softc *);
void	athn_set_power_sleep(struct athn_softc *);
void	athn_set_rxfilter(struct athn_softc *, uint32_t);
void	athn_set_sta_timers(struct athn_softc *);
void	athn_updateslot(struct ifnet *);

#ifdef notyet_edca
void	athn_updateedca(struct ieee80211com *);
#endif
#ifdef notyet
void	athn_delete_key(struct ieee80211com *, struct ieee80211_node *,
	    struct ieee80211_key *);
int	athn_set_key(struct ieee80211com *, struct ieee80211_node *,
	    struct ieee80211_key *);
#endif /* notyet */

/* used by ar9285.c */
uint8_t	athn_chan2fbin(struct ieee80211_channel *);
void	athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *);

/* used by arn5008.c and arn9003.c */
void	athn_config_nonpcie(struct athn_softc *);
void	athn_config_pcie(struct athn_softc *);
void	athn_get_delta_slope(uint32_t, uint32_t *, uint32_t *);
void	athn_inc_tx_trigger_level(struct athn_softc *);
void	athn_stop(struct ifnet *, int);
void	athn_stop_tx_dma(struct athn_softc *, int);
int	athn_tx_pending(struct athn_softc *, int);
int	athn_txtime(struct athn_softc *, int, int, u_int);

/* used by arn5008.c, arn9003.c, arn9287.c, and arn9380.c */
int	athn_interpolate(int, int, int, int, int);

#endif /* _ATHNVAR_H_ */