Deleted Added
full compact
if_ath.c (235676) if_ath.c (235679)
1/*-
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 14 unchanged lines hidden (view full) ---

23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 14 unchanged lines hidden (view full) ---

23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 235676 2012-05-20 02:05:10Z adrian $");
31__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 235679 2012-05-20 02:49:42Z adrian $");
32
33/*
34 * Driver for the Atheros Wireless LAN controller.
35 *
36 * This software is derived from work of Atsushi Onoe; his contribution
37 * is greatly appreciated.
38 */
39

--- 63 unchanged lines hidden (view full) ---

103#include <dev/ath/if_ath_debug.h>
104#include <dev/ath/if_ath_misc.h>
105#include <dev/ath/if_ath_tsf.h>
106#include <dev/ath/if_ath_tx.h>
107#include <dev/ath/if_ath_sysctl.h>
108#include <dev/ath/if_ath_led.h>
109#include <dev/ath/if_ath_keycache.h>
110#include <dev/ath/if_ath_rx.h>
32
33/*
34 * Driver for the Atheros Wireless LAN controller.
35 *
36 * This software is derived from work of Atsushi Onoe; his contribution
37 * is greatly appreciated.
38 */
39

--- 63 unchanged lines hidden (view full) ---

103#include <dev/ath/if_ath_debug.h>
104#include <dev/ath/if_ath_misc.h>
105#include <dev/ath/if_ath_tsf.h>
106#include <dev/ath/if_ath_tx.h>
107#include <dev/ath/if_ath_sysctl.h>
108#include <dev/ath/if_ath_led.h>
109#include <dev/ath/if_ath_keycache.h>
110#include <dev/ath/if_ath_rx.h>
111#include <dev/ath/if_ath_beacon.h>
111#include <dev/ath/if_athdfs.h>
112
113#ifdef ATH_TX99_DIAG
114#include <dev/ath/ath_tx99/ath_tx99.h>
115#endif
116
117#define ATH_KTR_INTR KTR_SPARE4
118#define ATH_KTR_ERR KTR_SPARE3

--- 35 unchanged lines hidden (view full) ---

154static void ath_update_promisc(struct ifnet *);
155static void ath_setslottime(struct ath_softc *);
156static void ath_updateslot(struct ifnet *);
157static int ath_beaconq_setup(struct ath_hal *);
158static int ath_beacon_alloc(struct ath_softc *, struct ieee80211_node *);
159static void ath_beacon_update(struct ieee80211vap *, int item);
160static void ath_beacon_setup(struct ath_softc *, struct ath_buf *);
161static void ath_beacon_proc(void *, int);
112#include <dev/ath/if_athdfs.h>
113
114#ifdef ATH_TX99_DIAG
115#include <dev/ath/ath_tx99/ath_tx99.h>
116#endif
117
118#define ATH_KTR_INTR KTR_SPARE4
119#define ATH_KTR_ERR KTR_SPARE3

--- 35 unchanged lines hidden (view full) ---

155static void ath_update_promisc(struct ifnet *);
156static void ath_setslottime(struct ath_softc *);
157static void ath_updateslot(struct ifnet *);
158static int ath_beaconq_setup(struct ath_hal *);
159static int ath_beacon_alloc(struct ath_softc *, struct ieee80211_node *);
160static void ath_beacon_update(struct ieee80211vap *, int item);
161static void ath_beacon_setup(struct ath_softc *, struct ath_buf *);
162static void ath_beacon_proc(void *, int);
162static struct ath_buf *ath_beacon_generate(struct ath_softc *,
163 struct ieee80211vap *);
164static void ath_bstuck_proc(void *, int);
165static void ath_reset_proc(void *, int);
166static void ath_beacon_return(struct ath_softc *, struct ath_buf *);
167static void ath_beacon_free(struct ath_softc *);
168static void ath_descdma_cleanup(struct ath_softc *sc,
169 struct ath_descdma *, ath_bufhead *);
170static int ath_desc_alloc(struct ath_softc *);
171static void ath_desc_free(struct ath_softc *);
172static struct ieee80211_node *ath_node_alloc(struct ieee80211vap *,
173 const uint8_t [IEEE80211_ADDR_LEN]);
174static void ath_node_cleanup(struct ieee80211_node *);
175static void ath_node_free(struct ieee80211_node *);
176static void ath_node_getsignal(const struct ieee80211_node *,
177 int8_t *, int8_t *);
178static void ath_txq_init(struct ath_softc *sc, struct ath_txq *, int);
179static struct ath_txq *ath_txq_setup(struct ath_softc*, int qtype, int subtype);
180static int ath_tx_setup(struct ath_softc *, int, int);
163static void ath_bstuck_proc(void *, int);
164static void ath_reset_proc(void *, int);
165static void ath_beacon_return(struct ath_softc *, struct ath_buf *);
166static void ath_beacon_free(struct ath_softc *);
167static void ath_descdma_cleanup(struct ath_softc *sc,
168 struct ath_descdma *, ath_bufhead *);
169static int ath_desc_alloc(struct ath_softc *);
170static void ath_desc_free(struct ath_softc *);
171static struct ieee80211_node *ath_node_alloc(struct ieee80211vap *,
172 const uint8_t [IEEE80211_ADDR_LEN]);
173static void ath_node_cleanup(struct ieee80211_node *);
174static void ath_node_free(struct ieee80211_node *);
175static void ath_node_getsignal(const struct ieee80211_node *,
176 int8_t *, int8_t *);
177static void ath_txq_init(struct ath_softc *sc, struct ath_txq *, int);
178static struct ath_txq *ath_txq_setup(struct ath_softc*, int qtype, int subtype);
179static int ath_tx_setup(struct ath_softc *, int, int);
181static int ath_wme_update(struct ieee80211com *);
182static void ath_tx_cleanupq(struct ath_softc *, struct ath_txq *);
183static void ath_tx_cleanup(struct ath_softc *);
184static void ath_tx_proc_q0(void *, int);
185static void ath_tx_proc_q0123(void *, int);
186static void ath_tx_proc(void *, int);
187static void ath_txq_sched_tasklet(void *, int);
188static int ath_chan_set(struct ath_softc *, struct ieee80211_channel *);
189static void ath_draintxq(struct ath_softc *, ATH_RESET_TYPE reset_type);

--- 18 unchanged lines hidden (view full) ---

208static int ath_rate_setup(struct ath_softc *, u_int mode);
209static void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode);
210
211static void ath_announce(struct ath_softc *);
212
213static void ath_dfs_tasklet(void *, int);
214
215#ifdef IEEE80211_SUPPORT_TDMA
180static void ath_tx_cleanupq(struct ath_softc *, struct ath_txq *);
181static void ath_tx_cleanup(struct ath_softc *);
182static void ath_tx_proc_q0(void *, int);
183static void ath_tx_proc_q0123(void *, int);
184static void ath_tx_proc(void *, int);
185static void ath_txq_sched_tasklet(void *, int);
186static int ath_chan_set(struct ath_softc *, struct ieee80211_channel *);
187static void ath_draintxq(struct ath_softc *, ATH_RESET_TYPE reset_type);

--- 18 unchanged lines hidden (view full) ---

206static int ath_rate_setup(struct ath_softc *, u_int mode);
207static void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode);
208
209static void ath_announce(struct ath_softc *);
210
211static void ath_dfs_tasklet(void *, int);
212
213#ifdef IEEE80211_SUPPORT_TDMA
216static void ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt,
217 u_int32_t bintval);
218static void ath_tdma_bintvalsetup(struct ath_softc *sc,
219 const struct ieee80211_tdma_state *tdma);
220static void ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap);
221static void ath_tdma_update(struct ieee80211_node *ni,
222 const struct ieee80211_tdma_param *tdma, int);
223static void ath_tdma_beacon_send(struct ath_softc *sc,
224 struct ieee80211vap *vap);
214#include <dev/ath/if_ath_tdma.h>
215#endif
225
216
217#if 0
226#define TDMA_EP_MULTIPLIER (1<<10) /* pow2 to optimize out * and / */
227#define TDMA_LPF_LEN 6
228#define TDMA_DUMMY_MARKER 0x127
229#define TDMA_EP_MUL(x, mul) ((x) * (mul))
230#define TDMA_IN(x) (TDMA_EP_MUL((x), TDMA_EP_MULTIPLIER))
231#define TDMA_LPF(x, y, len) \
232 ((x != TDMA_DUMMY_MARKER) ? (((x) * ((len)-1) + (y)) / (len)) : (y))
233#define TDMA_SAMPLE(x, y) do { \

--- 24 unchanged lines hidden (view full) ---

258SYSCTL_INT(_hw_ath, OID_AUTO, rxbuf, CTLFLAG_RW, &ath_rxbuf,
259 0, "rx buffers allocated");
260TUNABLE_INT("hw.ath.rxbuf", &ath_rxbuf);
261static int ath_txbuf = ATH_TXBUF; /* # tx buffers to allocate */
262SYSCTL_INT(_hw_ath, OID_AUTO, txbuf, CTLFLAG_RW, &ath_txbuf,
263 0, "tx buffers allocated");
264TUNABLE_INT("hw.ath.txbuf", &ath_txbuf);
265
218#define TDMA_EP_MULTIPLIER (1<<10) /* pow2 to optimize out * and / */
219#define TDMA_LPF_LEN 6
220#define TDMA_DUMMY_MARKER 0x127
221#define TDMA_EP_MUL(x, mul) ((x) * (mul))
222#define TDMA_IN(x) (TDMA_EP_MUL((x), TDMA_EP_MULTIPLIER))
223#define TDMA_LPF(x, y, len) \
224 ((x != TDMA_DUMMY_MARKER) ? (((x) * ((len)-1) + (y)) / (len)) : (y))
225#define TDMA_SAMPLE(x, y) do { \

--- 24 unchanged lines hidden (view full) ---

250SYSCTL_INT(_hw_ath, OID_AUTO, rxbuf, CTLFLAG_RW, &ath_rxbuf,
251 0, "rx buffers allocated");
252TUNABLE_INT("hw.ath.rxbuf", &ath_rxbuf);
253static int ath_txbuf = ATH_TXBUF; /* # tx buffers to allocate */
254SYSCTL_INT(_hw_ath, OID_AUTO, txbuf, CTLFLAG_RW, &ath_txbuf,
255 0, "tx buffers allocated");
256TUNABLE_INT("hw.ath.txbuf", &ath_txbuf);
257
266static int ath_bstuck_threshold = 4; /* max missed beacons */
258int ath_bstuck_threshold = 4; /* max missed beacons */
267SYSCTL_INT(_hw_ath, OID_AUTO, bstuck, CTLFLAG_RW, &ath_bstuck_threshold,
268 0, "max missed beacon xmits before chip reset");
269
270MALLOC_DEFINE(M_ATHDEV, "athdev", "ath driver dma buffers");
271
272#define HAL_MODE_HT20 (HAL_MODE_11NG_HT20 | HAL_MODE_11NA_HT20)
273#define HAL_MODE_HT40 \
274 (HAL_MODE_11NG_HT40PLUS | HAL_MODE_11NG_HT40MINUS | \

--- 2341 unchanged lines hidden (view full) ---

2616 /* NB: for dynamic turbo, don't enable any other interrupts */
2617 qi.tqi_qflags = HAL_TXQ_TXDESCINT_ENABLE;
2618 return ath_hal_setuptxqueue(ah, HAL_TX_QUEUE_BEACON, &qi);
2619}
2620
2621/*
2622 * Setup the transmit queue parameters for the beacon queue.
2623 */
259SYSCTL_INT(_hw_ath, OID_AUTO, bstuck, CTLFLAG_RW, &ath_bstuck_threshold,
260 0, "max missed beacon xmits before chip reset");
261
262MALLOC_DEFINE(M_ATHDEV, "athdev", "ath driver dma buffers");
263
264#define HAL_MODE_HT20 (HAL_MODE_11NG_HT20 | HAL_MODE_11NA_HT20)
265#define HAL_MODE_HT40 \
266 (HAL_MODE_11NG_HT40PLUS | HAL_MODE_11NG_HT40MINUS | \

--- 2341 unchanged lines hidden (view full) ---

2608 /* NB: for dynamic turbo, don't enable any other interrupts */
2609 qi.tqi_qflags = HAL_TXQ_TXDESCINT_ENABLE;
2610 return ath_hal_setuptxqueue(ah, HAL_TX_QUEUE_BEACON, &qi);
2611}
2612
2613/*
2614 * Setup the transmit queue parameters for the beacon queue.
2615 */
2624static int
2616int
2625ath_beaconq_config(struct ath_softc *sc)
2626{
2627#define ATH_EXPONENT_TO_VALUE(v) ((1<<(v))-1)
2628 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
2629 struct ath_hal *ah = sc->sc_ah;
2630 HAL_TXQ_INFO qi;
2631
2632 ath_hal_gettxqueueprops(ah, sc->sc_bhalq, &qi);

--- 338 unchanged lines hidden (view full) ---

2971 /* NB: cabq traffic should already be queued and primed */
2972 ath_hal_puttxbuf(ah, sc->sc_bhalq, bfaddr);
2973 ath_hal_txstart(ah, sc->sc_bhalq);
2974
2975 sc->sc_stats.ast_be_xmit++;
2976 }
2977}
2978
2617ath_beaconq_config(struct ath_softc *sc)
2618{
2619#define ATH_EXPONENT_TO_VALUE(v) ((1<<(v))-1)
2620 struct ieee80211com *ic = sc->sc_ifp->if_l2com;
2621 struct ath_hal *ah = sc->sc_ah;
2622 HAL_TXQ_INFO qi;
2623
2624 ath_hal_gettxqueueprops(ah, sc->sc_bhalq, &qi);

--- 338 unchanged lines hidden (view full) ---

2963 /* NB: cabq traffic should already be queued and primed */
2964 ath_hal_puttxbuf(ah, sc->sc_bhalq, bfaddr);
2965 ath_hal_txstart(ah, sc->sc_bhalq);
2966
2967 sc->sc_stats.ast_be_xmit++;
2968 }
2969}
2970
2979static struct ath_buf *
2971struct ath_buf *
2980ath_beacon_generate(struct ath_softc *sc, struct ieee80211vap *vap)
2981{
2982 struct ath_vap *avp = ATH_VAP(vap);
2983 struct ath_txq *cabq = sc->sc_cabq;
2984 struct ath_buf *bf;
2985 struct mbuf *m;
2986 int nmcastq, error;
2987

--- 883 unchanged lines hidden (view full) ---

3871 }
3872#undef ATH_TXOP_TO_US
3873#undef ATH_EXPONENT_TO_VALUE
3874}
3875
3876/*
3877 * Callback from the 802.11 layer to update WME parameters.
3878 */
2972ath_beacon_generate(struct ath_softc *sc, struct ieee80211vap *vap)
2973{
2974 struct ath_vap *avp = ATH_VAP(vap);
2975 struct ath_txq *cabq = sc->sc_cabq;
2976 struct ath_buf *bf;
2977 struct mbuf *m;
2978 int nmcastq, error;
2979

--- 883 unchanged lines hidden (view full) ---

3863 }
3864#undef ATH_TXOP_TO_US
3865#undef ATH_EXPONENT_TO_VALUE
3866}
3867
3868/*
3869 * Callback from the 802.11 layer to update WME parameters.
3870 */
3879static int
3871int
3880ath_wme_update(struct ieee80211com *ic)
3881{
3882 struct ath_softc *sc = ic->ic_ifp->if_softc;
3883
3884 return !ath_txq_update(sc, WME_AC_BE) ||
3885 !ath_txq_update(sc, WME_AC_BK) ||
3886 !ath_txq_update(sc, WME_AC_VI) ||
3887 !ath_txq_update(sc, WME_AC_VO) ? EIO : 0;

--- 1757 unchanged lines hidden (view full) ---

5645 if (ath_rxbuf != ATH_RXBUF)
5646 if_printf(ifp, "using %u rx buffers\n", ath_rxbuf);
5647 if (ath_txbuf != ATH_TXBUF)
5648 if_printf(ifp, "using %u tx buffers\n", ath_txbuf);
5649 if (sc->sc_mcastkey && bootverbose)
5650 if_printf(ifp, "using multicast key search\n");
5651}
5652
3872ath_wme_update(struct ieee80211com *ic)
3873{
3874 struct ath_softc *sc = ic->ic_ifp->if_softc;
3875
3876 return !ath_txq_update(sc, WME_AC_BE) ||
3877 !ath_txq_update(sc, WME_AC_BK) ||
3878 !ath_txq_update(sc, WME_AC_VI) ||
3879 !ath_txq_update(sc, WME_AC_VO) ? EIO : 0;

--- 1757 unchanged lines hidden (view full) ---

5637 if (ath_rxbuf != ATH_RXBUF)
5638 if_printf(ifp, "using %u rx buffers\n", ath_rxbuf);
5639 if (ath_txbuf != ATH_TXBUF)
5640 if_printf(ifp, "using %u tx buffers\n", ath_txbuf);
5641 if (sc->sc_mcastkey && bootverbose)
5642 if_printf(ifp, "using multicast key search\n");
5643}
5644
5653#ifdef IEEE80211_SUPPORT_TDMA
5654static void
5645static void
5655ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt, u_int32_t bintval)
5656{
5657 struct ath_hal *ah = sc->sc_ah;
5658 HAL_BEACON_TIMERS bt;
5659
5660 bt.bt_intval = bintval | HAL_BEACON_ENA;
5661 bt.bt_nexttbtt = nexttbtt;
5662 bt.bt_nextdba = (nexttbtt<<3) - sc->sc_tdmadbaprep;
5663 bt.bt_nextswba = (nexttbtt<<3) - sc->sc_tdmaswbaprep;
5664 bt.bt_nextatim = nexttbtt+1;
5665 /* Enables TBTT, DBA, SWBA timers by default */
5666 bt.bt_flags = 0;
5667 ath_hal_beaconsettimers(ah, &bt);
5668}
5669
5670/*
5671 * Calculate the beacon interval. This is periodic in the
5672 * superframe for the bss. We assume each station is configured
5673 * identically wrt transmit rate so the guard time we calculate
5674 * above will be the same on all stations. Note we need to
5675 * factor in the xmit time because the hardware will schedule
5676 * a frame for transmit if the start of the frame is within
5677 * the burst time. When we get hardware that properly kills
5678 * frames in the PCU we can reduce/eliminate the guard time.
5679 *
5680 * Roundup to 1024 is so we have 1 TU buffer in the guard time
5681 * to deal with the granularity of the nexttbtt timer. 11n MAC's
5682 * with 1us timer granularity should allow us to reduce/eliminate
5683 * this.
5684 */
5685static void
5686ath_tdma_bintvalsetup(struct ath_softc *sc,
5687 const struct ieee80211_tdma_state *tdma)
5688{
5689 /* copy from vap state (XXX check all vaps have same value?) */
5690 sc->sc_tdmaslotlen = tdma->tdma_slotlen;
5691
5692 sc->sc_tdmabintval = roundup((sc->sc_tdmaslotlen+sc->sc_tdmaguard) *
5693 tdma->tdma_slotcnt, 1024);
5694 sc->sc_tdmabintval >>= 10; /* TSF -> TU */
5695 if (sc->sc_tdmabintval & 1)
5696 sc->sc_tdmabintval++;
5697
5698 if (tdma->tdma_slot == 0) {
5699 /*
5700 * Only slot 0 beacons; other slots respond.
5701 */
5702 sc->sc_imask |= HAL_INT_SWBA;
5703 sc->sc_tdmaswba = 0; /* beacon immediately */
5704 } else {
5705 /* XXX all vaps must be slot 0 or slot !0 */
5706 sc->sc_imask &= ~HAL_INT_SWBA;
5707 }
5708}
5709
5710/*
5711 * Max 802.11 overhead. This assumes no 4-address frames and
5712 * the encapsulation done by ieee80211_encap (llc). We also
5713 * include potential crypto overhead.
5714 */
5715#define IEEE80211_MAXOVERHEAD \
5716 (sizeof(struct ieee80211_qosframe) \
5717 + sizeof(struct llc) \
5718 + IEEE80211_ADDR_LEN \
5719 + IEEE80211_WEP_IVLEN \
5720 + IEEE80211_WEP_KIDLEN \
5721 + IEEE80211_WEP_CRCLEN \
5722 + IEEE80211_WEP_MICLEN \
5723 + IEEE80211_CRC_LEN)
5724
5725/*
5726 * Setup initially for tdma operation. Start the beacon
5727 * timers and enable SWBA if we are slot 0. Otherwise
5728 * we wait for slot 0 to arrive so we can sync up before
5729 * starting to transmit.
5730 */
5731static void
5732ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap)
5733{
5734 struct ath_hal *ah = sc->sc_ah;
5735 struct ifnet *ifp = sc->sc_ifp;
5736 struct ieee80211com *ic = ifp->if_l2com;
5737 const struct ieee80211_txparam *tp;
5738 const struct ieee80211_tdma_state *tdma = NULL;
5739 int rix;
5740
5741 if (vap == NULL) {
5742 vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */
5743 if (vap == NULL) {
5744 if_printf(ifp, "%s: no vaps?\n", __func__);
5745 return;
5746 }
5747 }
5748 /* XXX should take a locked ref to iv_bss */
5749 tp = vap->iv_bss->ni_txparms;
5750 /*
5751 * Calculate the guard time for each slot. This is the
5752 * time to send a maximal-size frame according to the
5753 * fixed/lowest transmit rate. Note that the interface
5754 * mtu does not include the 802.11 overhead so we must
5755 * tack that on (ath_hal_computetxtime includes the
5756 * preamble and plcp in it's calculation).
5757 */
5758 tdma = vap->iv_tdma;
5759 if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
5760 rix = ath_tx_findrix(sc, tp->ucastrate);
5761 else
5762 rix = ath_tx_findrix(sc, tp->mcastrate);
5763 /* XXX short preamble assumed */
5764 sc->sc_tdmaguard = ath_hal_computetxtime(ah, sc->sc_currates,
5765 ifp->if_mtu + IEEE80211_MAXOVERHEAD, rix, AH_TRUE);
5766
5767 ath_hal_intrset(ah, 0);
5768
5769 ath_beaconq_config(sc); /* setup h/w beacon q */
5770 if (sc->sc_setcca)
5771 ath_hal_setcca(ah, AH_FALSE); /* disable CCA */
5772 ath_tdma_bintvalsetup(sc, tdma); /* calculate beacon interval */
5773 ath_tdma_settimers(sc, sc->sc_tdmabintval,
5774 sc->sc_tdmabintval | HAL_BEACON_RESET_TSF);
5775 sc->sc_syncbeacon = 0;
5776
5777 sc->sc_avgtsfdeltap = TDMA_DUMMY_MARKER;
5778 sc->sc_avgtsfdeltam = TDMA_DUMMY_MARKER;
5779
5780 ath_hal_intrset(ah, sc->sc_imask);
5781
5782 DPRINTF(sc, ATH_DEBUG_TDMA, "%s: slot %u len %uus cnt %u "
5783 "bsched %u guard %uus bintval %u TU dba prep %u\n", __func__,
5784 tdma->tdma_slot, tdma->tdma_slotlen, tdma->tdma_slotcnt,
5785 tdma->tdma_bintval, sc->sc_tdmaguard, sc->sc_tdmabintval,
5786 sc->sc_tdmadbaprep);
5787}
5788
5789/*
5790 * Update tdma operation. Called from the 802.11 layer
5791 * when a beacon is received from the TDMA station operating
5792 * in the slot immediately preceding us in the bss. Use
5793 * the rx timestamp for the beacon frame to update our
5794 * beacon timers so we follow their schedule. Note that
5795 * by using the rx timestamp we implicitly include the
5796 * propagation delay in our schedule.
5797 */
5798static void
5799ath_tdma_update(struct ieee80211_node *ni,
5800 const struct ieee80211_tdma_param *tdma, int changed)
5801{
5802#define TSF_TO_TU(_h,_l) \
5803 ((((u_int32_t)(_h)) << 22) | (((u_int32_t)(_l)) >> 10))
5804#define TU_TO_TSF(_tu) (((u_int64_t)(_tu)) << 10)
5805 struct ieee80211vap *vap = ni->ni_vap;
5806 struct ieee80211com *ic = ni->ni_ic;
5807 struct ath_softc *sc = ic->ic_ifp->if_softc;
5808 struct ath_hal *ah = sc->sc_ah;
5809 const HAL_RATE_TABLE *rt = sc->sc_currates;
5810 u_int64_t tsf, rstamp, nextslot, nexttbtt;
5811 u_int32_t txtime, nextslottu;
5812 int32_t tudelta, tsfdelta;
5813 const struct ath_rx_status *rs;
5814 int rix;
5815
5816 sc->sc_stats.ast_tdma_update++;
5817
5818 /*
5819 * Check for and adopt configuration changes.
5820 */
5821 if (changed != 0) {
5822 const struct ieee80211_tdma_state *ts = vap->iv_tdma;
5823
5824 ath_tdma_bintvalsetup(sc, ts);
5825 if (changed & TDMA_UPDATE_SLOTLEN)
5826 ath_wme_update(ic);
5827
5828 DPRINTF(sc, ATH_DEBUG_TDMA,
5829 "%s: adopt slot %u slotcnt %u slotlen %u us "
5830 "bintval %u TU\n", __func__,
5831 ts->tdma_slot, ts->tdma_slotcnt, ts->tdma_slotlen,
5832 sc->sc_tdmabintval);
5833
5834 /* XXX right? */
5835 ath_hal_intrset(ah, sc->sc_imask);
5836 /* NB: beacon timers programmed below */
5837 }
5838
5839 /* extend rx timestamp to 64 bits */
5840 rs = sc->sc_lastrs;
5841 tsf = ath_hal_gettsf64(ah);
5842 rstamp = ath_extend_tsf(sc, rs->rs_tstamp, tsf);
5843 /*
5844 * The rx timestamp is set by the hardware on completing
5845 * reception (at the point where the rx descriptor is DMA'd
5846 * to the host). To find the start of our next slot we
5847 * must adjust this time by the time required to send
5848 * the packet just received.
5849 */
5850 rix = rt->rateCodeToIndex[rs->rs_rate];
5851 txtime = ath_hal_computetxtime(ah, rt, rs->rs_datalen, rix,
5852 rt->info[rix].shortPreamble);
5853 /* NB: << 9 is to cvt to TU and /2 */
5854 nextslot = (rstamp - txtime) + (sc->sc_tdmabintval << 9);
5855 nextslottu = TSF_TO_TU(nextslot>>32, nextslot) & HAL_BEACON_PERIOD;
5856
5857 /*
5858 * Retrieve the hardware NextTBTT in usecs
5859 * and calculate the difference between what the
5860 * other station thinks and what we have programmed. This
5861 * lets us figure how to adjust our timers to match. The
5862 * adjustments are done by pulling the TSF forward and possibly
5863 * rewriting the beacon timers.
5864 */
5865 nexttbtt = ath_hal_getnexttbtt(ah);
5866 tsfdelta = (int32_t)((nextslot % TU_TO_TSF(HAL_BEACON_PERIOD + 1)) - nexttbtt);
5867
5868 DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
5869 "tsfdelta %d avg +%d/-%d\n", tsfdelta,
5870 TDMA_AVG(sc->sc_avgtsfdeltap), TDMA_AVG(sc->sc_avgtsfdeltam));
5871
5872 if (tsfdelta < 0) {
5873 TDMA_SAMPLE(sc->sc_avgtsfdeltap, 0);
5874 TDMA_SAMPLE(sc->sc_avgtsfdeltam, -tsfdelta);
5875 tsfdelta = -tsfdelta % 1024;
5876 nextslottu++;
5877 } else if (tsfdelta > 0) {
5878 TDMA_SAMPLE(sc->sc_avgtsfdeltap, tsfdelta);
5879 TDMA_SAMPLE(sc->sc_avgtsfdeltam, 0);
5880 tsfdelta = 1024 - (tsfdelta % 1024);
5881 nextslottu++;
5882 } else {
5883 TDMA_SAMPLE(sc->sc_avgtsfdeltap, 0);
5884 TDMA_SAMPLE(sc->sc_avgtsfdeltam, 0);
5885 }
5886 tudelta = nextslottu - TSF_TO_TU(nexttbtt >> 32, nexttbtt);
5887
5888 /*
5889 * Copy sender's timetstamp into tdma ie so they can
5890 * calculate roundtrip time. We submit a beacon frame
5891 * below after any timer adjustment. The frame goes out
5892 * at the next TBTT so the sender can calculate the
5893 * roundtrip by inspecting the tdma ie in our beacon frame.
5894 *
5895 * NB: This tstamp is subtlely preserved when
5896 * IEEE80211_BEACON_TDMA is marked (e.g. when the
5897 * slot position changes) because ieee80211_add_tdma
5898 * skips over the data.
5899 */
5900 memcpy(ATH_VAP(vap)->av_boff.bo_tdma +
5901 __offsetof(struct ieee80211_tdma_param, tdma_tstamp),
5902 &ni->ni_tstamp.data, 8);
5903#if 0
5904 DPRINTF(sc, ATH_DEBUG_TDMA_TIMER,
5905 "tsf %llu nextslot %llu (%d, %d) nextslottu %u nexttbtt %llu (%d)\n",
5906 (unsigned long long) tsf, (unsigned long long) nextslot,
5907 (int)(nextslot - tsf), tsfdelta, nextslottu, nexttbtt, tudelta);
5908#endif
5909 /*
5910 * Adjust the beacon timers only when pulling them forward
5911 * or when going back by less than the beacon interval.
5912 * Negative jumps larger than the beacon interval seem to
5913 * cause the timers to stop and generally cause instability.
5914 * This basically filters out jumps due to missed beacons.
5915 */
5916 if (tudelta != 0 && (tudelta > 0 || -tudelta < sc->sc_tdmabintval)) {
5917 ath_tdma_settimers(sc, nextslottu, sc->sc_tdmabintval);
5918 sc->sc_stats.ast_tdma_timers++;
5919 }
5920 if (tsfdelta > 0) {
5921 ath_hal_adjusttsf(ah, tsfdelta);
5922 sc->sc_stats.ast_tdma_tsf++;
5923 }
5924 ath_tdma_beacon_send(sc, vap); /* prepare response */
5925#undef TU_TO_TSF
5926#undef TSF_TO_TU
5927}
5928
5929/*
5930 * Transmit a beacon frame at SWBA. Dynamic updates
5931 * to the frame contents are done as needed.
5932 */
5933static void
5934ath_tdma_beacon_send(struct ath_softc *sc, struct ieee80211vap *vap)
5935{
5936 struct ath_hal *ah = sc->sc_ah;
5937 struct ath_buf *bf;
5938 int otherant;
5939
5940 /*
5941 * Check if the previous beacon has gone out. If
5942 * not don't try to post another, skip this period
5943 * and wait for the next. Missed beacons indicate
5944 * a problem and should not occur. If we miss too
5945 * many consecutive beacons reset the device.
5946 */
5947 if (ath_hal_numtxpending(ah, sc->sc_bhalq) != 0) {
5948 sc->sc_bmisscount++;
5949 DPRINTF(sc, ATH_DEBUG_BEACON,
5950 "%s: missed %u consecutive beacons\n",
5951 __func__, sc->sc_bmisscount);
5952 if (sc->sc_bmisscount >= ath_bstuck_threshold)
5953 taskqueue_enqueue(sc->sc_tq, &sc->sc_bstucktask);
5954 return;
5955 }
5956 if (sc->sc_bmisscount != 0) {
5957 DPRINTF(sc, ATH_DEBUG_BEACON,
5958 "%s: resume beacon xmit after %u misses\n",
5959 __func__, sc->sc_bmisscount);
5960 sc->sc_bmisscount = 0;
5961 }
5962
5963 /*
5964 * Check recent per-antenna transmit statistics and flip
5965 * the default antenna if noticeably more frames went out
5966 * on the non-default antenna.
5967 * XXX assumes 2 anntenae
5968 */
5969 if (!sc->sc_diversity) {
5970 otherant = sc->sc_defant & 1 ? 2 : 1;
5971 if (sc->sc_ant_tx[otherant] > sc->sc_ant_tx[sc->sc_defant] + 2)
5972 ath_setdefantenna(sc, otherant);
5973 sc->sc_ant_tx[1] = sc->sc_ant_tx[2] = 0;
5974 }
5975
5976 bf = ath_beacon_generate(sc, vap);
5977 if (bf != NULL) {
5978 /*
5979 * Stop any current dma and put the new frame on the queue.
5980 * This should never fail since we check above that no frames
5981 * are still pending on the queue.
5982 */
5983 if (!ath_hal_stoptxdma(ah, sc->sc_bhalq)) {
5984 DPRINTF(sc, ATH_DEBUG_ANY,
5985 "%s: beacon queue %u did not stop?\n",
5986 __func__, sc->sc_bhalq);
5987 /* NB: the HAL still stops DMA, so proceed */
5988 }
5989 ath_hal_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr);
5990 ath_hal_txstart(ah, sc->sc_bhalq);
5991
5992 sc->sc_stats.ast_be_xmit++; /* XXX per-vap? */
5993
5994 /*
5995 * Record local TSF for our last send for use
5996 * in arbitrating slot collisions.
5997 */
5998 /* XXX should take a locked ref to iv_bss */
5999 vap->iv_bss->ni_tstamp.tsf = ath_hal_gettsf64(ah);
6000 }
6001}
6002#endif /* IEEE80211_SUPPORT_TDMA */
6003
6004static void
6005ath_dfs_tasklet(void *p, int npending)
6006{
6007 struct ath_softc *sc = (struct ath_softc *) p;
6008 struct ifnet *ifp = sc->sc_ifp;
6009 struct ieee80211com *ic = ifp->if_l2com;
6010
6011 /*
6012 * If previous processing has found a radar event,

--- 21 unchanged lines hidden ---
5646ath_dfs_tasklet(void *p, int npending)
5647{
5648 struct ath_softc *sc = (struct ath_softc *) p;
5649 struct ifnet *ifp = sc->sc_ifp;
5650 struct ieee80211com *ic = ifp->if_l2com;
5651
5652 /*
5653 * If previous processing has found a radar event,

--- 21 unchanged lines hidden ---