Deleted Added
full compact
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 ---