/*
 * Copyright (c) 2007-2011 Atheros Communications Inc.
 * Copyright (c) 2011-2012 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 "hif.h"

#include <linux/export.h>

#include "core.h"
#include "target.h"
#include "hif-ops.h"
#include "debug.h"
#include "trace.h"

#define MAILBOX_FOR_BLOCK_SIZE          1

#define ATH6KL_TIME_QUANTUM	10  /* in ms */

static int ath6kl_hif_cp_scat_dma_buf(struct hif_scatter_req *req,
				      bool from_dma)
{
	u8 *buf;
	int i;

	buf = req->virt_dma_buf;

	for (i = 0; i < req->scat_entries; i++) {

		if (from_dma)
			memcpy(req->scat_list[i].buf, buf,
			       req->scat_list[i].len);
		else
			memcpy(buf, req->scat_list[i].buf,
			       req->scat_list[i].len);

		buf += req->scat_list[i].len;
	}

	return 0;
}

int ath6kl_hif_rw_comp_handler(void *context, int status)
{
	struct htc_packet *packet = context;

	ath6kl_dbg(ATH6KL_DBG_HIF, "hif rw completion pkt 0x%p status %d\n",
		   packet, status);

	packet->status = status;
	packet->completion(packet->context, packet);

	return 0;
}
EXPORT_SYMBOL(ath6kl_hif_rw_comp_handler);

#define REG_DUMP_COUNT_AR6003   60
#define REGISTER_DUMP_LEN_MAX   60

static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar)
{
	__le32 regdump_val[REGISTER_DUMP_LEN_MAX];
	u32 i, address, regdump_addr = 0;
	int ret;

	if (ar->target_type != TARGET_TYPE_AR6003)
		return;

	/* the reg dump pointer is copied to the host interest area */
	address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state));
	address = TARG_VTOP(ar->target_type, address);

	/* read RAM location through diagnostic window */
	ret = ath6kl_diag_read32(ar, address, &regdump_addr);

	if (ret || !regdump_addr) {
		ath6kl_warn("failed to get ptr to register dump area: %d\n",
			    ret);
		return;
	}

	ath6kl_dbg(ATH6KL_DBG_IRQ, "register dump data address 0x%x\n",
		   regdump_addr);
	regdump_addr = TARG_VTOP(ar->target_type, regdump_addr);

	/* fetch register dump data */
	ret = ath6kl_diag_read(ar, regdump_addr, (u8 *)&regdump_val[0],
				  REG_DUMP_COUNT_AR6003 * (sizeof(u32)));
	if (ret) {
		ath6kl_warn("failed to get register dump: %d\n", ret);
		return;
	}

	ath6kl_info("crash dump:\n");
	ath6kl_info("hw 0x%x fw %s\n", ar->wiphy->hw_version,
		    ar->wiphy->fw_version);

	BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4);

	for (i = 0; i < REG_DUMP_COUNT_AR6003; i += 4) {
		ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
			    i,
			    le32_to_cpu(regdump_val[i]),
			    le32_to_cpu(regdump_val[i + 1]),
			    le32_to_cpu(regdump_val[i + 2]),
			    le32_to_cpu(regdump_val[i + 3]));
	}

}

static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev)
{
	u32 dummy;
	int ret;

	ath6kl_warn("firmware crashed\n");

	/*
	 * read counter to clear the interrupt, the debug error interrupt is
	 * counter 0.
	 */
	ret = hif_read_write_sync(dev->ar, COUNT_DEC_ADDRESS,
				     (u8 *)&dummy, 4, HIF_RD_SYNC_BYTE_INC);
	if (ret)
		ath6kl_warn("Failed to clear debug interrupt: %d\n", ret);

	ath6kl_hif_dump_fw_crash(dev->ar);
	ath6kl_read_fwlogs(dev->ar);
	ath6kl_recovery_err_notify(dev->ar, ATH6KL_FW_ASSERT);

	return ret;
}

/* mailbox recv message polling */
int ath6kl_hif_poll_mboxmsg_rx(struct ath6kl_device *dev, u32 *lk_ahd,
			      int timeout)
{
	struct ath6kl_irq_proc_registers *rg;
	int status = 0, i;
	u8 htc_mbox = 1 << HTC_MAILBOX;

	for (i = timeout / ATH6KL_TIME_QUANTUM; i > 0; i--) {
		/* this is the standard HIF way, load the reg table */
		status = hif_read_write_sync(dev->ar, HOST_INT_STATUS_ADDRESS,
					     (u8 *) &dev->irq_proc_reg,
					     sizeof(dev->irq_proc_reg),
					     HIF_RD_SYNC_BYTE_INC);

		if (status) {
			ath6kl_err("failed to read reg table\n");
			return status;
		}

		/* check for MBOX data and valid lookahead */
		if (dev->irq_proc_reg.host_int_status & htc_mbox) {
			if (dev->irq_proc_reg.rx_lkahd_valid &
			    htc_mbox) {
				/*
				 * Mailbox has a message and the look ahead
				 * is valid.
				 */
				rg = &dev->irq_proc_reg;
				*lk_ahd =
					le32_to_cpu(rg->rx_lkahd[HTC_MAILBOX]);
				break;
			}
		}

		/* delay a little  */
		mdelay(ATH6KL_TIME_QUANTUM);
		ath6kl_dbg(ATH6KL_DBG_HIF, "hif retry mbox poll try %d\n", i);
	}

	if (i == 0) {
		ath6kl_err("timeout waiting for recv message\n");
		status = -ETIME;
		/* check if the target asserted */
		if (dev->irq_proc_reg.counter_int_status &
		    ATH6KL_TARGET_DEBUG_INTR_MASK)
			/*
			 * Target failure handler will be called in case of
			 * an assert.
			 */
			ath6kl_hif_proc_dbg_intr(dev);
	}

	return status;
}

/*
 * Disable packet reception (used in case the host runs out of buffers)
 * using the interrupt enable registers through the host I/F
 */
int ath6kl_hif_rx_control(struct ath6kl_device *dev, bool enable_rx)
{
	struct ath6kl_irq_enable_reg regs;
	int status = 0;

	ath6kl_dbg(ATH6KL_DBG_HIF, "hif rx %s\n",
		   enable_rx ? "enable" : "disable");

	/* take the lock to protect interrupt enable shadows */
	spin_lock_bh(&dev->lock);

	if (enable_rx)
		dev->irq_en_reg.int_status_en |=
			SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
	else
		dev->irq_en_reg.int_status_en &=
		    ~SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);

	memcpy(&regs, &dev->irq_en_reg, sizeof(regs));

	spin_unlock_bh(&dev->lock);

	status = hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
				     &regs.int_status_en,
				     sizeof(struct ath6kl_irq_enable_reg),
				     HIF_WR_SYNC_BYTE_INC);

	return status;
}

int ath6kl_hif_submit_scat_req(struct ath6kl_device *dev,
			      struct hif_scatter_req *scat_req, bool read)
{
	int status = 0;

	if (read) {
		scat_req->req = HIF_RD_SYNC_BLOCK_FIX;
		scat_req->addr = dev->ar->mbox_info.htc_addr;
	} else {
		scat_req->req = HIF_WR_ASYNC_BLOCK_INC;

		scat_req->addr =
			(scat_req->len > HIF_MBOX_WIDTH) ?
			dev->ar->mbox_info.htc_ext_addr :
			dev->ar->mbox_info.htc_addr;
	}

	ath6kl_dbg(ATH6KL_DBG_HIF,
		   "hif submit scatter request entries %d len %d mbox 0x%x %s %s\n",
		   scat_req->scat_entries, scat_req->len,
		   scat_req->addr, !read ? "async" : "sync",
		   (read) ? "rd" : "wr");

	if (!read && scat_req->virt_scat) {
		status = ath6kl_hif_cp_scat_dma_buf(scat_req, false);
		if (status) {
			scat_req->status = status;
			scat_req->complete(dev->ar->htc_target, scat_req);
			return 0;
		}
	}

	status = ath6kl_hif_scat_req_rw(dev->ar, scat_req);

	if (read) {
		/* in sync mode, we can touch the scatter request */
		scat_req->status = status;
		if (!status && scat_req->virt_scat)
			scat_req->status =
				ath6kl_hif_cp_scat_dma_buf(scat_req, true);
	}

	return status;
}

static int ath6kl_hif_proc_counter_intr(struct ath6kl_device *dev)
{
	u8 counter_int_status;

	ath6kl_dbg(ATH6KL_DBG_IRQ, "counter interrupt\n");

	counter_int_status = dev->irq_proc_reg.counter_int_status &
			     dev->irq_en_reg.cntr_int_status_en;

	ath6kl_dbg(ATH6KL_DBG_IRQ,
		   "valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
		counter_int_status);

	/*
	 * NOTE: other modules like GMBOX may use the counter interrupt for
	 * credit flow control on other counters, we only need to check for
	 * the debug assertion counter interrupt.
	 */
	if (counter_int_status & ATH6KL_TARGET_DEBUG_INTR_MASK)
		return ath6kl_hif_proc_dbg_intr(dev);

	return 0;
}

static int ath6kl_hif_proc_err_intr(struct ath6kl_device *dev)
{
	int status;
	u8 error_int_status;
	u8 reg_buf[4];

	ath6kl_dbg(ATH6KL_DBG_IRQ, "error interrupt\n");

	error_int_status = dev->irq_proc_reg.error_int_status & 0x0F;
	if (!error_int_status) {
		WARN_ON(1);
		return -EIO;
	}

	ath6kl_dbg(ATH6KL_DBG_IRQ,
		   "valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
		   error_int_status);

	if (MS(ERROR_INT_STATUS_WAKEUP, error_int_status))
		ath6kl_dbg(ATH6KL_DBG_IRQ, "error : wakeup\n");

	if (MS(ERROR_INT_STATUS_RX_UNDERFLOW, error_int_status))
		ath6kl_err("rx underflow\n");

	if (MS(ERROR_INT_STATUS_TX_OVERFLOW, error_int_status))
		ath6kl_err("tx overflow\n");

	/* Clear the interrupt */
	dev->irq_proc_reg.error_int_status &= ~error_int_status;

	/* set W1C value to clear the interrupt, this hits the register first */
	reg_buf[0] = error_int_status;
	reg_buf[1] = 0;
	reg_buf[2] = 0;
	reg_buf[3] = 0;

	status = hif_read_write_sync(dev->ar, ERROR_INT_STATUS_ADDRESS,
				     reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);

	WARN_ON(status);

	return status;
}

static int ath6kl_hif_proc_cpu_intr(struct ath6kl_device *dev)
{
	int status;
	u8 cpu_int_status;
	u8 reg_buf[4];

	ath6kl_dbg(ATH6KL_DBG_IRQ, "cpu interrupt\n");

	cpu_int_status = dev->irq_proc_reg.cpu_int_status &
			 dev->irq_en_reg.cpu_int_status_en;
	if (!cpu_int_status) {
		WARN_ON(1);
		return -EIO;
	}

	ath6kl_dbg(ATH6KL_DBG_IRQ,
		   "valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
		cpu_int_status);

	/* Clear the interrupt */
	dev->irq_proc_reg.cpu_int_status &= ~cpu_int_status;

	/*
	 * Set up the register transfer buffer to hit the register 4 times ,
	 * this is done to make the access 4-byte aligned to mitigate issues
	 * with host bus interconnects that restrict bus transfer lengths to
	 * be a multiple of 4-bytes.
	 */

	/* set W1C value to clear the interrupt, this hits the register first */
	reg_buf[0] = cpu_int_status;
	/* the remaining are set to zero which have no-effect  */
	reg_buf[1] = 0;
	reg_buf[2] = 0;
	reg_buf[3] = 0;

	status = hif_read_write_sync(dev->ar, CPU_INT_STATUS_ADDRESS,
				     reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);

	WARN_ON(status);

	return status;
}

/* process pending interrupts synchronously */
static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
{
	struct ath6kl_irq_proc_registers *rg;
	int status = 0;
	u8 host_int_status = 0;
	u32 lk_ahd = 0;
	u8 htc_mbox = 1 << HTC_MAILBOX;

	ath6kl_dbg(ATH6KL_DBG_IRQ, "proc_pending_irqs: (dev: 0x%p)\n", dev);

	/*
	 * NOTE: HIF implementation guarantees that the context of this
	 * call allows us to perform SYNCHRONOUS I/O, that is we can block,
	 * sleep or call any API that can block or switch thread/task
	 * contexts. This is a fully schedulable context.
	 */

	/*
	 * Process pending intr only when int_status_en is clear, it may
	 * result in unnecessary bus transaction otherwise. Target may be
	 * unresponsive at the time.
	 */
	if (dev->irq_en_reg.int_status_en) {
		/*
		 * Read the first 28 bytes of the HTC register table. This
		 * will yield us the value of different int status
		 * registers and the lookahead registers.
		 *
		 *    length = sizeof(int_status) + sizeof(cpu_int_status)
		 *             + sizeof(error_int_status) +
		 *             sizeof(counter_int_status) +
		 *             sizeof(mbox_frame) + sizeof(rx_lkahd_valid)
		 *             + sizeof(hole) + sizeof(rx_lkahd) +
		 *             sizeof(int_status_en) +
		 *             sizeof(cpu_int_status_en) +
		 *             sizeof(err_int_status_en) +
		 *             sizeof(cntr_int_status_en);
		 */
		status = hif_read_write_sync(dev->ar, HOST_INT_STATUS_ADDRESS,
					     (u8 *) &dev->irq_proc_reg,
					     sizeof(dev->irq_proc_reg),
					     HIF_RD_SYNC_BYTE_INC);
		if (status)
			goto out;

		ath6kl_dump_registers(dev, &dev->irq_proc_reg,
				      &dev->irq_en_reg);
		trace_ath6kl_sdio_irq(&dev->irq_en_reg,
				      sizeof(dev->irq_en_reg));

		/* Update only those registers that are enabled */
		host_int_status = dev->irq_proc_reg.host_int_status &
				  dev->irq_en_reg.int_status_en;

		/* Look at mbox status */
		if (host_int_status & htc_mbox) {
			/*
			 * Mask out pending mbox value, we use "lookAhead as
			 * the real flag for mbox processing.
			 */
			host_int_status &= ~htc_mbox;
			if (dev->irq_proc_reg.rx_lkahd_valid &
			    htc_mbox) {
				rg = &dev->irq_proc_reg;
				lk_ahd = le32_to_cpu(rg->rx_lkahd[HTC_MAILBOX]);
				if (!lk_ahd)
					ath6kl_err("lookAhead is zero!\n");
			}
		}
	}

	if (!host_int_status && !lk_ahd) {
		*done = true;
		goto out;
	}

	if (lk_ahd) {
		int fetched = 0;

		ath6kl_dbg(ATH6KL_DBG_IRQ,
			   "pending mailbox msg, lk_ahd: 0x%X\n", lk_ahd);
		/*
		 * Mailbox Interrupt, the HTC layer may issue async
		 * requests to empty the mailbox. When emptying the recv
		 * mailbox we use the async handler above called from the
		 * completion routine of the callers read request. This can
		 * improve performance by reducing context switching when
		 * we rapidly pull packets.
		 */
		status = ath6kl_htc_rxmsg_pending_handler(dev->htc_cnxt,
							  lk_ahd, &fetched);
		if (status)
			goto out;

		if (!fetched)
			/*
			 * HTC could not pull any messages out due to lack
			 * of resources.
			 */
			dev->htc_cnxt->chk_irq_status_cnt = 0;
	}

	/* now handle the rest of them */
	ath6kl_dbg(ATH6KL_DBG_IRQ,
		   "valid interrupt source(s) for other interrupts: 0x%x\n",
		   host_int_status);

	if (MS(HOST_INT_STATUS_CPU, host_int_status)) {
		/* CPU Interrupt */
		status = ath6kl_hif_proc_cpu_intr(dev);
		if (status)
			goto out;
	}

	if (MS(HOST_INT_STATUS_ERROR, host_int_status)) {
		/* Error Interrupt */
		status = ath6kl_hif_proc_err_intr(dev);
		if (status)
			goto out;
	}

	if (MS(HOST_INT_STATUS_COUNTER, host_int_status))
		/* Counter Interrupt */
		status = ath6kl_hif_proc_counter_intr(dev);

out:
	/*
	 * An optimization to bypass reading the IRQ status registers
	 * unecessarily which can re-wake the target, if upper layers
	 * determine that we are in a low-throughput mode, we can rely on
	 * taking another interrupt rather than re-checking the status
	 * registers which can re-wake the target.
	 *
	 * NOTE : for host interfaces that makes use of detecting pending
	 * mbox messages at hif can not use this optimization due to
	 * possible side effects, SPI requires the host to drain all
	 * messages from the mailbox before exiting the ISR routine.
	 */

	ath6kl_dbg(ATH6KL_DBG_IRQ,
		   "bypassing irq status re-check, forcing done\n");

	if (!dev->htc_cnxt->chk_irq_status_cnt)
		*done = true;

	ath6kl_dbg(ATH6KL_DBG_IRQ,
		   "proc_pending_irqs: (done:%d, status=%d\n", *done, status);

	return status;
}

/* interrupt handler, kicks off all interrupt processing */
int ath6kl_hif_intr_bh_handler(struct ath6kl *ar)
{
	struct ath6kl_device *dev = ar->htc_target->dev;
	unsigned long timeout;
	int status = 0;
	bool done = false;

	/*
	 * Reset counter used to flag a re-scan of IRQ status registers on
	 * the target.
	 */
	dev->htc_cnxt->chk_irq_status_cnt = 0;

	/*
	 * IRQ processing is synchronous, interrupt status registers can be
	 * re-read.
	 */
	timeout = jiffies + msecs_to_jiffies(ATH6KL_HIF_COMMUNICATION_TIMEOUT);
	while (time_before(jiffies, timeout) && !done) {
		status = proc_pending_irqs(dev, &done);
		if (status)
			break;
	}

	return status;
}
EXPORT_SYMBOL(ath6kl_hif_intr_bh_handler);

static int ath6kl_hif_enable_intrs(struct ath6kl_device *dev)
{
	struct ath6kl_irq_enable_reg regs;
	int status;

	spin_lock_bh(&dev->lock);

	/* Enable all but ATH6KL CPU interrupts */
	dev->irq_en_reg.int_status_en =
			SM(INT_STATUS_ENABLE_ERROR, 0x01) |
			SM(INT_STATUS_ENABLE_CPU, 0x01) |
			SM(INT_STATUS_ENABLE_COUNTER, 0x01);

	/*
	 * NOTE: There are some cases where HIF can do detection of
	 * pending mbox messages which is disabled now.
	 */
	dev->irq_en_reg.int_status_en |= SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);

	/* Set up the CPU Interrupt status Register */
	dev->irq_en_reg.cpu_int_status_en = 0;

	/* Set up the Error Interrupt status Register */
	dev->irq_en_reg.err_int_status_en =
		SM(ERROR_STATUS_ENABLE_RX_UNDERFLOW, 0x01) |
		SM(ERROR_STATUS_ENABLE_TX_OVERFLOW, 0x1);

	/*
	 * Enable Counter interrupt status register to get fatal errors for
	 * debugging.
	 */
	dev->irq_en_reg.cntr_int_status_en = SM(COUNTER_INT_STATUS_ENABLE_BIT,
						ATH6KL_TARGET_DEBUG_INTR_MASK);
	memcpy(&regs, &dev->irq_en_reg, sizeof(regs));

	spin_unlock_bh(&dev->lock);

	status = hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
				     &regs.int_status_en, sizeof(regs),
				     HIF_WR_SYNC_BYTE_INC);

	if (status)
		ath6kl_err("failed to update interrupt ctl reg err: %d\n",
			   status);

	return status;
}

int ath6kl_hif_disable_intrs(struct ath6kl_device *dev)
{
	struct ath6kl_irq_enable_reg regs;

	spin_lock_bh(&dev->lock);
	/* Disable all interrupts */
	dev->irq_en_reg.int_status_en = 0;
	dev->irq_en_reg.cpu_int_status_en = 0;
	dev->irq_en_reg.err_int_status_en = 0;
	dev->irq_en_reg.cntr_int_status_en = 0;
	memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
	spin_unlock_bh(&dev->lock);

	return hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
				   &regs.int_status_en, sizeof(regs),
				   HIF_WR_SYNC_BYTE_INC);
}

/* enable device interrupts */
int ath6kl_hif_unmask_intrs(struct ath6kl_device *dev)
{
	int status = 0;

	/*
	 * Make sure interrupt are disabled before unmasking at the HIF
	 * layer. The rationale here is that between device insertion
	 * (where we clear the interrupts the first time) and when HTC
	 * is finally ready to handle interrupts, other software can perform
	 * target "soft" resets. The ATH6KL interrupt enables reset back to an
	 * "enabled" state when this happens.
	 */
	ath6kl_hif_disable_intrs(dev);

	/* unmask the host controller interrupts */
	ath6kl_hif_irq_enable(dev->ar);
	status = ath6kl_hif_enable_intrs(dev);

	return status;
}

/* disable all device interrupts */
int ath6kl_hif_mask_intrs(struct ath6kl_device *dev)
{
	/*
	 * Mask the interrupt at the HIF layer to avoid any stray interrupt
	 * taken while we zero out our shadow registers in
	 * ath6kl_hif_disable_intrs().
	 */
	ath6kl_hif_irq_disable(dev->ar);

	return ath6kl_hif_disable_intrs(dev);
}

int ath6kl_hif_setup(struct ath6kl_device *dev)
{
	int status = 0;

	spin_lock_init(&dev->lock);

	/*
	 * NOTE: we actually get the block size of a mailbox other than 0,
	 * for SDIO the block size on mailbox 0 is artificially set to 1.
	 * So we use the block size that is set for the other 3 mailboxes.
	 */
	dev->htc_cnxt->block_sz = dev->ar->mbox_info.block_size;

	/* must be a power of 2 */
	if ((dev->htc_cnxt->block_sz & (dev->htc_cnxt->block_sz - 1)) != 0) {
		WARN_ON(1);
		status = -EINVAL;
		goto fail_setup;
	}

	/* assemble mask, used for padding to a block */
	dev->htc_cnxt->block_mask = dev->htc_cnxt->block_sz - 1;

	ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n",
		   dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr);

	status = ath6kl_hif_disable_intrs(dev);

fail_setup:
	return status;

}
