/*
 * Intel Wireless Multicomm 3200 WiFi driver
 *
 * Copyright (C) 2009 Intel Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *   * Neither the name of Intel Corporation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * Intel Corporation <ilw@linux.intel.com>
 * Samuel Ortiz <samuel.ortiz@intel.com>
 * Zhu Yi <yi.zhu@intel.com>
 *
 */

/*
 * iwm Tx theory of operation:
 *
 * 1) We receive a 802.3 frame from the stack
 * 2) We convert it to a 802.11 frame [iwm_xmit_frame]
 * 3) We queue it to its corresponding tx queue [iwm_xmit_frame]
 * 4) We schedule the tx worker. There is one worker per tx
 *    queue. [iwm_xmit_frame]
 * 5) The tx worker is scheduled
 * 6) We go through every queued skb on the tx queue, and for each
 *    and every one of them: [iwm_tx_worker]
 *    a) We check if we have enough Tx credits (see below for a Tx
 *       credits description) for the frame length. [iwm_tx_worker]
 *    b) If we do, we aggregate the Tx frame into a UDMA one, by
 *       concatenating one REPLY_TX command per Tx frame. [iwm_tx_worker]
 *    c) When we run out of credits, or when we reach the maximum
 *       concatenation size, we actually send the concatenated UDMA
 *       frame. [iwm_tx_worker]
 *
 * When we run out of Tx credits, the skbs are filling the tx queue,
 * and eventually we will stop the netdev queue. [iwm_tx_worker]
 * The tx queue is emptied as we're getting new tx credits, by
 * scheduling the tx_worker. [iwm_tx_credit_inc]
 * The netdev queue is started again when we have enough tx credits,
 * and when our tx queue has some reasonable amout of space available
 * (i.e. half of the max size). [iwm_tx_worker]
 */

#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/ieee80211.h>

#include "iwm.h"
#include "debug.h"
#include "commands.h"
#include "hal.h"
#include "umac.h"
#include "bus.h"

#define IWM_UMAC_PAGE_ALLOC_WRAP 0xffff

#define BYTES_TO_PAGES(n)	 (1 + ((n) >> ilog2(IWM_UMAC_PAGE_SIZE)) - \
				 (((n) & (IWM_UMAC_PAGE_SIZE - 1)) == 0))

#define pool_id_to_queue(id)	 ((id < IWM_TX_CMD_QUEUE) ? id : id - 1)
#define queue_to_pool_id(q)	 ((q < IWM_TX_CMD_QUEUE) ? q : q + 1)

/* require to hold tx_credit lock */
static int iwm_tx_credit_get(struct iwm_tx_credit *tx_credit, int id)
{
	struct pool_entry *pool = &tx_credit->pools[id];
	struct spool_entry *spool = &tx_credit->spools[pool->sid];
	int spool_pages;

	/* number of pages can be taken from spool by this pool */
	spool_pages = spool->max_pages - spool->alloc_pages +
		      max(pool->min_pages - pool->alloc_pages, 0);

	return min(pool->max_pages - pool->alloc_pages, spool_pages);
}

static bool iwm_tx_credit_ok(struct iwm_priv *iwm, int id, int nb)
{
	u32 npages = BYTES_TO_PAGES(nb);

	if (npages <= iwm_tx_credit_get(&iwm->tx_credit, id))
		return 1;

	set_bit(id, &iwm->tx_credit.full_pools_map);

	IWM_DBG_TX(iwm, DBG, "LINK: stop txq[%d], available credit: %d\n",
		   pool_id_to_queue(id),
		   iwm_tx_credit_get(&iwm->tx_credit, id));

	return 0;
}

void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages)
{
	struct pool_entry *pool;
	struct spool_entry *spool;
	int freed_pages;
	int queue;

	BUG_ON(id >= IWM_MACS_OUT_GROUPS);

	pool = &iwm->tx_credit.pools[id];
	spool = &iwm->tx_credit.spools[pool->sid];

	freed_pages = total_freed_pages - pool->total_freed_pages;
	IWM_DBG_TX(iwm, DBG, "Free %d pages for pool[%d]\n", freed_pages, id);

	if (!freed_pages) {
		IWM_DBG_TX(iwm, DBG, "No pages are freed by UMAC\n");
		return;
	} else if (freed_pages < 0)
		freed_pages += IWM_UMAC_PAGE_ALLOC_WRAP + 1;

	if (pool->alloc_pages > pool->min_pages) {
		int spool_pages = pool->alloc_pages - pool->min_pages;
		spool_pages = min(spool_pages, freed_pages);
		spool->alloc_pages -= spool_pages;
	}

	pool->alloc_pages -= freed_pages;
	pool->total_freed_pages = total_freed_pages;

	IWM_DBG_TX(iwm, DBG, "Pool[%d] pages alloc: %d, total_freed: %d, "
		   "Spool[%d] pages alloc: %d\n", id, pool->alloc_pages,
		   pool->total_freed_pages, pool->sid, spool->alloc_pages);

	if (test_bit(id, &iwm->tx_credit.full_pools_map) &&
	    (pool->alloc_pages < pool->max_pages / 2)) {
		clear_bit(id, &iwm->tx_credit.full_pools_map);

		queue = pool_id_to_queue(id);

		IWM_DBG_TX(iwm, DBG, "LINK: start txq[%d], available "
			   "credit: %d\n", queue,
			   iwm_tx_credit_get(&iwm->tx_credit, id));
		queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker);
	}
}

static void iwm_tx_credit_dec(struct iwm_priv *iwm, int id, int alloc_pages)
{
	struct pool_entry *pool;
	struct spool_entry *spool;
	int spool_pages;

	IWM_DBG_TX(iwm, DBG, "Allocate %d pages for pool[%d]\n",
		   alloc_pages, id);

	BUG_ON(id >= IWM_MACS_OUT_GROUPS);

	pool = &iwm->tx_credit.pools[id];
	spool = &iwm->tx_credit.spools[pool->sid];

	spool_pages = pool->alloc_pages + alloc_pages - pool->min_pages;

	if (pool->alloc_pages >= pool->min_pages)
		spool->alloc_pages += alloc_pages;
	else if (spool_pages > 0)
		spool->alloc_pages += spool_pages;

	pool->alloc_pages += alloc_pages;

	IWM_DBG_TX(iwm, DBG, "Pool[%d] pages alloc: %d, total_freed: %d, "
		   "Spool[%d] pages alloc: %d\n", id, pool->alloc_pages,
		   pool->total_freed_pages, pool->sid, spool->alloc_pages);
}

int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb)
{
	u32 npages = BYTES_TO_PAGES(nb);
	int ret = 0;

	spin_lock(&iwm->tx_credit.lock);

	if (!iwm_tx_credit_ok(iwm, id, nb)) {
		IWM_DBG_TX(iwm, DBG, "No credit avaliable for pool[%d]\n", id);
		ret = -ENOSPC;
		goto out;
	}

	iwm_tx_credit_dec(iwm, id, npages);

 out:
	spin_unlock(&iwm->tx_credit.lock);
	return ret;
}

/*
 * Since we're on an SDIO or USB bus, we are not sharing memory
 * for storing to be transmitted frames. The host needs to push
 * them upstream. As a consequence there needs to be a way for
 * the target to let us know if it can actually take more TX frames
 * or not. This is what Tx credits are for.
 *
 * For each Tx HW queue, we have a Tx pool, and then we have one
 * unique super pool (spool), which is actually a global pool of
 * all the UMAC pages.
 * For each Tx pool we have a min_pages, a max_pages fields, and a
 * alloc_pages fields. The alloc_pages tracks the number of pages
 * currently allocated from the tx pool.
 * Here are the rules to check if given a tx frame we have enough
 * tx credits for it:
 * 1) We translate the frame length into a number of UMAC pages.
 *    Let's call them n_pages.
 * 2) For the corresponding tx pool, we check if n_pages +
 *    pool->alloc_pages is higher than pool->min_pages. min_pages
 *    represent a set of pre-allocated pages on the tx pool. If
 *    that's the case, then we need to allocate those pages from
 *    the spool. We can do so until we reach spool->max_pages.
 * 3) Each tx pool is not allowed to allocate more than pool->max_pages
 *    from the spool, so once we're over min_pages, we can allocate
 *    pages from the spool, but not more than max_pages.
 *
 * When the tx code path needs to send a tx frame, it checks first
 * if it has enough tx credits, following those rules. [iwm_tx_credit_get]
 * If it does, it then updates the pool and spool counters and
 * then send the frame. [iwm_tx_credit_alloc and iwm_tx_credit_dec]
 * On the other side, when the UMAC is done transmitting frames, it
 * will send a credit update notification to the host. This is when
 * the pool and spool counters gets to be decreased. [iwm_tx_credit_inc,
 * called from rx.c:iwm_ntf_tx_credit_update]
 *
 */
void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
			      struct iwm_umac_notif_alive *alive)
{
	int i, sid, pool_pages;

	spin_lock(&iwm->tx_credit.lock);

	iwm->tx_credit.pool_nr = le16_to_cpu(alive->page_grp_count);
	iwm->tx_credit.full_pools_map = 0;
	memset(&iwm->tx_credit.spools[0], 0, sizeof(struct spool_entry));

	IWM_DBG_TX(iwm, DBG, "Pools number is %d\n", iwm->tx_credit.pool_nr);

	for (i = 0; i < iwm->tx_credit.pool_nr; i++) {
		__le32 page_grp_state = alive->page_grp_state[i];

		iwm->tx_credit.pools[i].id = GET_VAL32(page_grp_state,
				UMAC_ALIVE_PAGE_STS_GRP_NUM);
		iwm->tx_credit.pools[i].sid = GET_VAL32(page_grp_state,
				UMAC_ALIVE_PAGE_STS_SGRP_NUM);
		iwm->tx_credit.pools[i].min_pages = GET_VAL32(page_grp_state,
				UMAC_ALIVE_PAGE_STS_GRP_MIN_SIZE);
		iwm->tx_credit.pools[i].max_pages = GET_VAL32(page_grp_state,
				UMAC_ALIVE_PAGE_STS_GRP_MAX_SIZE);
		iwm->tx_credit.pools[i].alloc_pages = 0;
		iwm->tx_credit.pools[i].total_freed_pages = 0;

		sid = iwm->tx_credit.pools[i].sid;
		pool_pages = iwm->tx_credit.pools[i].min_pages;

		if (iwm->tx_credit.spools[sid].max_pages == 0) {
			iwm->tx_credit.spools[sid].id = sid;
			iwm->tx_credit.spools[sid].max_pages =
				GET_VAL32(page_grp_state,
					  UMAC_ALIVE_PAGE_STS_SGRP_MAX_SIZE);
			iwm->tx_credit.spools[sid].alloc_pages = 0;
		}

		iwm->tx_credit.spools[sid].alloc_pages += pool_pages;

		IWM_DBG_TX(iwm, DBG, "Pool idx: %d, id: %d, sid: %d, capacity "
			   "min: %d, max: %d, pool alloc: %d, total_free: %d, "
			   "super poll alloc: %d\n",
			   i, iwm->tx_credit.pools[i].id,
			   iwm->tx_credit.pools[i].sid,
			   iwm->tx_credit.pools[i].min_pages,
			   iwm->tx_credit.pools[i].max_pages,
			   iwm->tx_credit.pools[i].alloc_pages,
			   iwm->tx_credit.pools[i].total_freed_pages,
			   iwm->tx_credit.spools[sid].alloc_pages);
	}

	spin_unlock(&iwm->tx_credit.lock);
}

#define IWM_UDMA_HDR_LEN	sizeof(struct iwm_umac_wifi_out_hdr)

static int iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb,
			       int pool_id, u8 *buf)
{
	struct iwm_umac_wifi_out_hdr *hdr = (struct iwm_umac_wifi_out_hdr *)buf;
	struct iwm_udma_wifi_cmd udma_cmd;
	struct iwm_umac_cmd umac_cmd;
	struct iwm_tx_info *tx_info = skb_to_tx_info(skb);

	udma_cmd.count = cpu_to_le16(skb->len +
				     sizeof(struct iwm_umac_fw_cmd_hdr));
	/* set EOP to 0 here. iwm_udma_wifi_hdr_set_eop() will be
	 * called later to set EOP for the last packet. */
	udma_cmd.eop = 0;
	udma_cmd.credit_group = pool_id;
	udma_cmd.ra_tid = tx_info->sta << 4 | tx_info->tid;
	udma_cmd.lmac_offset = 0;

	umac_cmd.id = REPLY_TX;
	umac_cmd.count = cpu_to_le16(skb->len);
	umac_cmd.color = tx_info->color;
	umac_cmd.resp = 0;
	umac_cmd.seq_num = cpu_to_le16(iwm_alloc_wifi_cmd_seq(iwm));

	iwm_build_udma_wifi_hdr(iwm, &hdr->hw_hdr, &udma_cmd);
	iwm_build_umac_hdr(iwm, &hdr->sw_hdr, &umac_cmd);

	memcpy(buf + sizeof(*hdr), skb->data, skb->len);

	return umac_cmd.seq_num;
}

static int iwm_tx_send_concat_packets(struct iwm_priv *iwm,
				      struct iwm_tx_queue *txq)
{
	int ret;

	if (!txq->concat_count)
		return 0;

	IWM_DBG_TX(iwm, DBG, "Send concatenated Tx: queue %d, %d bytes\n",
		   txq->id, txq->concat_count);

	/* mark EOP for the last packet */
	iwm_udma_wifi_hdr_set_eop(iwm, txq->concat_ptr, 1);

	trace_iwm_tx_packets(iwm, txq->concat_buf, txq->concat_count);
	ret = iwm_bus_send_chunk(iwm, txq->concat_buf, txq->concat_count);

	txq->concat_count = 0;
	txq->concat_ptr = txq->concat_buf;

	return ret;
}

void iwm_tx_worker(struct work_struct *work)
{
	struct iwm_priv *iwm;
	struct iwm_tx_info *tx_info = NULL;
	struct sk_buff *skb;
	struct iwm_tx_queue *txq;
	struct iwm_sta_info *sta_info;
	struct iwm_tid_info *tid_info;
	int cmdlen, ret, pool_id;

	txq = container_of(work, struct iwm_tx_queue, worker);
	iwm = container_of(txq, struct iwm_priv, txq[txq->id]);

	pool_id = queue_to_pool_id(txq->id);

	while (!test_bit(pool_id, &iwm->tx_credit.full_pools_map) &&
	       !skb_queue_empty(&txq->queue)) {

		spin_lock_bh(&txq->lock);
		skb = skb_dequeue(&txq->queue);
		spin_unlock_bh(&txq->lock);

		tx_info = skb_to_tx_info(skb);
		sta_info = &iwm->sta_table[tx_info->sta];
		if (!sta_info->valid) {
			IWM_ERR(iwm, "Trying to send a frame to unknown STA\n");
			kfree_skb(skb);
			continue;
		}

		tid_info = &sta_info->tid_info[tx_info->tid];

		mutex_lock(&tid_info->mutex);

		/*
		 * If the RAxTID is stopped, we queue the skb to the stopped
		 * queue.
		 * Whenever we'll get a UMAC notification to resume the tx flow
		 * for this RAxTID, we'll merge back the stopped queue into the
		 * regular queue. See iwm_ntf_stop_resume_tx() from rx.c.
		 */
		if (tid_info->stopped) {
			IWM_DBG_TX(iwm, DBG, "%dx%d stopped\n",
				   tx_info->sta, tx_info->tid);
			spin_lock_bh(&txq->lock);
			skb_queue_tail(&txq->stopped_queue, skb);
			spin_unlock_bh(&txq->lock);

			mutex_unlock(&tid_info->mutex);
			continue;
		}

		cmdlen = IWM_UDMA_HDR_LEN + skb->len;

		IWM_DBG_TX(iwm, DBG, "Tx frame on queue %d: skb: 0x%p, sta: "
			   "%d, color: %d\n", txq->id, skb, tx_info->sta,
			   tx_info->color);

		if (txq->concat_count + cmdlen > IWM_HAL_CONCATENATE_BUF_SIZE)
			iwm_tx_send_concat_packets(iwm, txq);

		ret = iwm_tx_credit_alloc(iwm, pool_id, cmdlen);
		if (ret) {
			IWM_DBG_TX(iwm, DBG, "not enough tx_credit for queue "
				   "%d, Tx worker stopped\n", txq->id);
			spin_lock_bh(&txq->lock);
			skb_queue_head(&txq->queue, skb);
			spin_unlock_bh(&txq->lock);

			mutex_unlock(&tid_info->mutex);
			break;
		}

		txq->concat_ptr = txq->concat_buf + txq->concat_count;
		tid_info->last_seq_num =
			iwm_tx_build_packet(iwm, skb, pool_id, txq->concat_ptr);
		txq->concat_count += ALIGN(cmdlen, 16);

		mutex_unlock(&tid_info->mutex);

		kfree_skb(skb);
	}

	iwm_tx_send_concat_packets(iwm, txq);

	if (__netif_subqueue_stopped(iwm_to_ndev(iwm), txq->id) &&
	    !test_bit(pool_id, &iwm->tx_credit.full_pools_map) &&
	    (skb_queue_len(&txq->queue) < IWM_TX_LIST_SIZE / 2)) {
		IWM_DBG_TX(iwm, DBG, "LINK: start netif_subqueue[%d]", txq->id);
		netif_wake_subqueue(iwm_to_ndev(iwm), txq->id);
	}
}

int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
	struct iwm_priv *iwm = ndev_to_iwm(netdev);
	struct wireless_dev *wdev = iwm_to_wdev(iwm);
	struct iwm_tx_info *tx_info;
	struct iwm_tx_queue *txq;
	struct iwm_sta_info *sta_info;
	u8 *dst_addr, sta_id;
	u16 queue;
	int ret;


	if (!test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
		IWM_DBG_TX(iwm, DBG, "LINK: stop netif_all_queues: "
			   "not associated\n");
		netif_tx_stop_all_queues(netdev);
		goto drop;
	}

	queue = skb_get_queue_mapping(skb);
	BUG_ON(queue >= IWM_TX_DATA_QUEUES); /* no iPAN yet */

	txq = &iwm->txq[queue];

	/* No free space for Tx, tx_worker is too slow */
	if ((skb_queue_len(&txq->queue) > IWM_TX_LIST_SIZE) ||
	    (skb_queue_len(&txq->stopped_queue) > IWM_TX_LIST_SIZE)) {
		IWM_DBG_TX(iwm, DBG, "LINK: stop netif_subqueue[%d]\n", queue);
		netif_stop_subqueue(netdev, queue);
		return NETDEV_TX_BUSY;
	}

	ret = ieee80211_data_from_8023(skb, netdev->dev_addr, wdev->iftype,
				       iwm->bssid, 0);
	if (ret) {
		IWM_ERR(iwm, "build wifi header failed\n");
		goto drop;
	}

	dst_addr = ((struct ieee80211_hdr *)(skb->data))->addr1;

	for (sta_id = 0; sta_id < IWM_STA_TABLE_NUM; sta_id++) {
		sta_info = &iwm->sta_table[sta_id];
		if (sta_info->valid &&
		    !memcmp(dst_addr, sta_info->addr, ETH_ALEN))
			break;
	}

	if (sta_id == IWM_STA_TABLE_NUM) {
		IWM_ERR(iwm, "STA %pM not found in sta_table, Tx ignored\n",
			dst_addr);
		goto drop;
	}

	tx_info = skb_to_tx_info(skb);
	tx_info->sta = sta_id;
	tx_info->color = sta_info->color;
	/* UMAC uses TID 8 (vs. 0) for non QoS packets */
	if (sta_info->qos)
		tx_info->tid = skb->priority;
	else
		tx_info->tid = IWM_UMAC_MGMT_TID;

	spin_lock_bh(&iwm->txq[queue].lock);
	skb_queue_tail(&iwm->txq[queue].queue, skb);
	spin_unlock_bh(&iwm->txq[queue].lock);

	queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker);

	netdev->stats.tx_packets++;
	netdev->stats.tx_bytes += skb->len;
	return NETDEV_TX_OK;

 drop:
	netdev->stats.tx_dropped++;
	dev_kfree_skb_any(skb);
	return NETDEV_TX_OK;
}
