/*      $OpenBSD: athvar.h,v 1.35 2020/10/11 07:05:28 mpi Exp $  */
/*	$NetBSD: athvar.h,v 1.10 2004/08/10 01:03:53 dyoung Exp $	*/

/*-
 * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
 *    redistribution must be conditioned upon including a substantially
 *    similar Disclaimer requirement for further binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGES.
 *
 * $FreeBSD: src/sys/dev/ath/if_athvar.h,v 1.14 2004/04/03 03:33:02 sam Exp $
 */

/*
 * Definitions for the Atheros Wireless LAN controller driver.
 */
#ifndef _DEV_ATH_ATHVAR_H
#define _DEV_ATH_ATHVAR_H

#ifdef _KERNEL

#include <net80211/ieee80211_radiotap.h>
#include <dev/ic/ar5xxx.h>

#include "bpfilter.h"

#ifdef notyet
#include "gpio.h"
#endif

#define	ATH_TIMEOUT		1000

#define	ATH_RXBUF	40		/* number of RX buffers */
#define	ATH_TXBUF	60		/* number of TX buffers */
#define	ATH_TXDESC	8		/* number of descriptors per buffer */
#define ATH_MAXGPIO	10		/* maximal number of gpio pins */

struct ath_recv_hist {
	int		arh_ticks;	/* sample time by system clock */
	u_int8_t	arh_rssi;	/* rssi */
	u_int8_t	arh_antenna;	/* antenna */
};
#define	ATH_RHIST_SIZE		16	/* number of samples */
#define	ATH_RHIST_NOTIME	(~0)

/*
 * Ioctl-related definitions for the Atheros Wireless LAN controller driver.
 */
struct ath_stats {
	u_int32_t	ast_watchdog;	/* device reset by watchdog */
	u_int32_t	ast_hardware;	/* fatal hardware error interrupts */
	u_int32_t	ast_bmiss;	/* beacon miss interrupts */
	u_int32_t	ast_mib;	/* MIB counter interrupts */
	u_int32_t	ast_rxorn;	/* rx overrun interrupts */
	u_int32_t	ast_rxeol;	/* rx eol interrupts */
	u_int32_t	ast_txurn;	/* tx underrun interrupts */
	u_int32_t	ast_intrcoal;	/* interrupts coalesced */
	u_int32_t	ast_tx_mgmt;	/* management frames transmitted */
	u_int32_t	ast_tx_discard;	/* frames discarded prior to assoc */
	u_int32_t	ast_tx_qstop;	/* output stopped 'cuz no buffer */
	u_int32_t	ast_tx_encap;	/* tx encapsulation failed */
	u_int32_t	ast_tx_nonode;	/* tx failed 'cuz no node */
	u_int32_t	ast_tx_nombuf;	/* tx failed 'cuz no mbuf */
	u_int32_t	ast_tx_nomcl;	/* tx failed 'cuz no cluster */
	u_int32_t	ast_tx_linear;	/* tx linearized to cluster */
	u_int32_t	ast_tx_nodata;	/* tx discarded empty frame */
	u_int32_t	ast_tx_busdma;	/* tx failed for dma resrcs */
	u_int32_t	ast_tx_xretries;/* tx failed 'cuz too many retries */
	u_int32_t	ast_tx_fifoerr;	/* tx failed 'cuz FIFO underrun */
	u_int32_t	ast_tx_filtered;/* tx failed 'cuz xmit filtered */
	u_int32_t	ast_tx_shortretry;/* tx on-chip retries (short) */
	u_int32_t	ast_tx_longretry;/* tx on-chip retries (long) */
	u_int32_t	ast_tx_badrate;	/* tx failed 'cuz bogus xmit rate */
	u_int32_t	ast_tx_noack;	/* tx frames with no ack marked */
	u_int32_t	ast_tx_rts;	/* tx frames with rts enabled */
	u_int32_t	ast_tx_cts;	/* tx frames with cts enabled */
	u_int32_t	ast_tx_shortpre;/* tx frames with short preamble */
	u_int32_t	ast_tx_altrate;	/* tx frames with alternate rate */
	u_int32_t	ast_tx_protect;	/* tx frames with protection */
	u_int32_t	ast_rx_nombuf;	/* rx setup failed 'cuz no mbuf */
	u_int32_t	ast_rx_busdma;	/* rx setup failed for dma resrcs */
	u_int32_t	ast_rx_orn;	/* rx failed 'cuz of desc overrun */
	u_int32_t	ast_rx_crcerr;	/* rx failed 'cuz of bad CRC */
	u_int32_t	ast_rx_fifoerr;	/* rx failed 'cuz of FIFO overrun */
	u_int32_t	ast_rx_badcrypt;/* rx failed 'cuz decryption */
	u_int32_t	ast_rx_phyerr;	/* rx failed 'cuz of PHY err */
	u_int32_t	ast_rx_phy[32];	/* rx PHY error per-code counts */
	u_int32_t	ast_rx_tooshort;/* rx discarded 'cuz frame too short */
	u_int32_t	ast_rx_toobig;	/* rx discarded 'cuz frame too large */
	u_int32_t	ast_rx_ctl;	/* rx discarded 'cuz ctl frame */
	u_int32_t	ast_be_nombuf;	/* beacon setup failed 'cuz no mbuf */
	u_int32_t	ast_per_cal;	/* periodic calibration calls */
	u_int32_t	ast_per_calfail;/* periodic calibration failed */
	u_int32_t	ast_per_rfgain;	/* periodic calibration rfgain reset */
	u_int32_t	ast_rate_calls;	/* rate control checks */
	u_int32_t	ast_rate_raise;	/* rate control raised xmit rate */
	u_int32_t	ast_rate_drop;	/* rate control dropped xmit rate */
};

/*
 * Radio capture format.
 */
#define ATH_RX_RADIOTAP_PRESENT (		\
	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
	(1 << IEEE80211_RADIOTAP_RATE)		| \
	(1 << IEEE80211_RADIOTAP_CHANNEL)	| \
	(1 << IEEE80211_RADIOTAP_ANTENNA)	| \
	(1 << IEEE80211_RADIOTAP_RSSI)		| \
	0)

struct ath_rx_radiotap_header {
	struct ieee80211_radiotap_header wr_ihdr;
	u_int8_t	wr_flags;
	u_int8_t	wr_rate;
	u_int16_t	wr_chan_freq;
	u_int16_t	wr_chan_flags;
	u_int8_t	wr_antenna;
	u_int8_t	wr_rssi;
	u_int8_t	wr_max_rssi;
} __packed;

#define ATH_TX_RADIOTAP_PRESENT (		\
	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
	(1 << IEEE80211_RADIOTAP_RATE)		| \
	(1 << IEEE80211_RADIOTAP_CHANNEL)	| \
	(1 << IEEE80211_RADIOTAP_DBM_TX_POWER)	| \
	(1 << IEEE80211_RADIOTAP_ANTENNA)	| \
	0)

struct ath_tx_radiotap_header {
	struct ieee80211_radiotap_header wt_ihdr;
	u_int8_t	wt_flags;
	u_int8_t	wt_rate;
	u_int16_t	wt_chan_freq;
	u_int16_t	wt_chan_flags;
	u_int8_t	wt_txpower;
	u_int8_t	wt_antenna;
} __packed;

/* 
 * driver-specific node 
 */
struct ath_node {
	struct ieee80211_node		an_node;	/* base class */
	struct ieee80211_rssadapt	an_rssadapt;	/* rate adaption */
	u_int				an_tx_antenna;	/* antenna for last good frame */
	u_int				an_rx_antenna;	/* antenna for last rcvd frame */
	struct ath_recv_hist		an_rx_hist[ATH_RHIST_SIZE];
	u_int				an_rx_hist_next;/* index of next ``free entry'' */
};
#define	ATH_NODE(_n)	((struct ath_node *)(_n))

struct ath_buf {
	TAILQ_ENTRY(ath_buf)		bf_list;
	bus_dmamap_t			bf_dmamap;	/* DMA map of the buffer */
#define bf_nseg				bf_dmamap->dm_nsegs
#define bf_mapsize			bf_dmamap->dm_mapsize
#define bf_segs				bf_dmamap->dm_segs
	struct ath_desc			*bf_desc;	/* virtual addr of desc */
	bus_addr_t			bf_daddr;	/* physical addr of desc */
	struct mbuf			*bf_m;		/* mbuf for buf */
	struct ieee80211_node		*bf_node;	/* pointer to the node */
	struct ieee80211_rssdesc	bf_id;
#define	ATH_MAX_SCATTER			64
};

typedef struct ath_task {
	void	(*t_func)(void*, int);
	void	*t_context;
} ath_task_t;

struct ath_softc {
#ifndef __FreeBSD__
	struct device		sc_dev;
#endif
	struct ieee80211com	sc_ic;		/* IEEE 802.11 common */
#ifndef __FreeBSD__
	int			(*sc_enable)(struct ath_softc *);
	void			(*sc_disable)(struct ath_softc *);
	void			(*sc_power)(struct ath_softc *, int);
#endif
	int			(*sc_newstate)(struct ieee80211com *,
					enum ieee80211_state, int);
	void			(*sc_node_free)(struct ieee80211com *,
					struct ieee80211_node *);
	void			(*sc_node_copy)(struct ieee80211com *,
					struct ieee80211_node *,
					const struct ieee80211_node *);
	void			(*sc_recv_mgmt)(struct ieee80211com *,
				    struct mbuf *, struct ieee80211_node *,
				    struct ieee80211_rxinfo *, int);
#ifdef __FreeBSD__
	device_t		sc_dev;
#endif
	bus_space_tag_t		sc_st;		/* bus space tag */
	bus_space_handle_t	sc_sh;		/* bus space handle */
	bus_size_t		sc_ss;		/* bus space size */
	bus_dma_tag_t		sc_dmat;	/* bus DMA tag */
#ifdef __FreeBSD__
	struct mtx		sc_mtx;		/* master lock (recursive) */
#endif
	struct ath_hal		*sc_ah;		/* Atheros HAL */
	unsigned int		sc_invalid : 1,	/* disable hardware accesses */
				sc_doani : 1,	/* dynamic noise immunity */
				sc_veol : 1,	/* tx VEOL support */
				sc_softled : 1,	/* GPIO software LED */
				sc_probing : 1,	/* probing AP on beacon miss */
				sc_pcie : 1;	/* indicates PCI Express */
	u_int			sc_nchan;	/* number of valid channels */
	const HAL_RATE_TABLE	*sc_rates[IEEE80211_MODE_MAX];
	const HAL_RATE_TABLE	*sc_currates;	/* current rate table */
	enum ieee80211_phymode	sc_curmode;	/* current phy mode */
	u_int8_t		sc_rixmap[256];	/* IEEE to h/w rate table ix */
	u_int8_t		sc_hwmap[32];	/* h/w rate ix to IEEE table */
	HAL_INT			sc_imask;	/* interrupt mask copy */

#if NBPFILTER > 0
	caddr_t			sc_drvbpf;

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

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

	struct ath_desc		*sc_desc;	/* TX/RX descriptors */
	bus_dma_segment_t	sc_dseg;
	int			sc_dnseg;	/* number of segments */
	bus_dmamap_t		sc_ddmamap;	/* DMA map for descriptors */
	bus_addr_t		sc_desc_paddr;	/* physical addr of sc_desc */
	bus_addr_t		sc_desc_len;	/* size of sc_desc */

	ath_task_t		sc_fataltask;	/* fatal int processing */
	ath_task_t		sc_rxorntask;	/* rxorn int processing */

	TAILQ_HEAD(, ath_buf)	sc_rxbuf;	/* receive buffer */
	u_int32_t		*sc_rxlink;	/* link ptr in last RX desc */
	ath_task_t		sc_rxtask;	/* rx int processing */

	u_int			sc_txhalq[HAL_NUM_TX_QUEUES];	/* HAL q for outgoing frames */
	u_int32_t		*sc_txlink;	/* link ptr in last TX desc */
	int			sc_tx_timer;	/* transmit timeout */
	TAILQ_HEAD(, ath_buf)	sc_txbuf;	/* transmit buffer */
#ifdef __FreeBSD__
	struct mtx		sc_txbuflock;	/* txbuf lock */
#endif
	TAILQ_HEAD(, ath_buf)	sc_txq;		/* transmitting queue */
#ifdef __FreeBSD__
	struct mtx		sc_txqlock;	/* lock on txq and txlink */
#endif
	ath_task_t		sc_txtask;	/* tx int processing */

	u_int			sc_bhalq;	/* HAL q for outgoing beacons */
	struct ath_buf		*sc_bcbuf;	/* beacon buffer */
	struct ath_buf		*sc_bufptr;	/* allocated buffer ptr */
	ath_task_t		sc_swbatask;	/* swba int processing */
	ath_task_t		sc_bmisstask;	/* bmiss int processing */

#ifdef __OpenBSD__
	struct timeval		sc_last_ch;
	struct timeout		sc_cal_to;
	struct timeval		sc_last_beacon;
	struct timeout		sc_scan_to;
	struct timeout		sc_rssadapt_to;
#else
	struct callout		sc_cal_ch;	/* callout handle for cals */
	struct callout		sc_scan_ch;	/* callout handle for scan */
#endif
	struct ath_stats	sc_stats;	/* interface statistics */
	HAL_MIB_STATS		sc_mib_stats;	/* MIB counter statistics */

#ifndef __FreeBSD__
	u_int			sc_flags;	/* misc flags */
#endif

	u_int8_t                sc_broadcast_addr[IEEE80211_ADDR_LEN];

	struct gpio_chipset_tag sc_gpio_gc;	/* gpio(4) framework */
	gpio_pin_t		sc_gpio_pins[ATH_MAXGPIO];
};

/* unaligned little endian access */     
#define LE_READ_2(p)							\
	((u_int16_t)							\
	 ((((u_int8_t *)(p))[0]      ) | (((u_int8_t *)(p))[1] <<  8)))
#define LE_READ_4(p)							\
	((u_int32_t)							\
	 ((((u_int8_t *)(p))[0]      ) | (((u_int8_t *)(p))[1] <<  8) |	\
	 (((u_int8_t *)(p))[2] << 16) | (((u_int8_t *)(p))[3] << 24)))

#ifdef AR_DEBUG
enum {
	ATH_DEBUG_XMIT		= 0x00000001,	/* basic xmit operation */
	ATH_DEBUG_XMIT_DESC	= 0x00000002,	/* xmit descriptors */
	ATH_DEBUG_RECV		= 0x00000004,	/* basic recv operation */
	ATH_DEBUG_RECV_DESC	= 0x00000008,	/* recv descriptors */
	ATH_DEBUG_RATE		= 0x00000010,	/* rate control */
	ATH_DEBUG_RESET		= 0x00000020,	/* reset processing */
	ATH_DEBUG_MODE		= 0x00000040,	/* mode init/setup */
	ATH_DEBUG_BEACON	= 0x00000080,	/* beacon handling */
	ATH_DEBUG_WATCHDOG	= 0x00000100,	/* watchdog timeout */
	ATH_DEBUG_INTR		= 0x00001000,	/* ISR */
	ATH_DEBUG_TX_PROC	= 0x00002000,	/* tx ISR proc */
	ATH_DEBUG_RX_PROC	= 0x00004000,	/* rx ISR proc */
	ATH_DEBUG_BEACON_PROC	= 0x00008000,	/* beacon ISR proc */
	ATH_DEBUG_CALIBRATE	= 0x00010000,	/* periodic calibration */
	ATH_DEBUG_ANY		= 0xffffffff
};
#define	IFF_DUMPPKTS(_ifp, _m) \
	((ath_debug & _m) || \
	    ((_ifp)->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
#define	DPRINTF(_m,X)	if (ath_debug & (_m)) printf X
#else
#define	IFF_DUMPPKTS(_ifp, _m) \
	(((_ifp)->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
#define	DPRINTF(_m, X)
#endif

/*
 * Wrapper code
 */
#ifndef __FreeBSD__
#undef KASSERT
#define KASSERT(cond, complaint) if (!(cond)) panic complaint

#define	ATH_ATTACHED		0x0001		/* attach has succeeded */
#define ATH_ENABLED		0x0002		/* chip is enabled */
#define ATH_GPIO		0x0004		/* gpio device attached */

#define	ATH_IS_ENABLED(sc)	((sc)->sc_flags & ATH_ENABLED)
#endif

#define	ATH_LOCK_INIT(_sc) \
	mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
		 MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE)
#define	ATH_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_mtx)
#define	ATH_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
#define	ATH_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
#define	ATH_LOCK_ASSERT(_sc)	mtx_assert(&(_sc)->sc_mtx, MA_OWNED)

#define	ATH_TXBUF_LOCK_INIT(_sc) \
	mtx_init(&(_sc)->sc_txbuflock, \
		device_get_nameunit((_sc)->sc_dev), "xmit buf q", MTX_DEF)
#define	ATH_TXBUF_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_txbuflock)
#define	ATH_TXBUF_LOCK(_sc)		mtx_lock(&(_sc)->sc_txbuflock)
#define	ATH_TXBUF_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_txbuflock)
#define	ATH_TXBUF_LOCK_ASSERT(_sc) \
	mtx_assert(&(_sc)->sc_txbuflock, MA_OWNED)

#define	ATH_TXQ_LOCK_INIT(_sc) \
	mtx_init(&(_sc)->sc_txqlock, \
		device_get_nameunit((_sc)->sc_dev), "xmit q", MTX_DEF)
#define	ATH_TXQ_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_txqlock)
#define	ATH_TXQ_LOCK(_sc)		mtx_lock(&(_sc)->sc_txqlock)
#define	ATH_TXQ_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_txqlock)
#define	ATH_TXQ_LOCK_ASSERT(_sc)	mtx_assert(&(_sc)->sc_txqlock, MA_OWNED)

#define ATH_TICKS() (ticks)
#define ATH_CALLOUT_INIT(chp) callout_init((chp))
#define ATH_TASK_INIT(task, func, context)	\
	do {					\
		(task)->t_func = (func);	\
		(task)->t_context = (context);	\
	} while (0)
#define ATH_TASK_RUN_OR_ENQUEUE(task) ((*(task)->t_func)((task)->t_context, 1))

typedef unsigned long u_intptr_t;

int	ath_attach(u_int16_t, struct ath_softc *);
int	ath_detach(struct ath_softc *, int);
int	ath_enable(struct ath_softc *);
int	ath_activate(struct device *, int);
int	ath_intr(void *);
int	ath_enable(struct ath_softc *);

/*
 * HAL definitions to comply with local coding convention.
 */
#define	ath_hal_reset(_ah, _opmode, _chan, _outdoor, _pstatus) \
	((*(_ah)->ah_reset)((_ah), (_opmode), (_chan), (_outdoor), (_pstatus)))
#define	ath_hal_get_rate_table(_ah, _mode) \
	((*(_ah)->ah_get_rate_table)((_ah), (_mode)))
#define	ath_hal_get_lladdr(_ah, _mac) \
	((*(_ah)->ah_get_lladdr)((_ah), (_mac)))
#define	ath_hal_set_lladdr(_ah, _mac) \
	((*(_ah)->ah_set_lladdr)((_ah), (_mac)))
#define	ath_hal_set_intr(_ah, _mask) \
	((*(_ah)->ah_set_intr)((_ah), (_mask)))
#define	ath_hal_get_intr(_ah) \
	((*(_ah)->ah_get_intr)((_ah)))
#define	ath_hal_is_intr_pending(_ah) \
	((*(_ah)->ah_is_intr_pending)((_ah)))
#define	ath_hal_get_isr(_ah, _pmask) \
	((*(_ah)->ah_get_isr)((_ah), (_pmask)))
#define	ath_hal_update_tx_triglevel(_ah, _inc) \
	((*(_ah)->ah_update_tx_triglevel)((_ah), (_inc)))
#define	ath_hal_set_power(_ah, _mode, _sleepduration) \
	((*(_ah)->ah_set_power)((_ah), (_mode), AH_TRUE, (_sleepduration)))
#define	ath_hal_reset_key(_ah, _ix) \
	((*(_ah)->ah_reset_key)((_ah), (_ix)))
#define	ath_hal_set_key(_ah, _ix, _pk) \
	((*(_ah)->ah_set_key)((_ah), (_ix), (_pk), NULL, AH_FALSE))
#define	ath_hal_is_key_valid(_ah, _ix) \
	(((*(_ah)->ah_is_key_valid)((_ah), (_ix))))
#define	ath_hal_set_key_lladdr(_ah, _ix, _mac) \
	((*(_ah)->ah_set_key_lladdr)((_ah), (_ix), (_mac)))
#define	ath_hal_softcrypto(_ah, _val ) \
	((*(_ah)->ah_softcrypto)((_ah), (_val)))
#define	ath_hal_get_rx_filter(_ah) \
	((*(_ah)->ah_get_rx_filter)((_ah)))
#define	ath_hal_set_rx_filter(_ah, _filter) \
	((*(_ah)->ah_set_rx_filter)((_ah), (_filter)))
#define	ath_hal_set_mcast_filter(_ah, _mfilt0, _mfilt1) \
	((*(_ah)->ah_set_mcast_filter)((_ah), (_mfilt0), (_mfilt1)))
#define	ath_hal_wait_for_beacon(_ah, _bf) \
	((*(_ah)->ah_wait_for_beacon)((_ah), (_bf)->bf_daddr))
#define	ath_hal_put_rx_buf(_ah, _bufaddr) \
	((*(_ah)->ah_put_rx_buf)((_ah), (_bufaddr)))
#define	ath_hal_get_tsf32(_ah) \
	((*(_ah)->ah_get_tsf32)((_ah)))
#define	ath_hal_get_tsf64(_ah) \
	((*(_ah)->ah_get_tsf64)((_ah)))
#define	ath_hal_reset_tsf(_ah) \
	((*(_ah)->ah_reset_tsf)((_ah)))
#define	ath_hal_start_rx(_ah) \
	((*(_ah)->ah_start_rx)((_ah)))
#define	ath_hal_put_tx_buf(_ah, _q, _bufaddr) \
	((*(_ah)->ah_put_tx_buf)((_ah), (_q), (_bufaddr)))
#define	ath_hal_get_tx_buf(_ah, _q) \
	((*(_ah)->ah_get_tx_buf)((_ah), (_q)))
#define	ath_hal_get_rx_buf(_ah) \
	((*(_ah)->ah_get_rx_buf)((_ah)))
#define	ath_hal_tx_start(_ah, _q) \
	((*(_ah)->ah_tx_start)((_ah), (_q)))
#define	ath_hal_setchannel(_ah, _chan) \
	((*(_ah)->ah_setchannel)((_ah), (_chan)))
#define	ath_hal_calibrate(_ah, _chan) \
	((*(_ah)->ah_calibrate)((_ah), (_chan)))
#define	ath_hal_set_ledstate(_ah, _state) \
	((*(_ah)->ah_set_ledstate)((_ah), (_state)))
#define	ath_hal_init_beacon(_ah, _nextb, _bperiod) \
	((*(_ah)->ah_init_beacon)((_ah), (_nextb), (_bperiod)))
#define	ath_hal_reset_beacon(_ah) \
	((*(_ah)->ah_reset_beacon)((_ah)))
#define	ath_hal_set_beacon_timers(_ah, _bs, _tsf, _dc, _cc) \
	((*(_ah)->ah_set_beacon_timers)((_ah), (_bs), (_tsf), \
	 (_dc), (_cc)))
#define	ath_hal_set_associd(_ah, _bss, _associd) \
	((*(_ah)->ah_set_associd)((_ah), (_bss), (_associd), 0))
#define	ath_hal_get_regdomain(_ah, _prd) \
	(*(_prd) = (_ah)->ah_get_regdomain(_ah))
#define	ath_hal_detach(_ah) \
	((*(_ah)->ah_detach)(_ah))
#define ath_hal_set_slot_time(_ah, _t) \
	((*(_ah)->ah_set_slot_time)(_ah, _t))
#define ath_hal_set_gpio_output(_ah, _gpio) \
	((*(_ah)->ah_set_gpio_output)((_ah), (_gpio)))
#define ath_hal_set_gpio_input(_ah, _gpio) \
	((*(_ah)->ah_set_gpio_input)((_ah), (_gpio)))
#define ath_hal_get_gpio(_ah, _gpio) \
	((*(_ah)->ah_get_gpio)((_ah), (_gpio)))
#define ath_hal_set_gpio(_ah, _gpio, _b) \
	((*(_ah)->ah_set_gpio)((_ah), (_gpio), (_b)))
#define ath_hal_set_gpio_intr(_ah, _gpio, _b) \
	((*(_ah)->ah_set_gpio_intr)((_ah), (_gpio), (_b)))

#define	ath_hal_set_opmode(_ah) \
	((*(_ah)->ah_set_opmode)((_ah)))
#define	ath_hal_stop_tx_dma(_ah, _qnum) \
	((*(_ah)->ah_stop_tx_dma)((_ah), (_qnum)))
#define	ath_hal_stop_pcu_recv(_ah) \
	((*(_ah)->ah_stop_pcu_recv)((_ah)))
#define	ath_hal_start_rx_pcu(_ah) \
	((*(_ah)->ah_start_rx_pcu)((_ah)))
#define	ath_hal_stop_rx_dma(_ah) \
	((*(_ah)->ah_stop_rx_dma)((_ah)))
#define	ath_hal_get_diag_state(_ah, _id, _indata, _insize, _outdata, _outsize) \
	((*(_ah)->ah_get_diag_state)((_ah), (_id), \
	 (_indata), (_insize), (_outdata), (_outsize)))

#define	ath_hal_setup_tx_queue(_ah, _type, _qinfo) \
	((*(_ah)->ah_setup_tx_queue)((_ah), (_type), (_qinfo)))
#define	ath_hal_reset_tx_queue(_ah, _q) \
	((*(_ah)->ah_reset_tx_queue)((_ah), (_q)))
#define	ath_hal_release_tx_queue(_ah, _q) \
	((*(_ah)->ah_release_tx_queue)((_ah), (_q)))
#define	ath_hal_has_veol(_ah) \
	((*(_ah)->ah_has_veol)((_ah)))
#define ath_hal_update_mib_counters(_ah, _stats) \
	((*(_ah)->ah_update_mib_counters)((_ah), (_stats)))
#define	ath_hal_get_rf_gain(_ah) \
	((*(_ah)->ah_get_rf_gain)((_ah)))
#define	ath_hal_set_rx_signal(_ah) \
	((*(_ah)->ah_set_rx_signal)((_ah)))

#define	ath_hal_setup_rx_desc(_ah, _ds, _size, _intreq) \
	((*(_ah)->ah_setup_rx_desc)((_ah), (_ds), (_size), (_intreq)))
#define	ath_hal_proc_rx_desc(_ah, _ds, _dspa, _dsnext) \
	((*(_ah)->ah_proc_rx_desc)((_ah), (_ds), (_dspa), (_dsnext)))
#define	ath_hal_setup_tx_desc(_ah, _ds, _plen, _hlen, _atype, _txpow, \
	    _txr0, _txtr0, _keyix, _ant, _flags, \
	    _rtsrate, _rtsdura) \
	((*(_ah)->ah_setup_tx_desc)((_ah), (_ds), (_plen), (_hlen), (_atype), \
	    (_txpow), (_txr0), (_txtr0), (_keyix), (_ant), \
	    (_flags), (_rtsrate), (_rtsdura)))
#define	ath_hal_setup_xtx_desc(_ah, _ds, \
	    _txr1, _txtr1, _txr2, _txtr2, _txr3, _txtr3) \
	((*(_ah)->ah_setup_xtx_desc)((_ah), (_ds), \
	    (_txr1), (_txtr1), (_txr2), (_txtr2), (_txr3), (_txtr3)))
#define	ath_hal_fill_tx_desc(_ah, _ds, _l, _first, _last) \
	((*(_ah)->ah_fill_tx_desc)((_ah), (_ds), (_l), (_first), (_last)))
#define	ath_hal_proc_tx_desc(_ah, _ds) \
	((*(_ah)->ah_proc_tx_desc)((_ah), (_ds)))

#endif /* _KERNEL */

#define	SIOCGATHSTATS	_IOWR('i', 137, struct ifreq)

#endif /* _DEV_ATH_ATHVAR_H */
