56#include <sys/sysctl.h>
58#include <sys/malloc.h>
61#include <sys/kernel.h>
62#include <sys/socket.h>
63#include <sys/sockio.h>
65#include <sys/callout.h>
67#include <sys/endian.h>
68#include <sys/kthread.h>
69#include <sys/taskqueue.h>
71#include <sys/module.h>
75#include <machine/bus.h>
78#include <net/if_var.h>
80#include <net/if_media.h>
81#include <net/if_types.h>
82#include <net/if_arp.h>
83#include <net/ethernet.h>
84#include <net/if_llc.h>
86#include <net80211/ieee80211_var.h>
87#include <net80211/ieee80211_regdomain.h>
88#ifdef IEEE80211_SUPPORT_SUPERG
89#include <net80211/ieee80211_superg.h>
91#ifdef IEEE80211_SUPPORT_TDMA
92#include <net80211/ieee80211_tdma.h>
98#include <netinet/in.h>
99#include <netinet/if_ether.h>
119#include <dev/ath/ath_tx99/ath_tx99.h>
131#define INCR(_l, _sz) (_l) ++; (_l) &= ((_sz) - 1)
132#define DECR(_l, _sz) (_l) --; (_l) &= ((_sz) - 1)
137#define ATH_TXSTATUS_RING_SIZE 512
145ath_tx_alq_edma_push(
struct ath_softc *sc,
int txq,
int nframes,
146 int fifo_depth,
int frame_cnt)
183 DPRINTF(sc, ATH_DEBUG_XMIT | ATH_DEBUG_TX_PROC,
184 "%s: called; TXQ=%d, fifo.depth=%d, axq_q empty=%d\n",
188 !! (TAILQ_EMPTY(&txq->axq_q)));
196 if (TAILQ_EMPTY(&txq->axq_q))
206 for (i = 0; i < limit; i++) {
214 TAILQ_INSERT_TAIL(&sq, bf, bf_list);
228 bf = TAILQ_FIRST(&sq);
229 bf_last = TAILQ_LAST(&sq, axq_q_s);
246 TAILQ_FOREACH(bfi, &sq, bf_list) {
255 TAILQ_FOREACH(bfi, &sq, bf_list) {
257 if (sc->
sc_debug & ATH_DEBUG_XMIT_DESC)
258 ath_printtxbuf(sc, bfi, txq->
axq_qnum, i, 0);
262 ath_tx_alq_post(sc, bfi);
274 TAILQ_CONCAT(&txq->
fifo.axq_q, &sq, bf_list);
280 DPRINTF(sc, ATH_DEBUG_XMIT | ATH_DEBUG_TX_PROC,
281 "%s: queued %d packets; depth=%d, fifo depth=%d\n",
291 ath_tx_alq_edma_push(sc, txq->
axq_qnum, sqdepth,
297#define TX_BATCH_SIZE 32
309 "%s: Q%d: called; fifo.depth=%d, fifo depth=%d, depth=%d, aggr_depth=%d\n",
411 DPRINTF(sc, ATH_DEBUG_RESET,
"%s: Q%d: called\n",
432 TAILQ_FOREACH(bf, &txq->
fifo.axq_q, bf_list) {
441 if (sc->
sc_debug & ATH_DEBUG_XMIT_DESC)
442 ath_printtxbuf(sc, bf, txq->
axq_qnum, i, 0);
446 ath_tx_alq_post(sc, bf);
449 if (fifostart == 0) {
458 "%s: Q%d: more frames in the queue; FIFO depth=%d?!\n",
466 "%s: Q%d: depth=%d: pushing bf=%p; start=%d, end=%d\n",
500 DPRINTF(sc, ATH_DEBUG_RESET,
"%s: Q%d: FIFO depth was %d, is %d\n",
509 "%s: Q%d: FIFO depth should be %d, is %d\n",
537 (
"%s: busy status 0x%x", __func__, bf->
bf_flags));
573 (
"%s: busy status 0x%x", __func__, bf->
bf_flags));
581 struct ieee80211_frame *wh;
584 wh = mtod(bf_last->
bf_m,
struct ieee80211_frame *);
585 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
589 BUS_DMASYNC_PREWRITE);
598 ath_tx_alq_post(sc, bf);
626 DPRINTF(sc, ATH_DEBUG_XMIT_DESC,
627 "%s: called; bf=%p, txq=%p, qnum=%d\n",
648 device_printf(sc->
sc_dev,
"%s: malloc failed\n",
667 free(te->
m_fifo, M_ATHDEV);
716 DPRINTF(sc, ATH_DEBUG_RESET,
"%s: called\n", __func__);
776 DPRINTF(sc, ATH_DEBUG_TX_PROC,
"%s: called, npending=%d\n",
803 struct ieee80211_node *ni;
810 uint32_t txstatus[32];
813 DPRINTF(sc, ATH_DEBUG_TX_PROC,
"%s: called\n", __func__);
815 for (idx = 0; ; idx++) {
816 bzero(&ts,
sizeof(ts));
827 "%s: (%d): EINPROGRESS\n",
833 if (sc->
sc_debug & ATH_DEBUG_TX_PROC)
835 ath_printtxstatbuf(sc, NULL, txstatus, ts.ts_queue_id,
846 device_printf(sc->
sc_dev,
"%s: invalid TX status?\n",
851#if defined(ATH_DEBUG_ALQ) && defined(ATH_DEBUG)
878 txq = &sc->
sc_txq[ts.ts_queue_id];
889 device_printf(sc->
sc_dev,
"%s: Q%d: empty?\n",
896 DPRINTF(sc, ATH_DEBUG_TX_PROC,
"%s: Q%d, bf=%p, start=%d, end=%d\n",
908 "%s: mismatched descid (qid=%d, tsdescid=%d, "
935 DPRINTF(sc, ATH_DEBUG_TX_PROC,
"%s: Q%d: FIFO depth is now %d (%d)\n",
973 if (ts.ts_finaltsi < 4) {
976 switch (ts.ts_finaltsi) {
977 case 3: ts.ts_longretry +=
979 case 2: ts.ts_longretry +=
981 case 1: ts.ts_longretry +=
985 device_printf(sc->
sc_dev,
"%s: finaltsi=%d\n",
1002 memcpy(&bf->
bf_status, &ts,
sizeof(ts));
1008 if (ni != NULL && ts.ts_status == 0 &&
1048 DPRINTF(sc, ATH_DEBUG_TX_PROC,
"%s: end\n", __func__);
1068 device_printf(sc->
sc_dev,
"TX descriptor length: %d\n",
1070 device_printf(sc->
sc_dev,
"TX status length: %d\n",
1072 device_printf(sc->
sc_dev,
"TX buffers per descriptor: %d\n",
#define HAL_NUM_TX_QUEUES
void ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
void ath_txq_freeholdingbuf(struct ath_softc *sc, struct ath_txq *txq)
int ath_stoptxdma(struct ath_softc *sc)
void ath_tx_process_buf_completion(struct ath_softc *sc, struct ath_txq *txq, struct ath_tx_status *ts, struct ath_buf *bf)
#define ATH_ALQ_EDMA_TXSTATUS
#define ATH_ALQ_TX_FIFO_PUSH
#define ATH_ALQ_EDMA_TXDESC
static int if_ath_alq_checkdebug(struct if_ath_alq *alq, uint16_t op)
void if_ath_alq_post(struct if_ath_alq *alq, uint16_t op, uint16_t len, const char *buf)
#define DPRINTF(sc, m, fmt,...)
int ath_descdma_alloc_desc(struct ath_softc *sc, struct ath_descdma *dd, ath_bufhead *head, const char *name, int ds_size, int ndesc)
void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, ath_bufhead *head)
#define ath_power_restore_power_state(sc)
#define ath_power_set_power_state(sc, ps)
static void ath_tx_kick(struct ath_softc *sc)
static void ath_tx_swq_kick(struct ath_softc *sc)
void ath_txq_sched(struct ath_softc *sc, struct ath_txq *txq)
static int ath_edma_setup_txfifo(struct ath_softc *sc, int qnum)
static int ath_edma_dma_txsetup(struct ath_softc *sc)
static int ath_edma_free_txfifo(struct ath_softc *sc, int qnum)
static void ath_edma_dma_restart(struct ath_softc *sc, struct ath_txq *txq)
#define ATH_TXSTATUS_RING_SIZE
static void ath_tx_edma_push_staging_list(struct ath_softc *sc, struct ath_txq *txq, int limit)
static void ath_edma_tx_processq(struct ath_softc *sc, int dosched)
void ath_xmit_setup_edma(struct ath_softc *sc)
static void ath_edma_attach_comp_func(struct ath_softc *sc)
static void ath_edma_xmit_handoff_mcast(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
static void ath_edma_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
static void ath_edma_tx_proc(void *arg, int npending)
static int ath_edma_dma_txteardown(struct ath_softc *sc)
static void ath_edma_tx_fifo_fill(struct ath_softc *sc, struct ath_txq *txq)
static void ath_edma_xmit_handoff(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
static void ath_edma_xmit_handoff_hw(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
#define ATH_TXSTATUS_UNLOCK(_sc)
#define ath_hal_gettxrawtxdesc(_ah, _txstatus)
#define ath_hal_puttxbuf(_ah, _q, _bufaddr)
#define ATH_TXQ_REMOVE(_tq, _elm, _field)
#define ATH_TXQ_LAST(_tq, _field)
#define ATH_TXQ_LOCK_ASSERT(_tq)
#define ATH_TXQ_SETUP(sc, i)
#define ATH_PCU_UNLOCK(_sc)
#define ath_hal_setuptxstatusring(_ah, _tsstart, _tspstart, _size)
#define ATH_TXSTATUS_LOCK(_sc)
#define ATH_TX_LOCK_ASSERT(_sc)
#define ATH_TXQ_FIRST(_tq)
#define ATH_TXQ_LOCK(_tq)
#define ATH_RSSI_LPF(x, y)
#define ATH_TXQ_UNLOCK(_tq)
#define ATH_TX_UNLOCK(_sc)
#define ath_hal_settxdesclink(_ah, _ds, _link)
#define ath_hal_gettxdesclen(_ah, _req)
#define ath_hal_gettxstatuslen(_ah, _req)
#define ath_hal_txprocdesc(_ah, _ds, _ts)
#define ATH_PCU_LOCK(_sc)
#define ATH_TXQ_INSERT_TAIL(_tq, _elm, _field)
#define ath_hal_getntxmaps(_ah, _req)
#define ath_hal_txstart(_ah, _q)
struct ath_desc_status bf_status
struct ath_desc * bf_lastds
struct ath_rc_series bfs_rc[ATH_RC_NUM]
struct ath_buf::@32 bf_state
struct ieee80211_node * bf_node
struct ath_desc * dd_desc
HAL_NODE_STATS sc_halstats
struct ath_stats sc_stats
struct ath_descdma sc_txsdma
struct ath_txq sc_txq[HAL_NUM_TX_QUEUES]
struct ath_tx_methods sc_tx
struct ath_tx_edma_fifo sc_txedma[HAL_NUM_TX_QUEUES]
void(* xmit_drain)(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
void(* xmit_attach_comp_func)(struct ath_softc *sc)
int(* xmit_setup)(struct ath_softc *sc)
int(* xmit_teardown)(struct ath_softc *sc)
void(* xmit_handoff)(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
void(* xmit_dma_restart)(struct ath_softc *sc, struct ath_txq *txq)