1238710Sadrian/*- 2238710Sadrian * Copyright (c) 2012 Adrian Chadd <adrian@FreeBSD.org> 3238710Sadrian * All rights reserved. 4238710Sadrian * 5238710Sadrian * Redistribution and use in source and binary forms, with or without 6238710Sadrian * modification, are permitted provided that the following conditions 7238710Sadrian * are met: 8238710Sadrian * 1. Redistributions of source code must retain the above copyright 9238710Sadrian * notice, this list of conditions and the following disclaimer, 10238710Sadrian * without modification. 11238710Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12238710Sadrian * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13238710Sadrian * redistribution must be conditioned upon including a substantially 14238710Sadrian * similar Disclaimer requirement for further binary redistribution. 15238710Sadrian * 16238710Sadrian * NO WARRANTY 17238710Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18238710Sadrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19238710Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20238710Sadrian * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21238710Sadrian * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22238710Sadrian * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23238710Sadrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24238710Sadrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25238710Sadrian * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26238710Sadrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27238710Sadrian * THE POSSIBILITY OF SUCH DAMAGES. 28238710Sadrian */ 29238710Sadrian 30238710Sadrian#include <sys/cdefs.h> 31238710Sadrian__FBSDID("$FreeBSD$"); 32238710Sadrian 33238710Sadrian/* 34238710Sadrian * Driver for the Atheros Wireless LAN controller. 35238710Sadrian * 36238710Sadrian * This software is derived from work of Atsushi Onoe; his contribution 37238710Sadrian * is greatly appreciated. 38238710Sadrian */ 39238710Sadrian 40238710Sadrian#include "opt_inet.h" 41238710Sadrian#include "opt_ath.h" 42238710Sadrian/* 43238710Sadrian * This is needed for register operations which are performed 44238710Sadrian * by the driver - eg, calls to ath_hal_gettsf32(). 45238710Sadrian * 46238710Sadrian * It's also required for any AH_DEBUG checks in here, eg the 47238710Sadrian * module dependencies. 48238710Sadrian */ 49238710Sadrian#include "opt_ah.h" 50238710Sadrian#include "opt_wlan.h" 51238710Sadrian 52238710Sadrian#include <sys/param.h> 53238710Sadrian#include <sys/systm.h> 54238710Sadrian#include <sys/sysctl.h> 55238710Sadrian#include <sys/mbuf.h> 56238710Sadrian#include <sys/malloc.h> 57238710Sadrian#include <sys/lock.h> 58238710Sadrian#include <sys/mutex.h> 59238710Sadrian#include <sys/kernel.h> 60238710Sadrian#include <sys/socket.h> 61238710Sadrian#include <sys/sockio.h> 62238710Sadrian#include <sys/errno.h> 63238710Sadrian#include <sys/callout.h> 64238710Sadrian#include <sys/bus.h> 65238710Sadrian#include <sys/endian.h> 66238710Sadrian#include <sys/kthread.h> 67238710Sadrian#include <sys/taskqueue.h> 68238710Sadrian#include <sys/priv.h> 69238710Sadrian#include <sys/module.h> 70238710Sadrian#include <sys/ktr.h> 71238710Sadrian#include <sys/smp.h> /* for mp_ncpus */ 72238710Sadrian 73238710Sadrian#include <machine/bus.h> 74238710Sadrian 75238710Sadrian#include <net/if.h> 76238710Sadrian#include <net/if_dl.h> 77238710Sadrian#include <net/if_media.h> 78238710Sadrian#include <net/if_types.h> 79238710Sadrian#include <net/if_arp.h> 80238710Sadrian#include <net/ethernet.h> 81238710Sadrian#include <net/if_llc.h> 82238710Sadrian 83238710Sadrian#include <net80211/ieee80211_var.h> 84238710Sadrian#include <net80211/ieee80211_regdomain.h> 85238710Sadrian#ifdef IEEE80211_SUPPORT_SUPERG 86238710Sadrian#include <net80211/ieee80211_superg.h> 87238710Sadrian#endif 88238710Sadrian#ifdef IEEE80211_SUPPORT_TDMA 89238710Sadrian#include <net80211/ieee80211_tdma.h> 90238710Sadrian#endif 91238710Sadrian 92238710Sadrian#include <net/bpf.h> 93238710Sadrian 94238710Sadrian#ifdef INET 95238710Sadrian#include <netinet/in.h> 96238710Sadrian#include <netinet/if_ether.h> 97238710Sadrian#endif 98238710Sadrian 99238710Sadrian#include <dev/ath/if_athvar.h> 100238710Sadrian#include <dev/ath/ath_hal/ah_devid.h> /* XXX for softled */ 101238710Sadrian#include <dev/ath/ath_hal/ah_diagcodes.h> 102238710Sadrian 103238710Sadrian#include <dev/ath/if_ath_debug.h> 104238710Sadrian#include <dev/ath/if_ath_misc.h> 105238710Sadrian#include <dev/ath/if_ath_tsf.h> 106238710Sadrian#include <dev/ath/if_ath_tx.h> 107238710Sadrian#include <dev/ath/if_ath_sysctl.h> 108238710Sadrian#include <dev/ath/if_ath_led.h> 109238710Sadrian#include <dev/ath/if_ath_keycache.h> 110238710Sadrian#include <dev/ath/if_ath_rx.h> 111238710Sadrian#include <dev/ath/if_ath_beacon.h> 112238710Sadrian#include <dev/ath/if_athdfs.h> 113238710Sadrian 114238710Sadrian#ifdef ATH_TX99_DIAG 115238710Sadrian#include <dev/ath/ath_tx99/ath_tx99.h> 116238710Sadrian#endif 117238710Sadrian 118238710Sadrian#include <dev/ath/if_ath_tx_edma.h> 119238710Sadrian 120242782Sadrian#ifdef ATH_DEBUG_ALQ 121242782Sadrian#include <dev/ath/if_ath_alq.h> 122242782Sadrian#endif 123242782Sadrian 124238710Sadrian/* 125238710Sadrian * some general macros 126238836Sadrian */ 127238710Sadrian#define INCR(_l, _sz) (_l) ++; (_l) &= ((_sz) - 1) 128238710Sadrian#define DECR(_l, _sz) (_l) --; (_l) &= ((_sz) - 1) 129238710Sadrian 130238836Sadrian/* 131238836Sadrian * XXX doesn't belong here, and should be tunable 132238836Sadrian */ 133238836Sadrian#define ATH_TXSTATUS_RING_SIZE 512 134238836Sadrian 135238710SadrianMALLOC_DECLARE(M_ATHDEV); 136238710Sadrian 137242779Sadrianstatic void ath_edma_tx_processq(struct ath_softc *sc, int dosched); 138242779Sadrian 139248750Sadrian/* 140248750Sadrian * Push some frames into the TX FIFO if we have space. 141248750Sadrian */ 142239410Sadrianstatic void 143239410Sadrianath_edma_tx_fifo_fill(struct ath_softc *sc, struct ath_txq *txq) 144239410Sadrian{ 145248750Sadrian struct ath_buf *bf, *bf_last; 146242532Sadrian int i = 0; 147239410Sadrian 148248671Sadrian ATH_TXQ_LOCK_ASSERT(txq); 149239410Sadrian 150248750Sadrian DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: Q%d: called\n", 151248750Sadrian __func__, 152248750Sadrian txq->axq_qnum); 153239410Sadrian 154239410Sadrian TAILQ_FOREACH(bf, &txq->axq_q, bf_list) { 155239410Sadrian if (txq->axq_fifo_depth >= HAL_TXFIFO_DEPTH) 156239410Sadrian break; 157248750Sadrian 158248750Sadrian /* 159248750Sadrian * We have space in the FIFO - so let's push a frame 160248750Sadrian * into it. 161248750Sadrian */ 162248750Sadrian 163248750Sadrian /* 164248750Sadrian * Remove it from the normal list 165248750Sadrian */ 166248750Sadrian ATH_TXQ_REMOVE(txq, bf, bf_list); 167248750Sadrian 168248750Sadrian /* 169248750Sadrian * XXX for now, we only dequeue a frame at a time, so 170248750Sadrian * that's only one buffer. Later on when we just 171248750Sadrian * push this staging _list_ into the queue, we'll 172248750Sadrian * set bf_last to the end pointer in the list. 173248750Sadrian */ 174248750Sadrian bf_last = bf; 175248750Sadrian DPRINTF(sc, ATH_DEBUG_TX_PROC, 176248750Sadrian "%s: Q%d: depth=%d; pushing %p->%p\n", 177248750Sadrian __func__, 178248750Sadrian txq->axq_qnum, 179248750Sadrian txq->axq_fifo_depth, 180248750Sadrian bf, 181248750Sadrian bf_last); 182248750Sadrian 183248750Sadrian /* 184248750Sadrian * Append it to the FIFO staging list 185248750Sadrian */ 186248750Sadrian ATH_TXQ_INSERT_TAIL(&txq->fifo, bf, bf_list); 187248750Sadrian 188248750Sadrian /* 189248750Sadrian * Set fifo start / fifo end flags appropriately 190248750Sadrian * 191248750Sadrian */ 192248750Sadrian bf->bf_flags |= ATH_BUF_FIFOPTR; 193248750Sadrian bf_last->bf_flags |= ATH_BUF_FIFOEND; 194248750Sadrian 195248750Sadrian /* 196248750Sadrian * Push _into_ the FIFO. 197248750Sadrian */ 198239410Sadrian ath_hal_puttxbuf(sc->sc_ah, txq->axq_qnum, bf->bf_daddr); 199242532Sadrian#ifdef ATH_DEBUG 200242532Sadrian if (sc->sc_debug & ATH_DEBUG_XMIT_DESC) 201242532Sadrian ath_printtxbuf(sc, bf, txq->axq_qnum, i, 0); 202242782Sadrian#endif/* ATH_DEBUG */ 203242782Sadrian#ifdef ATH_DEBUG_ALQ 204242782Sadrian if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_TXDESC)) 205243163Sadrian ath_tx_alq_post(sc, bf); 206242782Sadrian#endif /* ATH_DEBUG_ALQ */ 207239410Sadrian txq->axq_fifo_depth++; 208242532Sadrian i++; 209239410Sadrian } 210242532Sadrian if (i > 0) 211242532Sadrian ath_hal_txstart(sc->sc_ah, txq->axq_qnum); 212239410Sadrian} 213239410Sadrian 214238930Sadrian/* 215238930Sadrian * Re-initialise the DMA FIFO with the current contents of 216239197Sadrian * said TXQ. 217238930Sadrian * 218238930Sadrian * This should only be called as part of the chip reset path, as it 219238930Sadrian * assumes the FIFO is currently empty. 220238930Sadrian */ 221238930Sadrianstatic void 222238930Sadrianath_edma_dma_restart(struct ath_softc *sc, struct ath_txq *txq) 223238930Sadrian{ 224248750Sadrian struct ath_buf *bf; 225248750Sadrian int i = 0; 226248750Sadrian int fifostart = 1; 227248750Sadrian int old_fifo_depth; 228238930Sadrian 229248750Sadrian DPRINTF(sc, ATH_DEBUG_RESET, "%s: Q%d: called\n", 230238930Sadrian __func__, 231238930Sadrian txq->axq_qnum); 232239410Sadrian 233248671Sadrian ATH_TXQ_LOCK_ASSERT(txq); 234248750Sadrian 235248750Sadrian /* 236248750Sadrian * Let's log if the tracked FIFO depth doesn't match 237248750Sadrian * what we actually push in. 238248750Sadrian */ 239248750Sadrian old_fifo_depth = txq->axq_fifo_depth; 240248750Sadrian txq->axq_fifo_depth = 0; 241248750Sadrian 242248750Sadrian /* 243248750Sadrian * Walk the FIFO staging list, looking for "head" entries. 244248750Sadrian * Since we may have a partially completed list of frames, 245248750Sadrian * we push the first frame we see into the FIFO and re-mark 246248750Sadrian * it as the head entry. We then skip entries until we see 247248750Sadrian * FIFO end, at which point we get ready to push another 248248750Sadrian * entry into the FIFO. 249248750Sadrian */ 250248750Sadrian TAILQ_FOREACH(bf, &txq->fifo.axq_q, bf_list) { 251248750Sadrian /* 252248750Sadrian * If we're looking for FIFOEND and we haven't found 253248750Sadrian * it, skip. 254248750Sadrian * 255248750Sadrian * If we're looking for FIFOEND and we've found it, 256248750Sadrian * reset for another descriptor. 257248750Sadrian */ 258248750Sadrian#ifdef ATH_DEBUG 259248750Sadrian if (sc->sc_debug & ATH_DEBUG_XMIT_DESC) 260248750Sadrian ath_printtxbuf(sc, bf, txq->axq_qnum, i, 0); 261248750Sadrian#endif/* ATH_DEBUG */ 262248750Sadrian#ifdef ATH_DEBUG_ALQ 263248750Sadrian if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_TXDESC)) 264248750Sadrian ath_tx_alq_post(sc, bf); 265248750Sadrian#endif /* ATH_DEBUG_ALQ */ 266248750Sadrian 267248750Sadrian if (fifostart == 0) { 268248750Sadrian if (bf->bf_flags & ATH_BUF_FIFOEND) 269248750Sadrian fifostart = 1; 270248750Sadrian continue; 271248750Sadrian } 272248750Sadrian 273248750Sadrian /* Make sure we're not overflowing the FIFO! */ 274248750Sadrian if (txq->axq_fifo_depth >= HAL_TXFIFO_DEPTH) { 275248750Sadrian device_printf(sc->sc_dev, 276248750Sadrian "%s: Q%d: more frames in the queue; FIFO depth=%d?!\n", 277248750Sadrian __func__, 278248750Sadrian txq->axq_qnum, 279248750Sadrian txq->axq_fifo_depth); 280248750Sadrian } 281248750Sadrian 282248750Sadrian#if 0 283248750Sadrian DPRINTF(sc, ATH_DEBUG_RESET, 284248750Sadrian "%s: Q%d: depth=%d: pushing bf=%p; start=%d, end=%d\n", 285248750Sadrian __func__, 286248750Sadrian txq->axq_qnum, 287248750Sadrian txq->axq_fifo_depth, 288248750Sadrian bf, 289248750Sadrian !! (bf->bf_flags & ATH_BUF_FIFOPTR), 290248750Sadrian !! (bf->bf_flags & ATH_BUF_FIFOEND)); 291248750Sadrian#endif 292248750Sadrian 293248750Sadrian /* 294248750Sadrian * Set this to be the first buffer in the FIFO 295248750Sadrian * list - even if it's also the last buffer in 296248750Sadrian * a FIFO list! 297248750Sadrian */ 298248750Sadrian bf->bf_flags |= ATH_BUF_FIFOPTR; 299248750Sadrian 300248750Sadrian /* Push it into the FIFO and bump the FIFO count */ 301248750Sadrian ath_hal_puttxbuf(sc->sc_ah, txq->axq_qnum, bf->bf_daddr); 302248750Sadrian txq->axq_fifo_depth++; 303248750Sadrian 304248750Sadrian /* 305248750Sadrian * If this isn't the last entry either, let's 306248750Sadrian * clear fifostart so we continue looking for 307248750Sadrian * said last entry. 308248750Sadrian */ 309248750Sadrian if (! (bf->bf_flags & ATH_BUF_FIFOEND)) 310248750Sadrian fifostart = 0; 311248750Sadrian i++; 312248750Sadrian } 313248750Sadrian 314248750Sadrian /* Only bother starting the queue if there's something in it */ 315248750Sadrian if (i > 0) 316248750Sadrian ath_hal_txstart(sc->sc_ah, txq->axq_qnum); 317248750Sadrian 318248750Sadrian DPRINTF(sc, ATH_DEBUG_RESET, "%s: Q%d: FIFO depth was %d, is %d\n", 319248750Sadrian __func__, 320248750Sadrian txq->axq_qnum, 321248750Sadrian old_fifo_depth, 322248750Sadrian txq->axq_fifo_depth); 323248750Sadrian 324248750Sadrian /* And now, let's check! */ 325248750Sadrian if (txq->axq_fifo_depth != old_fifo_depth) { 326248750Sadrian device_printf(sc->sc_dev, 327248750Sadrian "%s: Q%d: FIFO depth should be %d, is %d\n", 328248750Sadrian __func__, 329248750Sadrian txq->axq_qnum, 330248750Sadrian old_fifo_depth, 331248750Sadrian txq->axq_fifo_depth); 332248750Sadrian } 333238930Sadrian} 334238930Sadrian 335238930Sadrian/* 336239197Sadrian * Hand off this frame to a hardware queue. 337239197Sadrian * 338239197Sadrian * Things are a bit hairy in the EDMA world. The TX FIFO is only 339239197Sadrian * 8 entries deep, so we need to keep track of exactly what we've 340239197Sadrian * pushed into the FIFO and what's just sitting in the TX queue, 341239197Sadrian * waiting to go out. 342239197Sadrian * 343239197Sadrian * So this is split into two halves - frames get appended to the 344239197Sadrian * TXQ; then a scheduler is called to push some frames into the 345239197Sadrian * actual TX FIFO. 346239197Sadrian */ 347239197Sadrianstatic void 348239197Sadrianath_edma_xmit_handoff_hw(struct ath_softc *sc, struct ath_txq *txq, 349239197Sadrian struct ath_buf *bf) 350239197Sadrian{ 351239197Sadrian 352248675Sadrian ATH_TXQ_LOCK(txq); 353239197Sadrian 354239197Sadrian KASSERT((bf->bf_flags & ATH_BUF_BUSY) == 0, 355239197Sadrian ("%s: busy status 0x%x", __func__, bf->bf_flags)); 356239197Sadrian 357239197Sadrian /* 358239197Sadrian * XXX TODO: write a hard-coded check to ensure that 359239197Sadrian * the queue id in the TX descriptor matches txq->axq_qnum. 360239197Sadrian */ 361239197Sadrian 362239197Sadrian /* Update aggr stats */ 363239197Sadrian if (bf->bf_state.bfs_aggr) 364239197Sadrian txq->axq_aggr_depth++; 365239197Sadrian 366239197Sadrian /* Push and update frame stats */ 367239197Sadrian ATH_TXQ_INSERT_TAIL(txq, bf, bf_list); 368239197Sadrian 369248750Sadrian /* For now, set the link pointer in the last descriptor 370248750Sadrian * to be NULL. 371248750Sadrian * 372248750Sadrian * Later on, when it comes time to handling multiple descriptors 373248750Sadrian * in one FIFO push, we can link descriptors together this way. 374248750Sadrian */ 375248750Sadrian 376248750Sadrian /* 377248750Sadrian * Finally, call the FIFO schedule routine to schedule some 378248750Sadrian * frames to the FIFO. 379248750Sadrian */ 380248750Sadrian ath_edma_tx_fifo_fill(sc, txq); 381248675Sadrian ATH_TXQ_UNLOCK(txq); 382239197Sadrian} 383239197Sadrian 384239197Sadrian/* 385239197Sadrian * Hand off this frame to a multicast software queue. 386239197Sadrian * 387243163Sadrian * The EDMA TX CABQ will get a list of chained frames, chained 388243163Sadrian * together using the next pointer. The single head of that 389243163Sadrian * particular queue is pushed to the hardware CABQ. 390239197Sadrian */ 391239197Sadrianstatic void 392239197Sadrianath_edma_xmit_handoff_mcast(struct ath_softc *sc, struct ath_txq *txq, 393239197Sadrian struct ath_buf *bf) 394239197Sadrian{ 395239197Sadrian 396248714Sadrian ATH_TX_LOCK_ASSERT(sc); 397239197Sadrian KASSERT((bf->bf_flags & ATH_BUF_BUSY) == 0, 398239197Sadrian ("%s: busy status 0x%x", __func__, bf->bf_flags)); 399239197Sadrian 400248675Sadrian ATH_TXQ_LOCK(txq); 401239197Sadrian /* 402239197Sadrian * XXX this is mostly duplicated in ath_tx_handoff_mcast(). 403239197Sadrian */ 404248714Sadrian if (ATH_TXQ_LAST(txq, axq_q_s) != NULL) { 405239197Sadrian struct ath_buf *bf_last = ATH_TXQ_LAST(txq, axq_q_s); 406239197Sadrian struct ieee80211_frame *wh; 407239197Sadrian 408239197Sadrian /* mark previous frame */ 409239197Sadrian wh = mtod(bf_last->bf_m, struct ieee80211_frame *); 410239197Sadrian wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; 411239197Sadrian 412250408Sadrian /* re-sync buffer to memory */ 413239197Sadrian bus_dmamap_sync(sc->sc_dmat, bf_last->bf_dmamap, 414239197Sadrian BUS_DMASYNC_PREWRITE); 415248543Sadrian 416248543Sadrian /* link descriptor */ 417248714Sadrian ath_hal_settxdesclink(sc->sc_ah, 418248714Sadrian bf_last->bf_lastds, 419248714Sadrian bf->bf_daddr); 420239197Sadrian } 421243163Sadrian#ifdef ATH_DEBUG_ALQ 422243163Sadrian if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_TXDESC)) 423243163Sadrian ath_tx_alq_post(sc, bf); 424243163Sadrian#endif /* ATH_DEBUG_ALQ */ 425239197Sadrian ATH_TXQ_INSERT_TAIL(txq, bf, bf_list); 426248675Sadrian ATH_TXQ_UNLOCK(txq); 427239197Sadrian} 428239197Sadrian 429239197Sadrian/* 430238930Sadrian * Handoff this frame to the hardware. 431238930Sadrian * 432238930Sadrian * For the multicast queue, this will treat it as a software queue 433238930Sadrian * and append it to the list, after updating the MORE_DATA flag 434238930Sadrian * in the previous frame. The cabq processing code will ensure 435238930Sadrian * that the queue contents gets transferred over. 436238930Sadrian * 437238930Sadrian * For the hardware queues, this will queue a frame to the queue 438238930Sadrian * like before, then populate the FIFO from that. Since the 439238930Sadrian * EDMA hardware has 8 FIFO slots per TXQ, this ensures that 440238930Sadrian * frames such as management frames don't get prematurely dropped. 441238930Sadrian * 442238930Sadrian * This does imply that a similar flush-hwq-to-fifoq method will 443238930Sadrian * need to be called from the processq function, before the 444238930Sadrian * per-node software scheduler is called. 445238930Sadrian */ 446238930Sadrianstatic void 447238930Sadrianath_edma_xmit_handoff(struct ath_softc *sc, struct ath_txq *txq, 448238930Sadrian struct ath_buf *bf) 449238930Sadrian{ 450238930Sadrian 451239410Sadrian DPRINTF(sc, ATH_DEBUG_XMIT_DESC, 452239410Sadrian "%s: called; bf=%p, txq=%p, qnum=%d\n", 453238930Sadrian __func__, 454238930Sadrian bf, 455238930Sadrian txq, 456238930Sadrian txq->axq_qnum); 457238930Sadrian 458239197Sadrian if (txq->axq_qnum == ATH_TXQ_SWQ) 459239197Sadrian ath_edma_xmit_handoff_mcast(sc, txq, bf); 460239197Sadrian else 461239197Sadrian ath_edma_xmit_handoff_hw(sc, txq, bf); 462238930Sadrian} 463238930Sadrian 464238710Sadrianstatic int 465238855Sadrianath_edma_setup_txfifo(struct ath_softc *sc, int qnum) 466238855Sadrian{ 467238855Sadrian struct ath_tx_edma_fifo *te = &sc->sc_txedma[qnum]; 468238855Sadrian 469238855Sadrian te->m_fifo = malloc(sizeof(struct ath_buf *) * HAL_TXFIFO_DEPTH, 470238855Sadrian M_ATHDEV, 471238855Sadrian M_NOWAIT | M_ZERO); 472238855Sadrian if (te->m_fifo == NULL) { 473238855Sadrian device_printf(sc->sc_dev, "%s: malloc failed\n", 474238855Sadrian __func__); 475238855Sadrian return (-ENOMEM); 476238855Sadrian } 477238855Sadrian 478238855Sadrian /* 479238855Sadrian * Set initial "empty" state. 480238855Sadrian */ 481238855Sadrian te->m_fifo_head = te->m_fifo_tail = te->m_fifo_depth = 0; 482238855Sadrian 483238855Sadrian return (0); 484238855Sadrian} 485238855Sadrian 486238855Sadrianstatic int 487238855Sadrianath_edma_free_txfifo(struct ath_softc *sc, int qnum) 488238855Sadrian{ 489238855Sadrian struct ath_tx_edma_fifo *te = &sc->sc_txedma[qnum]; 490238855Sadrian 491238855Sadrian /* XXX TODO: actually deref the ath_buf entries? */ 492238855Sadrian free(te->m_fifo, M_ATHDEV); 493238855Sadrian return (0); 494238855Sadrian} 495238855Sadrian 496238855Sadrianstatic int 497238710Sadrianath_edma_dma_txsetup(struct ath_softc *sc) 498238710Sadrian{ 499238836Sadrian int error; 500238855Sadrian int i; 501238710Sadrian 502238836Sadrian error = ath_descdma_alloc_desc(sc, &sc->sc_txsdma, 503238836Sadrian NULL, "txcomp", sc->sc_tx_statuslen, ATH_TXSTATUS_RING_SIZE); 504238836Sadrian if (error != 0) 505238836Sadrian return (error); 506238836Sadrian 507238836Sadrian ath_hal_setuptxstatusring(sc->sc_ah, 508238836Sadrian (void *) sc->sc_txsdma.dd_desc, 509238836Sadrian sc->sc_txsdma.dd_desc_paddr, 510238836Sadrian ATH_TXSTATUS_RING_SIZE); 511238836Sadrian 512238855Sadrian for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { 513238855Sadrian ath_edma_setup_txfifo(sc, i); 514238855Sadrian } 515238836Sadrian 516238710Sadrian return (0); 517238710Sadrian} 518238710Sadrian 519238710Sadrianstatic int 520238710Sadrianath_edma_dma_txteardown(struct ath_softc *sc) 521238710Sadrian{ 522238855Sadrian int i; 523238710Sadrian 524238855Sadrian for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { 525238855Sadrian ath_edma_free_txfifo(sc, i); 526238855Sadrian } 527238855Sadrian 528238836Sadrian ath_descdma_cleanup(sc, &sc->sc_txsdma, NULL); 529238710Sadrian return (0); 530238710Sadrian} 531238710Sadrian 532239197Sadrian/* 533239204Sadrian * Drain all TXQs, potentially after completing the existing completed 534239204Sadrian * frames. 535239197Sadrian */ 536239204Sadrianstatic void 537239204Sadrianath_edma_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type) 538238931Sadrian{ 539239410Sadrian struct ifnet *ifp = sc->sc_ifp; 540239410Sadrian int i; 541238931Sadrian 542242779Sadrian DPRINTF(sc, ATH_DEBUG_RESET, "%s: called\n", __func__); 543239410Sadrian 544239410Sadrian (void) ath_stoptxdma(sc); 545239410Sadrian 546239410Sadrian /* 547239410Sadrian * If reset type is noloss, the TX FIFO needs to be serviced 548239410Sadrian * and those frames need to be handled. 549239410Sadrian * 550239410Sadrian * Otherwise, just toss everything in each TX queue. 551239410Sadrian */ 552242780Sadrian if (reset_type == ATH_RESET_NOLOSS) { 553242780Sadrian ath_edma_tx_processq(sc, 0); 554250444Sadrian for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { 555250444Sadrian if (ATH_TXQ_SETUP(sc, i)) { 556250444Sadrian ATH_TXQ_LOCK(&sc->sc_txq[i]); 557250444Sadrian /* 558250444Sadrian * Free the holding buffer; DMA is now 559250444Sadrian * stopped. 560250444Sadrian */ 561250444Sadrian ath_txq_freeholdingbuf(sc, &sc->sc_txq[i]); 562250444Sadrian /* 563250444Sadrian * Reset the link pointer to NULL; there's 564250444Sadrian * no frames to chain DMA to. 565250444Sadrian */ 566250444Sadrian sc->sc_txq[i].axq_link = NULL; 567250444Sadrian ATH_TXQ_UNLOCK(&sc->sc_txq[i]); 568250444Sadrian } 569250444Sadrian } 570242780Sadrian } else { 571242780Sadrian for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { 572242780Sadrian if (ATH_TXQ_SETUP(sc, i)) 573242780Sadrian ath_tx_draintxq(sc, &sc->sc_txq[i]); 574242780Sadrian } 575242780Sadrian } 576239410Sadrian 577239410Sadrian /* XXX dump out the TX completion FIFO contents */ 578239410Sadrian 579239410Sadrian /* XXX dump out the frames */ 580239410Sadrian 581239410Sadrian IF_LOCK(&ifp->if_snd); 582239410Sadrian ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 583239410Sadrian IF_UNLOCK(&ifp->if_snd); 584239410Sadrian sc->sc_wd_timer = 0; 585238931Sadrian} 586238931Sadrian 587239197Sadrian/* 588242779Sadrian * TX completion tasklet. 589239197Sadrian */ 590242779Sadrian 591238931Sadrianstatic void 592238931Sadrianath_edma_tx_proc(void *arg, int npending) 593238931Sadrian{ 594238931Sadrian struct ath_softc *sc = (struct ath_softc *) arg; 595242779Sadrian 596248750Sadrian#if 0 597242779Sadrian DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: called, npending=%d\n", 598242779Sadrian __func__, npending); 599248750Sadrian#endif 600242779Sadrian ath_edma_tx_processq(sc, 1); 601242779Sadrian} 602242779Sadrian 603242779Sadrian/* 604242779Sadrian * Process the TX status queue. 605242779Sadrian */ 606242779Sadrianstatic void 607242779Sadrianath_edma_tx_processq(struct ath_softc *sc, int dosched) 608242779Sadrian{ 609239197Sadrian struct ath_hal *ah = sc->sc_ah; 610239197Sadrian HAL_STATUS status; 611239197Sadrian struct ath_tx_status ts; 612239197Sadrian struct ath_txq *txq; 613239410Sadrian struct ath_buf *bf; 614239410Sadrian struct ieee80211_node *ni; 615239504Sadrian int nacked = 0; 616242532Sadrian int idx; 617238931Sadrian 618242532Sadrian#ifdef ATH_DEBUG 619242532Sadrian /* XXX */ 620242532Sadrian uint32_t txstatus[32]; 621242532Sadrian#endif 622242532Sadrian 623242532Sadrian for (idx = 0; ; idx++) { 624239410Sadrian bzero(&ts, sizeof(ts)); 625239410Sadrian 626239197Sadrian ATH_TXSTATUS_LOCK(sc); 627242540Sadrian#ifdef ATH_DEBUG 628242532Sadrian ath_hal_gettxrawtxdesc(ah, txstatus); 629242540Sadrian#endif 630242779Sadrian status = ath_hal_txprocdesc(ah, NULL, (void *) &ts); 631239197Sadrian ATH_TXSTATUS_UNLOCK(sc); 632239197Sadrian 633248750Sadrian if (status == HAL_EINPROGRESS) 634248750Sadrian break; 635248750Sadrian 636242532Sadrian#ifdef ATH_DEBUG 637242532Sadrian if (sc->sc_debug & ATH_DEBUG_TX_PROC) 638248750Sadrian if (ts.ts_queue_id != sc->sc_bhalq) 639242532Sadrian ath_printtxstatbuf(sc, NULL, txstatus, ts.ts_queue_id, 640242532Sadrian idx, (status == HAL_OK)); 641242532Sadrian#endif 642242532Sadrian 643239197Sadrian /* 644239410Sadrian * If there is an error with this descriptor, continue 645239410Sadrian * processing. 646239410Sadrian * 647239410Sadrian * XXX TBD: log some statistics? 648239410Sadrian */ 649239410Sadrian if (status == HAL_EIO) { 650239410Sadrian device_printf(sc->sc_dev, "%s: invalid TX status?\n", 651239410Sadrian __func__); 652248779Sadrian break; 653239410Sadrian } 654239410Sadrian 655249284Sadrian#if defined(ATH_DEBUG_ALQ) && defined(ATH_DEBUG) 656242782Sadrian if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_TXSTATUS)) 657242782Sadrian if_ath_alq_post(&sc->sc_alq, ATH_ALQ_EDMA_TXSTATUS, 658242782Sadrian sc->sc_tx_statuslen, 659242782Sadrian (char *) txstatus); 660242782Sadrian#endif /* ATH_DEBUG_ALQ */ 661242782Sadrian 662239410Sadrian /* 663239197Sadrian * At this point we have a valid status descriptor. 664239197Sadrian * The QID and descriptor ID (which currently isn't set) 665239197Sadrian * is part of the status. 666239197Sadrian * 667239197Sadrian * We then assume that the descriptor in question is the 668239197Sadrian * -head- of the given QID. Eventually we should verify 669239197Sadrian * this by using the descriptor ID. 670239197Sadrian */ 671239410Sadrian 672239410Sadrian /* 673239410Sadrian * The beacon queue is not currently a "real" queue. 674239410Sadrian * Frames aren't pushed onto it and the lock isn't setup. 675239410Sadrian * So skip it for now; the beacon handling code will 676239410Sadrian * free and alloc more beacon buffers as appropriate. 677239410Sadrian */ 678239410Sadrian if (ts.ts_queue_id == sc->sc_bhalq) 679239410Sadrian continue; 680239410Sadrian 681239410Sadrian txq = &sc->sc_txq[ts.ts_queue_id]; 682239410Sadrian 683248671Sadrian ATH_TXQ_LOCK(txq); 684248750Sadrian bf = ATH_TXQ_FIRST(&txq->fifo); 685239410Sadrian 686248750Sadrian /* 687248750Sadrian * Work around the situation where I'm seeing notifications 688248750Sadrian * for Q1 when no frames are available. That needs to be 689248750Sadrian * debugged but not by crashing _here_. 690248750Sadrian */ 691248750Sadrian if (bf == NULL) { 692248750Sadrian device_printf(sc->sc_dev, "%s: Q%d: empty?\n", 693248750Sadrian __func__, 694248750Sadrian ts.ts_queue_id); 695248779Sadrian ATH_TXQ_UNLOCK(txq); 696248750Sadrian continue; 697248750Sadrian } 698248750Sadrian 699248750Sadrian DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: Q%d, bf=%p, start=%d, end=%d\n", 700239197Sadrian __func__, 701248750Sadrian ts.ts_queue_id, bf, 702248750Sadrian !! (bf->bf_flags & ATH_BUF_FIFOPTR), 703248750Sadrian !! (bf->bf_flags & ATH_BUF_FIFOEND)); 704239197Sadrian 705242532Sadrian /* XXX TODO: actually output debugging info about this */ 706242532Sadrian 707239410Sadrian#if 0 708239410Sadrian /* XXX assert the buffer/descriptor matches the status descid */ 709239410Sadrian if (ts.ts_desc_id != bf->bf_descid) { 710239410Sadrian device_printf(sc->sc_dev, 711239410Sadrian "%s: mismatched descid (qid=%d, tsdescid=%d, " 712239410Sadrian "bfdescid=%d\n", 713239410Sadrian __func__, 714239410Sadrian ts.ts_queue_id, 715239410Sadrian ts.ts_desc_id, 716239410Sadrian bf->bf_descid); 717239410Sadrian } 718239410Sadrian#endif 719239410Sadrian 720239410Sadrian /* This removes the buffer and decrements the queue depth */ 721248750Sadrian ATH_TXQ_REMOVE(&txq->fifo, bf, bf_list); 722239410Sadrian if (bf->bf_state.bfs_aggr) 723239410Sadrian txq->axq_aggr_depth--; 724248750Sadrian 725248750Sadrian /* 726248750Sadrian * If this was the end of a FIFO set, decrement FIFO depth 727248750Sadrian */ 728248750Sadrian if (bf->bf_flags & ATH_BUF_FIFOEND) 729248750Sadrian txq->axq_fifo_depth--; 730248750Sadrian 731248750Sadrian /* 732248750Sadrian * If this isn't the final buffer in a FIFO set, mark 733248750Sadrian * the buffer as busy so it goes onto the holding queue. 734248750Sadrian */ 735248750Sadrian if (! (bf->bf_flags & ATH_BUF_FIFOEND)) 736248750Sadrian bf->bf_flags |= ATH_BUF_BUSY; 737248750Sadrian 738248750Sadrian DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: Q%d: FIFO depth is now %d (%d)\n", 739248750Sadrian __func__, 740248750Sadrian txq->axq_qnum, 741248750Sadrian txq->axq_fifo_depth, 742248750Sadrian txq->fifo.axq_depth); 743248750Sadrian 744239410Sadrian /* XXX assert FIFO depth >= 0 */ 745248671Sadrian ATH_TXQ_UNLOCK(txq); 746239410Sadrian 747239410Sadrian /* 748248750Sadrian * Outside of the TX lock - if the buffer is end 749248750Sadrian * end buffer in this FIFO, we don't need a holding 750248750Sadrian * buffer any longer. 751248750Sadrian */ 752248750Sadrian if (bf->bf_flags & ATH_BUF_FIFOEND) { 753250408Sadrian ATH_TXQ_LOCK(txq); 754248750Sadrian ath_txq_freeholdingbuf(sc, txq); 755250408Sadrian ATH_TXQ_UNLOCK(txq); 756248750Sadrian } 757248750Sadrian 758248750Sadrian /* 759239410Sadrian * First we need to make sure ts_rate is valid. 760239410Sadrian * 761239410Sadrian * Pre-EDMA chips pass the whole TX descriptor to 762239410Sadrian * the proctxdesc function which will then fill out 763239410Sadrian * ts_rate based on the ts_finaltsi (final TX index) 764239410Sadrian * in the TX descriptor. However the TX completion 765239410Sadrian * FIFO doesn't have this information. So here we 766239410Sadrian * do a separate HAL call to populate that information. 767242880Sadrian * 768242880Sadrian * The same problem exists with ts_longretry. 769242880Sadrian * The FreeBSD HAL corrects ts_longretry in the HAL layer; 770242880Sadrian * the AR9380 HAL currently doesn't. So until the HAL 771242880Sadrian * is imported and this can be added, we correct for it 772242880Sadrian * here. 773239410Sadrian */ 774239410Sadrian /* XXX TODO */ 775239410Sadrian /* XXX faked for now. Ew. */ 776239410Sadrian if (ts.ts_finaltsi < 4) { 777239410Sadrian ts.ts_rate = 778239410Sadrian bf->bf_state.bfs_rc[ts.ts_finaltsi].ratecode; 779242880Sadrian switch (ts.ts_finaltsi) { 780242880Sadrian case 3: ts.ts_longretry += 781242880Sadrian bf->bf_state.bfs_rc[2].tries; 782242880Sadrian case 2: ts.ts_longretry += 783242880Sadrian bf->bf_state.bfs_rc[1].tries; 784242880Sadrian case 1: ts.ts_longretry += 785242880Sadrian bf->bf_state.bfs_rc[0].tries; 786242880Sadrian } 787239410Sadrian } else { 788239410Sadrian device_printf(sc->sc_dev, "%s: finaltsi=%d\n", 789239410Sadrian __func__, 790239410Sadrian ts.ts_finaltsi); 791239410Sadrian ts.ts_rate = bf->bf_state.bfs_rc[0].ratecode; 792239410Sadrian } 793239410Sadrian 794239410Sadrian /* 795239410Sadrian * XXX This is terrible. 796239410Sadrian * 797239410Sadrian * Right now, some code uses the TX status that is 798239410Sadrian * passed in here, but the completion handlers in the 799239410Sadrian * software TX path also use bf_status.ds_txstat. 800239410Sadrian * Ew. That should all go away. 801239410Sadrian * 802239410Sadrian * XXX It's also possible the rate control completion 803239410Sadrian * routine is called twice. 804239410Sadrian */ 805239410Sadrian memcpy(&bf->bf_status, &ts, sizeof(ts)); 806239410Sadrian 807239410Sadrian ni = bf->bf_node; 808239410Sadrian 809239410Sadrian /* Update RSSI */ 810239410Sadrian /* XXX duplicate from ath_tx_processq */ 811239410Sadrian if (ni != NULL && ts.ts_status == 0 && 812239410Sadrian ((bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) == 0)) { 813239410Sadrian nacked++; 814239410Sadrian sc->sc_stats.ast_tx_rssi = ts.ts_rssi; 815239410Sadrian ATH_RSSI_LPF(sc->sc_halstats.ns_avgtxrssi, 816239410Sadrian ts.ts_rssi); 817239410Sadrian } 818239410Sadrian 819239410Sadrian /* Handle frame completion and rate control update */ 820239410Sadrian ath_tx_process_buf_completion(sc, txq, &ts, bf); 821239410Sadrian 822239410Sadrian /* bf is invalid at this point */ 823239410Sadrian 824239410Sadrian /* 825239410Sadrian * Now that there's space in the FIFO, let's push some 826239410Sadrian * more frames into it. 827239410Sadrian */ 828248671Sadrian ATH_TXQ_LOCK(txq); 829248750Sadrian if (dosched) 830239410Sadrian ath_edma_tx_fifo_fill(sc, txq); 831248671Sadrian ATH_TXQ_UNLOCK(txq); 832239197Sadrian } 833239410Sadrian 834239410Sadrian sc->sc_wd_timer = 0; 835239410Sadrian 836242604Sadrian if (idx > 0) { 837242604Sadrian IF_LOCK(&sc->sc_ifp->if_snd); 838242604Sadrian sc->sc_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 839242604Sadrian IF_UNLOCK(&sc->sc_ifp->if_snd); 840242604Sadrian } 841242604Sadrian 842239410Sadrian /* Kick software scheduler */ 843239410Sadrian /* 844239410Sadrian * XXX It's inefficient to do this if the FIFO queue is full, 845239410Sadrian * but there's no easy way right now to only populate 846239410Sadrian * the txq task for _one_ TXQ. This should be fixed. 847239410Sadrian */ 848242779Sadrian if (dosched) 849246450Sadrian ath_tx_swq_kick(sc); 850238931Sadrian} 851238931Sadrian 852238931Sadrianstatic void 853238931Sadrianath_edma_attach_comp_func(struct ath_softc *sc) 854238931Sadrian{ 855238931Sadrian 856238931Sadrian TASK_INIT(&sc->sc_txtask, 0, ath_edma_tx_proc, sc); 857238931Sadrian} 858238931Sadrian 859238710Sadrianvoid 860238710Sadrianath_xmit_setup_edma(struct ath_softc *sc) 861238710Sadrian{ 862238710Sadrian 863238710Sadrian /* Fetch EDMA field and buffer sizes */ 864238710Sadrian (void) ath_hal_gettxdesclen(sc->sc_ah, &sc->sc_tx_desclen); 865238710Sadrian (void) ath_hal_gettxstatuslen(sc->sc_ah, &sc->sc_tx_statuslen); 866238710Sadrian (void) ath_hal_getntxmaps(sc->sc_ah, &sc->sc_tx_nmaps); 867238710Sadrian 868238710Sadrian device_printf(sc->sc_dev, "TX descriptor length: %d\n", 869238710Sadrian sc->sc_tx_desclen); 870238710Sadrian device_printf(sc->sc_dev, "TX status length: %d\n", 871238710Sadrian sc->sc_tx_statuslen); 872238710Sadrian device_printf(sc->sc_dev, "TX buffers per descriptor: %d\n", 873238710Sadrian sc->sc_tx_nmaps); 874238710Sadrian 875238710Sadrian sc->sc_tx.xmit_setup = ath_edma_dma_txsetup; 876238710Sadrian sc->sc_tx.xmit_teardown = ath_edma_dma_txteardown; 877238931Sadrian sc->sc_tx.xmit_attach_comp_func = ath_edma_attach_comp_func; 878238930Sadrian 879238930Sadrian sc->sc_tx.xmit_dma_restart = ath_edma_dma_restart; 880238930Sadrian sc->sc_tx.xmit_handoff = ath_edma_xmit_handoff; 881239204Sadrian sc->sc_tx.xmit_drain = ath_edma_tx_drain; 882238710Sadrian} 883