Update for rev 0.9.16.16 hal:

o add dfs+radar hooks; DFS is presently disabled in the hal
o channel and mode handling changes
o various api changes
o be more aggressive about iq calibration settling so ap mode
  operation is better immediately after startup
o rfkill/rfsilent sysctl support
o tpc ack/cts sysctl support

MFC after:	2 weeks
This commit is contained in:
sam 2006-02-10 19:07:08 +00:00
parent eae8448069
commit 9c662a12a0
2 changed files with 291 additions and 29 deletions

View File

@ -117,6 +117,7 @@ static int ath_ioctl(struct ifnet *, u_long, caddr_t);
static void ath_fatal_proc(void *, int);
static void ath_rxorn_proc(void *, int);
static void ath_bmiss_proc(void *, int);
static void ath_radar_proc(void *, int);
static int ath_key_alloc(struct ieee80211com *,
const struct ieee80211_key *,
ieee80211_keyix *, ieee80211_keyix *);
@ -239,6 +240,8 @@ enum {
ATH_DEBUG_STATE = 0x00040000, /* 802.11 state transitions */
ATH_DEBUG_NODE = 0x00080000, /* node management */
ATH_DEBUG_LED = 0x00100000, /* led management */
ATH_DEBUG_FF = 0x00200000, /* fast frames */
ATH_DEBUG_DFS = 0x00400000, /* DFS processing */
ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */
ATH_DEBUG_ANY = 0xffffffff
};
@ -380,6 +383,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
}
callout_init(&sc->sc_scan_ch, debug_mpsafenet ? CALLOUT_MPSAFE : 0);
callout_init(&sc->sc_cal_ch, CALLOUT_MPSAFE);
callout_init(&sc->sc_dfs_ch, CALLOUT_MPSAFE);
ATH_TXBUF_LOCK_INIT(sc);
@ -392,7 +396,8 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
TASK_INIT(&sc->sc_rxorntask, 0, ath_rxorn_proc, sc);
TASK_INIT(&sc->sc_fataltask, 0, ath_fatal_proc, sc);
TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc);
TASK_INIT(&sc->sc_bstucktask, 0, ath_bstuck_proc, sc);
TASK_INIT(&sc->sc_bstucktask,0, ath_bstuck_proc, sc);
TASK_INIT(&sc->sc_radartask, 0, ath_radar_proc, sc);
/*
* Allocate hardware transmit queues: one queue for
@ -858,6 +863,24 @@ ath_bmiss_proc(void *arg, int pending)
}
}
static void
ath_radar_proc(void *arg, int pending)
{
struct ath_softc *sc = arg;
struct ifnet *ifp = sc->sc_ifp;
struct ath_hal *ah = sc->sc_ah;
HAL_CHANNEL hchan;
if (ath_hal_procdfs(ah, &hchan)) {
if_printf(ifp, "radar detected on channel %u/0x%x/0x%x\n",
hchan.channel, hchan.channelFlags, hchan.privFlags);
/*
* Initiate channel change.
*/
/* XXX not yet */
}
}
static u_int
ath_chan2flags(struct ieee80211com *ic, struct ieee80211_channel *chan)
{
@ -868,7 +891,7 @@ ath_chan2flags(struct ieee80211com *ic, struct ieee80211_channel *chan)
CHANNEL_B, /* IEEE80211_MODE_11B */
CHANNEL_PUREG, /* IEEE80211_MODE_11G */
0, /* IEEE80211_MODE_FH */
CHANNEL_T, /* IEEE80211_MODE_TURBO_A */
CHANNEL_ST, /* IEEE80211_MODE_TURBO_A */
CHANNEL_108G /* IEEE80211_MODE_TURBO_G */
};
enum ieee80211_phymode mode = ieee80211_chan2mode(ic, chan);
@ -923,6 +946,8 @@ ath_init(void *arg)
* state cached in the driver.
*/
sc->sc_diversity = ath_hal_getdiversity(ah);
sc->sc_calinterval = 1;
sc->sc_caltries = 0;
/*
* Setup the hardware after reset: the key cache
@ -1044,7 +1069,7 @@ ath_stop(struct ifnet *ifp)
* (and system). This varies by chip and is mostly an
* issue with newer parts that go to sleep more quickly.
*/
ath_hal_setpower(sc->sc_ah, HAL_PM_FULL_SLEEP, 0);
ath_hal_setpower(sc->sc_ah, HAL_PM_FULL_SLEEP);
}
ATH_UNLOCK(sc);
}
@ -1082,14 +1107,16 @@ ath_reset(struct ifnet *ifp)
__func__, status);
ath_update_txpow(sc); /* update tx power state */
sc->sc_diversity = ath_hal_getdiversity(ah);
if (ath_startrecv(sc) != 0) /* restart recv */
if_printf(ifp, "%s: unable to start recv logic\n", __func__);
sc->sc_calinterval = 1;
sc->sc_caltries = 0;
/*
* We may be doing a reset in response to an ioctl
* that changes the channel so update any state that
* might change as a result.
*/
ath_chan_change(sc, c);
if (ath_startrecv(sc) != 0) /* restart recv */
if_printf(ifp, "%s: unable to start recv logic\n", __func__);
if (ic->ic_state == IEEE80211_S_RUN)
ath_beacon_config(sc); /* restart beacons */
ath_hal_intrset(ah, sc->sc_imask);
@ -1664,12 +1691,13 @@ ath_key_update_end(struct ieee80211com *ic)
static u_int32_t
ath_calcrxfilter(struct ath_softc *sc, enum ieee80211_state state)
{
#define RX_FILTER_PRESERVE (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR)
struct ieee80211com *ic = &sc->sc_ic;
struct ath_hal *ah = sc->sc_ah;
struct ifnet *ifp = sc->sc_ifp;
u_int32_t rfilt;
rfilt = (ath_hal_getrxfilter(ah) & HAL_RX_FILTER_PHYERR)
rfilt = (ath_hal_getrxfilter(ah) & RX_FILTER_PRESERVE)
| HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST;
if (ic->ic_opmode != IEEE80211_M_STA)
rfilt |= HAL_RX_FILTER_PROBEREQ;
@ -1681,6 +1709,7 @@ ath_calcrxfilter(struct ath_softc *sc, enum ieee80211_state state)
state == IEEE80211_S_SCAN)
rfilt |= HAL_RX_FILTER_BEACON;
return rfilt;
#undef RX_FILTER_PRESERVE
}
static void
@ -1786,7 +1815,7 @@ ath_beaconq_setup(struct ath_hal *ah)
qi.tqi_cwmin = HAL_TXQ_USEDEFAULT;
qi.tqi_cwmax = HAL_TXQ_USEDEFAULT;
/* NB: for dynamic turbo, don't enable any other interrupts */
qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
qi.tqi_qflags = HAL_TXQ_TXDESCINT_ENABLE;
return ath_hal_setuptxqueue(ah, HAL_TX_QUEUE_BEACON, &qi);
}
@ -2600,6 +2629,7 @@ ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
ds = bf->bf_desc;
ds->ds_link = bf->bf_daddr; /* link to self */
ds->ds_data = bf->bf_segs[0].ds_addr;
ds->ds_vdata = mtod(m, void *); /* for radar */
ath_hal_setuprxdesc(ah, ds
, m->m_len /* buffer size */
, 0
@ -2980,7 +3010,9 @@ ath_rx_proc(void *arg, int npending)
} while (ath_rxbuf_init(sc, bf) == 0);
/* rx signal state monitoring */
ath_hal_rxmonitor(ah, &sc->sc_halstats);
ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan);
if (ath_hal_radar_event(ah))
taskqueue_enqueue(sc->sc_tq, &sc->sc_radartask);
if (ngood)
sc->sc_lastrx = tsf;
@ -3016,7 +3048,7 @@ ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
* up in which case the top half of the kernel may backup
* due to a lack of tx descriptors.
*/
qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | TXQ_FLAG_TXDESCINT_ENABLE;
qi.tqi_qflags = HAL_TXQ_TXEOLINT_ENABLE | HAL_TXQ_TXDESCINT_ENABLE;
qnum = ath_hal_setuptxqueue(ah, qtype, &qi);
if (qnum == -1) {
/*
@ -4096,6 +4128,42 @@ ath_chan_change(struct ath_softc *sc, struct ieee80211_channel *chan)
htole16(flags);
}
/*
* Poll for a channel clear indication; this is required
* for channels requiring DFS and not previously visited
* and/or with a recent radar detection.
*/
static void
ath_dfswait(void *arg)
{
struct ath_softc *sc = arg;
struct ath_hal *ah = sc->sc_ah;
HAL_CHANNEL hchan;
ath_hal_radar_wait(ah, &hchan);
DPRINTF(sc, ATH_DEBUG_DFS, "%s: radar_wait %u/%x/%x\n",
__func__, hchan.channel, hchan.channelFlags, hchan.privFlags);
if (hchan.privFlags & CHANNEL_INTERFERENCE) {
if_printf(sc->sc_ifp,
"channel %u/0x%x/0x%x has interference\n",
hchan.channel, hchan.channelFlags, hchan.privFlags);
return;
}
if ((hchan.privFlags & CHANNEL_DFS) == 0) {
/* XXX should not happen */
return;
}
if (hchan.privFlags & CHANNEL_DFS_CLEAR) {
sc->sc_curchan.privFlags |= CHANNEL_DFS_CLEAR;
sc->sc_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
if_printf(sc->sc_ifp,
"channel %u/0x%x/0x%x marked clear\n",
hchan.channel, hchan.channelFlags, hchan.privFlags);
} else
callout_reset(&sc->sc_dfs_ch, 2 * hz, ath_dfswait, sc);
}
/*
* Set/change channels. If the channel is really being changed,
* it's done by reseting the chip. To accomplish this we must
@ -4120,10 +4188,10 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
DPRINTF(sc, ATH_DEBUG_RESET,
"%s: %u (%u MHz, hal flags 0x%x) -> %u (%u MHz, hal flags 0x%x)\n",
__func__,
ath_hal_mhz2ieee(sc->sc_curchan.channel,
ath_hal_mhz2ieee(ah, sc->sc_curchan.channel,
sc->sc_curchan.channelFlags),
sc->sc_curchan.channel, sc->sc_curchan.channelFlags,
ath_hal_mhz2ieee(hchan.channel, hchan.channelFlags),
ath_hal_mhz2ieee(ah, hchan.channel, hchan.channelFlags),
hchan.channel, hchan.channelFlags);
if (hchan.channel != sc->sc_curchan.channel ||
hchan.channelFlags != sc->sc_curchan.channelFlags) {
@ -4148,6 +4216,8 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
sc->sc_curchan = hchan;
ath_update_txpow(sc); /* update tx power state */
sc->sc_diversity = ath_hal_getdiversity(ah);
sc->sc_calinterval = 1;
sc->sc_caltries = 0;
/*
* Re-enable rx framework.
@ -4165,6 +4235,25 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
ic->ic_ibss_chan = chan;
ath_chan_change(sc, chan);
/*
* Handle DFS required waiting period to determine
* if channel is clear of radar traffic.
*/
if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
#define DFS_AND_NOT_CLEAR(_c) \
(((_c)->privFlags & (CHANNEL_DFS | CHANNEL_DFS_CLEAR)) == CHANNEL_DFS)
if (DFS_AND_NOT_CLEAR(&sc->sc_curchan)) {
if_printf(sc->sc_ifp,
"wait for DFS clear channel signal\n");
/* XXX stop sndq */
sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE;
callout_reset(&sc->sc_dfs_ch,
2 * hz, ath_dfswait, sc);
} else
callout_stop(&sc->sc_dfs_ch);
#undef DFS_NOT_CLEAR
}
/*
* Re-enable interrupts.
*/
@ -4192,6 +4281,7 @@ ath_calibrate(void *arg)
{
struct ath_softc *sc = arg;
struct ath_hal *ah = sc->sc_ah;
HAL_BOOL iqCalDone;
sc->sc_stats.ast_per_cal++;
@ -4205,7 +4295,7 @@ ath_calibrate(void *arg)
sc->sc_stats.ast_per_rfgain++;
ath_reset(sc->sc_ifp);
}
if (!ath_hal_calibrate(ah, &sc->sc_curchan)) {
if (!ath_hal_calibrate(ah, &sc->sc_curchan, &iqCalDone)) {
DPRINTF(sc, ATH_DEBUG_ANY,
"%s: calibration of channel %u failed\n",
__func__, sc->sc_curchan.channel);
@ -4215,7 +4305,30 @@ ath_calibrate(void *arg)
* Calibrate noise floor data again in case of change.
*/
ath_hal_process_noisefloor(ah);
callout_reset(&sc->sc_cal_ch, ath_calinterval * hz, ath_calibrate, sc);
/*
* Poll more frequently when the IQ calibration is in
* progress to speedup loading the final settings.
* We temper this aggressive polling with an exponential
* back off after 4 tries up to ath_calinterval.
*/
if (iqCalDone || sc->sc_calinterval >= ath_calinterval) {
sc->sc_caltries = 0;
sc->sc_calinterval = ath_calinterval;
} else if (sc->sc_caltries > 4) {
sc->sc_caltries = 0;
sc->sc_calinterval <<= 1;
if (sc->sc_calinterval > ath_calinterval)
sc->sc_calinterval = ath_calinterval;
}
KASSERT(0 < sc->sc_calinterval && sc->sc_calinterval <= ath_calinterval,
("bad calibration interval %u", sc->sc_calinterval));
DPRINTF(sc, ATH_DEBUG_CALIBRATE,
"%s: next +%u (%siqCalDone tries %u)\n", __func__,
sc->sc_calinterval, iqCalDone ? "" : "!", sc->sc_caltries);
sc->sc_caltries++;
callout_reset(&sc->sc_cal_ch, sc->sc_calinterval * hz,
ath_calibrate, sc);
}
static int
@ -4242,6 +4355,7 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
callout_stop(&sc->sc_scan_ch);
callout_stop(&sc->sc_cal_ch);
callout_stop(&sc->sc_dfs_ch);
ath_hal_setledstate(ah, leds[nstate]); /* set LED */
if (nstate == IEEE80211_S_INIT) {
@ -4372,7 +4486,7 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
*/
if (nstate == IEEE80211_S_RUN) {
/* start periodic recalibration timer */
callout_reset(&sc->sc_cal_ch, ath_calinterval * hz,
callout_reset(&sc->sc_cal_ch, sc->sc_calinterval * hz,
ath_calibrate, sc);
} else if (nstate == IEEE80211_S_SCAN) {
/* start ap/neighbor scan timer */
@ -4439,6 +4553,7 @@ static int
ath_getchannels(struct ath_softc *sc, u_int cc,
HAL_BOOL outdoor, HAL_BOOL xchanmode)
{
#define COMPAT (CHANNEL_ALL_NOTURBO|CHANNEL_PASSIVE)
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = sc->sc_ifp;
struct ath_hal *ah = sc->sc_ah;
@ -4452,6 +4567,7 @@ ath_getchannels(struct ath_softc *sc, u_int cc,
return ENOMEM;
}
if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan,
NULL, 0, NULL,
cc, HAL_MODE_ALL, outdoor, xchanmode)) {
u_int32_t rd;
@ -4468,23 +4584,42 @@ ath_getchannels(struct ath_softc *sc, u_int cc,
*/
for (i = 0; i < nchan; i++) {
HAL_CHANNEL *c = &chans[i];
ix = ath_hal_mhz2ieee(c->channel, c->channelFlags);
u_int16_t flags;
ix = ath_hal_mhz2ieee(ah, c->channel, c->channelFlags);
if (ix > IEEE80211_CHAN_MAX) {
if_printf(ifp, "bad hal channel %u (%u/%x) ignored\n",
if_printf(ifp, "bad hal channel %d (%u/%x) ignored\n",
ix, c->channel, c->channelFlags);
continue;
}
/* NB: flags are known to be compatible */
if (ix < 0) {
/* XXX can't handle stuff <2400 right now */
if (bootverbose)
if_printf(ifp, "hal channel %d (%u/%x) "
"cannot be handled; ignored\n",
ix, c->channel, c->channelFlags);
continue;
}
/*
* Calculate net80211 flags; most are compatible
* but some need massaging. Note the static turbo
* conversion can be removed once net80211 is updated
* to understand static vs. dynamic turbo.
*/
flags = c->channelFlags & COMPAT;
if (c->channelFlags & CHANNEL_STURBO)
flags |= IEEE80211_CHAN_TURBO;
if (ic->ic_channels[ix].ic_freq == 0) {
ic->ic_channels[ix].ic_freq = c->channel;
ic->ic_channels[ix].ic_flags = c->channelFlags;
ic->ic_channels[ix].ic_flags = flags;
} else {
/* channels overlap; e.g. 11g and 11b */
ic->ic_channels[ix].ic_flags |= c->channelFlags;
ic->ic_channels[ix].ic_flags |= flags;
}
}
free(chans, M_TEMP);
return 0;
#undef COMPAT
}
static void
@ -5029,6 +5164,43 @@ ath_sysctl_tpc(SYSCTL_HANDLER_ARGS)
return !ath_hal_settpc(sc->sc_ah, tpc) ? EINVAL : 0;
}
static int
ath_sysctl_rfkill(SYSCTL_HANDLER_ARGS)
{
struct ath_softc *sc = arg1;
struct ath_hal *ah = sc->sc_ah;
u_int rfkill = ath_hal_getrfkill(ah);
int error;
error = sysctl_handle_int(oidp, &rfkill, 0, req);
if (error || !req->newptr)
return error;
if (rfkill == ath_hal_getrfkill(ah)) /* unchanged */
return 0;
if (!ath_hal_setrfkill(ah, rfkill) || ath_reset(sc->sc_ifp) != 0)
return EINVAL;
else
return 0;
}
static int
ath_sysctl_rfsilent(SYSCTL_HANDLER_ARGS)
{
struct ath_softc *sc = arg1;
u_int rfsilent;
int error;
ath_hal_getrfsilent(sc->sc_ah, &rfsilent);
error = sysctl_handle_int(oidp, &rfsilent, 0, req);
if (error || !req->newptr)
return error;
if (!ath_hal_setrfsilent(sc->sc_ah, rfsilent))
return EINVAL;
sc->sc_rfsilentpin = rfsilent & 0x1c;
sc->sc_rfsilentpol = (rfsilent & 0x2) != 0;
return 0;
}
static int
ath_sysctl_regdomain(SYSCTL_HANDLER_ARGS)
{
@ -5044,6 +5216,34 @@ ath_sysctl_regdomain(SYSCTL_HANDLER_ARGS)
return !ath_hal_setregdomain(sc->sc_ah, rd) ? EINVAL : 0;
}
static int
ath_sysctl_tpack(SYSCTL_HANDLER_ARGS)
{
struct ath_softc *sc = arg1;
u_int32_t tpack;
int error;
ath_hal_gettpack(sc->sc_ah, &tpack);
error = sysctl_handle_int(oidp, &tpack, 0, req);
if (error || !req->newptr)
return error;
return !ath_hal_settpack(sc->sc_ah, tpack) ? EINVAL : 0;
}
static int
ath_sysctl_tpcts(SYSCTL_HANDLER_ARGS)
{
struct ath_softc *sc = arg1;
u_int32_t tpcts;
int error;
ath_hal_gettpcts(sc->sc_ah, &tpcts);
error = sysctl_handle_int(oidp, &tpcts, 0, req);
if (error || !req->newptr)
return error;
return !ath_hal_settpcts(sc->sc_ah, tpcts) ? EINVAL : 0;
}
static void
ath_sysctlattach(struct ath_softc *sc)
{
@ -5104,10 +5304,25 @@ ath_sysctlattach(struct ath_softc *sc)
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"tpscale", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
ath_sysctl_tpscale, "I", "tx power scaling");
if (ath_hal_hastpc(ah))
if (ath_hal_hastpc(ah)) {
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"tpc", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
ath_sysctl_tpc, "I", "enable/disable per-packet TPC");
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"tpack", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
ath_sysctl_tpack, "I", "tx power for ack frames");
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"tpcts", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
ath_sysctl_tpcts, "I", "tx power for cts frames");
}
if (ath_hal_hasrfsilent(ah)) {
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"rfsilent", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
ath_sysctl_rfsilent, "I", "h/w RF silent config");
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"rfkill", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
ath_sysctl_rfkill, "I", "enable/disable RF kill switch");
}
sc->sc_monpass = HAL_RXERR_DECRYPT | HAL_RXERR_MIC;
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"monpass", CTLFLAG_RW, &sc->sc_monpass, 0,

View File

@ -235,6 +235,9 @@ struct ath_softc {
u_int16_t sc_ledoff; /* off time for current blink */
struct callout sc_ledtimer; /* led off timer */
u_int sc_rfsilentpin; /* GPIO pin for rfkill int */
u_int sc_rfsilentpol; /* pin setting for rfkill on */
struct bpf_if *sc_drvbpf;
union {
struct ath_tx_radiotap_header th;
@ -255,6 +258,7 @@ struct ath_softc {
u_int32_t *sc_rxlink; /* link ptr in last RX desc */
struct task sc_rxtask; /* rx int processing */
struct task sc_rxorntask; /* rxorn int processing */
struct task sc_radartask; /* radar processing */
u_int8_t sc_defant; /* current default antenna */
u_int8_t sc_rxotherant; /* rx's on non-default antenna*/
u_int64_t sc_lastrx; /* tsf at last rx'd frame */
@ -286,8 +290,11 @@ struct ath_softc {
} sc_updateslot; /* slot time update fsm */
struct callout sc_cal_ch; /* callout handle for cals */
int sc_calinterval; /* current polling interval */
int sc_caltries; /* cals at current interval */
HAL_NODE_STATS sc_halstats; /* station-mode rssi stats */
struct callout sc_scan_ch; /* callout handle for scan */
struct callout sc_dfs_ch; /* callout handle for dfs */
};
#define sc_tx_th u_tx_rt.th
#define sc_rx_th u_rx_rt.th
@ -343,8 +350,8 @@ void ath_intr(void *);
((*(_ah)->ah_getPendingInterrupts)((_ah), (_pmask)))
#define ath_hal_updatetxtriglevel(_ah, _inc) \
((*(_ah)->ah_updateTxTrigLevel)((_ah), (_inc)))
#define ath_hal_setpower(_ah, _mode, _sleepduration) \
((*(_ah)->ah_setPowerMode)((_ah), (_mode), AH_TRUE, (_sleepduration)))
#define ath_hal_setpower(_ah, _mode) \
((*(_ah)->ah_setPowerMode)((_ah), (_mode), AH_TRUE))
#define ath_hal_keycachesize(_ah) \
((*(_ah)->ah_getKeyCacheSize)((_ah)))
#define ath_hal_keyreset(_ah, _ix) \
@ -385,8 +392,8 @@ void ath_intr(void *);
((*(_ah)->ah_startTxDma)((_ah), (_q)))
#define ath_hal_setchannel(_ah, _chan) \
((*(_ah)->ah_setChannel)((_ah), (_chan)))
#define ath_hal_calibrate(_ah, _chan) \
((*(_ah)->ah_perCalibration)((_ah), (_chan)))
#define ath_hal_calibrate(_ah, _chan, _iqcal) \
((*(_ah)->ah_perCalibration)((_ah), (_chan), (_iqcal)))
#define ath_hal_setledstate(_ah, _state) \
((*(_ah)->ah_setLedState)((_ah), (_state)))
#define ath_hal_beaconinit(_ah, _nextb, _bperiod) \
@ -428,8 +435,8 @@ void ath_intr(void *);
((*(_ah)->ah_getDefAntenna)((_ah)))
#define ath_hal_setdefantenna(_ah, _ant) \
((*(_ah)->ah_setDefAntenna)((_ah), (_ant)))
#define ath_hal_rxmonitor(_ah, _arg) \
((*(_ah)->ah_rxMonitor)((_ah), (_arg)))
#define ath_hal_rxmonitor(_ah, _arg, _chan) \
((*(_ah)->ah_rxMonitor)((_ah), (_arg), (_chan)))
#define ath_hal_mibevent(_ah, _stats) \
((*(_ah)->ah_procMibEvent)((_ah), (_stats)))
#define ath_hal_setslottime(_ah, _us) \
@ -451,7 +458,7 @@ void ath_intr(void *);
#define ath_hal_ciphersupported(_ah, _cipher) \
(ath_hal_getcapability(_ah, HAL_CAP_CIPHER, _cipher, NULL) == HAL_OK)
#define ath_hal_getregdomain(_ah, _prd) \
ath_hal_getcapability(_ah, HAL_CAP_REG_DMN, 0, (_prd))
(ath_hal_getcapability(_ah, HAL_CAP_REG_DMN, 0, (_prd)) == HAL_OK)
#define ath_hal_setregdomain(_ah, _rd) \
((*(_ah)->ah_setRegulatoryDomain)((_ah), (_rd), NULL))
#define ath_hal_getcountrycode(_ah, _pcc) \
@ -502,6 +509,24 @@ void ath_intr(void *);
#else
#define ath_hal_getmcastkeysearch(_ah) 0
#endif
#define ath_hal_hasrfsilent(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_RFSILENT, 0, NULL) == HAL_OK)
#define ath_hal_getrfkill(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_RFSILENT, 1, NULL) == HAL_OK)
#define ath_hal_setrfkill(_ah, _onoff) \
ath_hal_setcapability(_ah, HAL_CAP_RFSILENT, 1, _onoff, NULL)
#define ath_hal_getrfsilent(_ah, _prfsilent) \
(ath_hal_getcapability(_ah, HAL_CAP_RFSILENT, 2, _prfsilent) == HAL_OK)
#define ath_hal_setrfsilent(_ah, _rfsilent) \
ath_hal_setcapability(_ah, HAL_CAP_RFSILENT, 2, _rfsilent, NULL)
#define ath_hal_gettpack(_ah, _ptpack) \
(ath_hal_getcapability(_ah, HAL_CAP_TPC_ACK, 0, _ptpack) == HAL_OK)
#define ath_hal_settpack(_ah, _tpack) \
ath_hal_setcapability(_ah, HAL_CAP_TPC_ACK, 0, _tpack, NULL)
#define ath_hal_gettpcts(_ah, _ptpcts) \
(ath_hal_getcapability(_ah, HAL_CAP_TPC_CTS, 0, _ptpcts) == HAL_OK)
#define ath_hal_settpcts(_ah, _tpcts) \
ath_hal_setcapability(_ah, HAL_CAP_TPC_CTS, 0, _tpcts, NULL)
#if HAL_ABI_VERSION < 0x05120700
#define ath_hal_process_noisefloor(_ah)
#define ath_hal_getchannoise(_ah, _c) (-96)
@ -511,17 +536,24 @@ void ath_intr(void *);
#define ath_hal_getchannoise(_ah, _c) \
((*(_ah)->ah_getChanNoise)((_ah), (_c)))
#endif
#if HAL_ABI_VERSION < 0x05122200
#define HAL_TXQ_TXOKINT_ENABLE TXQ_FLAG_TXOKINT_ENABLE
#define HAL_TXQ_TXERRINT_ENABLE TXQ_FLAG_TXERRINT_ENABLE
#define HAL_TXQ_TXDESCINT_ENABLE TXQ_FLAG_TXDESCINT_ENABLE
#define HAL_TXQ_TXEOLINT_ENABLE TXQ_FLAG_TXEOLINT_ENABLE
#define HAL_TXQ_TXURNINT_ENABLE TXQ_FLAG_TXURNINT_ENABLE
#endif
#define ath_hal_setuprxdesc(_ah, _ds, _size, _intreq) \
((*(_ah)->ah_setupRxDesc)((_ah), (_ds), (_size), (_intreq)))
#define ath_hal_rxprocdesc(_ah, _ds, _dspa, _dsnext) \
((*(_ah)->ah_procRxDesc)((_ah), (_ds), (_dspa), (_dsnext)))
((*(_ah)->ah_procRxDesc)((_ah), (_ds), (_dspa), (_dsnext), 0))
#define ath_hal_setuptxdesc(_ah, _ds, _plen, _hlen, _atype, _txpow, \
_txr0, _txtr0, _keyix, _ant, _flags, \
_rtsrate, _rtsdura) \
((*(_ah)->ah_setupTxDesc)((_ah), (_ds), (_plen), (_hlen), (_atype), \
(_txpow), (_txr0), (_txtr0), (_keyix), (_ant), \
(_flags), (_rtsrate), (_rtsdura)))
(_flags), (_rtsrate), (_rtsdura), 0, 0, 0))
#define ath_hal_setupxtxdesc(_ah, _ds, \
_txr1, _txtr1, _txr2, _txtr2, _txr3, _txtr3) \
((*(_ah)->ah_setupXTxDesc)((_ah), (_ds), \
@ -530,10 +562,25 @@ void ath_intr(void *);
((*(_ah)->ah_fillTxDesc)((_ah), (_ds), (_l), (_first), (_last), (_ds0)))
#define ath_hal_txprocdesc(_ah, _ds) \
((*(_ah)->ah_procTxDesc)((_ah), (_ds)))
#define ath_hal_gettxintrtxqs(_ah, _txqs) \
((*(_ah)->ah_getTxIntrQueue)((_ah), (_txqs)))
#define ath_hal_gpioCfgOutput(_ah, _gpio) \
((*(_ah)->ah_gpioCfgOutput)((_ah), (_gpio)))
#define ath_hal_gpioset(_ah, _gpio, _b) \
((*(_ah)->ah_gpioSet)((_ah), (_gpio), (_b)))
#define ath_hal_gpioget(_ah, _gpio) \
((*(_ah)->ah_gpioGet)((_ah), (_gpio)))
#define ath_hal_gpiosetintr(_ah, _gpio, _b) \
((*(_ah)->ah_gpioSetIntr)((_ah), (_gpio), (_b)))
#define ath_hal_radar_event(_ah) \
((*(_ah)->ah_radarHaveEvent)((_ah)))
#define ath_hal_procdfs(_ah, _chan) \
((*(_ah)->ah_processDfs)((_ah), (_chan)))
#define ath_hal_checknol(_ah, _chan, _nchans) \
((*(_ah)->ah_dfsNolCheck)((_ah), (_chan), (_nchans)))
#define ath_hal_radar_wait(_ah, _chan) \
((*(_ah)->ah_radarWait)((_ah), (_chan)))
#endif /* _DEV_ATH_ATHVAR_H */