/*
 * Marvell Wireless LAN device driver: PCIE specific handling
 *
 * Copyright (C) 2011, Marvell International Ltd.
 *
 * This software file (the "File") is distributed by Marvell International
 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
 * (the "License").  You may use, redistribute and/or modify this File in
 * accordance with the terms and conditions of the License, a copy of which
 * is available by writing to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
 *
 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
 * this warranty disclaimer.
 */

#include <linux/firmware.h>

#include "decl.h"
#include "ioctl.h"
#include "util.h"
#include "fw.h"
#include "main.h"
#include "wmm.h"
#include "11n.h"
#include "pcie.h"

#define PCIE_VERSION	"1.0"
#define DRV_NAME        "Marvell mwifiex PCIe"

static u8 user_rmmod;

static struct mwifiex_if_ops pcie_ops;

static struct semaphore add_remove_card_sem;
static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter);
static int mwifiex_pcie_resume(struct pci_dev *pdev);

/*
 * This function is called after skb allocation to update
 * "skb->cb" with physical address of data pointer.
 */
static phys_addr_t *mwifiex_update_sk_buff_pa(struct sk_buff *skb)
{
	phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb);

	*buf_pa = (phys_addr_t)virt_to_phys(skb->data);

	return buf_pa;
}

/*
 * This function reads sleep cookie and checks if FW is ready
 */
static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
{
	u32 *cookie_addr;
	struct pcie_service_card *card = adapter->card;

	if (card->sleep_cookie) {
		cookie_addr = (u32 *)card->sleep_cookie->data;
		dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n",
			*cookie_addr);
		if (*cookie_addr == FW_AWAKE_COOKIE)
			return true;
	}

	return false;
}

/*
 * This function probes an mwifiex device and registers it. It allocates
 * the card structure, enables PCIE function number and initiates the
 * device registration and initialization procedure by adding a logical
 * interface.
 */
static int mwifiex_pcie_probe(struct pci_dev *pdev,
					const struct pci_device_id *ent)
{
	struct pcie_service_card *card;

	pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
		 pdev->vendor, pdev->device, pdev->revision);

	card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
	if (!card)
		return -ENOMEM;

	card->dev = pdev;

	if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
			     MWIFIEX_PCIE)) {
		pr_err("%s failed\n", __func__);
		kfree(card);
		return -1;
	}

	return 0;
}

/*
 * This function removes the interface and frees up the card structure.
 */
static void mwifiex_pcie_remove(struct pci_dev *pdev)
{
	struct pcie_service_card *card;
	struct mwifiex_adapter *adapter;
	struct mwifiex_private *priv;
	int i;

	card = pci_get_drvdata(pdev);
	if (!card)
		return;

	adapter = card->adapter;
	if (!adapter || !adapter->priv_num)
		return;

	/* In case driver is removed when asynchronous FW load is in progress */
	wait_for_completion(&adapter->fw_load);

	if (user_rmmod) {
#ifdef CONFIG_PM
		if (adapter->is_suspended)
			mwifiex_pcie_resume(pdev);
#endif

		for (i = 0; i < adapter->priv_num; i++)
			if ((GET_BSS_ROLE(adapter->priv[i]) ==
			     MWIFIEX_BSS_ROLE_STA) &&
			    adapter->priv[i]->media_connected)
				mwifiex_deauthenticate(adapter->priv[i], NULL);

		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);

		mwifiex_disable_auto_ds(priv);

		mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
	}

	mwifiex_remove_card(card->adapter, &add_remove_card_sem);
	kfree(card);
}

/*
 * Kernel needs to suspend all functions separately. Therefore all
 * registered functions must have drivers with suspend and resume
 * methods. Failing that the kernel simply removes the whole card.
 *
 * If already not suspended, this function allocates and sends a host
 * sleep activate request to the firmware and turns off the traffic.
 */
static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct mwifiex_adapter *adapter;
	struct pcie_service_card *card;
	int hs_actived, i;

	if (pdev) {
		card = (struct pcie_service_card *) pci_get_drvdata(pdev);
		if (!card || !card->adapter) {
			pr_err("Card or adapter structure is not valid\n");
			return 0;
		}
	} else {
		pr_err("PCIE device is not specified\n");
		return 0;
	}

	adapter = card->adapter;

	hs_actived = mwifiex_enable_hs(adapter);

	/* Indicate device suspended */
	adapter->is_suspended = true;

	for (i = 0; i < adapter->priv_num; i++)
		netif_carrier_off(adapter->priv[i]->netdev);

	return 0;
}

/*
 * Kernel needs to suspend all functions separately. Therefore all
 * registered functions must have drivers with suspend and resume
 * methods. Failing that the kernel simply removes the whole card.
 *
 * If already not resumed, this function turns on the traffic and
 * sends a host sleep cancel request to the firmware.
 */
static int mwifiex_pcie_resume(struct pci_dev *pdev)
{
	struct mwifiex_adapter *adapter;
	struct pcie_service_card *card;
	int i;

	if (pdev) {
		card = (struct pcie_service_card *) pci_get_drvdata(pdev);
		if (!card || !card->adapter) {
			pr_err("Card or adapter structure is not valid\n");
			return 0;
		}
	} else {
		pr_err("PCIE device is not specified\n");
		return 0;
	}

	adapter = card->adapter;

	if (!adapter->is_suspended) {
		dev_warn(adapter->dev, "Device already resumed\n");
		return 0;
	}

	adapter->is_suspended = false;

	for (i = 0; i < adapter->priv_num; i++)
		if (adapter->priv[i]->media_connected)
			netif_carrier_on(adapter->priv[i]->netdev);

	mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
			  MWIFIEX_ASYNC_CMD);

	return 0;
}

#define PCIE_VENDOR_ID_MARVELL              (0x11ab)
#define PCIE_DEVICE_ID_MARVELL_88W8766P		(0x2b30)

static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
	{
		PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
	},
	{},
};

MODULE_DEVICE_TABLE(pci, mwifiex_ids);

/* PCI Device Driver */
static struct pci_driver __refdata mwifiex_pcie = {
	.name     = "mwifiex_pcie",
	.id_table = mwifiex_ids,
	.probe    = mwifiex_pcie_probe,
	.remove   = mwifiex_pcie_remove,
#ifdef CONFIG_PM
	/* Power Management Hooks */
	.suspend  = mwifiex_pcie_suspend,
	.resume   = mwifiex_pcie_resume,
#endif
};

/*
 * This function writes data into PCIE card register.
 */
static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
{
	struct pcie_service_card *card = adapter->card;

	iowrite32(data, card->pci_mmap1 + reg);

	return 0;
}

/*
 * This function reads data from PCIE card register.
 */
static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
{
	struct pcie_service_card *card = adapter->card;

	*data = ioread32(card->pci_mmap1 + reg);

	return 0;
}

/*
 * This function wakes up the card.
 *
 * A host power up command is written to the card configuration
 * register to wake up the card.
 */
static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
{
	int i = 0;

	while (mwifiex_pcie_ok_to_access_hw(adapter)) {
		i++;
		usleep_range(10, 20);
		/* 50ms max wait */
		if (i == 50000)
			break;
	}

	dev_dbg(adapter->dev, "event: Wakeup device...\n");

	/* Enable interrupts or any chip access will wakeup device */
	if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK, HOST_INTR_MASK)) {
		dev_warn(adapter->dev, "Enable host interrupt failed\n");
		return -1;
	}

	dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
	adapter->ps_state = PS_STATE_AWAKE;

	return 0;
}

/*
 * This function is called after the card has woken up.
 *
 * The card configuration register is reset.
 */
static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
{
	dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");

	return 0;
}

/*
 * This function disables the host interrupt.
 *
 * The host interrupt mask is read, the disable bit is reset and
 * written back to the card host interrupt mask register.
 */
static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
{
	if (mwifiex_pcie_ok_to_access_hw(adapter)) {
		if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
				      0x00000000)) {
			dev_warn(adapter->dev, "Disable host interrupt failed\n");
			return -1;
		}
	}

	return 0;
}

/*
 * This function enables the host interrupt.
 *
 * The host interrupt enable mask is written to the card
 * host interrupt mask register.
 */
static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
{
	if (mwifiex_pcie_ok_to_access_hw(adapter)) {
		/* Simply write the mask to the register */
		if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
				      HOST_INTR_MASK)) {
			dev_warn(adapter->dev, "Enable host interrupt failed\n");
			return -1;
		}
	}

	return 0;
}

/*
 * This function creates buffer descriptor ring for TX
 */
static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct sk_buff *skb;
	int i;
	phys_addr_t *buf_pa;

	/*
	 * driver maintaines the write pointer and firmware maintaines the read
	 * pointer. The write pointer starts at 0 (zero) while the read pointer
	 * starts at zero with rollover bit set
	 */
	card->txbd_wrptr = 0;
	card->txbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;

	/* allocate shared memory for the BD ring and divide the same in to
	   several descriptors */
	card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
							MWIFIEX_MAX_TXRX_BD;
	dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
		card->txbd_ring_size);
	card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL);
	if (!card->txbd_ring_vbase) {
		dev_err(adapter->dev, "Unable to alloc buffer for txbd ring\n");
		return -ENOMEM;
	}
	card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase);

	dev_dbg(adapter->dev,
		"info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
		card->txbd_ring_vbase, (u32)card->txbd_ring_pbase,
		(u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
		card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
				     (card->txbd_ring_vbase +
				      (sizeof(struct mwifiex_pcie_buf_desc)
				       * i));

		/* Allocate buffer here so that firmware can DMA data from it */
		skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
		if (!skb) {
			dev_err(adapter->dev, "Unable to allocate skb for TX ring.\n");
			kfree(card->txbd_ring_vbase);
			return -ENOMEM;
		}
		buf_pa = mwifiex_update_sk_buff_pa(skb);

		skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE);
		dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, "
			"buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
			skb, skb->data, (u32)*buf_pa,
			(u32)(((u64)*buf_pa >> 32)), skb->len);

		card->tx_buf_list[i] = skb;
		card->txbd_ring[i]->paddr = *buf_pa;
		card->txbd_ring[i]->len = (u16)skb->len;
		card->txbd_ring[i]->flags = 0;
	}

	return 0;
}

static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	int i;

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
		if (card->tx_buf_list[i])
			dev_kfree_skb_any(card->tx_buf_list[i]);
		card->tx_buf_list[i] = NULL;
		card->txbd_ring[i]->paddr = 0;
		card->txbd_ring[i]->len = 0;
		card->txbd_ring[i]->flags = 0;
		card->txbd_ring[i] = NULL;
	}

	kfree(card->txbd_ring_vbase);
	card->txbd_ring_size = 0;
	card->txbd_wrptr = 0;
	card->txbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
	card->txbd_ring_vbase = NULL;

	return 0;
}

/*
 * This function creates buffer descriptor ring for RX
 */
static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct sk_buff *skb;
	int i;
	phys_addr_t *buf_pa;

	/*
	 * driver maintaines the read pointer and firmware maintaines the write
	 * pointer. The write pointer starts at 0 (zero) while the read pointer
	 * starts at zero with rollover bit set
	 */
	card->rxbd_wrptr = 0;
	card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;

	card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
							MWIFIEX_MAX_TXRX_BD;
	dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
		card->rxbd_ring_size);
	card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL);
	if (!card->rxbd_ring_vbase) {
		dev_err(adapter->dev, "Unable to allocate buffer for "
				"rxbd_ring.\n");
		return -ENOMEM;
	}
	card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase);

	dev_dbg(adapter->dev,
		"info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
		card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
		(u32)((u64)card->rxbd_ring_pbase >> 32),
		card->rxbd_ring_size);

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
		card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
				     (card->rxbd_ring_vbase +
				      (sizeof(struct mwifiex_pcie_buf_desc)
				       * i));

		/* Allocate skb here so that firmware can DMA data from it */
		skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
		if (!skb) {
			dev_err(adapter->dev,
				"Unable to allocate skb for RX ring.\n");
			kfree(card->rxbd_ring_vbase);
			return -ENOMEM;
		}
		buf_pa = mwifiex_update_sk_buff_pa(skb);
		skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE);

		dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, "
			"buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
			skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
			skb->len);

		card->rx_buf_list[i] = skb;
		card->rxbd_ring[i]->paddr = *buf_pa;
		card->rxbd_ring[i]->len = (u16)skb->len;
		card->rxbd_ring[i]->flags = 0;
	}

	return 0;
}

/*
 * This function deletes Buffer descriptor ring for RX
 */
static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	int i;

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
		if (card->rx_buf_list[i])
			dev_kfree_skb_any(card->rx_buf_list[i]);
		card->rx_buf_list[i] = NULL;
		card->rxbd_ring[i]->paddr = 0;
		card->rxbd_ring[i]->len = 0;
		card->rxbd_ring[i]->flags = 0;
		card->rxbd_ring[i] = NULL;
	}

	kfree(card->rxbd_ring_vbase);
	card->rxbd_ring_size = 0;
	card->rxbd_wrptr = 0;
	card->rxbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
	card->rxbd_ring_vbase = NULL;

	return 0;
}

/*
 * This function creates buffer descriptor ring for Events
 */
static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct sk_buff *skb;
	int i;
	phys_addr_t *buf_pa;

	/*
	 * driver maintaines the read pointer and firmware maintaines the write
	 * pointer. The write pointer starts at 0 (zero) while the read pointer
	 * starts at zero with rollover bit set
	 */
	card->evtbd_wrptr = 0;
	card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;

	card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
							MWIFIEX_MAX_EVT_BD;
	dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
		card->evtbd_ring_size);
	card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL);
	if (!card->evtbd_ring_vbase) {
		dev_err(adapter->dev,
			"Unable to allocate buffer. Terminating download\n");
		return -ENOMEM;
	}
	card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase);

	dev_dbg(adapter->dev,
		"info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
		card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
		(u32)((u64)card->evtbd_ring_pbase >> 32),
		card->evtbd_ring_size);

	for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
		card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
				      (card->evtbd_ring_vbase +
				       (sizeof(struct mwifiex_pcie_buf_desc)
					* i));

		/* Allocate skb here so that firmware can DMA data from it */
		skb = dev_alloc_skb(MAX_EVENT_SIZE);
		if (!skb) {
			dev_err(adapter->dev,
				"Unable to allocate skb for EVENT buf.\n");
			kfree(card->evtbd_ring_vbase);
			return -ENOMEM;
		}
		buf_pa = mwifiex_update_sk_buff_pa(skb);
		skb_put(skb, MAX_EVENT_SIZE);

		dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, "
			"buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
			skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
			skb->len);

		card->evt_buf_list[i] = skb;
		card->evtbd_ring[i]->paddr = *buf_pa;
		card->evtbd_ring[i]->len = (u16)skb->len;
		card->evtbd_ring[i]->flags = 0;
	}

	return 0;
}

/*
 * This function deletes Buffer descriptor ring for Events
 */
static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	int i;

	for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
		if (card->evt_buf_list[i])
			dev_kfree_skb_any(card->evt_buf_list[i]);
		card->evt_buf_list[i] = NULL;
		card->evtbd_ring[i]->paddr = 0;
		card->evtbd_ring[i]->len = 0;
		card->evtbd_ring[i]->flags = 0;
		card->evtbd_ring[i] = NULL;
	}

	kfree(card->evtbd_ring_vbase);
	card->evtbd_wrptr = 0;
	card->evtbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
	card->evtbd_ring_size = 0;
	card->evtbd_ring_vbase = NULL;

	return 0;
}

/*
 * This function allocates a buffer for CMDRSP
 */
static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct sk_buff *skb;

	/* Allocate memory for receiving command response data */
	skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
	if (!skb) {
		dev_err(adapter->dev,
			"Unable to allocate skb for command response data.\n");
		return -ENOMEM;
	}
	mwifiex_update_sk_buff_pa(skb);
	skb_put(skb, MWIFIEX_UPLD_SIZE);
	card->cmdrsp_buf = skb;

	skb = NULL;
	/* Allocate memory for sending command to firmware */
	skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER);
	if (!skb) {
		dev_err(adapter->dev,
			"Unable to allocate skb for command data.\n");
		return -ENOMEM;
	}
	mwifiex_update_sk_buff_pa(skb);
	skb_put(skb, MWIFIEX_SIZE_OF_CMD_BUFFER);
	card->cmd_buf = skb;

	return 0;
}

/*
 * This function deletes a buffer for CMDRSP
 */
static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card;

	if (!adapter)
		return 0;

	card = adapter->card;

	if (card && card->cmdrsp_buf)
		dev_kfree_skb_any(card->cmdrsp_buf);

	if (card && card->cmd_buf)
		dev_kfree_skb_any(card->cmd_buf);

	return 0;
}

/*
 * This function allocates a buffer for sleep cookie
 */
static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
{
	struct sk_buff *skb;
	struct pcie_service_card *card = adapter->card;

	/* Allocate memory for sleep cookie */
	skb = dev_alloc_skb(sizeof(u32));
	if (!skb) {
		dev_err(adapter->dev,
			"Unable to allocate skb for sleep cookie!\n");
		return -ENOMEM;
	}
	mwifiex_update_sk_buff_pa(skb);
	skb_put(skb, sizeof(u32));

	/* Init val of Sleep Cookie */
	*(u32 *)skb->data = FW_AWAKE_COOKIE;

	dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
		*((u32 *)skb->data));

	/* Save the sleep cookie */
	card->sleep_cookie = skb;

	return 0;
}

/*
 * This function deletes buffer for sleep cookie
 */
static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card;

	if (!adapter)
		return 0;

	card = adapter->card;

	if (card && card->sleep_cookie) {
		dev_kfree_skb_any(card->sleep_cookie);
		card->sleep_cookie = NULL;
	}

	return 0;
}

/*
 * This function sends data buffer to device
 */
static int
mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb)
{
	struct pcie_service_card *card = adapter->card;
	u32 wrindx, rdptr;
	phys_addr_t *buf_pa;
	__le16 *tmp;

	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		mwifiex_pm_wakeup_card(adapter);

	/* Read the TX ring read pointer set by firmware */
	if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) {
		dev_err(adapter->dev,
			"SEND DATA: failed to read REG_TXBD_RDPTR\n");
		return -1;
	}

	wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK;

	dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr,
		card->txbd_wrptr);
	if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) !=
			(rdptr & MWIFIEX_TXBD_MASK)) ||
	    ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
			(rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
		struct sk_buff *skb_data;
		u8 *payload;

		adapter->data_sent = true;
		skb_data = card->tx_buf_list[wrindx];
		memcpy(skb_data->data, skb->data, skb->len);
		payload = skb_data->data;
		tmp = (__le16 *)&payload[0];
		*tmp = cpu_to_le16((u16)skb->len);
		tmp = (__le16 *)&payload[2];
		*tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
		skb_put(skb_data, MWIFIEX_RX_DATA_BUF_SIZE - skb_data->len);
		skb_trim(skb_data, skb->len);
		buf_pa = MWIFIEX_SKB_PACB(skb_data);
		card->txbd_ring[wrindx]->paddr = *buf_pa;
		card->txbd_ring[wrindx]->len = (u16)skb_data->len;
		card->txbd_ring[wrindx]->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
						MWIFIEX_BD_FLAG_LAST_DESC;

		if ((++card->txbd_wrptr & MWIFIEX_TXBD_MASK) ==
							MWIFIEX_MAX_TXRX_BD)
			card->txbd_wrptr = ((card->txbd_wrptr &
						MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
						MWIFIEX_BD_FLAG_ROLLOVER_IND);

		/* Write the TX ring write pointer in to REG_TXBD_WRPTR */
		if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR,
				      card->txbd_wrptr)) {
			dev_err(adapter->dev,
				"SEND DATA: failed to write REG_TXBD_WRPTR\n");
			return 0;
		}

		/* Send the TX ready interrupt */
		if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
				      CPU_INTR_DNLD_RDY)) {
			dev_err(adapter->dev,
				"SEND DATA: failed to assert door-bell intr\n");
			return -1;
		}
		dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
			"%#x> and sent packet to firmware successfully\n",
			rdptr, card->txbd_wrptr);
	} else {
		dev_dbg(adapter->dev,
			"info: TX Ring full, can't send packets to fw\n");
		adapter->data_sent = true;
		/* Send the TX ready interrupt */
		if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
				      CPU_INTR_DNLD_RDY))
			dev_err(adapter->dev,
				"SEND DATA: failed to assert door-bell intr\n");
		return -EBUSY;
	}

	return 0;
}

/*
 * This function handles received buffer ring and
 * dispatches packets to upper
 */
static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	u32 wrptr, rd_index;
	int ret = 0;
	struct sk_buff *skb_tmp = NULL;

	/* Read the RX ring Write pointer set by firmware */
	if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
		dev_err(adapter->dev,
			"RECV DATA: failed to read REG_TXBD_RDPTR\n");
		ret = -1;
		goto done;
	}

	while (((wrptr & MWIFIEX_RXBD_MASK) !=
		(card->rxbd_rdptr & MWIFIEX_RXBD_MASK)) ||
	       ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) ==
		(card->rxbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
		struct sk_buff *skb_data;
		u16 rx_len;

		rd_index = card->rxbd_rdptr & MWIFIEX_RXBD_MASK;
		skb_data = card->rx_buf_list[rd_index];

		/* Get data length from interface header -
		   first byte is len, second byte is type */
		rx_len = *((u16 *)skb_data->data);
		dev_dbg(adapter->dev,
			"info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
			card->rxbd_rdptr, wrptr, rx_len);
		skb_tmp = dev_alloc_skb(rx_len);
		if (!skb_tmp) {
			dev_dbg(adapter->dev,
				"info: Failed to alloc skb for RX\n");
			ret = -EBUSY;
			goto done;
		}

		skb_put(skb_tmp, rx_len);

		memcpy(skb_tmp->data, skb_data->data + INTF_HEADER_LEN, rx_len);
		if ((++card->rxbd_rdptr & MWIFIEX_RXBD_MASK) ==
							MWIFIEX_MAX_TXRX_BD) {
			card->rxbd_rdptr = ((card->rxbd_rdptr &
					     MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
					    MWIFIEX_BD_FLAG_ROLLOVER_IND);
		}
		dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
			card->rxbd_rdptr, wrptr);

		/* Write the RX ring read pointer in to REG_RXBD_RDPTR */
		if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR,
				      card->rxbd_rdptr)) {
			dev_err(adapter->dev,
				"RECV DATA: failed to write REG_RXBD_RDPTR\n");
			ret = -1;
			goto done;
		}

		/* Read the RX ring Write pointer set by firmware */
		if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
			dev_err(adapter->dev,
				"RECV DATA: failed to read REG_TXBD_RDPTR\n");
			ret = -1;
			goto done;
		}
		dev_dbg(adapter->dev,
			"info: RECV DATA: Rcvd packet from fw successfully\n");
		mwifiex_handle_rx_packet(adapter, skb_tmp);
	}

done:
	if (ret && skb_tmp)
		dev_kfree_skb_any(skb_tmp);
	return ret;
}

/*
 * This function downloads the boot command to device
 */
static int
mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
{
	phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb);

	if (!(skb->data && skb->len && *buf_pa)) {
		dev_err(adapter->dev,
			"Invalid parameter in %s <%p, %#x:%x, %x>\n",
			__func__, skb->data, skb->len,
			(u32)*buf_pa, (u32)((u64)*buf_pa >> 32));
		return -1;
	}

	/* Write the lower 32bits of the physical address to scratch
	 * register 0 */
	if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) {
		dev_err(adapter->dev,
			"%s: failed to write download command to boot code.\n",
			__func__);
		return -1;
	}

	/* Write the upper 32bits of the physical address to scratch
	 * register 1 */
	if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG,
			      (u32)((u64)*buf_pa >> 32))) {
		dev_err(adapter->dev,
			"%s: failed to write download command to boot code.\n",
			__func__);
		return -1;
	}

	/* Write the command length to scratch register 2 */
	if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) {
		dev_err(adapter->dev,
			"%s: failed to write command len to scratch reg 2\n",
			__func__);
		return -1;
	}

	/* Ring the door bell */
	if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
			      CPU_INTR_DOOR_BELL)) {
		dev_err(adapter->dev,
			"%s: failed to assert door-bell intr\n", __func__);
		return -1;
	}

	return 0;
}

/*
 * This function downloads commands to the device
 */
static int
mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
{
	struct pcie_service_card *card = adapter->card;
	int ret = 0;
	phys_addr_t *cmd_buf_pa;
	phys_addr_t *cmdrsp_buf_pa;

	if (!(skb->data && skb->len)) {
		dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
			__func__, skb->data, skb->len);
		return -1;
	}

	/* Make sure a command response buffer is available */
	if (!card->cmdrsp_buf) {
		dev_err(adapter->dev,
			"No response buffer available, send command failed\n");
		return -EBUSY;
	}

	/* Make sure a command buffer is available */
	if (!card->cmd_buf) {
		dev_err(adapter->dev, "Command buffer not available\n");
		return -EBUSY;
	}

	adapter->cmd_sent = true;
	/* Copy the given skb in to DMA accessable shared buffer */
	skb_put(card->cmd_buf, MWIFIEX_SIZE_OF_CMD_BUFFER - card->cmd_buf->len);
	skb_trim(card->cmd_buf, skb->len);
	memcpy(card->cmd_buf->data, skb->data, skb->len);

	/* To send a command, the driver will:
		1. Write the 64bit physical address of the data buffer to
		   SCRATCH1 + SCRATCH0
		2. Ring the door bell (i.e. set the door bell interrupt)

		In response to door bell interrupt, the firmware will perform
		the DMA of the command packet (first header to obtain the total
		length and then rest of the command).
	*/

	if (card->cmdrsp_buf) {
		cmdrsp_buf_pa = MWIFIEX_SKB_PACB(card->cmdrsp_buf);
		/* Write the lower 32bits of the cmdrsp buffer physical
		   address */
		if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO,
				      (u32)*cmdrsp_buf_pa)) {
			dev_err(adapter->dev,
				"Failed to write download cmd to boot code.\n");
			ret = -1;
			goto done;
		}
		/* Write the upper 32bits of the cmdrsp buffer physical
		   address */
		if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI,
				      (u32)((u64)*cmdrsp_buf_pa >> 32))) {
			dev_err(adapter->dev,
				"Failed to write download cmd to boot code.\n");
			ret = -1;
			goto done;
		}
	}

	cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf);
	/* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */
	if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)*cmd_buf_pa)) {
		dev_err(adapter->dev,
			"Failed to write download cmd to boot code.\n");
		ret = -1;
		goto done;
	}
	/* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */
	if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI,
			      (u32)((u64)*cmd_buf_pa >> 32))) {
		dev_err(adapter->dev,
			"Failed to write download cmd to boot code.\n");
		ret = -1;
		goto done;
	}

	/* Write the command length to REG_CMD_SIZE */
	if (mwifiex_write_reg(adapter, REG_CMD_SIZE, card->cmd_buf->len)) {
		dev_err(adapter->dev,
			"Failed to write cmd len to REG_CMD_SIZE\n");
		ret = -1;
		goto done;
	}

	/* Ring the door bell */
	if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
			      CPU_INTR_DOOR_BELL)) {
		dev_err(adapter->dev,
			"Failed to assert door-bell intr\n");
		ret = -1;
		goto done;
	}

done:
	if (ret)
		adapter->cmd_sent = false;

	return 0;
}

/*
 * This function handles command complete interrupt
 */
static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct sk_buff *skb = card->cmdrsp_buf;
	int count = 0;

	dev_dbg(adapter->dev, "info: Rx CMD Response\n");

	if (!adapter->curr_cmd) {
		skb_pull(skb, INTF_HEADER_LEN);
		if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
			mwifiex_process_sleep_confirm_resp(adapter, skb->data,
							   skb->len);
			while (mwifiex_pcie_ok_to_access_hw(adapter) &&
							(count++ < 10))
				usleep_range(50, 60);
		} else {
			dev_err(adapter->dev,
				"There is no command but got cmdrsp\n");
		}
		memcpy(adapter->upld_buf, skb->data,
		       min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
		skb_push(skb, INTF_HEADER_LEN);
	} else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
		skb_pull(skb, INTF_HEADER_LEN);
		adapter->curr_cmd->resp_skb = skb;
		adapter->cmd_resp_received = true;
		/* Take the pointer and set it to CMD node and will
		   return in the response complete callback */
		card->cmdrsp_buf = NULL;

		/* Clear the cmd-rsp buffer address in scratch registers. This
		   will prevent firmware from writing to the same response
		   buffer again. */
		if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) {
			dev_err(adapter->dev,
				"cmd_done: failed to clear cmd_rsp_addr_lo\n");
			return -1;
		}
		/* Write the upper 32bits of the cmdrsp buffer physical
		   address */
		if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) {
			dev_err(adapter->dev,
				"cmd_done: failed to clear cmd_rsp_addr_hi\n");
			return -1;
		}
	}

	return 0;
}

/*
 * Command Response processing complete handler
 */
static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
					struct sk_buff *skb)
{
	struct pcie_service_card *card = adapter->card;

	if (skb) {
		card->cmdrsp_buf = skb;
		skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
	}

	return 0;
}

/*
 * This function handles firmware event ready interrupt
 */
static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
	u32 wrptr, event;

	if (adapter->event_received) {
		dev_dbg(adapter->dev, "info: Event being processed, "
			"do not process this interrupt just yet\n");
		return 0;
	}

	if (rdptr >= MWIFIEX_MAX_EVT_BD) {
		dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
		return -1;
	}

	/* Read the event ring write pointer set by firmware */
	if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) {
		dev_err(adapter->dev,
			"EventReady: failed to read REG_EVTBD_WRPTR\n");
		return -1;
	}

	dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
		card->evtbd_rdptr, wrptr);
	if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
					      & MWIFIEX_EVTBD_MASK)) ||
	    ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) ==
	     (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
		struct sk_buff *skb_cmd;
		__le16 data_len = 0;
		u16 evt_len;

		dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
		skb_cmd = card->evt_buf_list[rdptr];
		/* Take the pointer and set it to event pointer in adapter
		   and will return back after event handling callback */
		card->evt_buf_list[rdptr] = NULL;
		card->evtbd_ring[rdptr]->paddr = 0;
		card->evtbd_ring[rdptr]->len = 0;
		card->evtbd_ring[rdptr]->flags = 0;

		event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
		adapter->event_cause = event;
		/* The first 4bytes will be the event transfer header
		   len is 2 bytes followed by type which is 2 bytes */
		memcpy(&data_len, skb_cmd->data, sizeof(__le16));
		evt_len = le16_to_cpu(data_len);

		skb_pull(skb_cmd, INTF_HEADER_LEN);
		dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);

		if ((evt_len > 0) && (evt_len  < MAX_EVENT_SIZE))
			memcpy(adapter->event_body, skb_cmd->data +
			       MWIFIEX_EVENT_HEADER_LEN, evt_len -
			       MWIFIEX_EVENT_HEADER_LEN);

		adapter->event_received = true;
		adapter->event_skb = skb_cmd;

		/* Do not update the event read pointer here, wait till the
		   buffer is released. This is just to make things simpler,
		   we need to find a better method of managing these buffers.
		*/
	}

	return 0;
}

/*
 * Event processing complete handler
 */
static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
				       struct sk_buff *skb)
{
	struct pcie_service_card *card = adapter->card;
	int ret = 0;
	u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
	u32 wrptr;
	phys_addr_t *buf_pa;

	if (!skb)
		return 0;

	if (rdptr >= MWIFIEX_MAX_EVT_BD) {
		dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
			rdptr);
		return -EINVAL;
	}

	/* Read the event ring write pointer set by firmware */
	if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) {
		dev_err(adapter->dev,
			"event_complete: failed to read REG_EVTBD_WRPTR\n");
		return -1;
	}

	if (!card->evt_buf_list[rdptr]) {
		skb_push(skb, INTF_HEADER_LEN);
		card->evt_buf_list[rdptr] = skb;
		buf_pa = MWIFIEX_SKB_PACB(skb);
		card->evtbd_ring[rdptr]->paddr = *buf_pa;
		card->evtbd_ring[rdptr]->len = (u16)skb->len;
		card->evtbd_ring[rdptr]->flags = 0;
		skb = NULL;
	} else {
		dev_dbg(adapter->dev,
			"info: ERROR: buf still valid at index %d, <%p, %p>\n",
			rdptr, card->evt_buf_list[rdptr], skb);
	}

	if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
		card->evtbd_rdptr = ((card->evtbd_rdptr &
					MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
					MWIFIEX_BD_FLAG_ROLLOVER_IND);
	}

	dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
		card->evtbd_rdptr, wrptr);

	/* Write the event ring read pointer in to REG_EVTBD_RDPTR */
	if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) {
		dev_err(adapter->dev,
			"event_complete: failed to read REG_EVTBD_RDPTR\n");
		return -1;
	}

	dev_dbg(adapter->dev, "info: Check Events Again\n");
	ret = mwifiex_pcie_process_event_ready(adapter);

	return ret;
}

/*
 * This function downloads the firmware to the card.
 *
 * Firmware is downloaded to the card in blocks. Every block download
 * is tested for CRC errors, and retried a number of times before
 * returning failure.
 */
static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
				    struct mwifiex_fw_image *fw)
{
	int ret;
	u8 *firmware = fw->fw_buf;
	u32 firmware_len = fw->fw_len;
	u32 offset = 0;
	struct sk_buff *skb;
	u32 txlen, tx_blocks = 0, tries, len;
	u32 block_retry_cnt = 0;

	if (!adapter) {
		pr_err("adapter structure is not valid\n");
		return -1;
	}

	if (!firmware || !firmware_len) {
		dev_err(adapter->dev,
			"No firmware image found! Terminating download\n");
		return -1;
	}

	dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
		firmware_len);

	if (mwifiex_pcie_disable_host_int(adapter)) {
		dev_err(adapter->dev,
			"%s: Disabling interrupts failed.\n", __func__);
		return -1;
	}

	skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
	if (!skb) {
		ret = -ENOMEM;
		goto done;
	}
	mwifiex_update_sk_buff_pa(skb);

	/* Perform firmware data transfer */
	do {
		u32 ireg_intr = 0;

		/* More data? */
		if (offset >= firmware_len)
			break;

		for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
			ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG,
					       &len);
			if (ret) {
				dev_warn(adapter->dev,
					 "Failed reading len from boot code\n");
				goto done;
			}
			if (len)
				break;
			usleep_range(10, 20);
		}

		if (!len) {
			break;
		} else if (len > MWIFIEX_UPLD_SIZE) {
			pr_err("FW download failure @ %d, invalid length %d\n",
			       offset, len);
			ret = -1;
			goto done;
		}

		txlen = len;

		if (len & BIT(0)) {
			block_retry_cnt++;
			if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
				pr_err("FW download failure @ %d, over max "
				       "retry count\n", offset);
				ret = -1;
				goto done;
			}
			dev_err(adapter->dev, "FW CRC error indicated by the "
				"helper: len = 0x%04X, txlen = %d\n",
				len, txlen);
			len &= ~BIT(0);
			/* Setting this to 0 to resend from same offset */
			txlen = 0;
		} else {
			block_retry_cnt = 0;
			/* Set blocksize to transfer - checking for
			   last block */
			if (firmware_len - offset < txlen)
				txlen = firmware_len - offset;

			dev_dbg(adapter->dev, ".");

			tx_blocks = (txlen +
				     MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) /
				     MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD;

			/* Copy payload to buffer */
			memmove(skb->data, &firmware[offset], txlen);
		}

		skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
		skb_trim(skb, tx_blocks * MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD);

		/* Send the boot command to device */
		if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
			dev_err(adapter->dev,
				"Failed to send firmware download command\n");
			ret = -1;
			goto done;
		}
		/* Wait for the command done interrupt */
		do {
			if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
					     &ireg_intr)) {
				dev_err(adapter->dev, "%s: Failed to read "
					"interrupt status during fw dnld.\n",
					__func__);
				ret = -1;
				goto done;
			}
		} while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
			 CPU_INTR_DOOR_BELL);
		offset += txlen;
	} while (true);

	dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
		offset);

	ret = 0;

done:
	dev_kfree_skb_any(skb);
	return ret;
}

/*
 * This function checks the firmware status in card.
 *
 * The winner interface is also determined by this function.
 */
static int
mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
{
	int ret = 0;
	u32 firmware_stat, winner_status;
	u32 tries;

	/* Mask spurios interrupts */
	if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
			      HOST_INTR_MASK)) {
		dev_warn(adapter->dev, "Write register failed\n");
		return -1;
	}

	dev_dbg(adapter->dev, "Setting driver ready signature\n");
	if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) {
		dev_err(adapter->dev,
			"Failed to write driver ready signature\n");
		return -1;
	}

	/* Wait for firmware initialization event */
	for (tries = 0; tries < poll_num; tries++) {
		if (mwifiex_read_reg(adapter, PCIE_SCRATCH_3_REG,
				     &firmware_stat))
			ret = -1;
		else
			ret = 0;
		if (ret)
			continue;
		if (firmware_stat == FIRMWARE_READY_PCIE) {
			ret = 0;
			break;
		} else {
			mdelay(100);
			ret = -1;
		}
	}

	if (ret) {
		if (mwifiex_read_reg(adapter, PCIE_SCRATCH_3_REG,
				     &winner_status))
			ret = -1;
		else if (!winner_status) {
			dev_err(adapter->dev, "PCI-E is the winner\n");
			adapter->winner = 1;
			ret = -1;
		} else {
			dev_err(adapter->dev,
				"PCI-E is not the winner <%#x,%d>, exit dnld\n",
				ret, adapter->winner);
			ret = 0;
		}
	}

	return ret;
}

/*
 * This function reads the interrupt status from card.
 */
static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
{
	u32 pcie_ireg;
	unsigned long flags;

	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		return;

	if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
		dev_warn(adapter->dev, "Read register failed\n");
		return;
	}

	if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {

		mwifiex_pcie_disable_host_int(adapter);

		/* Clear the pending interrupts */
		if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
				      ~pcie_ireg)) {
			dev_warn(adapter->dev, "Write register failed\n");
			return;
		}
		spin_lock_irqsave(&adapter->int_lock, flags);
		adapter->int_status |= pcie_ireg;
		spin_unlock_irqrestore(&adapter->int_lock, flags);

		if (pcie_ireg & HOST_INTR_CMD_DONE) {
			if ((adapter->ps_state == PS_STATE_SLEEP_CFM) ||
			    (adapter->ps_state == PS_STATE_SLEEP)) {
				mwifiex_pcie_enable_host_int(adapter);
				if (mwifiex_write_reg(adapter,
						      PCIE_CPU_INT_EVENT,
						      CPU_INTR_SLEEP_CFM_DONE)
						      ) {
					dev_warn(adapter->dev,
						 "Write register failed\n");
					return;

				}
			}
		} else if (!adapter->pps_uapsd_mode &&
			   adapter->ps_state == PS_STATE_SLEEP) {
				/* Potentially for PCIe we could get other
				 * interrupts like shared. Don't change power
				 * state until cookie is set */
				if (mwifiex_pcie_ok_to_access_hw(adapter))
					adapter->ps_state = PS_STATE_AWAKE;
		}
	}
}

/*
 * Interrupt handler for PCIe root port
 *
 * This function reads the interrupt status from firmware and assigns
 * the main process in workqueue which will handle the interrupt.
 */
static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
{
	struct pci_dev *pdev = (struct pci_dev *)context;
	struct pcie_service_card *card;
	struct mwifiex_adapter *adapter;

	if (!pdev) {
		pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
		goto exit;
	}

	card = (struct pcie_service_card *) pci_get_drvdata(pdev);
	if (!card || !card->adapter) {
		pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
			 card ? card->adapter : NULL);
		goto exit;
	}
	adapter = card->adapter;

	if (adapter->surprise_removed)
		goto exit;

	mwifiex_interrupt_status(adapter);
	queue_work(adapter->workqueue, &adapter->main_work);

exit:
	return IRQ_HANDLED;
}

/*
 * This function checks the current interrupt status.
 *
 * The following interrupts are checked and handled by this function -
 *      - Data sent
 *      - Command sent
 *      - Command received
 *      - Packets received
 *      - Events received
 *
 * In case of Rx packets received, the packets are uploaded from card to
 * host and processed accordingly.
 */
static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
{
	int ret;
	u32 pcie_ireg = 0;
	unsigned long flags;

	spin_lock_irqsave(&adapter->int_lock, flags);
	/* Clear out unused interrupts */
	adapter->int_status &= HOST_INTR_MASK;
	spin_unlock_irqrestore(&adapter->int_lock, flags);

	while (adapter->int_status & HOST_INTR_MASK) {
		if (adapter->int_status & HOST_INTR_DNLD_DONE) {
			adapter->int_status &= ~HOST_INTR_DNLD_DONE;
			if (adapter->data_sent) {
				dev_dbg(adapter->dev, "info: DATA sent intr\n");
				adapter->data_sent = false;
			}
		}
		if (adapter->int_status & HOST_INTR_UPLD_RDY) {
			adapter->int_status &= ~HOST_INTR_UPLD_RDY;
			dev_dbg(adapter->dev, "info: Rx DATA\n");
			ret = mwifiex_pcie_process_recv_data(adapter);
			if (ret)
				return ret;
		}
		if (adapter->int_status & HOST_INTR_EVENT_RDY) {
			adapter->int_status &= ~HOST_INTR_EVENT_RDY;
			dev_dbg(adapter->dev, "info: Rx EVENT\n");
			ret = mwifiex_pcie_process_event_ready(adapter);
			if (ret)
				return ret;
		}

		if (adapter->int_status & HOST_INTR_CMD_DONE) {
			adapter->int_status &= ~HOST_INTR_CMD_DONE;
			if (adapter->cmd_sent) {
				dev_dbg(adapter->dev,
					"info: CMD sent Interrupt\n");
				adapter->cmd_sent = false;
			}
			/* Handle command response */
			ret = mwifiex_pcie_process_cmd_complete(adapter);
			if (ret)
				return ret;
		}

		if (mwifiex_pcie_ok_to_access_hw(adapter)) {
			if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
					     &pcie_ireg)) {
				dev_warn(adapter->dev,
					 "Read register failed\n");
				return -1;
			}

			if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
				if (mwifiex_write_reg(adapter,
						      PCIE_HOST_INT_STATUS,
						      ~pcie_ireg)) {
					dev_warn(adapter->dev,
						 "Write register failed\n");
					return -1;
				}
				adapter->int_status |= pcie_ireg;
				adapter->int_status &= HOST_INTR_MASK;
			}

		}
	}
	dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
		adapter->cmd_sent, adapter->data_sent);
	mwifiex_pcie_enable_host_int(adapter);

	return 0;
}

/*
 * This function downloads data from driver to card.
 *
 * Both commands and data packets are transferred to the card by this
 * function.
 *
 * This function adds the PCIE specific header to the front of the buffer
 * before transferring. The header contains the length of the packet and
 * the type. The firmware handles the packets based upon this set type.
 */
static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
				     struct sk_buff *skb,
				     struct mwifiex_tx_param *tx_param)
{
	if (!skb) {
		dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
		return -1;
	}

	if (type == MWIFIEX_TYPE_DATA)
		return mwifiex_pcie_send_data(adapter, skb);
	else if (type == MWIFIEX_TYPE_CMD)
		return mwifiex_pcie_send_cmd(adapter, skb);

	return 0;
}

/*
 * This function initializes the PCI-E host memory space, WCB rings, etc.
 *
 * The following initializations steps are followed -
 *      - Allocate TXBD ring buffers
 *      - Allocate RXBD ring buffers
 *      - Allocate event BD ring buffers
 *      - Allocate command response ring buffer
 *      - Allocate sleep cookie buffer
 */
static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	int ret;
	struct pci_dev *pdev = card->dev;

	pci_set_drvdata(pdev, card);

	ret = pci_enable_device(pdev);
	if (ret)
		goto err_enable_dev;

	pci_set_master(pdev);

	dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
	if (ret) {
		dev_err(adapter->dev, "set_dma_mask(32) failed\n");
		goto err_set_dma_mask;
	}

	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
	if (ret) {
		dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
		goto err_set_dma_mask;
	}

	ret = pci_request_region(pdev, 0, DRV_NAME);
	if (ret) {
		dev_err(adapter->dev, "req_reg(0) error\n");
		goto err_req_region0;
	}
	card->pci_mmap = pci_iomap(pdev, 0, 0);
	if (!card->pci_mmap) {
		dev_err(adapter->dev, "iomap(0) error\n");
		goto err_iomap0;
	}
	ret = pci_request_region(pdev, 2, DRV_NAME);
	if (ret) {
		dev_err(adapter->dev, "req_reg(2) error\n");
		goto err_req_region2;
	}
	card->pci_mmap1 = pci_iomap(pdev, 2, 0);
	if (!card->pci_mmap1) {
		dev_err(adapter->dev, "iomap(2) error\n");
		goto err_iomap2;
	}

	dev_dbg(adapter->dev,
		"PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
		card->pci_mmap, card->pci_mmap1);

	card->cmdrsp_buf = NULL;
	ret = mwifiex_pcie_create_txbd_ring(adapter);
	if (ret)
		goto err_cre_txbd;
	ret = mwifiex_pcie_create_rxbd_ring(adapter);
	if (ret)
		goto err_cre_rxbd;
	ret = mwifiex_pcie_create_evtbd_ring(adapter);
	if (ret)
		goto err_cre_evtbd;
	ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
	if (ret)
		goto err_alloc_cmdbuf;
	ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
	if (ret)
		goto err_alloc_cookie;

	return ret;

err_alloc_cookie:
	mwifiex_pcie_delete_cmdrsp_buf(adapter);
err_alloc_cmdbuf:
	mwifiex_pcie_delete_evtbd_ring(adapter);
err_cre_evtbd:
	mwifiex_pcie_delete_rxbd_ring(adapter);
err_cre_rxbd:
	mwifiex_pcie_delete_txbd_ring(adapter);
err_cre_txbd:
	pci_iounmap(pdev, card->pci_mmap1);
err_iomap2:
	pci_release_region(pdev, 2);
err_req_region2:
	pci_iounmap(pdev, card->pci_mmap);
err_iomap0:
	pci_release_region(pdev, 0);
err_req_region0:
err_set_dma_mask:
	pci_disable_device(pdev);
err_enable_dev:
	pci_set_drvdata(pdev, NULL);
	return ret;
}

/*
 * This function cleans up the allocated card buffers.
 *
 * The following are freed by this function -
 *      - TXBD ring buffers
 *      - RXBD ring buffers
 *      - Event BD ring buffers
 *      - Command response ring buffer
 *      - Sleep cookie buffer
 */
static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct pci_dev *pdev = card->dev;

	mwifiex_pcie_delete_sleep_cookie_buf(adapter);
	mwifiex_pcie_delete_cmdrsp_buf(adapter);
	mwifiex_pcie_delete_evtbd_ring(adapter);
	mwifiex_pcie_delete_rxbd_ring(adapter);
	mwifiex_pcie_delete_txbd_ring(adapter);
	card->cmdrsp_buf = NULL;

	dev_dbg(adapter->dev, "Clearing driver ready signature\n");
	if (user_rmmod) {
		if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000))
			dev_err(adapter->dev,
				"Failed to write driver not-ready signature\n");
	}

	if (pdev) {
		pci_iounmap(pdev, card->pci_mmap);
		pci_iounmap(pdev, card->pci_mmap1);

		pci_release_regions(pdev);
		pci_disable_device(pdev);
		pci_set_drvdata(pdev, NULL);
	}
}

/*
 * This function registers the PCIE device.
 *
 * PCIE IRQ is claimed, block size is set and driver data is initialized.
 */
static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
{
	int ret;
	struct pcie_service_card *card = adapter->card;
	struct pci_dev *pdev = card->dev;

	/* save adapter pointer in card */
	card->adapter = adapter;

	ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
			  "MRVL_PCIE", pdev);
	if (ret) {
		pr_err("request_irq failed: ret=%d\n", ret);
		adapter->card = NULL;
		return -1;
	}

	adapter->dev = &pdev->dev;
	strcpy(adapter->fw_name, PCIE8766_DEFAULT_FW_NAME);

	return 0;
}

/*
 * This function unregisters the PCIE device.
 *
 * The PCIE IRQ is released, the function is disabled and driver
 * data is set to null.
 */
static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;

	if (card) {
		dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
		free_irq(card->dev->irq, card->dev);
	}
}

static struct mwifiex_if_ops pcie_ops = {
	.init_if =			mwifiex_pcie_init,
	.cleanup_if =			mwifiex_pcie_cleanup,
	.check_fw_status =		mwifiex_check_fw_status,
	.prog_fw =			mwifiex_prog_fw_w_helper,
	.register_dev =			mwifiex_register_dev,
	.unregister_dev =		mwifiex_unregister_dev,
	.enable_int =			mwifiex_pcie_enable_host_int,
	.process_int_status =		mwifiex_process_int_status,
	.host_to_card =			mwifiex_pcie_host_to_card,
	.wakeup =			mwifiex_pm_wakeup_card,
	.wakeup_complete =		mwifiex_pm_wakeup_card_complete,

	/* PCIE specific */
	.cmdrsp_complete =		mwifiex_pcie_cmdrsp_complete,
	.event_complete =		mwifiex_pcie_event_complete,
	.update_mp_end_port =		NULL,
	.cleanup_mpa_buf =		NULL,
};

/*
 * This function initializes the PCIE driver module.
 *
 * This initiates the semaphore and registers the device with
 * PCIE bus.
 */
static int mwifiex_pcie_init_module(void)
{
	int ret;

	pr_debug("Marvell 8766 PCIe Driver\n");

	sema_init(&add_remove_card_sem, 1);

	/* Clear the flag in case user removes the card. */
	user_rmmod = 0;

	ret = pci_register_driver(&mwifiex_pcie);
	if (ret)
		pr_err("Driver register failed!\n");
	else
		pr_debug("info: Driver registered successfully!\n");

	return ret;
}

/*
 * This function cleans up the PCIE driver.
 *
 * The following major steps are followed for cleanup -
 *      - Resume the device if its suspended
 *      - Disconnect the device if connected
 *      - Shutdown the firmware
 *      - Unregister the device from PCIE bus.
 */
static void mwifiex_pcie_cleanup_module(void)
{
	if (!down_interruptible(&add_remove_card_sem))
		up(&add_remove_card_sem);

	/* Set the flag as user is removing this module. */
	user_rmmod = 1;

	pci_unregister_driver(&mwifiex_pcie);
}

module_init(mwifiex_pcie_init_module);
module_exit(mwifiex_pcie_cleanup_module);

MODULE_AUTHOR("Marvell International Ltd.");
MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
MODULE_VERSION(PCIE_VERSION);
MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE("mrvl/pcie8766_uapsta.bin");
