diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 9269f5fa2f5b..58687a708c7d 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -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 @@ rx_next: } 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 @@ done: */ 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, diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index 2aaf43bb2483..b131e2a9d63f 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -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 */