Deleted Added
sdiff udiff text old ( 232041 ) new ( 232163 )
full compact
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 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);
162static void ath_reset_proc(void *, int);
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);
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
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
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/*
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
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++;
5554 sc->sc_resetcal = 0;
5555 sc->sc_doresetcal = AH_TRUE;
5556 taskqueue_enqueue(sc->sc_tq, &sc->sc_resettask);
5557 callout_reset(&sc->sc_cal_ch, 1, ath_calibrate, sc);
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.
6210 */
6211 if (do_reset) {
6212 taskqueue_enqueue(sc->sc_tq, &sc->sc_resettask);
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 ---