/*
 * 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");
