/*
 * Copyright (c) 2008 Atheros Communications Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * Implementation of transmit path.
 */

#include "core.h"

#define BITS_PER_BYTE           8
#define OFDM_PLCP_BITS          22
#define HT_RC_2_MCS(_rc)        ((_rc) & 0x0f)
#define HT_RC_2_STREAMS(_rc)    ((((_rc) & 0x78) >> 3) + 1)
#define L_STF                   8
#define L_LTF                   8
#define L_SIG                   4
#define HT_SIG                  8
#define HT_STF                  4
#define HT_LTF(_ns)             (4 * (_ns))
#define SYMBOL_TIME(_ns)        ((_ns) << 2) /* ns * 4 us */
#define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5)  /* ns * 3.6 us */
#define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2)
#define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18)

#define OFDM_SIFS_TIME    	    16

static u32 bits_per_symbol[][2] = {
	/* 20MHz 40MHz */
	{    26,   54 },     /*  0: BPSK */
	{    52,  108 },     /*  1: QPSK 1/2 */
	{    78,  162 },     /*  2: QPSK 3/4 */
	{   104,  216 },     /*  3: 16-QAM 1/2 */
	{   156,  324 },     /*  4: 16-QAM 3/4 */
	{   208,  432 },     /*  5: 64-QAM 2/3 */
	{   234,  486 },     /*  6: 64-QAM 3/4 */
	{   260,  540 },     /*  7: 64-QAM 5/6 */
	{    52,  108 },     /*  8: BPSK */
	{   104,  216 },     /*  9: QPSK 1/2 */
	{   156,  324 },     /* 10: QPSK 3/4 */
	{   208,  432 },     /* 11: 16-QAM 1/2 */
	{   312,  648 },     /* 12: 16-QAM 3/4 */
	{   416,  864 },     /* 13: 64-QAM 2/3 */
	{   468,  972 },     /* 14: 64-QAM 3/4 */
	{   520, 1080 },     /* 15: 64-QAM 5/6 */
};

#define IS_HT_RATE(_rate)     ((_rate) & 0x80)

/*
 * Insert a chain of ath_buf (descriptors) on a txq and
 * assume the descriptors are already chained together by caller.
 * NB: must be called with txq lock held
 */

static void ath_tx_txqaddbuf(struct ath_softc *sc,
		struct ath_txq *txq, struct list_head *head)
{
	struct ath_hal *ah = sc->sc_ah;
	struct ath_buf *bf;
	/*
	 * Insert the frame on the outbound list and
	 * pass it on to the hardware.
	 */

	if (list_empty(head))
		return;

	bf = list_first_entry(head, struct ath_buf, list);

	list_splice_tail_init(head, &txq->axq_q);
	txq->axq_depth++;
	txq->axq_totalqueued++;
	txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);

	DPRINTF(sc, ATH_DBG_QUEUE,
		"%s: txq depth = %d\n", __func__, txq->axq_depth);

	if (txq->axq_link == NULL) {
		ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
		DPRINTF(sc, ATH_DBG_XMIT,
			"%s: TXDP[%u] = %llx (%p)\n",
			__func__, txq->axq_qnum,
			ito64(bf->bf_daddr), bf->bf_desc);
	} else {
		*txq->axq_link = bf->bf_daddr;
		DPRINTF(sc, ATH_DBG_XMIT, "%s: link[%u] (%p)=%llx (%p)\n",
			__func__,
			txq->axq_qnum, txq->axq_link,
			ito64(bf->bf_daddr), bf->bf_desc);
	}
	txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
	ath9k_hw_txstart(ah, txq->axq_qnum);
}

/* Get transmit rate index using rate in Kbps */

static int ath_tx_findindex(const struct ath9k_rate_table *rt, int rate)
{
	int i;
	int ndx = 0;

	for (i = 0; i < rt->rateCount; i++) {
		if (rt->info[i].rateKbps == rate) {
			ndx = i;
			break;
		}
	}

	return ndx;
}

/* Check if it's okay to send out aggregates */

static int ath_aggr_query(struct ath_softc *sc,
	struct ath_node *an, u8 tidno)
{
	struct ath_atx_tid *tid;
	tid = ATH_AN_2_TID(an, tidno);

	if (tid->addba_exchangecomplete || tid->addba_exchangeinprogress)
		return 1;
	else
		return 0;
}

static enum ath9k_pkt_type get_hal_packet_type(struct ieee80211_hdr *hdr)
{
	enum ath9k_pkt_type htype;
	__le16 fc;

	fc = hdr->frame_control;

	/* Calculate Atheros packet type from IEEE80211 packet header */

	if (ieee80211_is_beacon(fc))
		htype = ATH9K_PKT_TYPE_BEACON;
	else if (ieee80211_is_probe_resp(fc))
		htype = ATH9K_PKT_TYPE_PROBE_RESP;
	else if (ieee80211_is_atim(fc))
		htype = ATH9K_PKT_TYPE_ATIM;
	else if (ieee80211_is_pspoll(fc))
		htype = ATH9K_PKT_TYPE_PSPOLL;
	else
		htype = ATH9K_PKT_TYPE_NORMAL;

	return htype;
}

static void fill_min_rates(struct sk_buff *skb, struct ath_tx_control *txctl)
{
	struct ieee80211_hdr *hdr;
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
	struct ath_tx_info_priv *tx_info_priv;
	__le16 fc;

	hdr = (struct ieee80211_hdr *)skb->data;
	fc = hdr->frame_control;
	tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];

	if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) {
		txctl->use_minrate = 1;
		txctl->min_rate = tx_info_priv->min_rate;
	} else if (ieee80211_is_data(fc)) {
		if (ieee80211_is_nullfunc(fc) ||
			/* Port Access Entity (IEEE 802.1X) */
			(skb->protocol == cpu_to_be16(0x888E))) {
			txctl->use_minrate = 1;
			txctl->min_rate = tx_info_priv->min_rate;
		}
		if (is_multicast_ether_addr(hdr->addr1))
			txctl->mcast_rate = tx_info_priv->min_rate;
	}

}

/* This function will setup additional txctl information, mostly rate stuff */
/* FIXME: seqno, ps */
static int ath_tx_prepare(struct ath_softc *sc,
			  struct sk_buff *skb,
			  struct ath_tx_control *txctl)
{
	struct ieee80211_hw *hw = sc->hw;
	struct ieee80211_hdr *hdr;
	struct ath_rc_series *rcs;
	struct ath_txq *txq = NULL;
	const struct ath9k_rate_table *rt;
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
	struct ath_tx_info_priv *tx_info_priv;
	int hdrlen;
	u8 rix, antenna;
	__le16 fc;
	u8 *qc;

	txctl->dev = sc;
	hdr = (struct ieee80211_hdr *)skb->data;
	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
	fc = hdr->frame_control;

	rt = sc->sc_currates;
	BUG_ON(!rt);

	/* Fill misc fields */

	spin_lock_bh(&sc->node_lock);
	txctl->an = ath_node_get(sc, hdr->addr1);
	/* create a temp node, if the node is not there already */
	if (!txctl->an)
		txctl->an = ath_node_attach(sc, hdr->addr1, 0);
	spin_unlock_bh(&sc->node_lock);

	if (ieee80211_is_data_qos(fc)) {
		qc = ieee80211_get_qos_ctl(hdr);
		txctl->tidno = qc[0] & 0xf;
	}

	txctl->if_id = 0;
	txctl->frmlen = skb->len + FCS_LEN - (hdrlen & 3);
	txctl->txpower = MAX_RATE_POWER; /* FIXME */

	/* Fill Key related fields */

	txctl->keytype = ATH9K_KEY_TYPE_CLEAR;
	txctl->keyix = ATH9K_TXKEYIX_INVALID;

	if (tx_info->control.hw_key) {
		txctl->keyix = tx_info->control.hw_key->hw_key_idx;
		txctl->frmlen += tx_info->control.hw_key->icv_len;

		if (tx_info->control.hw_key->alg == ALG_WEP)
			txctl->keytype = ATH9K_KEY_TYPE_WEP;
		else if (tx_info->control.hw_key->alg == ALG_TKIP)
			txctl->keytype = ATH9K_KEY_TYPE_TKIP;
		else if (tx_info->control.hw_key->alg == ALG_CCMP)
			txctl->keytype = ATH9K_KEY_TYPE_AES;
	}

	/* Fill packet type */

	txctl->atype = get_hal_packet_type(hdr);

	/* Fill qnum */

	if (unlikely(txctl->flags & ATH9K_TXDESC_CAB)) {
		txctl->qnum = 0;
		txq = sc->sc_cabq;
	} else {
		txctl->qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
		txq = &sc->sc_txq[txctl->qnum];
	}
	spin_lock_bh(&txq->axq_lock);

	/* Try to avoid running out of descriptors */
	if (txq->axq_depth >= (ATH_TXBUF - 20) &&
	    !(txctl->flags & ATH9K_TXDESC_CAB)) {
		DPRINTF(sc, ATH_DBG_FATAL,
			"%s: TX queue: %d is full, depth: %d\n",
			__func__,
			txctl->qnum,
			txq->axq_depth);
		ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
		txq->stopped = 1;
		spin_unlock_bh(&txq->axq_lock);
		return -1;
	}

	spin_unlock_bh(&txq->axq_lock);

	/* Fill rate */

	fill_min_rates(skb, txctl);

	/* Fill flags */

	txctl->flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */

	if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
		txctl->flags |= ATH9K_TXDESC_NOACK;
	if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
		txctl->flags |= ATH9K_TXDESC_RTSENA;

	/*
	 * Setup for rate calculations.
	 */
	tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
	rcs = tx_info_priv->rcs;

	if (ieee80211_is_data(fc) && !txctl->use_minrate) {

		/* Enable HT only for DATA frames and not for EAPOL */
		/* XXX why AMPDU only?? */
		txctl->ht = (hw->conf.ht.enabled &&
			    (tx_info->flags & IEEE80211_TX_CTL_AMPDU));

		if (is_multicast_ether_addr(hdr->addr1)) {
			rcs[0].rix = (u8)
				ath_tx_findindex(rt, txctl->mcast_rate);

			/*
			 * mcast packets are not re-tried.
			 */
			rcs[0].tries = 1;
		}
		/* For HT capable stations, we save tidno for later use.
		 * We also override seqno set by upper layer with the one
		 * in tx aggregation state.
		 *
		 * First, the fragmentation stat is determined.
		 * If fragmentation is on, the sequence number is
		 * not overridden, since it has been
		 * incremented by the fragmentation routine.
		 */
		if (likely(!(txctl->flags & ATH9K_TXDESC_FRAG_IS_ON)) &&
		    txctl->ht && (sc->sc_flags & SC_OP_TXAGGR)) {
			struct ath_atx_tid *tid;

			tid = ATH_AN_2_TID(txctl->an, txctl->tidno);

			hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
				IEEE80211_SEQ_SEQ_SHIFT);
			txctl->seqno = tid->seq_next;
			INCR(tid->seq_next, IEEE80211_SEQ_MAX);
		}
	} else {
		/* for management and control frames,
		 * or for NULL and EAPOL frames */
		if (txctl->min_rate)
			rcs[0].rix = ath_rate_findrateix(sc, txctl->min_rate);
		else
			rcs[0].rix = 0;
		rcs[0].tries = ATH_MGT_TXMAXTRY;
	}
	rix = rcs[0].rix;

	if (ieee80211_has_morefrags(fc) ||
	    (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
		/*
		**  Force hardware to use computed duration for next
		**  fragment by disabling multi-rate retry, which
		**  updates duration based on the multi-rate
		**  duration table.
		*/
		rcs[1].tries = rcs[2].tries = rcs[3].tries = 0;
		rcs[1].rix = rcs[2].rix = rcs[3].rix = 0;
		/* reset tries but keep rate index */
		rcs[0].tries = ATH_TXMAXTRY;
	}

	/*
	 * Determine if a tx interrupt should be generated for
	 * this descriptor.  We take a tx interrupt to reap
	 * descriptors when the h/w hits an EOL condition or
	 * when the descriptor is specifically marked to generate
	 * an interrupt.  We periodically mark descriptors in this
	 * way to insure timely replenishing of the supply needed
	 * for sending frames.  Defering interrupts reduces system
	 * load and potentially allows more concurrent work to be
	 * done but if done to aggressively can cause senders to
	 * backup.
	 *
	 * NB: use >= to deal with sc_txintrperiod changing
	 *     dynamically through sysctl.
	 */
	spin_lock_bh(&txq->axq_lock);
	if ((++txq->axq_intrcnt >= sc->sc_txintrperiod)) {
		txctl->flags |= ATH9K_TXDESC_INTREQ;
		txq->axq_intrcnt = 0;
	}
	spin_unlock_bh(&txq->axq_lock);

	if (is_multicast_ether_addr(hdr->addr1)) {
		antenna = sc->sc_mcastantenna + 1;
		sc->sc_mcastantenna = (sc->sc_mcastantenna + 1) & 0x1;
	}

	return 0;
}

/* To complete a chain of buffers associated a frame */

static void ath_tx_complete_buf(struct ath_softc *sc,
				struct ath_buf *bf,
				struct list_head *bf_q,
				int txok, int sendbar)
{
	struct sk_buff *skb = bf->bf_mpdu;
	struct ath_xmit_status tx_status;

	/*
	 * Set retry information.
	 * NB: Don't use the information in the descriptor, because the frame
	 * could be software retried.
	 */
	tx_status.retries = bf->bf_retries;
	tx_status.flags = 0;

	if (sendbar)
		tx_status.flags = ATH_TX_BAR;

	if (!txok) {
		tx_status.flags |= ATH_TX_ERROR;

		if (bf_isxretried(bf))
			tx_status.flags |= ATH_TX_XRETRY;
	}
	/* Unmap this frame */
	pci_unmap_single(sc->pdev,
			 bf->bf_dmacontext,
			 skb->len,
			 PCI_DMA_TODEVICE);
	/* complete this frame */
	ath_tx_complete(sc, skb, &tx_status, bf->bf_node);

	/*
	 * Return the list of ath_buf of this mpdu to free queue
	 */
	spin_lock_bh(&sc->sc_txbuflock);
	list_splice_tail_init(bf_q, &sc->sc_txbuf);
	spin_unlock_bh(&sc->sc_txbuflock);
}

/*
 * queue up a dest/ac pair for tx scheduling
 * NB: must be called with txq lock held
 */

static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
{
	struct ath_atx_ac *ac = tid->ac;

	/*
	 * if tid is paused, hold off
	 */
	if (tid->paused)
		return;

	/*
	 * add tid to ac atmost once
	 */
	if (tid->sched)
		return;

	tid->sched = true;
	list_add_tail(&tid->list, &ac->tid_q);

	/*
	 * add node ac to txq atmost once
	 */
	if (ac->sched)
		return;

	ac->sched = true;
	list_add_tail(&ac->list, &txq->axq_acq);
}

/* pause a tid */

static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
	struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];

	spin_lock_bh(&txq->axq_lock);

	tid->paused++;

	spin_unlock_bh(&txq->axq_lock);
}

/* resume a tid and schedule aggregate */

void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
	struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];

	ASSERT(tid->paused > 0);
	spin_lock_bh(&txq->axq_lock);

	tid->paused--;

	if (tid->paused > 0)
		goto unlock;

	if (list_empty(&tid->buf_q))
		goto unlock;

	/*
	 * Add this TID to scheduler and try to send out aggregates
	 */
	ath_tx_queue_tid(txq, tid);
	ath_txq_schedule(sc, txq);
unlock:
	spin_unlock_bh(&txq->axq_lock);
}

/* Compute the number of bad frames */

static int ath_tx_num_badfrms(struct ath_softc *sc,
	struct ath_buf *bf, int txok)
{
	struct ath_node *an = bf->bf_node;
	int isnodegone = (an->an_flags & ATH_NODE_CLEAN);
	struct ath_buf *bf_last = bf->bf_lastbf;
	struct ath_desc *ds = bf_last->bf_desc;
	u16 seq_st = 0;
	u32 ba[WME_BA_BMP_SIZE >> 5];
	int ba_index;
	int nbad = 0;
	int isaggr = 0;

	if (isnodegone || ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
		return 0;

	isaggr = bf_isaggr(bf);
	if (isaggr) {
		seq_st = ATH_DS_BA_SEQ(ds);
		memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
	}

	while (bf) {
		ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
		if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
			nbad++;

		bf = bf->bf_next;
	}

	return nbad;
}

static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
{
	struct sk_buff *skb;
	struct ieee80211_hdr *hdr;

	bf->bf_state.bf_type |= BUF_RETRY;
	bf->bf_retries++;

	skb = bf->bf_mpdu;
	hdr = (struct ieee80211_hdr *)skb->data;
	hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
}

/* Update block ack window */

static void ath_tx_update_baw(struct ath_softc *sc,
	struct ath_atx_tid *tid, int seqno)
{
	int index, cindex;

	index  = ATH_BA_INDEX(tid->seq_start, seqno);
	cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);

	tid->tx_buf[cindex] = NULL;

	while (tid->baw_head != tid->baw_tail && !tid->tx_buf[tid->baw_head]) {
		INCR(tid->seq_start, IEEE80211_SEQ_MAX);
		INCR(tid->baw_head, ATH_TID_MAX_BUFS);
	}
}

/*
 * ath_pkt_dur - compute packet duration (NB: not NAV)
 *
 * rix - rate index
 * pktlen - total bytes (delims + data + fcs + pads + pad delims)
 * width  - 0 for 20 MHz, 1 for 40 MHz
 * half_gi - to use 4us v/s 3.6 us for symbol time
 */

static u32 ath_pkt_duration(struct ath_softc *sc,
				  u8 rix,
				  struct ath_buf *bf,
				  int width,
				  int half_gi,
				  bool shortPreamble)
{
	const struct ath9k_rate_table *rt = sc->sc_currates;
	u32 nbits, nsymbits, duration, nsymbols;
	u8 rc;
	int streams, pktlen;

	pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
	rc = rt->info[rix].rateCode;

	/*
	 * for legacy rates, use old function to compute packet duration
	 */
	if (!IS_HT_RATE(rc))
		return ath9k_hw_computetxtime(sc->sc_ah,
					     rt,
					     pktlen,
					     rix,
					     shortPreamble);
	/*
	 * find number of symbols: PLCP + data
	 */
	nbits = (pktlen << 3) + OFDM_PLCP_BITS;
	nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
	nsymbols = (nbits + nsymbits - 1) / nsymbits;

	if (!half_gi)
		duration = SYMBOL_TIME(nsymbols);
	else
		duration = SYMBOL_TIME_HALFGI(nsymbols);

	/*
	 * addup duration for legacy/ht training and signal fields
	 */
	streams = HT_RC_2_STREAMS(rc);
	duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
	return duration;
}

/* Rate module function to set rate related fields in tx descriptor */

static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
{
	struct ath_hal *ah = sc->sc_ah;
	const struct ath9k_rate_table *rt;
	struct ath_desc *ds = bf->bf_desc;
	struct ath_desc *lastds = bf->bf_lastbf->bf_desc;
	struct ath9k_11n_rate_series series[4];
	int i, flags, rtsctsena = 0, dynamic_mimops = 0;
	u32 ctsduration = 0;
	u8 rix = 0, cix, ctsrate = 0;
	u32 aggr_limit_with_rts = ah->ah_caps.rts_aggr_limit;
	struct ath_node *an = (struct ath_node *) bf->bf_node;

	/*
	 * get the cix for the lowest valid rix.
	 */
	rt = sc->sc_currates;
	for (i = 4; i--;) {
		if (bf->bf_rcs[i].tries) {
			rix = bf->bf_rcs[i].rix;
			break;
		}
	}
	flags = (bf->bf_flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA));
	cix = rt->info[rix].controlRate;

	/*
	 * If 802.11g protection is enabled, determine whether
	 * to use RTS/CTS or just CTS.  Note that this is only
	 * done for OFDM/HT unicast frames.
	 */
	if (sc->sc_protmode != PROT_M_NONE &&
	    (rt->info[rix].phy == PHY_OFDM ||
	     rt->info[rix].phy == PHY_HT) &&
	    (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
		if (sc->sc_protmode == PROT_M_RTSCTS)
			flags = ATH9K_TXDESC_RTSENA;
		else if (sc->sc_protmode == PROT_M_CTSONLY)
			flags = ATH9K_TXDESC_CTSENA;

		cix = rt->info[sc->sc_protrix].controlRate;
		rtsctsena = 1;
	}

	/* For 11n, the default behavior is to enable RTS for
	 * hw retried frames. We enable the global flag here and
	 * let rate series flags determine which rates will actually
	 * use RTS.
	 */
	if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf_isdata(bf)) {
		BUG_ON(!an);
		/*
		 * 802.11g protection not needed, use our default behavior
		 */
		if (!rtsctsena)
			flags = ATH9K_TXDESC_RTSENA;
		/*
		 * For dynamic MIMO PS, RTS needs to precede the first aggregate
		 * and the second aggregate should have any protection at all.
		 */
		if (an->an_smmode == ATH_SM_PWRSAV_DYNAMIC) {
			if (!bf_isaggrburst(bf)) {
				flags = ATH9K_TXDESC_RTSENA;
				dynamic_mimops = 1;
			} else {
				flags = 0;
			}
		}
	}

	/*
	 * Set protection if aggregate protection on
	 */
	if (sc->sc_config.ath_aggr_prot &&
	    (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
		flags = ATH9K_TXDESC_RTSENA;
		cix = rt->info[sc->sc_protrix].controlRate;
		rtsctsena = 1;
	}

	/*
	 *  For AR5416 - RTS cannot be followed by a frame larger than 8K.
	 */
	if (bf_isaggr(bf) && (bf->bf_al > aggr_limit_with_rts)) {
		/*
		 * Ensure that in the case of SM Dynamic power save
		 * while we are bursting the second aggregate the
		 * RTS is cleared.
		 */
		flags &= ~(ATH9K_TXDESC_RTSENA);
	}

	/*
	 * CTS transmit rate is derived from the transmit rate
	 * by looking in the h/w rate table.  We must also factor
	 * in whether or not a short preamble is to be used.
	 */
	/* NB: cix is set above where RTS/CTS is enabled */
	BUG_ON(cix == 0xff);
	ctsrate = rt->info[cix].rateCode |
		(bf_isshpreamble(bf) ? rt->info[cix].shortPreamble : 0);

	/*
	 * Setup HAL rate series
	 */
	memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);

	for (i = 0; i < 4; i++) {
		if (!bf->bf_rcs[i].tries)
			continue;

		rix = bf->bf_rcs[i].rix;

		series[i].Rate = rt->info[rix].rateCode |
			(bf_isshpreamble(bf) ? rt->info[rix].shortPreamble : 0);

		series[i].Tries = bf->bf_rcs[i].tries;

		series[i].RateFlags = (
			(bf->bf_rcs[i].flags & ATH_RC_RTSCTS_FLAG) ?
				ATH9K_RATESERIES_RTS_CTS : 0) |
			((bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) ?
				ATH9K_RATESERIES_2040 : 0) |
			((bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG) ?
				ATH9K_RATESERIES_HALFGI : 0);

		series[i].PktDuration = ath_pkt_duration(
			sc, rix, bf,
			(bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) != 0,
			(bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG),
			bf_isshpreamble(bf));

		if ((an->an_smmode == ATH_SM_PWRSAV_STATIC) &&
		    (bf->bf_rcs[i].flags & ATH_RC_DS_FLAG) == 0) {
			/*
			 * When sending to an HT node that has enabled static
			 * SM/MIMO power save, send at single stream rates but
			 * use maximum allowed transmit chains per user,
			 * hardware, regulatory, or country limits for
			 * better range.
			 */
			series[i].ChSel = sc->sc_tx_chainmask;
		} else {
			if (bf_isht(bf))
				series[i].ChSel =
					ath_chainmask_sel_logic(sc, an);
			else
				series[i].ChSel = sc->sc_tx_chainmask;
		}

		if (rtsctsena)
			series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;

		/*
		 * Set RTS for all rates if node is in dynamic powersave
		 * mode and we are using dual stream rates.
		 */
		if (dynamic_mimops && (bf->bf_rcs[i].flags & ATH_RC_DS_FLAG))
			series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
	}

	/*
	 * For non-HT devices, calculate RTS/CTS duration in software
	 * and disable multi-rate retry.
	 */
	if (flags && !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)) {
		/*
		 * Compute the transmit duration based on the frame
		 * size and the size of an ACK frame.  We call into the
		 * HAL to do the computation since it depends on the
		 * characteristics of the actual PHY being used.
		 *
		 * NB: CTS is assumed the same size as an ACK so we can
		 *     use the precalculated ACK durations.
		 */
		if (flags & ATH9K_TXDESC_RTSENA) {    /* SIFS + CTS */
			ctsduration += bf_isshpreamble(bf) ?
				rt->info[cix].spAckDuration :
				rt->info[cix].lpAckDuration;
		}

		ctsduration += series[0].PktDuration;

		if ((bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { /* SIFS + ACK */
			ctsduration += bf_isshpreamble(bf) ?
				rt->info[rix].spAckDuration :
				rt->info[rix].lpAckDuration;
		}

		/*
		 * Disable multi-rate retry when using RTS/CTS by clearing
		 * series 1, 2 and 3.
		 */
		memset(&series[1], 0, sizeof(struct ath9k_11n_rate_series) * 3);
	}

	/*
	 * set dur_update_en for l-sig computation except for PS-Poll frames
	 */
	ath9k_hw_set11n_ratescenario(ah, ds, lastds,
				     !bf_ispspoll(bf),
				     ctsrate,
				     ctsduration,
				     series, 4, flags);
	if (sc->sc_config.ath_aggr_prot && flags)
		ath9k_hw_set11n_burstduration(ah, ds, 8192);
}

/*
 * Function to send a normal HT (non-AMPDU) frame
 * NB: must be called with txq lock held
 */

static int ath_tx_send_normal(struct ath_softc *sc,
			      struct ath_txq *txq,
			      struct ath_atx_tid *tid,
			      struct list_head *bf_head)
{
	struct ath_buf *bf;
	struct sk_buff *skb;
	struct ieee80211_tx_info *tx_info;
	struct ath_tx_info_priv *tx_info_priv;

	BUG_ON(list_empty(bf_head));

	bf = list_first_entry(bf_head, struct ath_buf, list);
	bf->bf_state.bf_type &= ~BUF_AMPDU; /* regular HT frame */

	skb = (struct sk_buff *)bf->bf_mpdu;
	tx_info = IEEE80211_SKB_CB(skb);
	tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
	memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));

	/* update starting sequence number for subsequent ADDBA request */
	INCR(tid->seq_start, IEEE80211_SEQ_MAX);

	/* Queue to h/w without aggregation */
	bf->bf_nframes = 1;
	bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
	ath_buf_set_rate(sc, bf);
	ath_tx_txqaddbuf(sc, txq, bf_head);

	return 0;
}

/* flush tid's software queue and send frames as non-ampdu's */

static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
	struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
	struct ath_buf *bf;
	struct list_head bf_head;
	INIT_LIST_HEAD(&bf_head);

	ASSERT(tid->paused > 0);
	spin_lock_bh(&txq->axq_lock);

	tid->paused--;

	if (tid->paused > 0) {
		spin_unlock_bh(&txq->axq_lock);
		return;
	}

	while (!list_empty(&tid->buf_q)) {
		bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
		ASSERT(!bf_isretried(bf));
		list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
		ath_tx_send_normal(sc, txq, tid, &bf_head);
	}

	spin_unlock_bh(&txq->axq_lock);
}

/* Completion routine of an aggregate */

static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
				      struct ath_txq *txq,
				      struct ath_buf *bf,
				      struct list_head *bf_q,
				      int txok)
{
	struct ath_node *an = bf->bf_node;
	struct ath_atx_tid *tid = ATH_AN_2_TID(an, bf->bf_tidno);
	struct ath_buf *bf_last = bf->bf_lastbf;
	struct ath_desc *ds = bf_last->bf_desc;
	struct ath_buf *bf_next, *bf_lastq = NULL;
	struct list_head bf_head, bf_pending;
	u16 seq_st = 0;
	u32 ba[WME_BA_BMP_SIZE >> 5];
	int isaggr, txfail, txpending, sendbar = 0, needreset = 0;
	int isnodegone = (an->an_flags & ATH_NODE_CLEAN);

	isaggr = bf_isaggr(bf);
	if (isaggr) {
		if (txok) {
			if (ATH_DS_TX_BA(ds)) {
				/*
				 * extract starting sequence and
				 * block-ack bitmap
				 */
				seq_st = ATH_DS_BA_SEQ(ds);
				memcpy(ba,
					ATH_DS_BA_BITMAP(ds),
					WME_BA_BMP_SIZE >> 3);
			} else {
				memset(ba, 0, WME_BA_BMP_SIZE >> 3);

				/*
				 * AR5416 can become deaf/mute when BA
				 * issue happens. Chip needs to be reset.
				 * But AP code may have sychronization issues
				 * when perform internal reset in this routine.
				 * Only enable reset in STA mode for now.
				 */
				if (sc->sc_ah->ah_opmode == ATH9K_M_STA)
					needreset = 1;
			}
		} else {
			memset(ba, 0, WME_BA_BMP_SIZE >> 3);
		}
	}

	INIT_LIST_HEAD(&bf_pending);
	INIT_LIST_HEAD(&bf_head);

	while (bf) {
		txfail = txpending = 0;
		bf_next = bf->bf_next;

		if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
			/* transmit completion, subframe is
			 * acked by block ack */
		} else if (!isaggr && txok) {
			/* transmit completion */
		} else {

			if (!tid->cleanup_inprogress && !isnodegone &&
			    ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
				if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
					ath_tx_set_retry(sc, bf);
					txpending = 1;
				} else {
					bf->bf_state.bf_type |= BUF_XRETRY;
					txfail = 1;
					sendbar = 1;
				}
			} else {
				/*
				 * cleanup in progress, just fail
				 * the un-acked sub-frames
				 */
				txfail = 1;
			}
		}
		/*
		 * Remove ath_buf's of this sub-frame from aggregate queue.
		 */
		if (bf_next == NULL) {  /* last subframe in the aggregate */
			ASSERT(bf->bf_lastfrm == bf_last);

			/*
			 * The last descriptor of the last sub frame could be
			 * a holding descriptor for h/w. If that's the case,
			 * bf->bf_lastfrm won't be in the bf_q.
			 * Make sure we handle bf_q properly here.
			 */

			if (!list_empty(bf_q)) {
				bf_lastq = list_entry(bf_q->prev,
					struct ath_buf, list);
				list_cut_position(&bf_head,
					bf_q, &bf_lastq->list);
			} else {
				/*
				 * XXX: if the last subframe only has one
				 * descriptor which is also being used as
				 * a holding descriptor. Then the ath_buf
				 * is not in the bf_q at all.
				 */
				INIT_LIST_HEAD(&bf_head);
			}
		} else {
			ASSERT(!list_empty(bf_q));
			list_cut_position(&bf_head,
				bf_q, &bf->bf_lastfrm->list);
		}

		if (!txpending) {
			/*
			 * complete the acked-ones/xretried ones; update
			 * block-ack window
			 */
			spin_lock_bh(&txq->axq_lock);
			ath_tx_update_baw(sc, tid, bf->bf_seqno);
			spin_unlock_bh(&txq->axq_lock);

			/* complete this sub-frame */
			ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
		} else {
			/*
			 * retry the un-acked ones
			 */
			/*
			 * XXX: if the last descriptor is holding descriptor,
			 * in order to requeue the frame to software queue, we
			 * need to allocate a new descriptor and
			 * copy the content of holding descriptor to it.
			 */
			if (bf->bf_next == NULL &&
			    bf_last->bf_status & ATH_BUFSTATUS_STALE) {
				struct ath_buf *tbf;

				/* allocate new descriptor */
				spin_lock_bh(&sc->sc_txbuflock);
				ASSERT(!list_empty((&sc->sc_txbuf)));
				tbf = list_first_entry(&sc->sc_txbuf,
						struct ath_buf, list);
				list_del(&tbf->list);
				spin_unlock_bh(&sc->sc_txbuflock);

				ATH_TXBUF_RESET(tbf);

				/* copy descriptor content */
				tbf->bf_mpdu = bf_last->bf_mpdu;
				tbf->bf_node = bf_last->bf_node;
				tbf->bf_buf_addr = bf_last->bf_buf_addr;
				*(tbf->bf_desc) = *(bf_last->bf_desc);

				/* link it to the frame */
				if (bf_lastq) {
					bf_lastq->bf_desc->ds_link =
						tbf->bf_daddr;
					bf->bf_lastfrm = tbf;
					ath9k_hw_cleartxdesc(sc->sc_ah,
						bf->bf_lastfrm->bf_desc);
				} else {
					tbf->bf_state = bf_last->bf_state;
					tbf->bf_lastfrm = tbf;
					ath9k_hw_cleartxdesc(sc->sc_ah,
						tbf->bf_lastfrm->bf_desc);

					/* copy the DMA context */
					tbf->bf_dmacontext =
						bf_last->bf_dmacontext;
				}
				list_add_tail(&tbf->list, &bf_head);
			} else {
				/*
				 * Clear descriptor status words for
				 * software retry
				 */
				ath9k_hw_cleartxdesc(sc->sc_ah,
						     bf->bf_lastfrm->bf_desc);
			}

			/*
			 * Put this buffer to the temporary pending
			 * queue to retain ordering
			 */
			list_splice_tail_init(&bf_head, &bf_pending);
		}

		bf = bf_next;
	}

	/*
	 * node is already gone. no more assocication
	 * with the node. the node might have been freed
	 * any  node acces can result in panic.note tid
	 * is part of the node.
	 */
	if (isnodegone)
		return;

	if (tid->cleanup_inprogress) {
		/* check to see if we're done with cleaning the h/w queue */
		spin_lock_bh(&txq->axq_lock);

		if (tid->baw_head == tid->baw_tail) {
			tid->addba_exchangecomplete = 0;
			tid->addba_exchangeattempts = 0;
			spin_unlock_bh(&txq->axq_lock);

			tid->cleanup_inprogress = false;

			/* send buffered frames as singles */
			ath_tx_flush_tid(sc, tid);
		} else
			spin_unlock_bh(&txq->axq_lock);

		return;
	}

	/*
	 * prepend un-acked frames to the beginning of the pending frame queue
	 */
	if (!list_empty(&bf_pending)) {
		spin_lock_bh(&txq->axq_lock);
		/* Note: we _prepend_, we _do_not_ at to
		 * the end of the queue ! */
		list_splice(&bf_pending, &tid->buf_q);
		ath_tx_queue_tid(txq, tid);
		spin_unlock_bh(&txq->axq_lock);
	}

	if (needreset)
		ath_reset(sc, false);

	return;
}

/* Process completed xmit descriptors from the specified queue */

static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
{
	struct ath_hal *ah = sc->sc_ah;
	struct ath_buf *bf, *lastbf, *bf_held = NULL;
	struct list_head bf_head;
	struct ath_desc *ds, *tmp_ds;
	struct sk_buff *skb;
	struct ieee80211_tx_info *tx_info;
	struct ath_tx_info_priv *tx_info_priv;
	int nacked, txok, nbad = 0, isrifs = 0;
	int status;

	DPRINTF(sc, ATH_DBG_QUEUE,
		"%s: tx queue %d (%x), link %p\n", __func__,
		txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
		txq->axq_link);

	nacked = 0;
	for (;;) {
		spin_lock_bh(&txq->axq_lock);
		txq->axq_intrcnt = 0; /* reset periodic desc intr count */
		if (list_empty(&txq->axq_q)) {
			txq->axq_link = NULL;
			txq->axq_linkbuf = NULL;
			spin_unlock_bh(&txq->axq_lock);
			break;
		}
		bf = list_first_entry(&txq->axq_q, struct ath_buf, list);

		/*
		 * There is a race condition that a BH gets scheduled
		 * after sw writes TxE and before hw re-load the last
		 * descriptor to get the newly chained one.
		 * Software must keep the last DONE descriptor as a
		 * holding descriptor - software does so by marking
		 * it with the STALE flag.
		 */
		bf_held = NULL;
		if (bf->bf_status & ATH_BUFSTATUS_STALE) {
			bf_held = bf;
			if (list_is_last(&bf_held->list, &txq->axq_q)) {
				/* FIXME:
				 * The holding descriptor is the last
				 * descriptor in queue. It's safe to remove
				 * the last holding descriptor in BH context.
				 */
				spin_unlock_bh(&txq->axq_lock);
				break;
			} else {
				/* Lets work with the next buffer now */
				bf = list_entry(bf_held->list.next,
					struct ath_buf, list);
			}
		}

		lastbf = bf->bf_lastbf;
		ds = lastbf->bf_desc;    /* NB: last decriptor */

		status = ath9k_hw_txprocdesc(ah, ds);
		if (status == -EINPROGRESS) {
			spin_unlock_bh(&txq->axq_lock);
			break;
		}
		if (bf->bf_desc == txq->axq_lastdsWithCTS)
			txq->axq_lastdsWithCTS = NULL;
		if (ds == txq->axq_gatingds)
			txq->axq_gatingds = NULL;

		/*
		 * Remove ath_buf's of the same transmit unit from txq,
		 * however leave the last descriptor back as the holding
		 * descriptor for hw.
		 */
		lastbf->bf_status |= ATH_BUFSTATUS_STALE;
		INIT_LIST_HEAD(&bf_head);

		if (!list_is_singular(&lastbf->list))
			list_cut_position(&bf_head,
				&txq->axq_q, lastbf->list.prev);

		txq->axq_depth--;

		if (bf_isaggr(bf))
			txq->axq_aggr_depth--;

		txok = (ds->ds_txstat.ts_status == 0);

		spin_unlock_bh(&txq->axq_lock);

		if (bf_held) {
			list_del(&bf_held->list);
			spin_lock_bh(&sc->sc_txbuflock);
			list_add_tail(&bf_held->list, &sc->sc_txbuf);
			spin_unlock_bh(&sc->sc_txbuflock);
		}

		if (!bf_isampdu(bf)) {
			/*
			 * This frame is sent out as a single frame.
			 * Use hardware retry status for this frame.
			 */
			bf->bf_retries = ds->ds_txstat.ts_longretry;
			if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
				bf->bf_state.bf_type |= BUF_XRETRY;
			nbad = 0;
		} else {
			nbad = ath_tx_num_badfrms(sc, bf, txok);
		}
		skb = bf->bf_mpdu;
		tx_info = IEEE80211_SKB_CB(skb);
		tx_info_priv = (struct ath_tx_info_priv *)
			tx_info->driver_data[0];
		if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
			tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
		if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
				(bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
			if (ds->ds_txstat.ts_status == 0)
				nacked++;

			if (bf_isdata(bf)) {
				if (isrifs)
					tmp_ds = bf->bf_rifslast->bf_desc;
				else
					tmp_ds = ds;
				memcpy(&tx_info_priv->tx,
					&tmp_ds->ds_txstat,
					sizeof(tx_info_priv->tx));
				tx_info_priv->n_frames = bf->bf_nframes;
				tx_info_priv->n_bad_frames = nbad;
			}
		}

		/*
		 * Complete this transmit unit
		 */
		if (bf_isampdu(bf))
			ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, txok);
		else
			ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);

		/* Wake up mac80211 queue */

		spin_lock_bh(&txq->axq_lock);
		if (txq->stopped && ath_txq_depth(sc, txq->axq_qnum) <=
				(ATH_TXBUF - 20)) {
			int qnum;
			qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
			if (qnum != -1) {
				ieee80211_wake_queue(sc->hw, qnum);
				txq->stopped = 0;
			}

		}

		/*
		 * schedule any pending packets if aggregation is enabled
		 */
		if (sc->sc_flags & SC_OP_TXAGGR)
			ath_txq_schedule(sc, txq);
		spin_unlock_bh(&txq->axq_lock);
	}
	return nacked;
}

static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)
{
	struct ath_hal *ah = sc->sc_ah;

	(void) ath9k_hw_stoptxdma(ah, txq->axq_qnum);
	DPRINTF(sc, ATH_DBG_XMIT, "%s: tx queue [%u] %x, link %p\n",
		__func__, txq->axq_qnum,
		ath9k_hw_gettxbuf(ah, txq->axq_qnum), txq->axq_link);
}

/* Drain only the data queues */

static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
{
	struct ath_hal *ah = sc->sc_ah;
	int i;
	int npend = 0;

	/* XXX return value */
	if (!(sc->sc_flags & SC_OP_INVALID)) {
		for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
			if (ATH_TXQ_SETUP(sc, i)) {
				ath_tx_stopdma(sc, &sc->sc_txq[i]);

				/* The TxDMA may not really be stopped.
				 * Double check the hal tx pending count */
				npend += ath9k_hw_numtxpending(ah,
					sc->sc_txq[i].axq_qnum);
			}
		}
	}

	if (npend) {
		int status;

		/* TxDMA not stopped, reset the hal */
		DPRINTF(sc, ATH_DBG_XMIT,
			"%s: Unable to stop TxDMA. Reset HAL!\n", __func__);

		spin_lock_bh(&sc->sc_resetlock);
		if (!ath9k_hw_reset(ah,
				    sc->sc_ah->ah_curchan,
				    sc->sc_ht_info.tx_chan_width,
				    sc->sc_tx_chainmask, sc->sc_rx_chainmask,
				    sc->sc_ht_extprotspacing, true, &status)) {

			DPRINTF(sc, ATH_DBG_FATAL,
				"%s: unable to reset hardware; hal status %u\n",
				__func__,
				status);
		}
		spin_unlock_bh(&sc->sc_resetlock);
	}

	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
		if (ATH_TXQ_SETUP(sc, i))
			ath_tx_draintxq(sc, &sc->sc_txq[i], retry_tx);
	}
}

/* Add a sub-frame to block ack window */

static void ath_tx_addto_baw(struct ath_softc *sc,
			     struct ath_atx_tid *tid,
			     struct ath_buf *bf)
{
	int index, cindex;

	if (bf_isretried(bf))
		return;

	index  = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
	cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);

	ASSERT(tid->tx_buf[cindex] == NULL);
	tid->tx_buf[cindex] = bf;

	if (index >= ((tid->baw_tail - tid->baw_head) &
		(ATH_TID_MAX_BUFS - 1))) {
		tid->baw_tail = cindex;
		INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
	}
}

/*
 * Function to send an A-MPDU
 * NB: must be called with txq lock held
 */

static int ath_tx_send_ampdu(struct ath_softc *sc,
			     struct ath_txq *txq,
			     struct ath_atx_tid *tid,
			     struct list_head *bf_head,
			     struct ath_tx_control *txctl)
{
	struct ath_buf *bf;
	struct sk_buff *skb;
	struct ieee80211_tx_info *tx_info;
	struct ath_tx_info_priv *tx_info_priv;

	BUG_ON(list_empty(bf_head));

	bf = list_first_entry(bf_head, struct ath_buf, list);
	bf->bf_state.bf_type |= BUF_AMPDU;
	bf->bf_seqno = txctl->seqno; /* save seqno and tidno in buffer */
	bf->bf_tidno = txctl->tidno;

	/*
	 * Do not queue to h/w when any of the following conditions is true:
	 * - there are pending frames in software queue
	 * - the TID is currently paused for ADDBA/BAR request
	 * - seqno is not within block-ack window
	 * - h/w queue depth exceeds low water mark
	 */
	if (!list_empty(&tid->buf_q) || tid->paused ||
	    !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
	    txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
		/*
		 * Add this frame to software queue for scheduling later
		 * for aggregation.
		 */
		list_splice_tail_init(bf_head, &tid->buf_q);
		ath_tx_queue_tid(txq, tid);
		return 0;
	}

	skb = (struct sk_buff *)bf->bf_mpdu;
	tx_info = IEEE80211_SKB_CB(skb);
	tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
	memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));

	/* Add sub-frame to BAW */
	ath_tx_addto_baw(sc, tid, bf);

	/* Queue to h/w without aggregation */
	bf->bf_nframes = 1;
	bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
	ath_buf_set_rate(sc, bf);
	ath_tx_txqaddbuf(sc, txq, bf_head);
	return 0;
}

/*
 * looks up the rate
 * returns aggr limit based on lowest of the rates
 */

static u32 ath_lookup_rate(struct ath_softc *sc,
			   struct ath_buf *bf,
			   struct ath_atx_tid *tid)
{
	const struct ath9k_rate_table *rt = sc->sc_currates;
	struct sk_buff *skb;
	struct ieee80211_tx_info *tx_info;
	struct ath_tx_info_priv *tx_info_priv;
	u32 max_4ms_framelen, frame_length;
	u16 aggr_limit, legacy = 0, maxampdu;
	int i;


	skb = (struct sk_buff *)bf->bf_mpdu;
	tx_info = IEEE80211_SKB_CB(skb);
	tx_info_priv = (struct ath_tx_info_priv *)
		tx_info->driver_data[0];
	memcpy(bf->bf_rcs,
		tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));

	/*
	 * Find the lowest frame length among the rate series that will have a
	 * 4ms transmit duration.
	 * TODO - TXOP limit needs to be considered.
	 */
	max_4ms_framelen = ATH_AMPDU_LIMIT_MAX;

	for (i = 0; i < 4; i++) {
		if (bf->bf_rcs[i].tries) {
			frame_length = bf->bf_rcs[i].max_4ms_framelen;

			if (rt->info[bf->bf_rcs[i].rix].phy != PHY_HT) {
				legacy = 1;
				break;
			}

			max_4ms_framelen = min(max_4ms_framelen, frame_length);
		}
	}

	/*
	 * limit aggregate size by the minimum rate if rate selected is
	 * not a probe rate, if rate selected is a probe rate then
	 * avoid aggregation of this packet.
	 */
	if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
		return 0;

	aggr_limit = min(max_4ms_framelen,
		(u32)ATH_AMPDU_LIMIT_DEFAULT);

	/*
	 * h/w can accept aggregates upto 16 bit lengths (65535).
	 * The IE, however can hold upto 65536, which shows up here
	 * as zero. Ignore 65536 since we  are constrained by hw.
	 */
	maxampdu = tid->an->maxampdu;
	if (maxampdu)
		aggr_limit = min(aggr_limit, maxampdu);

	return aggr_limit;
}

/*
 * returns the number of delimiters to be added to
 * meet the minimum required mpdudensity.
 * caller should make sure that the rate is  HT rate .
 */

static int ath_compute_num_delims(struct ath_softc *sc,
				  struct ath_atx_tid *tid,
				  struct ath_buf *bf,
				  u16 frmlen)
{
	const struct ath9k_rate_table *rt = sc->sc_currates;
	u32 nsymbits, nsymbols, mpdudensity;
	u16 minlen;
	u8 rc, flags, rix;
	int width, half_gi, ndelim, mindelim;

	/* Select standard number of delimiters based on frame length alone */
	ndelim = ATH_AGGR_GET_NDELIM(frmlen);

	/*
	 * If encryption enabled, hardware requires some more padding between
	 * subframes.
	 * TODO - this could be improved to be dependent on the rate.
	 *      The hardware can keep up at lower rates, but not higher rates
	 */
	if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR)
		ndelim += ATH_AGGR_ENCRYPTDELIM;

	/*
	 * Convert desired mpdu density from microeconds to bytes based
	 * on highest rate in rate series (i.e. first rate) to determine
	 * required minimum length for subframe. Take into account
	 * whether high rate is 20 or 40Mhz and half or full GI.
	 */
	mpdudensity = tid->an->mpdudensity;

	/*
	 * If there is no mpdu density restriction, no further calculation
	 * is needed.
	 */
	if (mpdudensity == 0)
		return ndelim;

	rix = bf->bf_rcs[0].rix;
	flags = bf->bf_rcs[0].flags;
	rc = rt->info[rix].rateCode;
	width = (flags & ATH_RC_CW40_FLAG) ? 1 : 0;
	half_gi = (flags & ATH_RC_SGI_FLAG) ? 1 : 0;

	if (half_gi)
		nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity);
	else
		nsymbols = NUM_SYMBOLS_PER_USEC(mpdudensity);

	if (nsymbols == 0)
		nsymbols = 1;

	nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
	minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;

	/* Is frame shorter than required minimum length? */
	if (frmlen < minlen) {
		/* Get the minimum number of delimiters required. */
		mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ;
		ndelim = max(mindelim, ndelim);
	}

	return ndelim;
}

/*
 * For aggregation from software buffer queue.
 * NB: must be called with txq lock held
 */

static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
					struct ath_atx_tid *tid,
					struct list_head *bf_q,
					struct ath_buf **bf_last,
					struct aggr_rifs_param *param,
					int *prev_frames)
{
#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
	struct ath_buf *bf, *tbf, *bf_first, *bf_prev = NULL;
	struct list_head bf_head;
	int rl = 0, nframes = 0, ndelim;
	u16 aggr_limit = 0, al = 0, bpad = 0,
		al_delta, h_baw = tid->baw_size / 2;
	enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
	int prev_al = 0, is_ds_rate = 0;
	INIT_LIST_HEAD(&bf_head);

	BUG_ON(list_empty(&tid->buf_q));

	bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);

	do {
		bf = list_first_entry(&tid->buf_q, struct ath_buf, list);

		/*
		 * do not step over block-ack window
		 */
		if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) {
			status = ATH_AGGR_BAW_CLOSED;
			break;
		}

		if (!rl) {
			aggr_limit = ath_lookup_rate(sc, bf, tid);
			rl = 1;
			/*
			 * Is rate dual stream
			 */
			is_ds_rate =
				(bf->bf_rcs[0].flags & ATH_RC_DS_FLAG) ? 1 : 0;
		}

		/*
		 * do not exceed aggregation limit
		 */
		al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen;

		if (nframes && (aggr_limit <
			(al + bpad + al_delta + prev_al))) {
			status = ATH_AGGR_LIMITED;
			break;
		}

		/*
		 * do not exceed subframe limit
		 */
		if ((nframes + *prev_frames) >=
		    min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
			status = ATH_AGGR_LIMITED;
			break;
		}

		/*
		 * add padding for previous frame to aggregation length
		 */
		al += bpad + al_delta;

		/*
		 * Get the delimiters needed to meet the MPDU
		 * density for this node.
		 */
		ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen);

		bpad = PADBYTES(al_delta) + (ndelim << 2);

		bf->bf_next = NULL;
		bf->bf_lastfrm->bf_desc->ds_link = 0;

		/*
		 * this packet is part of an aggregate
		 * - remove all descriptors belonging to this frame from
		 *   software queue
		 * - add it to block ack window
		 * - set up descriptors for aggregation
		 */
		list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
		ath_tx_addto_baw(sc, tid, bf);

		list_for_each_entry(tbf, &bf_head, list) {
			ath9k_hw_set11n_aggr_middle(sc->sc_ah,
				tbf->bf_desc, ndelim);
		}

		/*
		 * link buffers of this frame to the aggregate
		 */
		list_splice_tail_init(&bf_head, bf_q);
		nframes++;

		if (bf_prev) {
			bf_prev->bf_next = bf;
			bf_prev->bf_lastfrm->bf_desc->ds_link = bf->bf_daddr;
		}
		bf_prev = bf;

#ifdef AGGR_NOSHORT
		/*
		 * terminate aggregation on a small packet boundary
		 */
		if (bf->bf_frmlen < ATH_AGGR_MINPLEN) {
			status = ATH_AGGR_SHORTPKT;
			break;
		}
#endif
	} while (!list_empty(&tid->buf_q));

	bf_first->bf_al = al;
	bf_first->bf_nframes = nframes;
	*bf_last = bf_prev;
	return status;
#undef PADBYTES
}

/*
 * process pending frames possibly doing a-mpdu aggregation
 * NB: must be called with txq lock held
 */

static void ath_tx_sched_aggr(struct ath_softc *sc,
	struct ath_txq *txq, struct ath_atx_tid *tid)
{
	struct ath_buf *bf, *tbf, *bf_last, *bf_lastaggr = NULL;
	enum ATH_AGGR_STATUS status;
	struct list_head bf_q;
	struct aggr_rifs_param param = {0, 0, 0, 0, NULL};
	int prev_frames = 0;

	do {
		if (list_empty(&tid->buf_q))
			return;

		INIT_LIST_HEAD(&bf_q);

		status = ath_tx_form_aggr(sc, tid, &bf_q, &bf_lastaggr, &param,
					  &prev_frames);

		/*
		 * no frames picked up to be aggregated; block-ack
		 * window is not open
		 */
		if (list_empty(&bf_q))
			break;

		bf = list_first_entry(&bf_q, struct ath_buf, list);
		bf_last = list_entry(bf_q.prev, struct ath_buf, list);
		bf->bf_lastbf = bf_last;

		/*
		 * if only one frame, send as non-aggregate
		 */
		if (bf->bf_nframes == 1) {
			ASSERT(bf->bf_lastfrm == bf_last);

			bf->bf_state.bf_type &= ~BUF_AGGR;
			/*
			 * clear aggr bits for every descriptor
			 * XXX TODO: is there a way to optimize it?
			 */
			list_for_each_entry(tbf, &bf_q, list) {
				ath9k_hw_clr11n_aggr(sc->sc_ah, tbf->bf_desc);
			}

			ath_buf_set_rate(sc, bf);
			ath_tx_txqaddbuf(sc, txq, &bf_q);
			continue;
		}

		/*
		 * setup first desc with rate and aggr info
		 */
		bf->bf_state.bf_type |= BUF_AGGR;
		ath_buf_set_rate(sc, bf);
		ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);

		/*
		 * anchor last frame of aggregate correctly
		 */
		ASSERT(bf_lastaggr);
		ASSERT(bf_lastaggr->bf_lastfrm == bf_last);
		tbf = bf_lastaggr;
		ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc);

		/* XXX: We don't enter into this loop, consider removing this */
		while (!list_empty(&bf_q) && !list_is_last(&tbf->list, &bf_q)) {
			tbf = list_entry(tbf->list.next, struct ath_buf, list);
			ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc);
		}

		txq->axq_aggr_depth++;

		/*
		 * Normal aggregate, queue to hardware
		 */
		ath_tx_txqaddbuf(sc, txq, &bf_q);

	} while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
		 status != ATH_AGGR_BAW_CLOSED);
}

/* Called with txq lock held */

static void ath_tid_drain(struct ath_softc *sc,
			  struct ath_txq *txq,
			  struct ath_atx_tid *tid,
			  bool bh_flag)
{
	struct ath_buf *bf;
	struct list_head bf_head;
	INIT_LIST_HEAD(&bf_head);

	for (;;) {
		if (list_empty(&tid->buf_q))
			break;
		bf = list_first_entry(&tid->buf_q, struct ath_buf, list);

		list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);

		/* update baw for software retried frame */
		if (bf_isretried(bf))
			ath_tx_update_baw(sc, tid, bf->bf_seqno);

		/*
		 * do not indicate packets while holding txq spinlock.
		 * unlock is intentional here
		 */
		if (likely(bh_flag))
			spin_unlock_bh(&txq->axq_lock);
		else
			spin_unlock(&txq->axq_lock);

		/* complete this sub-frame */
		ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);

		if (likely(bh_flag))
			spin_lock_bh(&txq->axq_lock);
		else
			spin_lock(&txq->axq_lock);
	}

	/*
	 * TODO: For frame(s) that are in the retry state, we will reuse the
	 * sequence number(s) without setting the retry bit. The
	 * alternative is to give up on these and BAR the receiver's window
	 * forward.
	 */
	tid->seq_next = tid->seq_start;
	tid->baw_tail = tid->baw_head;
}

/*
 * Drain all pending buffers
 * NB: must be called with txq lock held
 */

static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
					  struct ath_txq *txq,
					  bool bh_flag)
{
	struct ath_atx_ac *ac, *ac_tmp;
	struct ath_atx_tid *tid, *tid_tmp;

	list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
		list_del(&ac->list);
		ac->sched = false;
		list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
			list_del(&tid->list);
			tid->sched = false;
			ath_tid_drain(sc, txq, tid, bh_flag);
		}
	}
}

static int ath_tx_start_dma(struct ath_softc *sc,
			    struct sk_buff *skb,
			    struct scatterlist *sg,
			    u32 n_sg,
			    struct ath_tx_control *txctl)
{
	struct ath_node *an = txctl->an;
	struct ath_buf *bf = NULL;
	struct list_head bf_head;
	struct ath_desc *ds;
	struct ath_hal *ah = sc->sc_ah;
	struct ath_txq *txq;
	struct ath_tx_info_priv *tx_info_priv;
	struct ath_rc_series *rcs;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
	struct ieee80211_tx_info *tx_info =  IEEE80211_SKB_CB(skb);
	__le16 fc = hdr->frame_control;

	if (unlikely(txctl->flags & ATH9K_TXDESC_CAB))
		txq = sc->sc_cabq;
	else
		txq = &sc->sc_txq[txctl->qnum];

	/* For each sglist entry, allocate an ath_buf for DMA */
	INIT_LIST_HEAD(&bf_head);
	spin_lock_bh(&sc->sc_txbuflock);
	if (unlikely(list_empty(&sc->sc_txbuf))) {
		spin_unlock_bh(&sc->sc_txbuflock);
		return -ENOMEM;
	}

	bf = list_first_entry(&sc->sc_txbuf, struct ath_buf, list);
	list_del(&bf->list);
	spin_unlock_bh(&sc->sc_txbuflock);

	list_add_tail(&bf->list, &bf_head);

	/* set up this buffer */
	ATH_TXBUF_RESET(bf);
	bf->bf_frmlen = txctl->frmlen;

	ieee80211_is_data(fc) ?
		(bf->bf_state.bf_type |= BUF_DATA) :
		(bf->bf_state.bf_type &= ~BUF_DATA);
	ieee80211_is_back_req(fc) ?
		(bf->bf_state.bf_type |= BUF_BAR) :
		(bf->bf_state.bf_type &= ~BUF_BAR);
	ieee80211_is_pspoll(fc) ?
		(bf->bf_state.bf_type |= BUF_PSPOLL) :
		(bf->bf_state.bf_type &= ~BUF_PSPOLL);
	(sc->sc_flags & SC_OP_PREAMBLE_SHORT) ?
		(bf->bf_state.bf_type |= BUF_SHORT_PREAMBLE) :
		(bf->bf_state.bf_type &= ~BUF_SHORT_PREAMBLE);

	bf->bf_flags = txctl->flags;
	bf->bf_keytype = txctl->keytype;
	tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
	rcs = tx_info_priv->rcs;
	bf->bf_rcs[0] = rcs[0];
	bf->bf_rcs[1] = rcs[1];
	bf->bf_rcs[2] = rcs[2];
	bf->bf_rcs[3] = rcs[3];
	bf->bf_node = an;
	bf->bf_mpdu = skb;
	bf->bf_buf_addr = sg_dma_address(sg);

	/* setup descriptor */
	ds = bf->bf_desc;
	ds->ds_link = 0;
	ds->ds_data = bf->bf_buf_addr;

	/*
	 * Save the DMA context in the first ath_buf
	 */
	bf->bf_dmacontext = txctl->dmacontext;

	/*
	 * Formulate first tx descriptor with tx controls.
	 */
	ath9k_hw_set11n_txdesc(ah,
			       ds,
			       bf->bf_frmlen, /* frame length */
			       txctl->atype, /* Atheros packet type */
			       min(txctl->txpower, (u16)60), /* txpower */
			       txctl->keyix,            /* key cache index */
			       txctl->keytype,          /* key type */
			       txctl->flags);           /* flags */
	ath9k_hw_filltxdesc(ah,
			    ds,
			    sg_dma_len(sg),     /* segment length */
			    true,            /* first segment */
			    (n_sg == 1) ? true : false, /* last segment */
			    ds);                /* first descriptor */

	bf->bf_lastfrm = bf;
	(txctl->ht) ?
		(bf->bf_state.bf_type |= BUF_HT) :
		(bf->bf_state.bf_type &= ~BUF_HT);

	spin_lock_bh(&txq->axq_lock);

	if (txctl->ht && (sc->sc_flags & SC_OP_TXAGGR)) {
		struct ath_atx_tid *tid = ATH_AN_2_TID(an, txctl->tidno);
		if (ath_aggr_query(sc, an, txctl->tidno)) {
			/*
			 * Try aggregation if it's a unicast data frame
			 * and the destination is HT capable.
			 */
			ath_tx_send_ampdu(sc, txq, tid, &bf_head, txctl);
		} else {
			/*
			 * Send this frame as regular when ADDBA exchange
			 * is neither complete nor pending.
			 */
			ath_tx_send_normal(sc, txq, tid, &bf_head);
		}
	} else {
		bf->bf_lastbf = bf;
		bf->bf_nframes = 1;
		ath_buf_set_rate(sc, bf);

		if (ieee80211_is_back_req(fc)) {
			/* This is required for resuming tid
			 * during BAR completion */
			bf->bf_tidno = txctl->tidno;
		}

		ath_tx_txqaddbuf(sc, txq, &bf_head);
	}
	spin_unlock_bh(&txq->axq_lock);
	return 0;
}

static void xmit_map_sg(struct ath_softc *sc,
			struct sk_buff *skb,
			struct ath_tx_control *txctl)
{
	struct ath_xmit_status tx_status;
	struct ath_atx_tid *tid;
	struct scatterlist sg;

	txctl->dmacontext = pci_map_single(sc->pdev, skb->data,
					   skb->len, PCI_DMA_TODEVICE);

	/* setup S/G list */
	memset(&sg, 0, sizeof(struct scatterlist));
	sg_dma_address(&sg) = txctl->dmacontext;
	sg_dma_len(&sg) = skb->len;

	if (ath_tx_start_dma(sc, skb, &sg, 1, txctl) != 0) {
		/*
		 *  We have to do drop frame here.
		 */
		pci_unmap_single(sc->pdev, txctl->dmacontext,
				 skb->len, PCI_DMA_TODEVICE);

		tx_status.retries = 0;
		tx_status.flags = ATH_TX_ERROR;

		if (txctl->ht && (sc->sc_flags & SC_OP_TXAGGR)) {
			/* Reclaim the seqno. */
			tid = ATH_AN_2_TID((struct ath_node *)
				txctl->an, txctl->tidno);
			DECR(tid->seq_next, IEEE80211_SEQ_MAX);
		}
		ath_tx_complete(sc, skb, &tx_status, txctl->an);
	}
}

/* Initialize TX queue and h/w */

int ath_tx_init(struct ath_softc *sc, int nbufs)
{
	int error = 0;

	do {
		spin_lock_init(&sc->sc_txbuflock);

		/* Setup tx descriptors */
		error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf,
			"tx", nbufs, 1);
		if (error != 0) {
			DPRINTF(sc, ATH_DBG_FATAL,
				"%s: failed to allocate tx descriptors: %d\n",
				__func__, error);
			break;
		}

		/* XXX allocate beacon state together with vap */
		error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
					  "beacon", ATH_BCBUF, 1);
		if (error != 0) {
			DPRINTF(sc, ATH_DBG_FATAL,
				"%s: failed to allocate "
				"beacon descripotrs: %d\n",
				__func__, error);
			break;
		}

	} while (0);

	if (error != 0)
		ath_tx_cleanup(sc);

	return error;
}

/* Reclaim all tx queue resources */

int ath_tx_cleanup(struct ath_softc *sc)
{
	/* cleanup beacon descriptors */
	if (sc->sc_bdma.dd_desc_len != 0)
		ath_descdma_cleanup(sc, &sc->sc_bdma, &sc->sc_bbuf);

	/* cleanup tx descriptors */
	if (sc->sc_txdma.dd_desc_len != 0)
		ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf);

	return 0;
}

/* Setup a h/w transmit queue */

struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
{
	struct ath_hal *ah = sc->sc_ah;
	struct ath9k_tx_queue_info qi;
	int qnum;

	memset(&qi, 0, sizeof(qi));
	qi.tqi_subtype = subtype;
	qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
	qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
	qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
	qi.tqi_physCompBuf = 0;

	/*
	 * Enable interrupts only for EOL and DESC conditions.
	 * We mark tx descriptors to receive a DESC interrupt
	 * when a tx queue gets deep; otherwise waiting for the
	 * EOL to reap descriptors.  Note that this is done to
	 * reduce interrupt load and this only defers reaping
	 * descriptors, never transmitting frames.  Aside from
	 * reducing interrupts this also permits more concurrency.
	 * The only potential downside is if the tx queue backs
	 * up in which case the top half of the kernel may backup
	 * due to a lack of tx descriptors.
	 *
	 * The UAPSD queue is an exception, since we take a desc-
	 * based intr on the EOSP frames.
	 */
	if (qtype == ATH9K_TX_QUEUE_UAPSD)
		qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
	else
		qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
			TXQ_FLAG_TXDESCINT_ENABLE;
	qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
	if (qnum == -1) {
		/*
		 * NB: don't print a message, this happens
		 * normally on parts with too few tx queues
		 */
		return NULL;
	}
	if (qnum >= ARRAY_SIZE(sc->sc_txq)) {
		DPRINTF(sc, ATH_DBG_FATAL,
			"%s: hal qnum %u out of range, max %u!\n",
			__func__, qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq));
		ath9k_hw_releasetxqueue(ah, qnum);
		return NULL;
	}
	if (!ATH_TXQ_SETUP(sc, qnum)) {
		struct ath_txq *txq = &sc->sc_txq[qnum];

		txq->axq_qnum = qnum;
		txq->axq_link = NULL;
		INIT_LIST_HEAD(&txq->axq_q);
		INIT_LIST_HEAD(&txq->axq_acq);
		spin_lock_init(&txq->axq_lock);
		txq->axq_depth = 0;
		txq->axq_aggr_depth = 0;
		txq->axq_totalqueued = 0;
		txq->axq_intrcnt = 0;
		txq->axq_linkbuf = NULL;
		sc->sc_txqsetup |= 1<<qnum;
	}
	return &sc->sc_txq[qnum];
}

/* Reclaim resources for a setup queue */

void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
{
	ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
	sc->sc_txqsetup &= ~(1<<txq->axq_qnum);
}

/*
 * Setup a hardware data transmit queue for the specified
 * access control.  The hal may not support all requested
 * queues in which case it will return a reference to a
 * previously setup queue.  We record the mapping from ac's
 * to h/w queues for use by ath_tx_start and also track
 * the set of h/w queues being used to optimize work in the
 * transmit interrupt handler and related routines.
 */

int ath_tx_setup(struct ath_softc *sc, int haltype)
{
	struct ath_txq *txq;

	if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
		DPRINTF(sc, ATH_DBG_FATAL,
			"%s: HAL AC %u out of range, max %zu!\n",
			__func__, haltype, ARRAY_SIZE(sc->sc_haltype2q));
		return 0;
	}
	txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
	if (txq != NULL) {
		sc->sc_haltype2q[haltype] = txq->axq_qnum;
		return 1;
	} else
		return 0;
}

int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
{
	int qnum;

	switch (qtype) {
	case ATH9K_TX_QUEUE_DATA:
		if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
			DPRINTF(sc, ATH_DBG_FATAL,
				"%s: HAL AC %u out of range, max %zu!\n",
				__func__,
				haltype, ARRAY_SIZE(sc->sc_haltype2q));
			return -1;
		}
		qnum = sc->sc_haltype2q[haltype];
		break;
	case ATH9K_TX_QUEUE_BEACON:
		qnum = sc->sc_bhalq;
		break;
	case ATH9K_TX_QUEUE_CAB:
		qnum = sc->sc_cabq->axq_qnum;
		break;
	default:
		qnum = -1;
	}
	return qnum;
}

/* Update parameters for a transmit queue */

int ath_txq_update(struct ath_softc *sc, int qnum,
		   struct ath9k_tx_queue_info *qinfo)
{
	struct ath_hal *ah = sc->sc_ah;
	int error = 0;
	struct ath9k_tx_queue_info qi;

	if (qnum == sc->sc_bhalq) {
		/*
		 * XXX: for beacon queue, we just save the parameter.
		 * It will be picked up by ath_beaconq_config when
		 * it's necessary.
		 */
		sc->sc_beacon_qi = *qinfo;
		return 0;
	}

	ASSERT(sc->sc_txq[qnum].axq_qnum == qnum);

	ath9k_hw_get_txq_props(ah, qnum, &qi);
	qi.tqi_aifs = qinfo->tqi_aifs;
	qi.tqi_cwmin = qinfo->tqi_cwmin;
	qi.tqi_cwmax = qinfo->tqi_cwmax;
	qi.tqi_burstTime = qinfo->tqi_burstTime;
	qi.tqi_readyTime = qinfo->tqi_readyTime;

	if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
		DPRINTF(sc, ATH_DBG_FATAL,
			"%s: unable to update hardware queue %u!\n",
			__func__, qnum);
		error = -EIO;
	} else {
		ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */
	}

	return error;
}

int ath_cabq_update(struct ath_softc *sc)
{
	struct ath9k_tx_queue_info qi;
	int qnum = sc->sc_cabq->axq_qnum;
	struct ath_beacon_config conf;

	ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
	/*
	 * Ensure the readytime % is within the bounds.
	 */
	if (sc->sc_config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
		sc->sc_config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
	else if (sc->sc_config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
		sc->sc_config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;

	ath_get_beaconconfig(sc, ATH_IF_ID_ANY, &conf);
	qi.tqi_readyTime =
		(conf.beacon_interval * sc->sc_config.cabqReadytime) / 100;
	ath_txq_update(sc, qnum, &qi);

	return 0;
}

int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb)
{
	struct ath_tx_control txctl;
	int error = 0;

	memset(&txctl, 0, sizeof(struct ath_tx_control));
	error = ath_tx_prepare(sc, skb, &txctl);
	if (error == 0)
		/*
		 * Start DMA mapping.
		 * ath_tx_start_dma() will be called either synchronously
		 * or asynchrounsly once DMA is complete.
		 */
		xmit_map_sg(sc, skb, &txctl);
	else
		ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE);

	/* failed packets will be dropped by the caller */
	return error;
}

/* Deferred processing of transmit interrupt */

void ath_tx_tasklet(struct ath_softc *sc)
{
	int i;
	u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);

	ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);

	/*
	 * Process each active queue.
	 */
	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
		if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
			ath_tx_processq(sc, &sc->sc_txq[i]);
	}
}

void ath_tx_draintxq(struct ath_softc *sc,
	struct ath_txq *txq, bool retry_tx)
{
	struct ath_buf *bf, *lastbf;
	struct list_head bf_head;

	INIT_LIST_HEAD(&bf_head);

	/*
	 * NB: this assumes output has been stopped and
	 *     we do not need to block ath_tx_tasklet
	 */
	for (;;) {
		spin_lock_bh(&txq->axq_lock);

		if (list_empty(&txq->axq_q)) {
			txq->axq_link = NULL;
			txq->axq_linkbuf = NULL;
			spin_unlock_bh(&txq->axq_lock);
			break;
		}

		bf = list_first_entry(&txq->axq_q, struct ath_buf, list);

		if (bf->bf_status & ATH_BUFSTATUS_STALE) {
			list_del(&bf->list);
			spin_unlock_bh(&txq->axq_lock);

			spin_lock_bh(&sc->sc_txbuflock);
			list_add_tail(&bf->list, &sc->sc_txbuf);
			spin_unlock_bh(&sc->sc_txbuflock);
			continue;
		}

		lastbf = bf->bf_lastbf;
		if (!retry_tx)
			lastbf->bf_desc->ds_txstat.ts_flags =
				ATH9K_TX_SW_ABORTED;

		/* remove ath_buf's of the same mpdu from txq */
		list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
		txq->axq_depth--;

		spin_unlock_bh(&txq->axq_lock);

		if (bf_isampdu(bf))
			ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, 0);
		else
			ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
	}

	/* flush any pending frames if aggregation is enabled */
	if (sc->sc_flags & SC_OP_TXAGGR) {
		if (!retry_tx) {
			spin_lock_bh(&txq->axq_lock);
			ath_txq_drain_pending_buffers(sc, txq,
				ATH9K_BH_STATUS_CHANGE);
			spin_unlock_bh(&txq->axq_lock);
		}
	}
}

/* Drain the transmit queues and reclaim resources */

void ath_draintxq(struct ath_softc *sc, bool retry_tx)
{
	/* stop beacon queue. The beacon will be freed when
	 * we go to INIT state */
	if (!(sc->sc_flags & SC_OP_INVALID)) {
		(void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
		DPRINTF(sc, ATH_DBG_XMIT, "%s: beacon queue %x\n", __func__,
			ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq));
	}

	ath_drain_txdataq(sc, retry_tx);
}

u32 ath_txq_depth(struct ath_softc *sc, int qnum)
{
	return sc->sc_txq[qnum].axq_depth;
}

u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum)
{
	return sc->sc_txq[qnum].axq_aggr_depth;
}

/* Check if an ADDBA is required. A valid node must be passed. */
enum ATH_AGGR_CHECK ath_tx_aggr_check(struct ath_softc *sc,
				      struct ath_node *an,
				      u8 tidno)
{
	struct ath_atx_tid *txtid;

	if (!(sc->sc_flags & SC_OP_TXAGGR))
		return AGGR_NOT_REQUIRED;

	/* ADDBA exchange must be completed before sending aggregates */
	txtid = ATH_AN_2_TID(an, tidno);

	if (txtid->addba_exchangecomplete)
		return AGGR_EXCHANGE_DONE;

	if (txtid->cleanup_inprogress)
		return AGGR_CLEANUP_PROGRESS;

	if (txtid->addba_exchangeinprogress)
		return AGGR_EXCHANGE_PROGRESS;

	if (!txtid->addba_exchangecomplete) {
		if (!txtid->addba_exchangeinprogress &&
		    (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
			txtid->addba_exchangeattempts++;
			return AGGR_REQUIRED;
		}
	}

	return AGGR_NOT_REQUIRED;
}

/* Start TX aggregation */

int ath_tx_aggr_start(struct ath_softc *sc,
		      const u8 *addr,
		      u16 tid,
		      u16 *ssn)
{
	struct ath_atx_tid *txtid;
	struct ath_node *an;

	spin_lock_bh(&sc->node_lock);
	an = ath_node_find(sc, (u8 *) addr);
	spin_unlock_bh(&sc->node_lock);

	if (!an) {
		DPRINTF(sc, ATH_DBG_AGGR,
			"%s: Node not found to initialize "
			"TX aggregation\n", __func__);
		return -1;
	}

	if (sc->sc_flags & SC_OP_TXAGGR) {
		txtid = ATH_AN_2_TID(an, tid);
		txtid->addba_exchangeinprogress = 1;
		ath_tx_pause_tid(sc, txtid);
	}

	return 0;
}

/* Stop tx aggregation */

int ath_tx_aggr_stop(struct ath_softc *sc,
		     const u8 *addr,
		     u16 tid)
{
	struct ath_node *an;

	spin_lock_bh(&sc->node_lock);
	an = ath_node_find(sc, (u8 *) addr);
	spin_unlock_bh(&sc->node_lock);

	if (!an) {
		DPRINTF(sc, ATH_DBG_AGGR,
			"%s: TX aggr stop for non-existent node\n", __func__);
		return -1;
	}

	ath_tx_aggr_teardown(sc, an, tid);
	return 0;
}

/*
 * Performs transmit side cleanup when TID changes from aggregated to
 * unaggregated.
 * - Pause the TID and mark cleanup in progress
 * - Discard all retry frames from the s/w queue.
 */

void ath_tx_aggr_teardown(struct ath_softc *sc,
	struct ath_node *an, u8 tid)
{
	struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
	struct ath_txq *txq = &sc->sc_txq[txtid->ac->qnum];
	struct ath_buf *bf;
	struct list_head bf_head;
	INIT_LIST_HEAD(&bf_head);

	DPRINTF(sc, ATH_DBG_AGGR, "%s: teardown TX aggregation\n", __func__);

	if (txtid->cleanup_inprogress) /* cleanup is in progress */
		return;

	if (!txtid->addba_exchangecomplete) {
		txtid->addba_exchangeattempts = 0;
		return;
	}

	/* TID must be paused first */
	ath_tx_pause_tid(sc, txtid);

	/* drop all software retried frames and mark this TID */
	spin_lock_bh(&txq->axq_lock);
	while (!list_empty(&txtid->buf_q)) {
		bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
		if (!bf_isretried(bf)) {
			/*
			 * NB: it's based on the assumption that
			 * software retried frame will always stay
			 * at the head of software queue.
			 */
			break;
		}
		list_cut_position(&bf_head,
			&txtid->buf_q, &bf->bf_lastfrm->list);
		ath_tx_update_baw(sc, txtid, bf->bf_seqno);

		/* complete this sub-frame */
		ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
	}

	if (txtid->baw_head != txtid->baw_tail) {
		spin_unlock_bh(&txq->axq_lock);
		txtid->cleanup_inprogress = true;
	} else {
		txtid->addba_exchangecomplete = 0;
		txtid->addba_exchangeattempts = 0;
		spin_unlock_bh(&txq->axq_lock);
		ath_tx_flush_tid(sc, txtid);
	}
}

/*
 * Tx scheduling logic
 * NB: must be called with txq lock held
 */

void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
{
	struct ath_atx_ac *ac;
	struct ath_atx_tid *tid;

	/* nothing to schedule */
	if (list_empty(&txq->axq_acq))
		return;
	/*
	 * get the first node/ac pair on the queue
	 */
	ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
	list_del(&ac->list);
	ac->sched = false;

	/*
	 * process a single tid per destination
	 */
	do {
		/* nothing to schedule */
		if (list_empty(&ac->tid_q))
			return;

		tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
		list_del(&tid->list);
		tid->sched = false;

		if (tid->paused)    /* check next tid to keep h/w busy */
			continue;

		if (!(tid->an->an_smmode == ATH_SM_PWRSAV_DYNAMIC) ||
		    ((txq->axq_depth % 2) == 0)) {
			ath_tx_sched_aggr(sc, txq, tid);
		}

		/*
		 * add tid to round-robin queue if more frames
		 * are pending for the tid
		 */
		if (!list_empty(&tid->buf_q))
			ath_tx_queue_tid(txq, tid);

		/* only schedule one TID at a time */
		break;
	} while (!list_empty(&ac->tid_q));

	/*
	 * schedule AC if more TIDs need processing
	 */
	if (!list_empty(&ac->tid_q)) {
		/*
		 * add dest ac to txq if not already added
		 */
		if (!ac->sched) {
			ac->sched = true;
			list_add_tail(&ac->list, &txq->axq_acq);
		}
	}
}

/* Initialize per-node transmit state */

void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
{
	if (sc->sc_flags & SC_OP_TXAGGR) {
		struct ath_atx_tid *tid;
		struct ath_atx_ac *ac;
		int tidno, acno;

		an->maxampdu = ATH_AMPDU_LIMIT_DEFAULT;

		/*
		 * Init per tid tx state
		 */
		for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno];
				tidno < WME_NUM_TID;
				tidno++, tid++) {
			tid->an        = an;
			tid->tidno     = tidno;
			tid->seq_start = tid->seq_next = 0;
			tid->baw_size  = WME_MAX_BA;
			tid->baw_head  = tid->baw_tail = 0;
			tid->sched     = false;
			tid->paused = false;
			tid->cleanup_inprogress = false;
			INIT_LIST_HEAD(&tid->buf_q);

			acno = TID_TO_WME_AC(tidno);
			tid->ac = &an->an_aggr.tx.ac[acno];

			/* ADDBA state */
			tid->addba_exchangecomplete     = 0;
			tid->addba_exchangeinprogress   = 0;
			tid->addba_exchangeattempts     = 0;
		}

		/*
		 * Init per ac tx state
		 */
		for (acno = 0, ac = &an->an_aggr.tx.ac[acno];
				acno < WME_NUM_AC; acno++, ac++) {
			ac->sched    = false;
			INIT_LIST_HEAD(&ac->tid_q);

			switch (acno) {
			case WME_AC_BE:
				ac->qnum = ath_tx_get_qnum(sc,
					ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
				break;
			case WME_AC_BK:
				ac->qnum = ath_tx_get_qnum(sc,
					ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK);
				break;
			case WME_AC_VI:
				ac->qnum = ath_tx_get_qnum(sc,
					ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI);
				break;
			case WME_AC_VO:
				ac->qnum = ath_tx_get_qnum(sc,
					ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO);
				break;
			}
		}
	}
}

/* Cleanupthe pending buffers for the node. */

void ath_tx_node_cleanup(struct ath_softc *sc,
	struct ath_node *an, bool bh_flag)
{
	int i;
	struct ath_atx_ac *ac, *ac_tmp;
	struct ath_atx_tid *tid, *tid_tmp;
	struct ath_txq *txq;
	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
		if (ATH_TXQ_SETUP(sc, i)) {
			txq = &sc->sc_txq[i];

			if (likely(bh_flag))
				spin_lock_bh(&txq->axq_lock);
			else
				spin_lock(&txq->axq_lock);

			list_for_each_entry_safe(ac,
					ac_tmp, &txq->axq_acq, list) {
				tid = list_first_entry(&ac->tid_q,
						struct ath_atx_tid, list);
				if (tid && tid->an != an)
					continue;
				list_del(&ac->list);
				ac->sched = false;

				list_for_each_entry_safe(tid,
						tid_tmp, &ac->tid_q, list) {
					list_del(&tid->list);
					tid->sched = false;
					ath_tid_drain(sc, txq, tid, bh_flag);
					tid->addba_exchangecomplete = 0;
					tid->addba_exchangeattempts = 0;
					tid->cleanup_inprogress = false;
				}
			}

			if (likely(bh_flag))
				spin_unlock_bh(&txq->axq_lock);
			else
				spin_unlock(&txq->axq_lock);
		}
	}
}

/* Cleanup per node transmit state */

void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an)
{
	if (sc->sc_flags & SC_OP_TXAGGR) {
		struct ath_atx_tid *tid;
		int tidno, i;

		/* Init per tid rx state */
		for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno];
			tidno < WME_NUM_TID;
		     tidno++, tid++) {

			for (i = 0; i < ATH_TID_MAX_BUFS; i++)
				ASSERT(tid->tx_buf[i] == NULL);
		}
	}
}

void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
{
	int hdrlen, padsize;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	struct ath_tx_control txctl;

	/*
	 * As a temporary workaround, assign seq# here; this will likely need
	 * to be cleaned up to work better with Beacon transmission and virtual
	 * BSSes.
	 */
	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
		if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
			sc->seq_no += 0x10;
		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
		hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
	}

	/* Add the padding after the header if this is not already done */
	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
	if (hdrlen & 3) {
		padsize = hdrlen % 4;
		if (skb_headroom(skb) < padsize) {
			DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ padding "
				"failed\n", __func__);
			dev_kfree_skb_any(skb);
			return;
		}
		skb_push(skb, padsize);
		memmove(skb->data, skb->data + padsize, hdrlen);
	}

	DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting CABQ packet, skb: %p\n",
		__func__,
		skb);

	memset(&txctl, 0, sizeof(struct ath_tx_control));
	txctl.flags = ATH9K_TXDESC_CAB;
	if (ath_tx_prepare(sc, skb, &txctl) == 0) {
		/*
		 * Start DMA mapping.
		 * ath_tx_start_dma() will be called either synchronously
		 * or asynchrounsly once DMA is complete.
		 */
		xmit_map_sg(sc, skb, &txctl);
	} else {
		ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE);
		DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ failed\n", __func__);
		dev_kfree_skb_any(skb);
	}
}

