/*
 * Copyright (c) 2014-2015 Qualcomm Atheros, 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.
 */

#include "wil6210.h"
#include "txrx.h"

#define SEQ_MODULO 0x1000
#define SEQ_MASK   0xfff

static inline int seq_less(u16 sq1, u16 sq2)
{
	return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1);
}

static inline u16 seq_inc(u16 sq)
{
	return (sq + 1) & SEQ_MASK;
}

static inline u16 seq_sub(u16 sq1, u16 sq2)
{
	return (sq1 - sq2) & SEQ_MASK;
}

static inline int reorder_index(struct wil_tid_ampdu_rx *r, u16 seq)
{
	return seq_sub(seq, r->ssn) % r->buf_size;
}

static void wil_release_reorder_frame(struct wil6210_priv *wil,
				      struct wil_tid_ampdu_rx *r,
				      int index)
{
	struct net_device *ndev = wil_to_ndev(wil);
	struct sk_buff *skb = r->reorder_buf[index];

	if (!skb)
		goto no_frame;

	/* release the frame from the reorder ring buffer */
	r->stored_mpdu_num--;
	r->reorder_buf[index] = NULL;
	wil_netif_rx_any(skb, ndev);

no_frame:
	r->head_seq_num = seq_inc(r->head_seq_num);
}

static void wil_release_reorder_frames(struct wil6210_priv *wil,
				       struct wil_tid_ampdu_rx *r,
				       u16 hseq)
{
	int index;

	/* note: this function is never called with
	 * hseq preceding r->head_seq_num, i.e it is always true
	 * !seq_less(hseq, r->head_seq_num)
	 * and thus on loop exit it should be
	 * r->head_seq_num == hseq
	 */
	while (seq_less(r->head_seq_num, hseq) && r->stored_mpdu_num) {
		index = reorder_index(r, r->head_seq_num);
		wil_release_reorder_frame(wil, r, index);
	}
	r->head_seq_num = hseq;
}

static void wil_reorder_release(struct wil6210_priv *wil,
				struct wil_tid_ampdu_rx *r)
{
	int index = reorder_index(r, r->head_seq_num);

	while (r->reorder_buf[index]) {
		wil_release_reorder_frame(wil, r, index);
		index = reorder_index(r, r->head_seq_num);
	}
}

/* called in NAPI context */
void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
{
	struct net_device *ndev = wil_to_ndev(wil);
	struct vring_rx_desc *d = wil_skb_rxdesc(skb);
	int tid = wil_rxdesc_tid(d);
	int cid = wil_rxdesc_cid(d);
	int mid = wil_rxdesc_mid(d);
	u16 seq = wil_rxdesc_seq(d);
	int mcast = wil_rxdesc_mcast(d);
	struct wil_sta_info *sta = &wil->sta[cid];
	struct wil_tid_ampdu_rx *r;
	u16 hseq;
	int index;

	wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x mcast %01x\n",
		     mid, cid, tid, seq, mcast);

	if (unlikely(mcast)) {
		wil_netif_rx_any(skb, ndev);
		return;
	}

	spin_lock(&sta->tid_rx_lock);

	r = sta->tid_rx[tid];
	if (!r) {
		wil_netif_rx_any(skb, ndev);
		goto out;
	}

	r->total++;
	hseq = r->head_seq_num;

	/** Due to the race between WMI events, where BACK establishment
	 * reported, and data Rx, few packets may be pass up before reorder
	 * buffer get allocated. Catch up by pretending SSN is what we
	 * see in the 1-st Rx packet
	 *
	 * Another scenario, Rx get delayed and we got packet from before
	 * BACK. Pass it to the stack and wait.
	 */
	if (r->first_time) {
		r->first_time = false;
		if (seq != r->head_seq_num) {
			if (seq_less(seq, r->head_seq_num)) {
				wil_err(wil,
					"Error: frame with early sequence 0x%03x, should be 0x%03x. Waiting...\n",
					seq, r->head_seq_num);
				r->first_time = true;
				wil_netif_rx_any(skb, ndev);
				goto out;
			}
			wil_err(wil,
				"Error: 1-st frame with wrong sequence 0x%03x, should be 0x%03x. Fixing...\n",
				seq, r->head_seq_num);
			r->head_seq_num = seq;
			r->ssn = seq;
		}
	}

	/* frame with out of date sequence number */
	if (seq_less(seq, r->head_seq_num)) {
		r->ssn_last_drop = seq;
		r->drop_old++;
		wil_dbg_txrx(wil, "Rx drop: old seq 0x%03x head 0x%03x\n",
			     seq, r->head_seq_num);
		dev_kfree_skb(skb);
		goto out;
	}

	/*
	 * If frame the sequence number exceeds our buffering window
	 * size release some previous frames to make room for this one.
	 */
	if (!seq_less(seq, r->head_seq_num + r->buf_size)) {
		hseq = seq_inc(seq_sub(seq, r->buf_size));
		/* release stored frames up to new head to stack */
		wil_release_reorder_frames(wil, r, hseq);
	}

	/* Now the new frame is always in the range of the reordering buffer */

	index = reorder_index(r, seq);

	/* check if we already stored this frame */
	if (r->reorder_buf[index]) {
		r->drop_dup++;
		wil_dbg_txrx(wil, "Rx drop: dup seq 0x%03x\n", seq);
		dev_kfree_skb(skb);
		goto out;
	}

	/*
	 * If the current MPDU is in the right order and nothing else
	 * is stored we can process it directly, no need to buffer it.
	 * If it is first but there's something stored, we may be able
	 * to release frames after this one.
	 */
	if (seq == r->head_seq_num && r->stored_mpdu_num == 0) {
		r->head_seq_num = seq_inc(r->head_seq_num);
		wil_netif_rx_any(skb, ndev);
		goto out;
	}

	/* put the frame in the reordering buffer */
	r->reorder_buf[index] = skb;
	r->reorder_time[index] = jiffies;
	r->stored_mpdu_num++;
	wil_reorder_release(wil, r);

out:
	spin_unlock(&sta->tid_rx_lock);
}

/* process BAR frame, called in NAPI context */
void wil_rx_bar(struct wil6210_priv *wil, u8 cid, u8 tid, u16 seq)
{
	struct wil_sta_info *sta = &wil->sta[cid];
	struct wil_tid_ampdu_rx *r;

	spin_lock(&sta->tid_rx_lock);

	r = sta->tid_rx[tid];
	if (!r) {
		wil_err(wil, "BAR for non-existing CID %d TID %d\n", cid, tid);
		goto out;
	}
	if (seq_less(seq, r->head_seq_num)) {
		wil_err(wil, "BAR Seq 0x%03x preceding head 0x%03x\n",
			seq, r->head_seq_num);
		goto out;
	}
	wil_dbg_txrx(wil, "BAR: CID %d TID %d Seq 0x%03x head 0x%03x\n",
		     cid, tid, seq, r->head_seq_num);
	wil_release_reorder_frames(wil, r, seq);

out:
	spin_unlock(&sta->tid_rx_lock);
}

struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
						int size, u16 ssn)
{
	struct wil_tid_ampdu_rx *r = kzalloc(sizeof(*r), GFP_KERNEL);

	if (!r)
		return NULL;

	r->reorder_buf =
		kcalloc(size, sizeof(struct sk_buff *), GFP_KERNEL);
	r->reorder_time =
		kcalloc(size, sizeof(unsigned long), GFP_KERNEL);
	if (!r->reorder_buf || !r->reorder_time) {
		kfree(r->reorder_buf);
		kfree(r->reorder_time);
		kfree(r);
		return NULL;
	}

	r->ssn = ssn;
	r->head_seq_num = ssn;
	r->buf_size = size;
	r->stored_mpdu_num = 0;
	r->first_time = true;
	return r;
}

void wil_tid_ampdu_rx_free(struct wil6210_priv *wil,
			   struct wil_tid_ampdu_rx *r)
{
	if (!r)
		return;
	wil_release_reorder_frames(wil, r, r->head_seq_num + r->buf_size);
	kfree(r->reorder_buf);
	kfree(r->reorder_time);
	kfree(r);
}

/* ADDBA processing */
static u16 wil_agg_size(struct wil6210_priv *wil, u16 req_agg_wsize)
{
	u16 max_agg_size = min_t(u16, WIL_MAX_AGG_WSIZE, WIL_MAX_AMPDU_SIZE /
				 (mtu_max + WIL_MAX_MPDU_OVERHEAD));

	if (!req_agg_wsize)
		return max_agg_size;

	return min(max_agg_size, req_agg_wsize);
}

/* Block Ack - Rx side (recipient */
int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid,
			 u8 dialog_token, __le16 ba_param_set,
			 __le16 ba_timeout, __le16 ba_seq_ctrl)
{
	struct wil_back_rx *req = kzalloc(sizeof(*req), GFP_KERNEL);

	if (!req)
		return -ENOMEM;

	req->cidxtid = cidxtid;
	req->dialog_token = dialog_token;
	req->ba_param_set = le16_to_cpu(ba_param_set);
	req->ba_timeout = le16_to_cpu(ba_timeout);
	req->ba_seq_ctrl = le16_to_cpu(ba_seq_ctrl);

	mutex_lock(&wil->back_rx_mutex);
	list_add_tail(&req->list, &wil->back_rx_pending);
	mutex_unlock(&wil->back_rx_mutex);

	queue_work(wil->wq_service, &wil->back_rx_worker);

	return 0;
}

static void wil_back_rx_handle(struct wil6210_priv *wil,
			       struct wil_back_rx *req)
__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
{
	struct wil_sta_info *sta;
	u8 cid, tid;
	u16 agg_wsize = 0;
	/* bit 0: A-MSDU supported
	 * bit 1: policy (should be 0 for us)
	 * bits 2..5: TID
	 * bits 6..15: buffer size
	 */
	u16 req_agg_wsize = WIL_GET_BITS(req->ba_param_set, 6, 15);
	bool agg_amsdu = !!(req->ba_param_set & BIT(0));
	int ba_policy = req->ba_param_set & BIT(1);
	u16 agg_timeout = req->ba_timeout;
	u16 status = WLAN_STATUS_SUCCESS;
	u16 ssn = req->ba_seq_ctrl >> 4;
	struct wil_tid_ampdu_rx *r;
	int rc;

	might_sleep();
	parse_cidxtid(req->cidxtid, &cid, &tid);

	/* sanity checks */
	if (cid >= WIL6210_MAX_CID) {
		wil_err(wil, "BACK: invalid CID %d\n", cid);
		return;
	}

	sta = &wil->sta[cid];
	if (sta->status != wil_sta_connected) {
		wil_err(wil, "BACK: CID %d not connected\n", cid);
		return;
	}

	wil_dbg_wmi(wil,
		    "ADDBA request for CID %d %pM TID %d size %d timeout %d AMSDU%s policy %d token %d SSN 0x%03x\n",
		    cid, sta->addr, tid, req_agg_wsize, req->ba_timeout,
		    agg_amsdu ? "+" : "-", !!ba_policy, req->dialog_token, ssn);

	/* apply policies */
	if (ba_policy) {
		wil_err(wil, "BACK requested unsupported ba_policy == 1\n");
		status = WLAN_STATUS_INVALID_QOS_PARAM;
	}
	if (status == WLAN_STATUS_SUCCESS)
		agg_wsize = wil_agg_size(wil, req_agg_wsize);

	rc = wmi_addba_rx_resp(wil, cid, tid, req->dialog_token, status,
			       agg_amsdu, agg_wsize, agg_timeout);
	if (rc || (status != WLAN_STATUS_SUCCESS))
		return;

	/* apply */
	r = wil_tid_ampdu_rx_alloc(wil, agg_wsize, ssn);
	spin_lock_bh(&sta->tid_rx_lock);
	wil_tid_ampdu_rx_free(wil, sta->tid_rx[tid]);
	sta->tid_rx[tid] = r;
	spin_unlock_bh(&sta->tid_rx_lock);
}

void wil_back_rx_flush(struct wil6210_priv *wil)
{
	struct wil_back_rx *evt, *t;

	wil_dbg_misc(wil, "%s()\n", __func__);

	mutex_lock(&wil->back_rx_mutex);

	list_for_each_entry_safe(evt, t, &wil->back_rx_pending, list) {
		list_del(&evt->list);
		kfree(evt);
	}

	mutex_unlock(&wil->back_rx_mutex);
}

/* Retrieve next ADDBA request from the pending list */
static struct list_head *next_back_rx(struct wil6210_priv *wil)
{
	struct list_head *ret = NULL;

	mutex_lock(&wil->back_rx_mutex);

	if (!list_empty(&wil->back_rx_pending)) {
		ret = wil->back_rx_pending.next;
		list_del(ret);
	}

	mutex_unlock(&wil->back_rx_mutex);

	return ret;
}

void wil_back_rx_worker(struct work_struct *work)
{
	struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
						back_rx_worker);
	struct wil_back_rx *evt;
	struct list_head *lh;

	while ((lh = next_back_rx(wil)) != NULL) {
		evt = list_entry(lh, struct wil_back_rx, list);

		wil_back_rx_handle(wil, evt);
		kfree(evt);
	}
}

/* BACK - Tx (originator) side */
static void wil_back_tx_handle(struct wil6210_priv *wil,
			       struct wil_back_tx *req)
{
	struct vring_tx_data *txdata = &wil->vring_tx_data[req->ringid];
	int rc;

	if (txdata->addba_in_progress) {
		wil_dbg_misc(wil, "ADDBA for vring[%d] already in progress\n",
			     req->ringid);
		return;
	}
	if (txdata->agg_wsize) {
		wil_dbg_misc(wil,
			     "ADDBA for vring[%d] already established wsize %d\n",
			     req->ringid, txdata->agg_wsize);
		return;
	}
	txdata->addba_in_progress = true;
	rc = wmi_addba(wil, req->ringid, req->agg_wsize, req->agg_timeout);
	if (rc)
		txdata->addba_in_progress = false;
}

static struct list_head *next_back_tx(struct wil6210_priv *wil)
{
	struct list_head *ret = NULL;

	mutex_lock(&wil->back_tx_mutex);

	if (!list_empty(&wil->back_tx_pending)) {
		ret = wil->back_tx_pending.next;
		list_del(ret);
	}

	mutex_unlock(&wil->back_tx_mutex);

	return ret;
}

void wil_back_tx_worker(struct work_struct *work)
{
	struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
						 back_tx_worker);
	struct wil_back_tx *evt;
	struct list_head *lh;

	while ((lh = next_back_tx(wil)) != NULL) {
		evt = list_entry(lh, struct wil_back_tx, list);

		wil_back_tx_handle(wil, evt);
		kfree(evt);
	}
}

void wil_back_tx_flush(struct wil6210_priv *wil)
{
	struct wil_back_tx *evt, *t;

	wil_dbg_misc(wil, "%s()\n", __func__);

	mutex_lock(&wil->back_tx_mutex);

	list_for_each_entry_safe(evt, t, &wil->back_tx_pending, list) {
		list_del(&evt->list);
		kfree(evt);
	}

	mutex_unlock(&wil->back_tx_mutex);
}

int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize)
{
	struct wil_back_tx *req = kzalloc(sizeof(*req), GFP_KERNEL);

	if (!req)
		return -ENOMEM;

	req->ringid = ringid;
	req->agg_wsize = wil_agg_size(wil, wsize);
	req->agg_timeout = 0;

	mutex_lock(&wil->back_tx_mutex);
	list_add_tail(&req->list, &wil->back_tx_pending);
	mutex_unlock(&wil->back_tx_mutex);

	queue_work(wil->wq_service, &wil->back_tx_worker);

	return 0;
}
