/*
 * 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 receive path.
 */

#include "core.h"

/*
 * Setup and link descriptors.
 *
 * 11N: we can no longer afford to self link the last descriptor.
 * MAC acknowledges BA status as long as it copies frames to host
 * buffer (or rx fifo). This can incorrectly acknowledge packets
 * to a sender if last desc is self-linked.
 *
 * NOTE: Caller should hold the rxbuf lock.
 */

static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
{
	struct ath_hal *ah = sc->sc_ah;
	struct ath_desc *ds;
	struct sk_buff *skb;

	ATH_RXBUF_RESET(bf);

	ds = bf->bf_desc;
	ds->ds_link = 0;    /* link to null */
	ds->ds_data = bf->bf_buf_addr;

	/* XXX For RADAR?
	 * virtual addr of the beginning of the buffer. */
	skb = bf->bf_mpdu;
	ASSERT(skb != NULL);
	ds->ds_vdata = skb->data;

	/* setup rx descriptors */
	ath9k_hw_setuprxdesc(ah,
			     ds,
			     skb_tailroom(skb),   /* buffer size */
			     0);

	if (sc->sc_rxlink == NULL)
		ath9k_hw_putrxbuf(ah, bf->bf_daddr);
	else
		*sc->sc_rxlink = bf->bf_daddr;

	sc->sc_rxlink = &ds->ds_link;
	ath9k_hw_rxena(ah);
}

/* Process received BAR frame */

static int ath_bar_rx(struct ath_softc *sc,
		      struct ath_node *an,
		      struct sk_buff *skb)
{
	struct ieee80211_bar *bar;
	struct ath_arx_tid *rxtid;
	struct sk_buff *tskb;
	struct ath_recv_status *rx_status;
	int tidno, index, cindex;
	u16 seqno;

	/* look at BAR contents	 */

	bar = (struct ieee80211_bar *)skb->data;
	tidno = (le16_to_cpu(bar->control) & IEEE80211_BAR_CTL_TID_M)
		>> IEEE80211_BAR_CTL_TID_S;
	seqno = le16_to_cpu(bar->start_seq_num) >> IEEE80211_SEQ_SEQ_SHIFT;

	/* process BAR - indicate all pending RX frames till the BAR seqno */

	rxtid = &an->an_aggr.rx.tid[tidno];

	spin_lock_bh(&rxtid->tidlock);

	/* get relative index */

	index = ATH_BA_INDEX(rxtid->seq_next, seqno);

	/* drop BAR if old sequence (index is too large) */

	if ((index > rxtid->baw_size) &&
	    (index > (IEEE80211_SEQ_MAX - (rxtid->baw_size << 2))))
		/* discard frame, ieee layer may not treat frame as a dup */
		goto unlock_and_free;

	/* complete receive processing for all pending frames upto BAR seqno */

	cindex = (rxtid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
	while ((rxtid->baw_head != rxtid->baw_tail) &&
	       (rxtid->baw_head != cindex)) {
		tskb = rxtid->rxbuf[rxtid->baw_head].rx_wbuf;
		rx_status = &rxtid->rxbuf[rxtid->baw_head].rx_status;
		rxtid->rxbuf[rxtid->baw_head].rx_wbuf = NULL;

		if (tskb != NULL)
			ath_rx_subframe(an, tskb, rx_status);

		INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
		INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
	}

	/* ... and indicate rest of the frames in-order */

	while (rxtid->baw_head != rxtid->baw_tail &&
	       rxtid->rxbuf[rxtid->baw_head].rx_wbuf != NULL) {
		tskb = rxtid->rxbuf[rxtid->baw_head].rx_wbuf;
		rx_status = &rxtid->rxbuf[rxtid->baw_head].rx_status;
		rxtid->rxbuf[rxtid->baw_head].rx_wbuf = NULL;

		ath_rx_subframe(an, tskb, rx_status);

		INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
		INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
	}

unlock_and_free:
	spin_unlock_bh(&rxtid->tidlock);
	/* free bar itself */
	dev_kfree_skb(skb);
	return IEEE80211_FTYPE_CTL;
}

/* Function to handle a subframe of aggregation when HT is enabled */

static int ath_ampdu_input(struct ath_softc *sc,
			   struct ath_node *an,
			   struct sk_buff *skb,
			   struct ath_recv_status *rx_status)
{
	struct ieee80211_hdr *hdr;
	struct ath_arx_tid *rxtid;
	struct ath_rxbuf *rxbuf;
	u8 type, subtype;
	u16 rxseq;
	int tid = 0, index, cindex, rxdiff;
	__le16 fc;
	u8 *qc;

	hdr = (struct ieee80211_hdr *)skb->data;
	fc = hdr->frame_control;

	/* collect stats of frames with non-zero version */

	if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_VERS) != 0) {
		dev_kfree_skb(skb);
		return -1;
	}

	type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE;
	subtype = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE;

	if (ieee80211_is_back_req(fc))
		return ath_bar_rx(sc, an, skb);

	/* special aggregate processing only for qos unicast data frames */

	if (!ieee80211_is_data(fc) ||
	    !ieee80211_is_data_qos(fc) ||
	    is_multicast_ether_addr(hdr->addr1))
		return ath_rx_subframe(an, skb, rx_status);

	/* lookup rx tid state */

	if (ieee80211_is_data_qos(fc)) {
		qc = ieee80211_get_qos_ctl(hdr);
		tid = qc[0] & 0xf;
	}

	if (sc->sc_opmode == ATH9K_M_STA) {
		/* Drop the frame not belonging to me. */
		if (memcmp(hdr->addr1, sc->sc_myaddr, ETH_ALEN)) {
			dev_kfree_skb(skb);
			return -1;
		}
	}

	rxtid = &an->an_aggr.rx.tid[tid];

	spin_lock(&rxtid->tidlock);

	rxdiff = (rxtid->baw_tail - rxtid->baw_head) &
		(ATH_TID_MAX_BUFS - 1);

	/*
	 * If the ADDBA exchange has not been completed by the source,
	 * process via legacy path (i.e. no reordering buffer is needed)
	 */
	if (!rxtid->addba_exchangecomplete) {
		spin_unlock(&rxtid->tidlock);
		return ath_rx_subframe(an, skb, rx_status);
	}

	/* extract sequence number from recvd frame */

	rxseq = le16_to_cpu(hdr->seq_ctrl) >> IEEE80211_SEQ_SEQ_SHIFT;

	if (rxtid->seq_reset) {
		rxtid->seq_reset = 0;
		rxtid->seq_next = rxseq;
	}

	index = ATH_BA_INDEX(rxtid->seq_next, rxseq);

	/* drop frame if old sequence (index is too large) */

	if (index > (IEEE80211_SEQ_MAX - (rxtid->baw_size << 2))) {
		/* discard frame, ieee layer may not treat frame as a dup */
		spin_unlock(&rxtid->tidlock);
		dev_kfree_skb(skb);
		return IEEE80211_FTYPE_DATA;
	}

	/* sequence number is beyond block-ack window */

	if (index >= rxtid->baw_size) {

		/* complete receive processing for all pending frames */

		while (index >= rxtid->baw_size) {

			rxbuf = rxtid->rxbuf + rxtid->baw_head;

			if (rxbuf->rx_wbuf != NULL) {
				ath_rx_subframe(an, rxbuf->rx_wbuf,
						&rxbuf->rx_status);
				rxbuf->rx_wbuf = NULL;
			}

			INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
			INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);

			index--;
		}
	}

	/* add buffer to the recv ba window */

	cindex = (rxtid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
	rxbuf = rxtid->rxbuf + cindex;

	if (rxbuf->rx_wbuf != NULL) {
		spin_unlock(&rxtid->tidlock);
		/* duplicate frame */
		dev_kfree_skb(skb);
		return IEEE80211_FTYPE_DATA;
	}

	rxbuf->rx_wbuf = skb;
	rxbuf->rx_time = get_timestamp();
	rxbuf->rx_status = *rx_status;

	/* advance tail if sequence received is newer
	 * than any received so far */

	if (index >= rxdiff) {
		rxtid->baw_tail = cindex;
		INCR(rxtid->baw_tail, ATH_TID_MAX_BUFS);
	}

	/* indicate all in-order received frames */

	while (rxtid->baw_head != rxtid->baw_tail) {
		rxbuf = rxtid->rxbuf + rxtid->baw_head;
		if (!rxbuf->rx_wbuf)
			break;

		ath_rx_subframe(an, rxbuf->rx_wbuf, &rxbuf->rx_status);
		rxbuf->rx_wbuf = NULL;

		INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
		INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
	}

	/*
	 * start a timer to flush all received frames if there are pending
	 * receive frames
	 */
	if (rxtid->baw_head != rxtid->baw_tail)
		mod_timer(&rxtid->timer, ATH_RX_TIMEOUT);
	else
		del_timer_sync(&rxtid->timer);

	spin_unlock(&rxtid->tidlock);
	return IEEE80211_FTYPE_DATA;
}

/* Timer to flush all received sub-frames */

static void ath_rx_timer(unsigned long data)
{
	struct ath_arx_tid *rxtid = (struct ath_arx_tid *)data;
	struct ath_node *an = rxtid->an;
	struct ath_rxbuf *rxbuf;
	int nosched;

	spin_lock_bh(&rxtid->tidlock);
	while (rxtid->baw_head != rxtid->baw_tail) {
		rxbuf = rxtid->rxbuf + rxtid->baw_head;
		if (!rxbuf->rx_wbuf) {
			INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
			INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
			continue;
		}

		/*
		 * Stop if the next one is a very recent frame.
		 *
		 * Call get_timestamp in every iteration to protect against the
		 * case in which a new frame is received while we are executing
		 * this function. Using a timestamp obtained before entering
		 * the loop could lead to a very large time interval
		 * (a negative value typecast to unsigned), breaking the
		 * function's logic.
		 */
		if ((get_timestamp() - rxbuf->rx_time) <
			(ATH_RX_TIMEOUT * HZ / 1000))
			break;

		ath_rx_subframe(an, rxbuf->rx_wbuf,
				&rxbuf->rx_status);
		rxbuf->rx_wbuf = NULL;

		INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
		INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
	}

	/*
	 * start a timer to flush all received frames if there are pending
	 * receive frames
	 */
	if (rxtid->baw_head != rxtid->baw_tail)
		nosched = 0;
	else
		nosched = 1; /* no need to re-arm the timer again */

	spin_unlock_bh(&rxtid->tidlock);
}

/* Free all pending sub-frames in the re-ordering buffer */

static void ath_rx_flush_tid(struct ath_softc *sc,
	struct ath_arx_tid *rxtid, int drop)
{
	struct ath_rxbuf *rxbuf;
	unsigned long flag;

	spin_lock_irqsave(&rxtid->tidlock, flag);
	while (rxtid->baw_head != rxtid->baw_tail) {
		rxbuf = rxtid->rxbuf + rxtid->baw_head;
		if (!rxbuf->rx_wbuf) {
			INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
			INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
			continue;
		}

		if (drop)
			dev_kfree_skb(rxbuf->rx_wbuf);
		else
			ath_rx_subframe(rxtid->an,
					rxbuf->rx_wbuf,
					&rxbuf->rx_status);

		rxbuf->rx_wbuf = NULL;

		INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
		INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
	}
	spin_unlock_irqrestore(&rxtid->tidlock, flag);
}

static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc,
	u32 len)
{
	struct sk_buff *skb;
	u32 off;

	/*
	 * Cache-line-align.  This is important (for the
	 * 5210 at least) as not doing so causes bogus data
	 * in rx'd frames.
	 */

	skb = dev_alloc_skb(len + sc->sc_cachelsz - 1);
	if (skb != NULL) {
		off = ((unsigned long) skb->data) % sc->sc_cachelsz;
		if (off != 0)
			skb_reserve(skb, sc->sc_cachelsz - off);
	} else {
		DPRINTF(sc, ATH_DBG_FATAL,
			"%s: skbuff alloc of size %u failed\n",
			__func__, len);
		return NULL;
	}

	return skb;
}

static void ath_rx_requeue(struct ath_softc *sc, struct sk_buff *skb)
{
	struct ath_buf *bf = ATH_RX_CONTEXT(skb)->ctx_rxbuf;

	ASSERT(bf != NULL);

	spin_lock_bh(&sc->sc_rxbuflock);
	if (bf->bf_status & ATH_BUFSTATUS_STALE) {
		/*
		 * This buffer is still held for hw acess.
		 * Mark it as free to be re-queued it later.
		 */
		bf->bf_status |= ATH_BUFSTATUS_FREE;
	} else {
		/* XXX: we probably never enter here, remove after
		 * verification */
		list_add_tail(&bf->list, &sc->sc_rxbuf);
		ath_rx_buf_link(sc, bf);
	}
	spin_unlock_bh(&sc->sc_rxbuflock);
}

/*
 * The skb indicated to upper stack won't be returned to us.
 * So we have to allocate a new one and queue it by ourselves.
 */
static int ath_rx_indicate(struct ath_softc *sc,
			   struct sk_buff *skb,
			   struct ath_recv_status *status,
			   u16 keyix)
{
	struct ath_buf *bf = ATH_RX_CONTEXT(skb)->ctx_rxbuf;
	struct sk_buff *nskb;
	int type;

	/* indicate frame to the stack, which will free the old skb. */
	type = ath__rx_indicate(sc, skb, status, keyix);

	/* allocate a new skb and queue it to for H/W processing */
	nskb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
	if (nskb != NULL) {
		bf->bf_mpdu = nskb;
		bf->bf_buf_addr = ath_skb_map_single(sc,
			nskb,
			PCI_DMA_FROMDEVICE,
			/* XXX: Remove get_dma_mem_context() */
			get_dma_mem_context(bf, bf_dmacontext));
		ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf;

		/* queue the new wbuf to H/W */
		ath_rx_requeue(sc, nskb);
	}

	return type;
}

static void ath_opmode_init(struct ath_softc *sc)
{
	struct ath_hal *ah = sc->sc_ah;
	u32 rfilt, mfilt[2];

	/* configure rx filter */
	rfilt = ath_calcrxfilter(sc);
	ath9k_hw_setrxfilter(ah, rfilt);

	/* configure bssid mask */
	if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
		ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);

	/* configure operational mode */
	ath9k_hw_setopmode(ah);

	/* Handle any link-level address change. */
	ath9k_hw_setmac(ah, sc->sc_myaddr);

	/* calculate and install multicast filter */
	mfilt[0] = mfilt[1] = ~0;

	ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
	DPRINTF(sc, ATH_DBG_CONFIG ,
		"%s: RX filter 0x%x, MC filter %08x:%08x\n",
		__func__, rfilt, mfilt[0], mfilt[1]);
}

int ath_rx_init(struct ath_softc *sc, int nbufs)
{
	struct sk_buff *skb;
	struct ath_buf *bf;
	int error = 0;

	do {
		spin_lock_init(&sc->sc_rxflushlock);
		sc->sc_rxflush = 0;
		spin_lock_init(&sc->sc_rxbuflock);

		/*
		 * Cisco's VPN software requires that drivers be able to
		 * receive encapsulated frames that are larger than the MTU.
		 * Since we can't be sure how large a frame we'll get, setup
		 * to handle the larges on possible.
		 */
		sc->sc_rxbufsize = roundup(IEEE80211_MAX_MPDU_LEN,
					   min(sc->sc_cachelsz,
					       (u16)64));

		DPRINTF(sc, ATH_DBG_CONFIG, "%s: cachelsz %u rxbufsize %u\n",
			__func__, sc->sc_cachelsz, sc->sc_rxbufsize);

		/* Initialize rx descriptors */

		error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
					  "rx", nbufs, 1);
		if (error != 0) {
			DPRINTF(sc, ATH_DBG_FATAL,
				"%s: failed to allocate rx descriptors: %d\n",
				__func__, error);
			break;
		}

		/* Pre-allocate a wbuf for each rx buffer */

		list_for_each_entry(bf, &sc->sc_rxbuf, list) {
			skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
			if (skb == NULL) {
				error = -ENOMEM;
				break;
			}

			bf->bf_mpdu = skb;
			bf->bf_buf_addr =
				ath_skb_map_single(sc, skb, PCI_DMA_FROMDEVICE,
				       get_dma_mem_context(bf, bf_dmacontext));
			ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf;
		}
		sc->sc_rxlink = NULL;

	} while (0);

	if (error)
		ath_rx_cleanup(sc);

	return error;
}

/* Reclaim all rx queue resources */

void ath_rx_cleanup(struct ath_softc *sc)
{
	struct sk_buff *skb;
	struct ath_buf *bf;

	list_for_each_entry(bf, &sc->sc_rxbuf, list) {
		skb = bf->bf_mpdu;
		if (skb)
			dev_kfree_skb(skb);
	}

	/* cleanup rx descriptors */

	if (sc->sc_rxdma.dd_desc_len != 0)
		ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
}

/*
 * Calculate the receive filter according to the
 * operating mode and state:
 *
 * o always accept unicast, broadcast, and multicast traffic
 * o maintain current state of phy error reception (the hal
 *   may enable phy error frames for noise immunity work)
 * o probe request frames are accepted only when operating in
 *   hostap, adhoc, or monitor modes
 * o enable promiscuous mode according to the interface state
 * o accept beacons:
 *   - when operating in adhoc mode so the 802.11 layer creates
 *     node table entries for peers,
 *   - when operating in station mode for collecting rssi data when
 *     the station is otherwise quiet, or
 *   - when operating as a repeater so we see repeater-sta beacons
 *   - when scanning
 */

u32 ath_calcrxfilter(struct ath_softc *sc)
{
#define	RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
	u32 rfilt;

	rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE)
		| ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
		| ATH9K_RX_FILTER_MCAST;

	/* If not a STA, enable processing of Probe Requests */
	if (sc->sc_opmode != ATH9K_M_STA)
		rfilt |= ATH9K_RX_FILTER_PROBEREQ;

	/* Can't set HOSTAP into promiscous mode */
	if (sc->sc_opmode == ATH9K_M_MONITOR) {
		rfilt |= ATH9K_RX_FILTER_PROM;
		/* ??? To prevent from sending ACK */
		rfilt &= ~ATH9K_RX_FILTER_UCAST;
	}

	if (sc->sc_opmode == ATH9K_M_STA || sc->sc_opmode == ATH9K_M_IBSS ||
	    sc->sc_scanning)
		rfilt |= ATH9K_RX_FILTER_BEACON;

	/* If in HOSTAP mode, want to enable reception of PSPOLL frames
	   & beacon frames */
	if (sc->sc_opmode == ATH9K_M_HOSTAP)
		rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL);
	return rfilt;
#undef RX_FILTER_PRESERVE
}

/* Enable the receive h/w following a reset. */

int ath_startrecv(struct ath_softc *sc)
{
	struct ath_hal *ah = sc->sc_ah;
	struct ath_buf *bf, *tbf;

	spin_lock_bh(&sc->sc_rxbuflock);
	if (list_empty(&sc->sc_rxbuf))
		goto start_recv;

	sc->sc_rxlink = NULL;
	list_for_each_entry_safe(bf, tbf, &sc->sc_rxbuf, list) {
		if (bf->bf_status & ATH_BUFSTATUS_STALE) {
			/* restarting h/w, no need for holding descriptors */
			bf->bf_status &= ~ATH_BUFSTATUS_STALE;
			/*
			 * Upper layer may not be done with the frame yet so
			 * we can't just re-queue it to hardware. Remove it
			 * from h/w queue. It'll be re-queued when upper layer
			 * returns the frame and ath_rx_requeue_mpdu is called.
			 */
			if (!(bf->bf_status & ATH_BUFSTATUS_FREE)) {
				list_del(&bf->list);
				continue;
			}
		}
		/* chain descriptors */
		ath_rx_buf_link(sc, bf);
	}

	/* We could have deleted elements so the list may be empty now */
	if (list_empty(&sc->sc_rxbuf))
		goto start_recv;

	bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list);
	ath9k_hw_putrxbuf(ah, bf->bf_daddr);
	ath9k_hw_rxena(ah);      /* enable recv descriptors */

start_recv:
	spin_unlock_bh(&sc->sc_rxbuflock);
	ath_opmode_init(sc);        /* set filters, etc. */
	ath9k_hw_startpcureceive(ah);	/* re-enable PCU/DMA engine */
	return 0;
}

/* Disable the receive h/w in preparation for a reset. */

bool ath_stoprecv(struct ath_softc *sc)
{
	struct ath_hal *ah = sc->sc_ah;
	u64 tsf;
	bool stopped;

	ath9k_hw_stoppcurecv(ah);	/* disable PCU */
	ath9k_hw_setrxfilter(ah, 0);	/* clear recv filter */
	stopped = ath9k_hw_stopdmarecv(ah);	/* disable DMA engine */
	mdelay(3);			/* 3ms is long enough for 1 frame */
	tsf = ath9k_hw_gettsf64(ah);
	sc->sc_rxlink = NULL;		/* just in case */
	return stopped;
}

/* Flush receive queue */

void ath_flushrecv(struct ath_softc *sc)
{
	/*
	 * ath_rx_tasklet may be used to handle rx interrupt and flush receive
	 * queue at the same time. Use a lock to serialize the access of rx
	 * queue.
	 * ath_rx_tasklet cannot hold the spinlock while indicating packets.
	 * Instead, do not claim the spinlock but check for a flush in
	 * progress (see references to sc_rxflush)
	 */
	spin_lock_bh(&sc->sc_rxflushlock);
	sc->sc_rxflush = 1;

	ath_rx_tasklet(sc, 1);

	sc->sc_rxflush = 0;
	spin_unlock_bh(&sc->sc_rxflushlock);
}

/* Process an individual frame */

int ath_rx_input(struct ath_softc *sc,
		 struct ath_node *an,
		 int is_ampdu,
		 struct sk_buff *skb,
		 struct ath_recv_status *rx_status,
		 enum ATH_RX_TYPE *status)
{
	if (is_ampdu && sc->sc_rxaggr) {
		*status = ATH_RX_CONSUMED;
		return ath_ampdu_input(sc, an, skb, rx_status);
	} else {
		*status = ATH_RX_NON_CONSUMED;
		return -1;
	}
}

/* Process receive queue, as well as LED, etc. */

int ath_rx_tasklet(struct ath_softc *sc, int flush)
{
#define PA2DESC(_sc, _pa)                                               \
	((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc +		\
			     ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))

	struct ath_buf *bf, *bf_held = NULL;
	struct ath_desc *ds;
	struct ieee80211_hdr *hdr;
	struct sk_buff *skb = NULL;
	struct ath_recv_status rx_status;
	struct ath_hal *ah = sc->sc_ah;
	int type, rx_processed = 0;
	u32 phyerr;
	u8 chainreset = 0;
	int retval;
	__le16 fc;

	do {
		/* If handling rx interrupt and flush is in progress => exit */
		if (sc->sc_rxflush && (flush == 0))
			break;

		spin_lock_bh(&sc->sc_rxbuflock);
		if (list_empty(&sc->sc_rxbuf)) {
			sc->sc_rxlink = NULL;
			spin_unlock_bh(&sc->sc_rxbuflock);
			break;
		}

		bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list);

		/*
		 * There is a race condition that BH gets scheduled after sw
		 * writes RxE 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.
		 */
		if (bf->bf_status & ATH_BUFSTATUS_STALE) {
			bf_held = bf;
			if (list_is_last(&bf_held->list, &sc->sc_rxbuf)) {
				/*
				 * The holding descriptor is the last
				 * descriptor in queue. It's safe to
				 * remove the last holding descriptor
				 * in BH context.
				 */
				list_del(&bf_held->list);
				bf_held->bf_status &= ~ATH_BUFSTATUS_STALE;
				sc->sc_rxlink = NULL;

				if (bf_held->bf_status & ATH_BUFSTATUS_FREE) {
					list_add_tail(&bf_held->list,
						&sc->sc_rxbuf);
					ath_rx_buf_link(sc, bf_held);
				}
				spin_unlock_bh(&sc->sc_rxbuflock);
				break;
			}
			bf = list_entry(bf->list.next, struct ath_buf, list);
		}

		ds = bf->bf_desc;
		++rx_processed;

		/*
		 * Must provide the virtual address of the current
		 * descriptor, the physical address, and the virtual
		 * address of the next descriptor in the h/w chain.
		 * This allows the HAL to look ahead to see if the
		 * hardware is done with a descriptor by checking the
		 * done bit in the following descriptor and the address
		 * of the current descriptor the DMA engine is working
		 * on.  All this is necessary because of our use of
		 * a self-linked list to avoid rx overruns.
		 */
		retval = ath9k_hw_rxprocdesc(ah,
					     ds,
					     bf->bf_daddr,
					     PA2DESC(sc, ds->ds_link),
					     0);
		if (retval == -EINPROGRESS) {
			struct ath_buf *tbf;
			struct ath_desc *tds;

			if (list_is_last(&bf->list, &sc->sc_rxbuf)) {
				spin_unlock_bh(&sc->sc_rxbuflock);
				break;
			}

			tbf = list_entry(bf->list.next, struct ath_buf, list);

			/*
			 * On some hardware the descriptor status words could
			 * get corrupted, including the done bit. Because of
			 * this, check if the next descriptor's done bit is
			 * set or not.
			 *
			 * If the next descriptor's done bit is set, the current
			 * descriptor has been corrupted. Force s/w to discard
			 * this descriptor and continue...
			 */

			tds = tbf->bf_desc;
			retval = ath9k_hw_rxprocdesc(ah,
				tds, tbf->bf_daddr,
				PA2DESC(sc, tds->ds_link), 0);
			if (retval == -EINPROGRESS) {
				spin_unlock_bh(&sc->sc_rxbuflock);
				break;
			}
		}

		/* XXX: we do not support frames spanning
		 * multiple descriptors */
		bf->bf_status |= ATH_BUFSTATUS_DONE;

		skb = bf->bf_mpdu;
		if (skb == NULL) {		/* XXX ??? can this happen */
			spin_unlock_bh(&sc->sc_rxbuflock);
			continue;
		}
		/*
		 * Now we know it's a completed frame, we can indicate the
		 * frame. Remove the previous holding descriptor and leave
		 * this one in the queue as the new holding descriptor.
		 */
		if (bf_held) {
			list_del(&bf_held->list);
			bf_held->bf_status &= ~ATH_BUFSTATUS_STALE;
			if (bf_held->bf_status & ATH_BUFSTATUS_FREE) {
				list_add_tail(&bf_held->list, &sc->sc_rxbuf);
				/* try to requeue this descriptor */
				ath_rx_buf_link(sc, bf_held);
			}
		}

		bf->bf_status |= ATH_BUFSTATUS_STALE;
		bf_held = bf;
		/*
		 * Release the lock here in case ieee80211_input() return
		 * the frame immediately by calling ath_rx_mpdu_requeue().
		 */
		spin_unlock_bh(&sc->sc_rxbuflock);

		if (flush) {
			/*
			 * If we're asked to flush receive queue, directly
			 * chain it back at the queue without processing it.
			 */
			goto rx_next;
		}

		hdr = (struct ieee80211_hdr *)skb->data;
		fc = hdr->frame_control;
		memzero(&rx_status, sizeof(struct ath_recv_status));

		if (ds->ds_rxstat.rs_more) {
			/*
			 * Frame spans multiple descriptors; this
			 * cannot happen yet as we don't support
			 * jumbograms.  If not in monitor mode,
			 * discard the frame.
			 */
#ifndef ERROR_FRAMES
			/*
			 * Enable this if you want to see
			 * error frames in Monitor mode.
			 */
			if (sc->sc_opmode != ATH9K_M_MONITOR)
				goto rx_next;
#endif
			/* fall thru for monitor mode handling... */
		} else if (ds->ds_rxstat.rs_status != 0) {
			if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
				rx_status.flags |= ATH_RX_FCS_ERROR;
			if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) {
				phyerr = ds->ds_rxstat.rs_phyerr & 0x1f;
				goto rx_next;
			}

			if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) {
				/*
				 * Decrypt error. We only mark packet status
				 * here and always push up the frame up to let
				 * mac80211 handle the actual error case, be
				 * it no decryption key or real decryption
				 * error. This let us keep statistics there.
				 */
				rx_status.flags |= ATH_RX_DECRYPT_ERROR;
			} else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) {
				/*
				 * Demic error. We only mark frame status here
				 * and always push up the frame up to let
				 * mac80211 handle the actual error case. This
				 * let us keep statistics there. Hardware may
				 * post a false-positive MIC error.
				 */
				if (ieee80211_is_ctl(fc))
					/*
					 * Sometimes, we get invalid
					 * MIC failures on valid control frames.
					 * Remove these mic errors.
					 */
					ds->ds_rxstat.rs_status &=
						~ATH9K_RXERR_MIC;
				else
					rx_status.flags |= ATH_RX_MIC_ERROR;
			}
			/*
			 * Reject error frames with the exception of
			 * decryption and MIC failures. For monitor mode,
			 * we also ignore the CRC error.
			 */
			if (sc->sc_opmode == ATH9K_M_MONITOR) {
				if (ds->ds_rxstat.rs_status &
				    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
					ATH9K_RXERR_CRC))
					goto rx_next;
			} else {
				if (ds->ds_rxstat.rs_status &
				    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
					goto rx_next;
				}
			}
		}
		/*
		 * The status portion of the descriptor could get corrupted.
		 */
		if (sc->sc_rxbufsize < ds->ds_rxstat.rs_datalen)
			goto rx_next;
		/*
		 * Sync and unmap the frame.  At this point we're
		 * committed to passing the sk_buff somewhere so
		 * clear buf_skb; this means a new sk_buff must be
		 * allocated when the rx descriptor is setup again
		 * to receive another frame.
		 */
		skb_put(skb, ds->ds_rxstat.rs_datalen);
		skb->protocol = cpu_to_be16(ETH_P_CONTROL);
		rx_status.tsf = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
		rx_status.rateieee =
			sc->sc_hwmap[ds->ds_rxstat.rs_rate].ieeerate;
		rx_status.rateKbps =
			sc->sc_hwmap[ds->ds_rxstat.rs_rate].rateKbps;
		rx_status.ratecode = ds->ds_rxstat.rs_rate;

		/* HT rate */
		if (rx_status.ratecode & 0x80) {
			/* TODO - add table to avoid division */
			if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040) {
				rx_status.flags |= ATH_RX_40MHZ;
				rx_status.rateKbps =
					(rx_status.rateKbps * 27) / 13;
			}
			if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI)
				rx_status.rateKbps =
					(rx_status.rateKbps * 10) / 9;
			else
				rx_status.flags |= ATH_RX_SHORT_GI;
		}

		/* sc->sc_noise_floor is only available when the station
		   attaches to an AP, so we use a default value
		   if we are not yet attached. */

		/* XXX we should use either sc->sc_noise_floor or
		 * ath_hal_getChanNoise(ah, &sc->sc_curchan)
		 * to calculate the noise floor.
		 * However, the value returned by ath_hal_getChanNoise
		 * seems to be incorrect (-31dBm on the last test),
		 * so we will use a hard-coded value until we
		 * figure out what is going on.
		 */
		rx_status.abs_rssi =
			ds->ds_rxstat.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;

		pci_dma_sync_single_for_cpu(sc->pdev,
					    bf->bf_buf_addr,
					    skb_tailroom(skb),
					    PCI_DMA_FROMDEVICE);
		pci_unmap_single(sc->pdev,
				 bf->bf_buf_addr,
				 sc->sc_rxbufsize,
				 PCI_DMA_FROMDEVICE);

		/* XXX: Ah! make me more readable, use a helper */
		if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
			if (ds->ds_rxstat.rs_moreaggr == 0) {
				rx_status.rssictl[0] =
					ds->ds_rxstat.rs_rssi_ctl0;
				rx_status.rssictl[1] =
					ds->ds_rxstat.rs_rssi_ctl1;
				rx_status.rssictl[2] =
					ds->ds_rxstat.rs_rssi_ctl2;
				rx_status.rssi = ds->ds_rxstat.rs_rssi;
				if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040) {
					rx_status.rssiextn[0] =
						ds->ds_rxstat.rs_rssi_ext0;
					rx_status.rssiextn[1] =
						ds->ds_rxstat.rs_rssi_ext1;
					rx_status.rssiextn[2] =
						ds->ds_rxstat.rs_rssi_ext2;
					rx_status.flags |=
						ATH_RX_RSSI_EXTN_VALID;
				}
				rx_status.flags |= ATH_RX_RSSI_VALID |
					ATH_RX_CHAIN_RSSI_VALID;
			}
		} else {
			/*
			 * Need to insert the "combined" rssi into the
			 * status structure for upper layer processing
			 */
			rx_status.rssi = ds->ds_rxstat.rs_rssi;
			rx_status.flags |= ATH_RX_RSSI_VALID;
		}

		/* Pass frames up to the stack. */

		type = ath_rx_indicate(sc, skb,
			&rx_status, ds->ds_rxstat.rs_keyix);

		/*
		 * change the default rx antenna if rx diversity chooses the
		 * other antenna 3 times in a row.
		 */
		if (sc->sc_defant != ds->ds_rxstat.rs_antenna) {
			if (++sc->sc_rxotherant >= 3)
				ath_setdefantenna(sc,
						ds->ds_rxstat.rs_antenna);
		} else {
			sc->sc_rxotherant = 0;
		}

#ifdef CONFIG_SLOW_ANT_DIV
		if ((rx_status.flags & ATH_RX_RSSI_VALID) &&
		    ieee80211_is_beacon(fc)) {
			ath_slow_ant_div(&sc->sc_antdiv, hdr, &ds->ds_rxstat);
		}
#endif
		/*
		 * For frames successfully indicated, the buffer will be
		 * returned to us by upper layers by calling
		 * ath_rx_mpdu_requeue, either synchronusly or asynchronously.
		 * So we don't want to do it here in this loop.
		 */
		continue;

rx_next:
		bf->bf_status |= ATH_BUFSTATUS_FREE;
	} while (TRUE);

	if (chainreset) {
		DPRINTF(sc, ATH_DBG_CONFIG,
			"%s: Reset rx chain mask. "
			"Do internal reset\n", __func__);
		ASSERT(flush == 0);
		ath_internal_reset(sc);
	}

	return 0;
#undef PA2DESC
}

/* Process ADDBA request in per-TID data structure */

int ath_rx_aggr_start(struct ath_softc *sc,
		      const u8 *addr,
		      u16 tid,
		      u16 *ssn)
{
	struct ath_arx_tid *rxtid;
	struct ath_node *an;
	struct ieee80211_hw *hw = sc->hw;
	struct ieee80211_supported_band *sband;
	u16 buffersize = 0;

	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 RX aggregation\n",
			__func__);
		return -1;
	}

	sband = hw->wiphy->bands[hw->conf.channel->band];
	buffersize = IEEE80211_MIN_AMPDU_BUF <<
		sband->ht_info.ampdu_factor; /* FIXME */

	rxtid = &an->an_aggr.rx.tid[tid];

	spin_lock_bh(&rxtid->tidlock);
	if (sc->sc_rxaggr) {
		/* Allow aggregation reception
		 * Adjust rx BA window size. Peer might indicate a
		 * zero buffer size for a _dont_care_ condition.
		 */
		if (buffersize)
			rxtid->baw_size = min(buffersize, rxtid->baw_size);

		/* set rx sequence number */
		rxtid->seq_next = *ssn;

		/* Allocate the receive buffers for this TID */
		DPRINTF(sc, ATH_DBG_AGGR,
			"%s: Allcating rxbuffer for TID %d\n", __func__, tid);

		if (rxtid->rxbuf == NULL) {
			/*
			* If the rxbuff is not NULL at this point, we *probably*
			* already allocated the buffer on a previous ADDBA,
			* and this is a subsequent ADDBA that got through.
			* Don't allocate, but use the value in the pointer,
			* we zero it out when we de-allocate.
			*/
			rxtid->rxbuf = kmalloc(ATH_TID_MAX_BUFS *
				sizeof(struct ath_rxbuf), GFP_ATOMIC);
		}
		if (rxtid->rxbuf == NULL) {
			DPRINTF(sc, ATH_DBG_AGGR,
				"%s: Unable to allocate RX buffer, "
				"refusing ADDBA\n", __func__);
		} else {
			/* Ensure the memory is zeroed out (all internal
			 * pointers are null) */
			memzero(rxtid->rxbuf, ATH_TID_MAX_BUFS *
				sizeof(struct ath_rxbuf));
			DPRINTF(sc, ATH_DBG_AGGR,
				"%s: Allocated @%p\n", __func__, rxtid->rxbuf);

			/* Allow aggregation reception */
			rxtid->addba_exchangecomplete = 1;
		}
	}
	spin_unlock_bh(&rxtid->tidlock);

	return 0;
}

/* Process DELBA */

int ath_rx_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: RX aggr stop for non-existent node\n", __func__);
		return -1;
	}

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

/* Rx aggregation tear down */

void ath_rx_aggr_teardown(struct ath_softc *sc,
	struct ath_node *an, u8 tid)
{
	struct ath_arx_tid *rxtid = &an->an_aggr.rx.tid[tid];

	if (!rxtid->addba_exchangecomplete)
		return;

	del_timer_sync(&rxtid->timer);
	ath_rx_flush_tid(sc, rxtid, 0);
	rxtid->addba_exchangecomplete = 0;

	/* De-allocate the receive buffer array allocated when addba started */

	if (rxtid->rxbuf) {
		DPRINTF(sc, ATH_DBG_AGGR,
			"%s: Deallocating TID %d rxbuff @%p\n",
			__func__, tid, rxtid->rxbuf);
		kfree(rxtid->rxbuf);

		/* Set pointer to null to avoid reuse*/
		rxtid->rxbuf = NULL;
	}
}

/* Initialize per-node receive state */

void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an)
{
	if (sc->sc_rxaggr) {
		struct ath_arx_tid *rxtid;
		int tidno;

		/* Init per tid rx state */
		for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno];
				tidno < WME_NUM_TID;
				tidno++, rxtid++) {
			rxtid->an        = an;
			rxtid->seq_reset = 1;
			rxtid->seq_next  = 0;
			rxtid->baw_size  = WME_MAX_BA;
			rxtid->baw_head  = rxtid->baw_tail = 0;

			/*
			 * Ensure the buffer pointer is null at this point
			 * (needs to be allocated when addba is received)
			*/

			rxtid->rxbuf     = NULL;
			setup_timer(&rxtid->timer, ath_rx_timer,
				(unsigned long)rxtid);
			spin_lock_init(&rxtid->tidlock);

			/* ADDBA state */
			rxtid->addba_exchangecomplete = 0;
		}
	}
}

void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
{
	if (sc->sc_rxaggr) {
		struct ath_arx_tid *rxtid;
		int tidno, i;

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

			if (!rxtid->addba_exchangecomplete)
				continue;

			/* must cancel timer first */
			del_timer_sync(&rxtid->timer);

			/* drop any pending sub-frames */
			ath_rx_flush_tid(sc, rxtid, 1);

			for (i = 0; i < ATH_TID_MAX_BUFS; i++)
				ASSERT(rxtid->rxbuf[i].rx_wbuf == NULL);

			rxtid->addba_exchangecomplete = 0;
		}
	}

}

/* Cleanup per-node receive state */

void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an)
{
	ath_rx_node_cleanup(sc, an);
}

dma_addr_t ath_skb_map_single(struct ath_softc *sc,
			      struct sk_buff *skb,
			      int direction,
			      dma_addr_t *pa)
{
	/*
	 * NB: do NOT use skb->len, which is 0 on initialization.
	 * Use skb's entire data area instead.
	 */
	*pa = pci_map_single(sc->pdev, skb->data,
		skb_end_pointer(skb) - skb->head, direction);
	return *pa;
}

void ath_skb_unmap_single(struct ath_softc *sc,
			  struct sk_buff *skb,
			  int direction,
			  dma_addr_t *pa)
{
	/* Unmap skb's entire data area */
	pci_unmap_single(sc->pdev, *pa,
		skb_end_pointer(skb) - skb->head, direction);
}
