/**
 * Copyright (c) 2014 Redpine Signals 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 <linux/firmware.h>
#include <net/rsi_91x.h>
#include "rsi_sdio.h"
#include "rsi_common.h"

/**
 * rsi_sdio_master_access_msword() - This function sets the AHB master access
 *				     MS word in the SDIO slave registers.
 * @adapter: Pointer to the adapter structure.
 * @ms_word: ms word need to be initialized.
 *
 * Return: status: 0 on success, -1 on failure.
 */
int rsi_sdio_master_access_msword(struct rsi_hw *adapter, u16 ms_word)
{
	u8 byte;
	u8 function = 0;
	int status = 0;

	byte = (u8)(ms_word & 0x00FF);

	rsi_dbg(INIT_ZONE,
		"%s: MASTER_ACCESS_MSBYTE:0x%x\n", __func__, byte);

	status = rsi_sdio_write_register(adapter,
					 function,
					 SDIO_MASTER_ACCESS_MSBYTE,
					 &byte);
	if (status) {
		rsi_dbg(ERR_ZONE,
			"%s: fail to access MASTER_ACCESS_MSBYTE\n",
			__func__);
		return -1;
	}

	byte = (u8)(ms_word >> 8);

	rsi_dbg(INIT_ZONE, "%s:MASTER_ACCESS_LSBYTE:0x%x\n", __func__, byte);
	status = rsi_sdio_write_register(adapter,
					 function,
					 SDIO_MASTER_ACCESS_LSBYTE,
					 &byte);
	return status;
}

void rsi_sdio_rx_thread(struct rsi_common *common)
{
	struct rsi_hw *adapter = common->priv;
	struct rsi_91x_sdiodev *sdev = adapter->rsi_dev;
	struct sk_buff *skb;
	int status;

	do {
		rsi_wait_event(&sdev->rx_thread.event, EVENT_WAIT_FOREVER);
		rsi_reset_event(&sdev->rx_thread.event);

		while (true) {
			if (atomic_read(&sdev->rx_thread.thread_done))
				goto out;

			skb = skb_dequeue(&sdev->rx_q.head);
			if (!skb)
				break;
			if (sdev->rx_q.num_rx_pkts > 0)
				sdev->rx_q.num_rx_pkts--;
			status = rsi_read_pkt(common, skb->data, skb->len);
			if (status) {
				rsi_dbg(ERR_ZONE, "Failed to read the packet\n");
				dev_kfree_skb(skb);
				break;
			}
			dev_kfree_skb(skb);
		}
	} while (1);

out:
	rsi_dbg(INFO_ZONE, "%s: Terminated SDIO RX thread\n", __func__);
	skb_queue_purge(&sdev->rx_q.head);
	atomic_inc(&sdev->rx_thread.thread_done);
	complete_and_exit(&sdev->rx_thread.completion, 0);
}

/**
 * rsi_process_pkt() - This Function reads rx_blocks register and figures out
 *		       the size of the rx pkt.
 * @common: Pointer to the driver private structure.
 *
 * Return: 0 on success, -1 on failure.
 */
static int rsi_process_pkt(struct rsi_common *common)
{
	struct rsi_hw *adapter = common->priv;
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	u8 num_blks = 0;
	u32 rcv_pkt_len = 0;
	int status = 0;
	u8 value = 0;
	struct sk_buff *skb;

	if (dev->rx_q.num_rx_pkts >= RSI_MAX_RX_PKTS)
		return 0;

	num_blks = ((adapter->interrupt_status & 1) |
			((adapter->interrupt_status >> RECV_NUM_BLOCKS) << 1));

	if (!num_blks) {
		status = rsi_sdio_read_register(adapter,
						SDIO_RX_NUM_BLOCKS_REG,
						&value);
		if (status) {
			rsi_dbg(ERR_ZONE,
				"%s: Failed to read pkt length from the card:\n",
				__func__);
			return status;
		}
		num_blks = value & 0x1f;
	}

	if (dev->write_fail == 2)
		rsi_sdio_ack_intr(common->priv, (1 << MSDU_PKT_PENDING));

	if (unlikely(!num_blks)) {
		dev->write_fail = 2;
		return -1;
	}

	rcv_pkt_len = (num_blks * 256);

	skb = dev_alloc_skb(rcv_pkt_len);
	if (!skb)
		return -ENOMEM;

	status = rsi_sdio_host_intf_read_pkt(adapter, skb->data, rcv_pkt_len);
	if (status) {
		rsi_dbg(ERR_ZONE, "%s: Failed to read packet from card\n",
			__func__);
		dev_kfree_skb(skb);
		return status;
	}
	skb_put(skb, rcv_pkt_len);
	skb_queue_tail(&dev->rx_q.head, skb);
	dev->rx_q.num_rx_pkts++;

	rsi_set_event(&dev->rx_thread.event);

	return 0;
}

/**
 * rsi_init_sdio_slave_regs() - This function does the actual initialization
 *				of SDBUS slave registers.
 * @adapter: Pointer to the adapter structure.
 *
 * Return: status: 0 on success, -1 on failure.
 */
int rsi_init_sdio_slave_regs(struct rsi_hw *adapter)
{
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	u8 function = 0;
	u8 byte;
	int status = 0;

	if (dev->next_read_delay) {
		byte = dev->next_read_delay;
		status = rsi_sdio_write_register(adapter,
						 function,
						 SDIO_NXT_RD_DELAY2,
						 &byte);
		if (status) {
			rsi_dbg(ERR_ZONE,
				"%s: Failed to write SDIO_NXT_RD_DELAY2\n",
				__func__);
			return -1;
		}
	}

	if (dev->sdio_high_speed_enable) {
		rsi_dbg(INIT_ZONE, "%s: Enabling SDIO High speed\n", __func__);
		byte = 0x3;

		status = rsi_sdio_write_register(adapter,
						 function,
						 SDIO_REG_HIGH_SPEED,
						 &byte);
		if (status) {
			rsi_dbg(ERR_ZONE,
				"%s: Failed to enable SDIO high speed\n",
				__func__);
			return -1;
		}
	}

	/* This tells SDIO FIFO when to start read to host */
	rsi_dbg(INIT_ZONE, "%s: Initialzing SDIO read start level\n", __func__);
	byte = 0x24;

	status = rsi_sdio_write_register(adapter,
					 function,
					 SDIO_READ_START_LVL,
					 &byte);
	if (status) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to write SDIO_READ_START_LVL\n", __func__);
		return -1;
	}

	rsi_dbg(INIT_ZONE, "%s: Initialzing FIFO ctrl registers\n", __func__);
	byte = (128 - 32);

	status = rsi_sdio_write_register(adapter,
					 function,
					 SDIO_READ_FIFO_CTL,
					 &byte);
	if (status) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to write SDIO_READ_FIFO_CTL\n", __func__);
		return -1;
	}

	byte = 32;
	status = rsi_sdio_write_register(adapter,
					 function,
					 SDIO_WRITE_FIFO_CTL,
					 &byte);
	if (status) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to write SDIO_WRITE_FIFO_CTL\n", __func__);
		return -1;
	}

	return 0;
}

/**
 * rsi_interrupt_handler() - This function read and process SDIO interrupts.
 * @adapter: Pointer to the adapter structure.
 *
 * Return: None.
 */
void rsi_interrupt_handler(struct rsi_hw *adapter)
{
	struct rsi_common *common = adapter->priv;
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	int status;
	enum sdio_interrupt_type isr_type;
	u8 isr_status = 0;
	u8 fw_status = 0;

	dev->rx_info.sdio_int_counter++;

	do {
		mutex_lock(&common->rx_lock);
		status = rsi_sdio_read_register(common->priv,
						RSI_FN1_INT_REGISTER,
						&isr_status);
		if (status) {
			rsi_dbg(ERR_ZONE,
				"%s: Failed to Read Intr Status Register\n",
				__func__);
			mutex_unlock(&common->rx_lock);
			return;
		}
		adapter->interrupt_status = isr_status;

		if (isr_status == 0) {
			rsi_set_event(&common->tx_thread.event);
			dev->rx_info.sdio_intr_status_zero++;
			mutex_unlock(&common->rx_lock);
			return;
		}

		rsi_dbg(ISR_ZONE, "%s: Intr_status = %x %d %d\n",
			__func__, isr_status, (1 << MSDU_PKT_PENDING),
			(1 << FW_ASSERT_IND));

		do {
			RSI_GET_SDIO_INTERRUPT_TYPE(isr_status, isr_type);

			switch (isr_type) {
			case BUFFER_AVAILABLE:
				status = rsi_sdio_check_buffer_status(adapter,
								      0);
				if (status < 0)
					rsi_dbg(ERR_ZONE,
						"%s: Failed to check buffer status\n",
						__func__);
				rsi_sdio_ack_intr(common->priv,
						  (1 << PKT_BUFF_AVAILABLE));
				rsi_set_event(&common->tx_thread.event);

				rsi_dbg(ISR_ZONE,
					"%s: ==> BUFFER_AVAILABLE <==\n",
					__func__);
				dev->buff_status_updated = true;
				break;

			case FIRMWARE_ASSERT_IND:
				rsi_dbg(ERR_ZONE,
					"%s: ==> FIRMWARE Assert <==\n",
					__func__);
				status = rsi_sdio_read_register(common->priv,
							SDIO_FW_STATUS_REG,
							&fw_status);
				if (status) {
					rsi_dbg(ERR_ZONE,
						"%s: Failed to read f/w reg\n",
						__func__);
				} else {
					rsi_dbg(ERR_ZONE,
						"%s: Firmware Status is 0x%x\n",
						__func__ , fw_status);
					rsi_sdio_ack_intr(common->priv,
							  (1 << FW_ASSERT_IND));
				}

				common->fsm_state = FSM_CARD_NOT_READY;
				break;

			case MSDU_PACKET_PENDING:
				rsi_dbg(ISR_ZONE, "Pkt pending interrupt\n");
				dev->rx_info.total_sdio_msdu_pending_intr++;

				status = rsi_process_pkt(common);
				if (status) {
					rsi_dbg(ERR_ZONE,
						"%s: Failed to read pkt\n",
						__func__);
					mutex_unlock(&common->rx_lock);
					return;
				}
				break;
			default:
				rsi_sdio_ack_intr(common->priv, isr_status);
				dev->rx_info.total_sdio_unknown_intr++;
				isr_status = 0;
				rsi_dbg(ISR_ZONE,
					"Unknown Interrupt %x\n",
					isr_status);
				break;
			}
			isr_status ^= BIT(isr_type - 1);
		} while (isr_status);
		mutex_unlock(&common->rx_lock);
	} while (1);
}

/* This function is used to read buffer status register and
 * set relevant fields in rsi_91x_sdiodev struct.
 */
int rsi_sdio_check_buffer_status(struct rsi_hw *adapter, u8 q_num)
{
	struct rsi_common *common = adapter->priv;
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	u8 buf_status = 0;
	int status = 0;
	static int counter = 4;

	if (!dev->buff_status_updated && counter) {
		counter--;
		goto out;
	}

	dev->buff_status_updated = false;
	status = rsi_sdio_read_register(common->priv,
					RSI_DEVICE_BUFFER_STATUS_REGISTER,
					&buf_status);

	if (status) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to read status register\n", __func__);
		return -1;
	}

	if (buf_status & (BIT(PKT_MGMT_BUFF_FULL))) {
		if (!dev->rx_info.mgmt_buffer_full)
			dev->rx_info.mgmt_buf_full_counter++;
		dev->rx_info.mgmt_buffer_full = true;
	} else {
		dev->rx_info.mgmt_buffer_full = false;
	}

	if (buf_status & (BIT(PKT_BUFF_FULL))) {
		if (!dev->rx_info.buffer_full)
			dev->rx_info.buf_full_counter++;
		dev->rx_info.buffer_full = true;
	} else {
		dev->rx_info.buffer_full = false;
	}

	if (buf_status & (BIT(PKT_BUFF_SEMI_FULL))) {
		if (!dev->rx_info.semi_buffer_full)
			dev->rx_info.buf_semi_full_counter++;
		dev->rx_info.semi_buffer_full = true;
	} else {
		dev->rx_info.semi_buffer_full = false;
	}

	if (dev->rx_info.mgmt_buffer_full || dev->rx_info.buf_full_counter)
		counter = 1;
	else
		counter = 4;

out:
	if ((q_num == MGMT_SOFT_Q) && (dev->rx_info.mgmt_buffer_full))
		return QUEUE_FULL;

	if ((q_num < MGMT_SOFT_Q) && (dev->rx_info.buffer_full))
		return QUEUE_FULL;

	return QUEUE_NOT_FULL;
}

/**
 * rsi_sdio_determine_event_timeout() - This Function determines the event
 *					timeout duration.
 * @adapter: Pointer to the adapter structure.
 *
 * Return: timeout duration is returned.
 */
int rsi_sdio_determine_event_timeout(struct rsi_hw *adapter)
{
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;

	/* Once buffer full is seen, event timeout to occur every 2 msecs */
	if (dev->rx_info.buffer_full)
		return 2;

	return EVENT_WAIT_FOREVER;
}
