if_ath.c (232041) | if_ath.c (232163) |
---|---|
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 232041 2012-02-23 08:32:54Z adrian $"); | 31__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 232163 2012-02-25 19:12:54Z 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 --- 114 unchanged lines hidden (view full) --- 154static int ath_beaconq_setup(struct ath_hal *); 155static int ath_beacon_alloc(struct ath_softc *, struct ieee80211_node *); 156static void ath_beacon_update(struct ieee80211vap *, int item); 157static void ath_beacon_setup(struct ath_softc *, struct ath_buf *); 158static void ath_beacon_proc(void *, int); 159static struct ath_buf *ath_beacon_generate(struct ath_softc *, 160 struct ieee80211vap *); 161static void ath_bstuck_proc(void *, int); | 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 --- 114 unchanged lines hidden (view full) --- 154static int ath_beaconq_setup(struct ath_hal *); 155static int ath_beacon_alloc(struct ath_softc *, struct ieee80211_node *); 156static void ath_beacon_update(struct ieee80211vap *, int item); 157static void ath_beacon_setup(struct ath_softc *, struct ath_buf *); 158static void ath_beacon_proc(void *, int); 159static struct ath_buf *ath_beacon_generate(struct ath_softc *, 160 struct ieee80211vap *); 161static void ath_bstuck_proc(void *, int); |
162static void ath_reset_proc(void *, int); |
|
162static void ath_beacon_return(struct ath_softc *, struct ath_buf *); 163static void ath_beacon_free(struct ath_softc *); 164static void ath_beacon_config(struct ath_softc *, struct ieee80211vap *); 165static void ath_descdma_cleanup(struct ath_softc *sc, 166 struct ath_descdma *, ath_bufhead *); 167static int ath_desc_alloc(struct ath_softc *); 168static void ath_desc_free(struct ath_softc *); 169static struct ieee80211_node *ath_node_alloc(struct ieee80211vap *, --- 217 unchanged lines hidden (view full) --- 387 sc->sc_tq = taskqueue_create("ath_taskq", M_NOWAIT, 388 taskqueue_thread_enqueue, &sc->sc_tq); 389 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 390 "%s taskq", ifp->if_xname); 391 392 TASK_INIT(&sc->sc_rxtask, 0, ath_rx_tasklet, sc); 393 TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc); 394 TASK_INIT(&sc->sc_bstucktask,0, ath_bstuck_proc, sc); | 163static void ath_beacon_return(struct ath_softc *, struct ath_buf *); 164static void ath_beacon_free(struct ath_softc *); 165static void ath_beacon_config(struct ath_softc *, struct ieee80211vap *); 166static void ath_descdma_cleanup(struct ath_softc *sc, 167 struct ath_descdma *, ath_bufhead *); 168static int ath_desc_alloc(struct ath_softc *); 169static void ath_desc_free(struct ath_softc *); 170static struct ieee80211_node *ath_node_alloc(struct ieee80211vap *, --- 217 unchanged lines hidden (view full) --- 388 sc->sc_tq = taskqueue_create("ath_taskq", M_NOWAIT, 389 taskqueue_thread_enqueue, &sc->sc_tq); 390 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 391 "%s taskq", ifp->if_xname); 392 393 TASK_INIT(&sc->sc_rxtask, 0, ath_rx_tasklet, sc); 394 TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc); 395 TASK_INIT(&sc->sc_bstucktask,0, ath_bstuck_proc, sc); |
396 TASK_INIT(&sc->sc_resettask,0, ath_reset_proc, sc); |
|
395 396 /* 397 * Allocate hardware transmit queues: one queue for 398 * beacon frames and one data queue for each QoS 399 * priority. Note that the hal handles resetting 400 * these queues at the needed time. 401 * 402 * XXX PS-Poll --- 1502 unchanged lines hidden (view full) --- 1905static void 1906ath_txrx_stop_locked(struct ath_softc *sc) 1907{ 1908 int i = MAX_TXRX_ITERATIONS; 1909 1910 ATH_UNLOCK_ASSERT(sc); 1911 ATH_PCU_LOCK_ASSERT(sc); 1912 | 397 398 /* 399 * Allocate hardware transmit queues: one queue for 400 * beacon frames and one data queue for each QoS 401 * priority. Note that the hal handles resetting 402 * these queues at the needed time. 403 * 404 * XXX PS-Poll --- 1502 unchanged lines hidden (view full) --- 1907static void 1908ath_txrx_stop_locked(struct ath_softc *sc) 1909{ 1910 int i = MAX_TXRX_ITERATIONS; 1911 1912 ATH_UNLOCK_ASSERT(sc); 1913 ATH_PCU_LOCK_ASSERT(sc); 1914 |
1913 /* Stop any new TX/RX from occuring */ 1914 taskqueue_block(sc->sc_tq); 1915 | |
1916 /* 1917 * Sleep until all the pending operations have completed. 1918 * 1919 * The caller must ensure that reset has been incremented 1920 * or the pending operations may continue being queued. 1921 */ 1922 while (sc->sc_rxproc_cnt || sc->sc_txproc_cnt || 1923 sc->sc_txstart_cnt || sc->sc_intr_cnt) { --- 121 unchanged lines hidden (view full) --- 2045 int i; 2046 2047 DPRINTF(sc, ATH_DEBUG_RESET, "%s: called\n", __func__); 2048 2049 /* Ensure ATH_LOCK isn't held; ath_rx_proc can't be locked */ 2050 ATH_PCU_UNLOCK_ASSERT(sc); 2051 ATH_UNLOCK_ASSERT(sc); 2052 | 1915 /* 1916 * Sleep until all the pending operations have completed. 1917 * 1918 * The caller must ensure that reset has been incremented 1919 * or the pending operations may continue being queued. 1920 */ 1921 while (sc->sc_rxproc_cnt || sc->sc_txproc_cnt || 1922 sc->sc_txstart_cnt || sc->sc_intr_cnt) { --- 121 unchanged lines hidden (view full) --- 2044 int i; 2045 2046 DPRINTF(sc, ATH_DEBUG_RESET, "%s: called\n", __func__); 2047 2048 /* Ensure ATH_LOCK isn't held; ath_rx_proc can't be locked */ 2049 ATH_PCU_UNLOCK_ASSERT(sc); 2050 ATH_UNLOCK_ASSERT(sc); 2051 |
2052 /* Try to (stop any further TX/RX from occuring */ 2053 taskqueue_block(sc->sc_tq); 2054 |
|
2053 ATH_PCU_LOCK(sc); 2054 ath_hal_intrset(ah, 0); /* disable interrupts */ 2055 ath_txrx_stop_locked(sc); /* Ensure TX/RX is stopped */ 2056 if (ath_reset_grablock(sc, 1) == 0) { 2057 device_printf(sc->sc_dev, "%s: concurrent reset! Danger!\n", 2058 __func__); 2059 } 2060 ATH_PCU_UNLOCK(sc); --- 1097 unchanged lines hidden (view full) --- 3158 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE); 3159 3160 /* NB: caller is known to have already stopped tx dma */ 3161 ath_hal_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr); 3162 ath_hal_txstart(ah, sc->sc_bhalq); 3163} 3164 3165/* | 2055 ATH_PCU_LOCK(sc); 2056 ath_hal_intrset(ah, 0); /* disable interrupts */ 2057 ath_txrx_stop_locked(sc); /* Ensure TX/RX is stopped */ 2058 if (ath_reset_grablock(sc, 1) == 0) { 2059 device_printf(sc->sc_dev, "%s: concurrent reset! Danger!\n", 2060 __func__); 2061 } 2062 ATH_PCU_UNLOCK(sc); --- 1097 unchanged lines hidden (view full) --- 3160 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE); 3161 3162 /* NB: caller is known to have already stopped tx dma */ 3163 ath_hal_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr); 3164 ath_hal_txstart(ah, sc->sc_bhalq); 3165} 3166 3167/* |
3168 * Reset the hardware, with no loss. 3169 * 3170 * This can't be used for a general case reset. 3171 */ 3172static void 3173ath_reset_proc(void *arg, int pending) 3174{ 3175 struct ath_softc *sc = arg; 3176 struct ifnet *ifp = sc->sc_ifp; 3177 3178#if 0 3179 if_printf(ifp, "%s: resetting\n", __func__); 3180#endif 3181 ath_reset(ifp, ATH_RESET_NOLOSS); 3182} 3183 3184/* |
|
3166 * Reset the hardware after detecting beacons have stopped. 3167 */ 3168static void 3169ath_bstuck_proc(void *arg, int pending) 3170{ 3171 struct ath_softc *sc = arg; 3172 struct ifnet *ifp = sc->sc_ifp; 3173 uint32_t hangs = 0; --- 2208 unchanged lines hidden (view full) --- 5382ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) 5383{ 5384 struct ifnet *ifp = sc->sc_ifp; 5385 struct ieee80211com *ic = ifp->if_l2com; 5386 struct ath_hal *ah = sc->sc_ah; 5387 int ret = 0; 5388 5389 /* Treat this as an interface reset */ | 3185 * Reset the hardware after detecting beacons have stopped. 3186 */ 3187static void 3188ath_bstuck_proc(void *arg, int pending) 3189{ 3190 struct ath_softc *sc = arg; 3191 struct ifnet *ifp = sc->sc_ifp; 3192 uint32_t hangs = 0; --- 2208 unchanged lines hidden (view full) --- 5401ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) 5402{ 5403 struct ifnet *ifp = sc->sc_ifp; 5404 struct ieee80211com *ic = ifp->if_l2com; 5405 struct ath_hal *ah = sc->sc_ah; 5406 int ret = 0; 5407 5408 /* Treat this as an interface reset */ |
5409 ATH_PCU_UNLOCK_ASSERT(sc); 5410 ATH_UNLOCK_ASSERT(sc); 5411 5412 /* (Try to) stop TX/RX from occuring */ 5413 taskqueue_block(sc->sc_tq); 5414 |
|
5390 ATH_PCU_LOCK(sc); 5391 ath_hal_intrset(ah, 0); /* Stop new RX/TX completion */ 5392 ath_txrx_stop_locked(sc); /* Stop pending RX/TX completion */ 5393 if (ath_reset_grablock(sc, 1) == 0) { 5394 device_printf(sc->sc_dev, "%s: concurrent reset! Danger!\n", 5395 __func__); 5396 } 5397 ATH_PCU_UNLOCK(sc); --- 123 unchanged lines hidden (view full) --- 5521 if (ath_hal_getrfgain(ah) == HAL_RFGAIN_NEED_CHANGE) { 5522 /* 5523 * Rfgain is out of bounds, reset the chip 5524 * to load new gain values. 5525 */ 5526 DPRINTF(sc, ATH_DEBUG_CALIBRATE, 5527 "%s: rfgain change\n", __func__); 5528 sc->sc_stats.ast_per_rfgain++; | 5415 ATH_PCU_LOCK(sc); 5416 ath_hal_intrset(ah, 0); /* Stop new RX/TX completion */ 5417 ath_txrx_stop_locked(sc); /* Stop pending RX/TX completion */ 5418 if (ath_reset_grablock(sc, 1) == 0) { 5419 device_printf(sc->sc_dev, "%s: concurrent reset! Danger!\n", 5420 __func__); 5421 } 5422 ATH_PCU_UNLOCK(sc); --- 123 unchanged lines hidden (view full) --- 5546 if (ath_hal_getrfgain(ah) == HAL_RFGAIN_NEED_CHANGE) { 5547 /* 5548 * Rfgain is out of bounds, reset the chip 5549 * to load new gain values. 5550 */ 5551 DPRINTF(sc, ATH_DEBUG_CALIBRATE, 5552 "%s: rfgain change\n", __func__); 5553 sc->sc_stats.ast_per_rfgain++; |
5529 /* 5530 * Drop lock - we can't hold it across the 5531 * ath_reset() call. Instead, we'll drop 5532 * out here, do a reset, then reschedule 5533 * the callout. 5534 */ 5535 callout_reset(&sc->sc_cal_ch, 1, ath_calibrate, sc); | |
5536 sc->sc_resetcal = 0; 5537 sc->sc_doresetcal = AH_TRUE; | 5554 sc->sc_resetcal = 0; 5555 sc->sc_doresetcal = AH_TRUE; |
5538 ATH_UNLOCK(sc); 5539 ath_reset(ifp, ATH_RESET_NOLOSS); 5540 ATH_LOCK(sc); | 5556 taskqueue_enqueue(sc->sc_tq, &sc->sc_resettask); 5557 callout_reset(&sc->sc_cal_ch, 1, ath_calibrate, sc); |
5541 return; 5542 } 5543 /* 5544 * If this long cal is after an idle period, then 5545 * reset the data collection state so we start fresh. 5546 */ 5547 if (sc->sc_resetcal) { 5548 (void) ath_hal_calreset(ah, sc->sc_curchan); --- 633 unchanged lines hidden (view full) --- 6182 if_printf(ifp, "device timeout\n"); 6183 do_reset = 1; 6184 ifp->if_oerrors++; 6185 sc->sc_stats.ast_watchdog++; 6186 } 6187 6188 /* 6189 * We can't hold the lock across the ath_reset() call. | 5558 return; 5559 } 5560 /* 5561 * If this long cal is after an idle period, then 5562 * reset the data collection state so we start fresh. 5563 */ 5564 if (sc->sc_resetcal) { 5565 (void) ath_hal_calreset(ah, sc->sc_curchan); --- 633 unchanged lines hidden (view full) --- 6199 if_printf(ifp, "device timeout\n"); 6200 do_reset = 1; 6201 ifp->if_oerrors++; 6202 sc->sc_stats.ast_watchdog++; 6203 } 6204 6205 /* 6206 * We can't hold the lock across the ath_reset() call. |
6207 * 6208 * And since this routine can't hold a lock and sleep, 6209 * do the reset deferred. |
|
6190 */ 6191 if (do_reset) { | 6210 */ 6211 if (do_reset) { |
6192 ATH_UNLOCK(sc); 6193 ath_reset(sc->sc_ifp, ATH_RESET_NOLOSS); 6194 ATH_LOCK(sc); | 6212 taskqueue_enqueue(sc->sc_tq, &sc->sc_resettask); |
6195 } 6196 6197 callout_schedule(&sc->sc_wd_ch, hz); 6198} 6199 6200#ifdef ATH_DIAGAPI 6201/* 6202 * Diagnostic interface to the HAL. This is used by various --- 559 unchanged lines hidden --- | 6213 } 6214 6215 callout_schedule(&sc->sc_wd_ch, hz); 6216} 6217 6218#ifdef ATH_DIAGAPI 6219/* 6220 * Diagnostic interface to the HAL. This is used by various --- 559 unchanged lines hidden --- |