// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *
 *  Bluetooth support for Intel PCIe devices
 *
 *  Copyright (C) 2024  Intel Corporation
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/pci.h>
#include <linux/wait.h>
#include <linux/delay.h>
#include <linux/interrupt.h>

#include <linux/unaligned.h>
#include <linux/devcoredump.h>

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci_drv.h>

#include "btintel.h"
#include "btintel_pcie.h"

#define VERSION "0.1"

#define BTINTEL_PCI_DEVICE(dev, subdev)	\
	.vendor = PCI_VENDOR_ID_INTEL,	\
	.device = (dev),		\
	.subvendor = PCI_ANY_ID,	\
	.subdevice = (subdev),		\
	.driver_data = 0

#define POLL_INTERVAL_US	10

/* Intel Bluetooth PCIe device id table */
static const struct pci_device_id btintel_pcie_table[] = {
	/* BlazarI, Wildcat Lake */
	{ BTINTEL_PCI_DEVICE(0x4D76, PCI_ANY_ID) },
	/* BlazarI, Lunar Lake */
	{ BTINTEL_PCI_DEVICE(0xA876, PCI_ANY_ID) },
	/* Scorpious, Panther Lake-H484 */
	{ BTINTEL_PCI_DEVICE(0xE376, PCI_ANY_ID) },
	 /* Scorpious, Panther Lake-H404 */
	{ BTINTEL_PCI_DEVICE(0xE476, PCI_ANY_ID) },
	{ 0 }
};
MODULE_DEVICE_TABLE(pci, btintel_pcie_table);

struct btintel_pcie_dev_recovery {
	struct list_head list;
	u8 count;
	time64_t last_error;
	char name[];
};

/* Intel PCIe uses 4 bytes of HCI type instead of 1 byte BT SIG HCI type */
#define BTINTEL_PCIE_HCI_TYPE_LEN	4
#define BTINTEL_PCIE_HCI_CMD_PKT	0x00000001
#define BTINTEL_PCIE_HCI_ACL_PKT	0x00000002
#define BTINTEL_PCIE_HCI_SCO_PKT	0x00000003
#define BTINTEL_PCIE_HCI_EVT_PKT	0x00000004
#define BTINTEL_PCIE_HCI_ISO_PKT	0x00000005

#define BTINTEL_PCIE_MAGIC_NUM    0xA5A5A5A5

#define BTINTEL_PCIE_BLZR_HWEXP_SIZE		1024
#define BTINTEL_PCIE_BLZR_HWEXP_DMP_ADDR	0xB00A7C00

#define BTINTEL_PCIE_SCP_HWEXP_SIZE		4096
#define BTINTEL_PCIE_SCP_HWEXP_DMP_ADDR		0xB030F800

#define BTINTEL_PCIE_MAGIC_NUM	0xA5A5A5A5

#define BTINTEL_PCIE_TRIGGER_REASON_USER_TRIGGER	0x17A2
#define BTINTEL_PCIE_TRIGGER_REASON_FW_ASSERT		0x1E61

#define BTINTEL_PCIE_RESET_WINDOW_SECS		5
#define BTINTEL_PCIE_FLR_MAX_RETRY	1

/* Alive interrupt context */
enum {
	BTINTEL_PCIE_ROM,
	BTINTEL_PCIE_FW_DL,
	BTINTEL_PCIE_HCI_RESET,
	BTINTEL_PCIE_INTEL_HCI_RESET1,
	BTINTEL_PCIE_INTEL_HCI_RESET2,
	BTINTEL_PCIE_D0,
	BTINTEL_PCIE_D3
};

/* Structure for dbgc fragment buffer
 * @buf_addr_lsb: LSB of the buffer's physical address
 * @buf_addr_msb: MSB of the buffer's physical address
 * @buf_size: Total size of the buffer
 */
struct btintel_pcie_dbgc_ctxt_buf {
	u32	buf_addr_lsb;
	u32	buf_addr_msb;
	u32	buf_size;
};

/* Structure for dbgc fragment
 * @magic_num: 0XA5A5A5A5
 * @ver: For Driver-FW compatibility
 * @total_size: Total size of the payload debug info
 * @num_buf: Num of allocated debug bufs
 * @bufs: All buffer's addresses and sizes
 */
struct btintel_pcie_dbgc_ctxt {
	u32	magic_num;
	u32     ver;
	u32     total_size;
	u32     num_buf;
	struct btintel_pcie_dbgc_ctxt_buf bufs[BTINTEL_PCIE_DBGC_BUFFER_COUNT];
};

struct btintel_pcie_removal {
	struct pci_dev *pdev;
	struct work_struct work;
};

static LIST_HEAD(btintel_pcie_recovery_list);
static DEFINE_SPINLOCK(btintel_pcie_recovery_lock);

static inline char *btintel_pcie_alivectxt_state2str(u32 alive_intr_ctxt)
{
	switch (alive_intr_ctxt) {
	case BTINTEL_PCIE_ROM:
		return "rom";
	case BTINTEL_PCIE_FW_DL:
		return "fw_dl";
	case BTINTEL_PCIE_D0:
		return "d0";
	case BTINTEL_PCIE_D3:
		return "d3";
	case BTINTEL_PCIE_HCI_RESET:
		return "hci_reset";
	case BTINTEL_PCIE_INTEL_HCI_RESET1:
		return "intel_reset1";
	case BTINTEL_PCIE_INTEL_HCI_RESET2:
		return "intel_reset2";
	default:
		return "unknown";
	}
}

/* This function initializes the memory for DBGC buffers and formats the
 * DBGC fragment which consists header info and DBGC buffer's LSB, MSB and
 * size as the payload
 */
static int btintel_pcie_setup_dbgc(struct btintel_pcie_data *data)
{
	struct btintel_pcie_dbgc_ctxt db_frag;
	struct data_buf *buf;
	int i;

	data->dbgc.count = BTINTEL_PCIE_DBGC_BUFFER_COUNT;
	data->dbgc.bufs = devm_kcalloc(&data->pdev->dev, data->dbgc.count,
				       sizeof(*buf), GFP_KERNEL);
	if (!data->dbgc.bufs)
		return -ENOMEM;

	data->dbgc.buf_v_addr = dmam_alloc_coherent(&data->pdev->dev,
						    data->dbgc.count *
						    BTINTEL_PCIE_DBGC_BUFFER_SIZE,
						    &data->dbgc.buf_p_addr,
						    GFP_KERNEL | __GFP_NOWARN);
	if (!data->dbgc.buf_v_addr)
		return -ENOMEM;

	data->dbgc.frag_v_addr = dmam_alloc_coherent(&data->pdev->dev,
						     sizeof(struct btintel_pcie_dbgc_ctxt),
						     &data->dbgc.frag_p_addr,
						     GFP_KERNEL | __GFP_NOWARN);
	if (!data->dbgc.frag_v_addr)
		return -ENOMEM;

	data->dbgc.frag_size = sizeof(struct btintel_pcie_dbgc_ctxt);

	db_frag.magic_num = BTINTEL_PCIE_MAGIC_NUM;
	db_frag.ver = BTINTEL_PCIE_DBGC_FRAG_VERSION;
	db_frag.total_size = BTINTEL_PCIE_DBGC_FRAG_PAYLOAD_SIZE;
	db_frag.num_buf = BTINTEL_PCIE_DBGC_FRAG_BUFFER_COUNT;

	for (i = 0; i < data->dbgc.count; i++) {
		buf = &data->dbgc.bufs[i];
		buf->data_p_addr = data->dbgc.buf_p_addr + i * BTINTEL_PCIE_DBGC_BUFFER_SIZE;
		buf->data = data->dbgc.buf_v_addr + i * BTINTEL_PCIE_DBGC_BUFFER_SIZE;
		db_frag.bufs[i].buf_addr_lsb = lower_32_bits(buf->data_p_addr);
		db_frag.bufs[i].buf_addr_msb = upper_32_bits(buf->data_p_addr);
		db_frag.bufs[i].buf_size = BTINTEL_PCIE_DBGC_BUFFER_SIZE;
	}

	memcpy(data->dbgc.frag_v_addr, &db_frag, sizeof(db_frag));
	return 0;
}

static inline void ipc_print_ia_ring(struct hci_dev *hdev, struct ia *ia,
				     u16 queue_num)
{
	bt_dev_dbg(hdev, "IA: %s: tr-h:%02u  tr-t:%02u  cr-h:%02u  cr-t:%02u",
		   queue_num == BTINTEL_PCIE_TXQ_NUM ? "TXQ" : "RXQ",
		   ia->tr_hia[queue_num], ia->tr_tia[queue_num],
		   ia->cr_hia[queue_num], ia->cr_tia[queue_num]);
}

static inline void ipc_print_urbd1(struct hci_dev *hdev, struct urbd1 *urbd1,
				   u16 index)
{
	bt_dev_dbg(hdev, "RXQ:urbd1(%u) frbd_tag:%u status: 0x%x fixed:0x%x",
		   index, urbd1->frbd_tag, urbd1->status, urbd1->fixed);
}

static struct btintel_pcie_data *btintel_pcie_get_data(struct msix_entry *entry)
{
	u8 queue = entry->entry;
	struct msix_entry *entries = entry - queue;

	return container_of(entries, struct btintel_pcie_data, msix_entries[0]);
}

/* Set the doorbell for TXQ to notify the device that @index (actually index-1)
 * of the TFD is updated and ready to transmit.
 */
static void btintel_pcie_set_tx_db(struct btintel_pcie_data *data, u16 index)
{
	u32 val;

	val = index;
	val |= (BTINTEL_PCIE_TX_DB_VEC << 16);

	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_HBUS_TARG_WRPTR, val);
}

/* Copy the data to next(@tfd_index) data buffer and update the TFD(transfer
 * descriptor) with the data length and the DMA address of the data buffer.
 */
static void btintel_pcie_prepare_tx(struct txq *txq, u16 tfd_index,
				    struct sk_buff *skb)
{
	struct data_buf *buf;
	struct tfd *tfd;

	tfd = &txq->tfds[tfd_index];
	memset(tfd, 0, sizeof(*tfd));

	buf = &txq->bufs[tfd_index];

	tfd->size = skb->len;
	tfd->addr = buf->data_p_addr;

	/* Copy the outgoing data to DMA buffer */
	memcpy(buf->data, skb->data, tfd->size);
}

static inline void btintel_pcie_dump_debug_registers(struct hci_dev *hdev)
{
	struct btintel_pcie_data *data = hci_get_drvdata(hdev);
	u16 cr_hia, cr_tia;
	u32 reg, mbox_reg;
	struct sk_buff *skb;
	u8 buf[80];

	skb = alloc_skb(1024, GFP_ATOMIC);
	if (!skb)
		return;

	snprintf(buf, sizeof(buf), "%s", "---- Dump of debug registers ---");
	bt_dev_dbg(hdev, "%s", buf);
	skb_put_data(skb, buf, strlen(buf));

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_BOOT_STAGE_REG);
	snprintf(buf, sizeof(buf), "boot stage: 0x%8.8x", reg);
	bt_dev_dbg(hdev, "%s", buf);
	skb_put_data(skb, buf, strlen(buf));
	data->boot_stage_cache = reg;

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_IPC_STATUS_REG);
	snprintf(buf, sizeof(buf), "ipc status: 0x%8.8x", reg);
	skb_put_data(skb, buf, strlen(buf));
	bt_dev_dbg(hdev, "%s", buf);

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_IPC_CONTROL_REG);
	snprintf(buf, sizeof(buf), "ipc control: 0x%8.8x", reg);
	skb_put_data(skb, buf, strlen(buf));
	bt_dev_dbg(hdev, "%s", buf);

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_IPC_SLEEP_CTL_REG);
	snprintf(buf, sizeof(buf), "ipc sleep control: 0x%8.8x", reg);
	skb_put_data(skb, buf, strlen(buf));
	bt_dev_dbg(hdev, "%s", buf);

	/*Read the Mail box status and registers*/
	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_MBOX_STATUS_REG);
	snprintf(buf, sizeof(buf), "mbox status: 0x%8.8x", reg);
	skb_put_data(skb, buf, strlen(buf));
	if (reg & BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX1) {
		mbox_reg = btintel_pcie_rd_reg32(data,
						 BTINTEL_PCIE_CSR_MBOX_1_REG);
		snprintf(buf, sizeof(buf), "mbox_1: 0x%8.8x", mbox_reg);
		skb_put_data(skb, buf, strlen(buf));
		bt_dev_dbg(hdev, "%s", buf);
	}

	if (reg & BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX2) {
		mbox_reg = btintel_pcie_rd_reg32(data,
						 BTINTEL_PCIE_CSR_MBOX_2_REG);
		snprintf(buf, sizeof(buf), "mbox_2: 0x%8.8x", mbox_reg);
		skb_put_data(skb, buf, strlen(buf));
		bt_dev_dbg(hdev, "%s", buf);
	}

	if (reg & BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX3) {
		mbox_reg = btintel_pcie_rd_reg32(data,
						 BTINTEL_PCIE_CSR_MBOX_3_REG);
		snprintf(buf, sizeof(buf), "mbox_3: 0x%8.8x", mbox_reg);
		skb_put_data(skb, buf, strlen(buf));
		bt_dev_dbg(hdev, "%s", buf);
	}

	if (reg & BTINTEL_PCIE_CSR_MBOX_STATUS_MBOX4) {
		mbox_reg = btintel_pcie_rd_reg32(data,
						 BTINTEL_PCIE_CSR_MBOX_4_REG);
		snprintf(buf, sizeof(buf), "mbox_4: 0x%8.8x", mbox_reg);
		skb_put_data(skb, buf, strlen(buf));
		bt_dev_dbg(hdev, "%s", buf);
	}

	cr_hia = data->ia.cr_hia[BTINTEL_PCIE_RXQ_NUM];
	cr_tia = data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM];
	snprintf(buf, sizeof(buf), "rxq: cr_tia: %u cr_hia: %u", cr_tia, cr_hia);
	skb_put_data(skb, buf, strlen(buf));
	bt_dev_dbg(hdev, "%s", buf);

	cr_hia = data->ia.cr_hia[BTINTEL_PCIE_TXQ_NUM];
	cr_tia = data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM];
	snprintf(buf, sizeof(buf), "txq: cr_tia: %u cr_hia: %u", cr_tia, cr_hia);
	skb_put_data(skb, buf, strlen(buf));
	bt_dev_dbg(hdev, "%s", buf);
	snprintf(buf, sizeof(buf), "--------------------------------");
	bt_dev_dbg(hdev, "%s", buf);

	hci_recv_diag(hdev, skb);
}

static int btintel_pcie_send_sync(struct btintel_pcie_data *data,
				  struct sk_buff *skb, u32 pkt_type, u16 opcode)
{
	int ret;
	u16 tfd_index;
	u32 old_ctxt;
	bool wait_on_alive = false;
	struct hci_dev *hdev = data->hdev;

	struct txq *txq = &data->txq;

	tfd_index = data->ia.tr_hia[BTINTEL_PCIE_TXQ_NUM];

	if (tfd_index > txq->count)
		return -ERANGE;

	/* Firmware raises alive interrupt on HCI_OP_RESET or
	 * BTINTEL_HCI_OP_RESET
	 */
	wait_on_alive = (pkt_type == BTINTEL_PCIE_HCI_CMD_PKT &&
		(opcode == BTINTEL_HCI_OP_RESET || opcode == HCI_OP_RESET));

	if (wait_on_alive) {
		data->gp0_received = false;
		old_ctxt = data->alive_intr_ctxt;
		data->alive_intr_ctxt =
			(opcode == BTINTEL_HCI_OP_RESET ? BTINTEL_PCIE_INTEL_HCI_RESET1 :
				BTINTEL_PCIE_HCI_RESET);
		bt_dev_dbg(data->hdev, "sending cmd: 0x%4.4x alive context changed: %s  ->  %s",
			   opcode, btintel_pcie_alivectxt_state2str(old_ctxt),
			   btintel_pcie_alivectxt_state2str(data->alive_intr_ctxt));
	}

	memcpy(skb_push(skb, BTINTEL_PCIE_HCI_TYPE_LEN), &pkt_type,
	       BTINTEL_PCIE_HCI_TYPE_LEN);

	/* Prepare for TX. It updates the TFD with the length of data and
	 * address of the DMA buffer, and copy the data to the DMA buffer
	 */
	btintel_pcie_prepare_tx(txq, tfd_index, skb);

	tfd_index = (tfd_index + 1) % txq->count;
	data->ia.tr_hia[BTINTEL_PCIE_TXQ_NUM] = tfd_index;

	/* Arm wait event condition */
	data->tx_wait_done = false;

	/* Set the doorbell to notify the device */
	btintel_pcie_set_tx_db(data, tfd_index);

	/* Wait for the complete interrupt - URBD0 */
	ret = wait_event_timeout(data->tx_wait_q, data->tx_wait_done,
				 msecs_to_jiffies(BTINTEL_PCIE_TX_WAIT_TIMEOUT_MS));
	if (!ret) {
		bt_dev_err(data->hdev, "Timeout (%u ms) on tx completion",
			   BTINTEL_PCIE_TX_WAIT_TIMEOUT_MS);
		btintel_pcie_dump_debug_registers(data->hdev);
		return -ETIME;
	}

	if (wait_on_alive) {
		ret = wait_event_timeout(data->gp0_wait_q,
					 data->gp0_received,
					 msecs_to_jiffies(BTINTEL_DEFAULT_INTR_TIMEOUT_MS));
		if (!ret) {
			hdev->stat.err_tx++;
			bt_dev_err(hdev, "Timeout (%u ms)  on alive interrupt, alive context: %s",
				   BTINTEL_DEFAULT_INTR_TIMEOUT_MS,
				   btintel_pcie_alivectxt_state2str(data->alive_intr_ctxt));
			return  -ETIME;
		}
	}
	return 0;
}

/* Set the doorbell for RXQ to notify the device that @index (actually index-1)
 * is available to receive the data
 */
static void btintel_pcie_set_rx_db(struct btintel_pcie_data *data, u16 index)
{
	u32 val;

	val = index;
	val |= (BTINTEL_PCIE_RX_DB_VEC << 16);

	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_HBUS_TARG_WRPTR, val);
}

/* Update the FRBD (free buffer descriptor) with the @frbd_index and the
 * DMA address of the free buffer.
 */
static void btintel_pcie_prepare_rx(struct rxq *rxq, u16 frbd_index)
{
	struct data_buf *buf;
	struct frbd *frbd;

	/* Get the buffer of the FRBD for DMA */
	buf = &rxq->bufs[frbd_index];

	frbd = &rxq->frbds[frbd_index];
	memset(frbd, 0, sizeof(*frbd));

	/* Update FRBD */
	frbd->tag = frbd_index;
	frbd->addr = buf->data_p_addr;
}

static int btintel_pcie_submit_rx(struct btintel_pcie_data *data)
{
	u16 frbd_index;
	struct rxq *rxq = &data->rxq;

	frbd_index = data->ia.tr_hia[BTINTEL_PCIE_RXQ_NUM];

	if (frbd_index > rxq->count)
		return -ERANGE;

	/* Prepare for RX submit. It updates the FRBD with the address of DMA
	 * buffer
	 */
	btintel_pcie_prepare_rx(rxq, frbd_index);

	frbd_index = (frbd_index + 1) % rxq->count;
	data->ia.tr_hia[BTINTEL_PCIE_RXQ_NUM] = frbd_index;
	ipc_print_ia_ring(data->hdev, &data->ia, BTINTEL_PCIE_RXQ_NUM);

	/* Set the doorbell to notify the device */
	btintel_pcie_set_rx_db(data, frbd_index);

	return 0;
}

static int btintel_pcie_start_rx(struct btintel_pcie_data *data)
{
	int i, ret;
	struct rxq *rxq = &data->rxq;

	/* Post (BTINTEL_PCIE_RX_DESCS_COUNT - 3) buffers to overcome the
	 * hardware issues leading to race condition at the firmware.
	 */

	for (i = 0; i < rxq->count - 3; i++) {
		ret = btintel_pcie_submit_rx(data);
		if (ret)
			return ret;
	}

	return 0;
}

static void btintel_pcie_reset_ia(struct btintel_pcie_data *data)
{
	memset(data->ia.tr_hia, 0, sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES);
	memset(data->ia.tr_tia, 0, sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES);
	memset(data->ia.cr_hia, 0, sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES);
	memset(data->ia.cr_tia, 0, sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES);
}

static int btintel_pcie_reset_bt(struct btintel_pcie_data *data)
{
	u32 reg;
	int retry = 3;

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);

	reg &= ~(BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_ENA |
			BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_INIT |
			BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_INIT);
	reg |= BTINTEL_PCIE_CSR_FUNC_CTRL_BUS_MASTER_DISCON;

	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg);

	do {
		reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);
		if (reg & BTINTEL_PCIE_CSR_FUNC_CTRL_BUS_MASTER_STS)
			break;
		usleep_range(10000, 12000);

	} while (--retry > 0);
	usleep_range(10000, 12000);

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);

	reg &= ~(BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_ENA |
			BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_INIT |
			BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_INIT);
	reg |= BTINTEL_PCIE_CSR_FUNC_CTRL_SW_RESET;
	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg);
	usleep_range(10000, 12000);

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);
	bt_dev_dbg(data->hdev, "csr register after reset: 0x%8.8x", reg);

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_BOOT_STAGE_REG);

	/* If shared hardware reset is success then boot stage register shall be
	 * set to 0
	 */
	return reg == 0 ? 0 : -ENODEV;
}

static void btintel_pcie_mac_init(struct btintel_pcie_data *data)
{
	u32 reg;

	/* Set MAC_INIT bit to start primary bootloader */
	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);
	reg &= ~(BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_INIT |
			BTINTEL_PCIE_CSR_FUNC_CTRL_BUS_MASTER_DISCON |
			BTINTEL_PCIE_CSR_FUNC_CTRL_SW_RESET);
	reg |= (BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_ENA |
			BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_INIT);
	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg);
}

static int btintel_pcie_get_mac_access(struct btintel_pcie_data *data)
{
	u32 reg;
	int retry = 15;

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);

	reg |= BTINTEL_PCIE_CSR_FUNC_CTRL_STOP_MAC_ACCESS_DIS;
	reg |= BTINTEL_PCIE_CSR_FUNC_CTRL_XTAL_CLK_REQ;
	if ((reg & BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_STS) == 0)
		reg |= BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ;

	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg);

	do {
		reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);
		if (reg & BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_STS)
			return 0;
		/* Need delay here for Target Access harwdware to settle down*/
		usleep_range(1000, 1200);

	} while (--retry > 0);

	return -ETIME;
}

static void btintel_pcie_release_mac_access(struct btintel_pcie_data *data)
{
	u32 reg;

	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);

	if (reg & BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ)
		reg &= ~BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ;

	if (reg & BTINTEL_PCIE_CSR_FUNC_CTRL_STOP_MAC_ACCESS_DIS)
		reg &= ~BTINTEL_PCIE_CSR_FUNC_CTRL_STOP_MAC_ACCESS_DIS;

	if (reg & BTINTEL_PCIE_CSR_FUNC_CTRL_XTAL_CLK_REQ)
		reg &= ~BTINTEL_PCIE_CSR_FUNC_CTRL_XTAL_CLK_REQ;

	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg);
}

static void *btintel_pcie_copy_tlv(void *dest, enum btintel_pcie_tlv_type type,
				   void *data, size_t size)
{
	struct intel_tlv *tlv;

	tlv = dest;
	tlv->type = type;
	tlv->len = size;
	memcpy(tlv->val, data, tlv->len);
	return dest + sizeof(*tlv) + size;
}

static int btintel_pcie_read_dram_buffers(struct btintel_pcie_data *data)
{
	u32 offset, prev_size, wr_ptr_status, dump_size, data_len;
	struct btintel_pcie_dbgc *dbgc = &data->dbgc;
	struct hci_dev *hdev = data->hdev;
	u8 *pdata, *p, buf_idx;
	struct intel_tlv *tlv;
	struct timespec64 now;
	struct tm tm_now;
	char fw_build[128];
	char ts[128];
	char vendor[64];
	char driver[64];

	if (!IS_ENABLED(CONFIG_DEV_COREDUMP))
		return -EOPNOTSUPP;


	wr_ptr_status = btintel_pcie_rd_dev_mem(data, BTINTEL_PCIE_DBGC_CUR_DBGBUFF_STATUS);
	offset = wr_ptr_status & BTINTEL_PCIE_DBG_OFFSET_BIT_MASK;

	buf_idx = BTINTEL_PCIE_DBGC_DBG_BUF_IDX(wr_ptr_status);
	if (buf_idx > dbgc->count) {
		bt_dev_warn(hdev, "Buffer index is invalid");
		return -EINVAL;
	}

	prev_size = buf_idx * BTINTEL_PCIE_DBGC_BUFFER_SIZE;
	if (prev_size + offset >= prev_size)
		data->dmp_hdr.write_ptr = prev_size + offset;
	else
		return -EINVAL;

	snprintf(vendor, sizeof(vendor), "Vendor: Intel\n");
	snprintf(driver, sizeof(driver), "Driver: %s\n",
		 data->dmp_hdr.driver_name);

	ktime_get_real_ts64(&now);
	time64_to_tm(now.tv_sec, 0, &tm_now);
	snprintf(ts, sizeof(ts), "Dump Time: %02d-%02d-%04ld %02d:%02d:%02d",
				 tm_now.tm_mday, tm_now.tm_mon + 1, tm_now.tm_year + 1900,
				 tm_now.tm_hour, tm_now.tm_min, tm_now.tm_sec);

	snprintf(fw_build, sizeof(fw_build),
			    "Firmware Timestamp: Year %u WW %02u buildtype %u build %u",
			    2000 + (data->dmp_hdr.fw_timestamp >> 8),
			    data->dmp_hdr.fw_timestamp & 0xff, data->dmp_hdr.fw_build_type,
			    data->dmp_hdr.fw_build_num);

	data_len = sizeof(*tlv) + sizeof(data->dmp_hdr.cnvi_bt) +
		sizeof(*tlv) + sizeof(data->dmp_hdr.write_ptr) +
		sizeof(*tlv) + sizeof(data->dmp_hdr.wrap_ctr) +
		sizeof(*tlv) + sizeof(data->dmp_hdr.trigger_reason) +
		sizeof(*tlv) + sizeof(data->dmp_hdr.fw_git_sha1) +
		sizeof(*tlv) + sizeof(data->dmp_hdr.cnvr_top) +
		sizeof(*tlv) + sizeof(data->dmp_hdr.cnvi_top) +
		sizeof(*tlv) + strlen(ts) +
		sizeof(*tlv) + strlen(fw_build) +
		sizeof(*tlv) + strlen(vendor) +
		sizeof(*tlv) + strlen(driver);

	/*
	 * sizeof(u32) - signature
	 * sizeof(data_len) - to store tlv data size
	 * data_len - TLV data
	 */
	dump_size = sizeof(u32) + sizeof(data_len) + data_len;


	/* Add debug buffers data length to dump size */
	dump_size += BTINTEL_PCIE_DBGC_BUFFER_SIZE * dbgc->count;

	pdata = vmalloc(dump_size);
	if (!pdata)
		return -ENOMEM;
	p = pdata;

	*(u32 *)p = BTINTEL_PCIE_MAGIC_NUM;
	p += sizeof(u32);

	*(u32 *)p = data_len;
	p += sizeof(u32);


	p = btintel_pcie_copy_tlv(p, BTINTEL_VENDOR, vendor, strlen(vendor));
	p = btintel_pcie_copy_tlv(p, BTINTEL_DRIVER, driver, strlen(driver));
	p = btintel_pcie_copy_tlv(p, BTINTEL_DUMP_TIME, ts, strlen(ts));
	p = btintel_pcie_copy_tlv(p, BTINTEL_FW_BUILD, fw_build,
				  strlen(fw_build));
	p = btintel_pcie_copy_tlv(p, BTINTEL_CNVI_BT, &data->dmp_hdr.cnvi_bt,
				  sizeof(data->dmp_hdr.cnvi_bt));
	p = btintel_pcie_copy_tlv(p, BTINTEL_WRITE_PTR, &data->dmp_hdr.write_ptr,
				  sizeof(data->dmp_hdr.write_ptr));
	p = btintel_pcie_copy_tlv(p, BTINTEL_WRAP_CTR, &data->dmp_hdr.wrap_ctr,
				  sizeof(data->dmp_hdr.wrap_ctr));

	data->dmp_hdr.wrap_ctr = btintel_pcie_rd_dev_mem(data,
							 BTINTEL_PCIE_DBGC_DBGBUFF_WRAP_ARND);

	p = btintel_pcie_copy_tlv(p, BTINTEL_TRIGGER_REASON, &data->dmp_hdr.trigger_reason,
				  sizeof(data->dmp_hdr.trigger_reason));
	p = btintel_pcie_copy_tlv(p, BTINTEL_FW_SHA, &data->dmp_hdr.fw_git_sha1,
				  sizeof(data->dmp_hdr.fw_git_sha1));
	p = btintel_pcie_copy_tlv(p, BTINTEL_CNVR_TOP, &data->dmp_hdr.cnvr_top,
				  sizeof(data->dmp_hdr.cnvr_top));
	p = btintel_pcie_copy_tlv(p, BTINTEL_CNVI_TOP, &data->dmp_hdr.cnvi_top,
				  sizeof(data->dmp_hdr.cnvi_top));

	memcpy(p, dbgc->bufs[0].data, dbgc->count * BTINTEL_PCIE_DBGC_BUFFER_SIZE);
	dev_coredumpv(&hdev->dev, pdata, dump_size, GFP_KERNEL);
	return 0;
}

static void btintel_pcie_dump_traces(struct hci_dev *hdev)
{
	struct btintel_pcie_data *data = hci_get_drvdata(hdev);
	int ret = 0;

	ret = btintel_pcie_get_mac_access(data);
	if (ret) {
		bt_dev_err(hdev, "Failed to get mac access: (%d)", ret);
		return;
	}

	ret = btintel_pcie_read_dram_buffers(data);

	btintel_pcie_release_mac_access(data);

	if (ret)
		bt_dev_err(hdev, "Failed to dump traces: (%d)", ret);
}

/* This function enables BT function by setting BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_INIT bit in
 * BTINTEL_PCIE_CSR_FUNC_CTRL_REG register and wait for MSI-X with
 * BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0.
 * Then the host reads firmware version from BTINTEL_CSR_F2D_MBX and the boot stage
 * from BTINTEL_PCIE_CSR_BOOT_STAGE_REG.
 */
static int btintel_pcie_enable_bt(struct btintel_pcie_data *data)
{
	int err;
	u32 reg;

	data->gp0_received = false;

	/* Update the DMA address of CI struct to CSR */
	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_CI_ADDR_LSB_REG,
			      data->ci_p_addr & 0xffffffff);
	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_CI_ADDR_MSB_REG,
			      (u64)data->ci_p_addr >> 32);

	/* Reset the cached value of boot stage. it is updated by the MSI-X
	 * gp0 interrupt handler.
	 */
	data->boot_stage_cache = 0x0;

	/* Set MAC_INIT bit to start primary bootloader */
	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);
	reg &= ~(BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_INIT |
			BTINTEL_PCIE_CSR_FUNC_CTRL_BUS_MASTER_DISCON |
			BTINTEL_PCIE_CSR_FUNC_CTRL_SW_RESET);
	reg |= (BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_ENA |
			BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_INIT);

	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg);

	/* MAC is ready. Enable BT FUNC */
	btintel_pcie_set_reg_bits(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG,
				  BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_INIT);

	btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);

	/* wait for interrupt from the device after booting up to primary
	 * bootloader.
	 */
	data->alive_intr_ctxt = BTINTEL_PCIE_ROM;
	err = wait_event_timeout(data->gp0_wait_q, data->gp0_received,
				 msecs_to_jiffies(BTINTEL_DEFAULT_INTR_TIMEOUT_MS));
	if (!err)
		return -ETIME;

	/* Check cached boot stage is BTINTEL_PCIE_CSR_BOOT_STAGE_ROM(BIT(0)) */
	if (~data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_ROM)
		return -ENODEV;

	return 0;
}

static inline bool btintel_pcie_in_op(struct btintel_pcie_data *data)
{
	return data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_OPFW;
}

static inline bool btintel_pcie_in_iml(struct btintel_pcie_data *data)
{
	return data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_IML &&
		!(data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_OPFW);
}

static inline bool btintel_pcie_in_d3(struct btintel_pcie_data *data)
{
	return data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY;
}

static inline bool btintel_pcie_in_d0(struct btintel_pcie_data *data)
{
	return !(data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_D3_STATE_READY);
}

static inline bool btintel_pcie_in_device_halt(struct btintel_pcie_data *data)
{
	return data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_HALTED;
}

static void btintel_pcie_wr_sleep_cntrl(struct btintel_pcie_data *data,
					u32 dxstate)
{
	bt_dev_dbg(data->hdev, "writing sleep_ctl_reg: 0x%8.8x", dxstate);
	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_IPC_SLEEP_CTL_REG, dxstate);
}

static int btintel_pcie_read_device_mem(struct btintel_pcie_data *data,
					void *buf, u32 dev_addr, int len)
{
	int err;
	u32 *val = buf;

	/* Get device mac access */
	err = btintel_pcie_get_mac_access(data);
	if (err) {
		bt_dev_err(data->hdev, "Failed to get mac access %d", err);
		return err;
	}

	for (; len > 0; len -= 4, dev_addr += 4, val++)
		*val = btintel_pcie_rd_dev_mem(data, dev_addr);

	btintel_pcie_release_mac_access(data);

	return 0;
}

static inline bool btintel_pcie_in_lockdown(struct btintel_pcie_data *data)
{
	return (data->boot_stage_cache &
		BTINTEL_PCIE_CSR_BOOT_STAGE_ROM_LOCKDOWN) ||
		(data->boot_stage_cache &
		 BTINTEL_PCIE_CSR_BOOT_STAGE_IML_LOCKDOWN);
}

static inline bool btintel_pcie_in_error(struct btintel_pcie_data *data)
{
	return (data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_DEVICE_ERR) ||
		(data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_ABORT_HANDLER);
}

static void btintel_pcie_msix_gp1_handler(struct btintel_pcie_data *data)
{
	bt_dev_err(data->hdev, "Received gp1 mailbox interrupt");
	btintel_pcie_dump_debug_registers(data->hdev);
}

/* This function handles the MSI-X interrupt for gp0 cause (bit 0 in
 * BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES) which is sent for boot stage and image response.
 */
static void btintel_pcie_msix_gp0_handler(struct btintel_pcie_data *data)
{
	bool submit_rx, signal_waitq;
	u32 reg, old_ctxt;

	/* This interrupt is for three different causes and it is not easy to
	 * know what causes the interrupt. So, it compares each register value
	 * with cached value and update it before it wake up the queue.
	 */
	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_BOOT_STAGE_REG);
	if (reg != data->boot_stage_cache)
		data->boot_stage_cache = reg;

	bt_dev_dbg(data->hdev, "Alive context: %s old_boot_stage: 0x%8.8x new_boot_stage: 0x%8.8x",
		   btintel_pcie_alivectxt_state2str(data->alive_intr_ctxt),
		   data->boot_stage_cache, reg);
	reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_IMG_RESPONSE_REG);
	if (reg != data->img_resp_cache)
		data->img_resp_cache = reg;

	if (btintel_pcie_in_error(data)) {
		bt_dev_err(data->hdev, "Controller in error state");
		btintel_pcie_dump_debug_registers(data->hdev);
		return;
	}

	if (btintel_pcie_in_lockdown(data)) {
		bt_dev_err(data->hdev, "Controller in lockdown state");
		btintel_pcie_dump_debug_registers(data->hdev);
		return;
	}

	data->gp0_received = true;

	old_ctxt = data->alive_intr_ctxt;
	submit_rx = false;
	signal_waitq = false;

	switch (data->alive_intr_ctxt) {
	case BTINTEL_PCIE_ROM:
		data->alive_intr_ctxt = BTINTEL_PCIE_FW_DL;
		signal_waitq = true;
		break;
	case BTINTEL_PCIE_FW_DL:
		/* Error case is already handled. Ideally control shall not
		 * reach here
		 */
		break;
	case BTINTEL_PCIE_INTEL_HCI_RESET1:
		if (btintel_pcie_in_op(data)) {
			submit_rx = true;
			signal_waitq = true;
			break;
		}

		if (btintel_pcie_in_iml(data)) {
			submit_rx = true;
			signal_waitq = true;
			data->alive_intr_ctxt = BTINTEL_PCIE_FW_DL;
			break;
		}
		break;
	case BTINTEL_PCIE_INTEL_HCI_RESET2:
		if (btintel_test_and_clear_flag(data->hdev, INTEL_WAIT_FOR_D0)) {
			btintel_wake_up_flag(data->hdev, INTEL_WAIT_FOR_D0);
			data->alive_intr_ctxt = BTINTEL_PCIE_D0;
		}
		break;
	case BTINTEL_PCIE_D0:
		if (btintel_pcie_in_d3(data)) {
			data->alive_intr_ctxt = BTINTEL_PCIE_D3;
			signal_waitq = true;
			break;
		}
		break;
	case BTINTEL_PCIE_D3:
		if (btintel_pcie_in_d0(data)) {
			data->alive_intr_ctxt = BTINTEL_PCIE_D0;
			submit_rx = true;
			signal_waitq = true;
			break;
		}
		break;
	case BTINTEL_PCIE_HCI_RESET:
		data->alive_intr_ctxt = BTINTEL_PCIE_D0;
		submit_rx = true;
		signal_waitq = true;
		break;
	default:
		bt_dev_err(data->hdev, "Unknown state: 0x%2.2x",
			   data->alive_intr_ctxt);
		break;
	}

	if (submit_rx) {
		btintel_pcie_reset_ia(data);
		btintel_pcie_start_rx(data);
	}

	if (signal_waitq) {
		bt_dev_dbg(data->hdev, "wake up gp0 wait_q");
		wake_up(&data->gp0_wait_q);
	}

	if (old_ctxt != data->alive_intr_ctxt)
		bt_dev_dbg(data->hdev, "alive context changed: %s  ->  %s",
			   btintel_pcie_alivectxt_state2str(old_ctxt),
			   btintel_pcie_alivectxt_state2str(data->alive_intr_ctxt));
}

/* This function handles the MSX-X interrupt for rx queue 0 which is for TX
 */
static void btintel_pcie_msix_tx_handle(struct btintel_pcie_data *data)
{
	u16 cr_tia, cr_hia;
	struct txq *txq;
	struct urbd0 *urbd0;

	cr_tia = data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM];
	cr_hia = data->ia.cr_hia[BTINTEL_PCIE_TXQ_NUM];

	if (cr_tia == cr_hia)
		return;

	txq = &data->txq;

	while (cr_tia != cr_hia) {
		data->tx_wait_done = true;
		wake_up(&data->tx_wait_q);

		urbd0 = &txq->urbd0s[cr_tia];

		if (urbd0->tfd_index > txq->count)
			return;

		cr_tia = (cr_tia + 1) % txq->count;
		data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM] = cr_tia;
		ipc_print_ia_ring(data->hdev, &data->ia, BTINTEL_PCIE_TXQ_NUM);
	}
}

static int btintel_pcie_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_event_hdr *hdr = (void *)skb->data;
	struct btintel_pcie_data *data = hci_get_drvdata(hdev);

	if (skb->len > HCI_EVENT_HDR_SIZE && hdr->evt == 0xff &&
	    hdr->plen > 0) {
		const void *ptr = skb->data + HCI_EVENT_HDR_SIZE + 1;
		unsigned int len = skb->len - HCI_EVENT_HDR_SIZE - 1;

		if (btintel_test_flag(hdev, INTEL_BOOTLOADER)) {
			switch (skb->data[2]) {
			case 0x02:
				/* When switching to the operational firmware
				 * the device sends a vendor specific event
				 * indicating that the bootup completed.
				 */
				btintel_bootup(hdev, ptr, len);

				/* If bootup event is from operational image,
				 * driver needs to write sleep control register to
				 * move into D0 state
				 */
				if (btintel_pcie_in_op(data)) {
					btintel_pcie_wr_sleep_cntrl(data, BTINTEL_PCIE_STATE_D0);
					data->alive_intr_ctxt = BTINTEL_PCIE_INTEL_HCI_RESET2;
					kfree_skb(skb);
					return 0;
				}

				if (btintel_pcie_in_iml(data)) {
					/* In case of IML, there is no concept
					 * of D0 transition. Just mimic as if
					 * IML moved to D0 by clearing INTEL_WAIT_FOR_D0
					 * bit and waking up the task waiting on
					 * INTEL_WAIT_FOR_D0. This is required
					 * as intel_boot() is common function for
					 * both IML and OP image loading.
					 */
					if (btintel_test_and_clear_flag(data->hdev,
									INTEL_WAIT_FOR_D0))
						btintel_wake_up_flag(data->hdev,
								     INTEL_WAIT_FOR_D0);
				}
				kfree_skb(skb);
				return 0;
			case 0x06:
				/* When the firmware loading completes the
				 * device sends out a vendor specific event
				 * indicating the result of the firmware
				 * loading.
				 */
				btintel_secure_send_result(hdev, ptr, len);
				kfree_skb(skb);
				return 0;
			}
		}

		/* This is a debug event that comes from IML and OP image when it
		 * starts execution. There is no need pass this event to stack.
		 */
		if (skb->data[2] == 0x97) {
			hci_recv_diag(hdev, skb);
			return 0;
		}
	}

	return hci_recv_frame(hdev, skb);
}
/* Process the received rx data
 * It check the frame header to identify the data type and create skb
 * and calling HCI API
 */
static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,
				       struct sk_buff *skb)
{
	int ret;
	u8 pkt_type;
	u16 plen;
	u32 pcie_pkt_type;
	void *pdata;
	struct hci_dev *hdev = data->hdev;

	spin_lock(&data->hci_rx_lock);

	/* The first 4 bytes indicates the Intel PCIe specific packet type */
	pdata = skb_pull_data(skb, BTINTEL_PCIE_HCI_TYPE_LEN);
	if (!pdata) {
		bt_dev_err(hdev, "Corrupted packet received");
		ret = -EILSEQ;
		goto exit_error;
	}

	pcie_pkt_type = get_unaligned_le32(pdata);

	switch (pcie_pkt_type) {
	case BTINTEL_PCIE_HCI_ACL_PKT:
		if (skb->len >= HCI_ACL_HDR_SIZE) {
			plen = HCI_ACL_HDR_SIZE + __le16_to_cpu(hci_acl_hdr(skb)->dlen);
			pkt_type = HCI_ACLDATA_PKT;
		} else {
			bt_dev_err(hdev, "ACL packet is too short");
			ret = -EILSEQ;
			goto exit_error;
		}
		break;

	case BTINTEL_PCIE_HCI_SCO_PKT:
		if (skb->len >= HCI_SCO_HDR_SIZE) {
			plen = HCI_SCO_HDR_SIZE + hci_sco_hdr(skb)->dlen;
			pkt_type = HCI_SCODATA_PKT;
		} else {
			bt_dev_err(hdev, "SCO packet is too short");
			ret = -EILSEQ;
			goto exit_error;
		}
		break;

	case BTINTEL_PCIE_HCI_EVT_PKT:
		if (skb->len >= HCI_EVENT_HDR_SIZE) {
			plen = HCI_EVENT_HDR_SIZE + hci_event_hdr(skb)->plen;
			pkt_type = HCI_EVENT_PKT;
		} else {
			bt_dev_err(hdev, "Event packet is too short");
			ret = -EILSEQ;
			goto exit_error;
		}
		break;

	case BTINTEL_PCIE_HCI_ISO_PKT:
		if (skb->len >= HCI_ISO_HDR_SIZE) {
			plen = HCI_ISO_HDR_SIZE + __le16_to_cpu(hci_iso_hdr(skb)->dlen);
			pkt_type = HCI_ISODATA_PKT;
		} else {
			bt_dev_err(hdev, "ISO packet is too short");
			ret = -EILSEQ;
			goto exit_error;
		}
		break;

	default:
		bt_dev_err(hdev, "Invalid packet type received: 0x%4.4x",
			   pcie_pkt_type);
		ret = -EINVAL;
		goto exit_error;
	}

	if (skb->len < plen) {
		bt_dev_err(hdev, "Received corrupted packet. type: 0x%2.2x",
			   pkt_type);
		ret = -EILSEQ;
		goto exit_error;
	}

	bt_dev_dbg(hdev, "pkt_type: 0x%2.2x len: %u", pkt_type, plen);

	hci_skb_pkt_type(skb) = pkt_type;
	hdev->stat.byte_rx += plen;
	skb_trim(skb, plen);

	if (pcie_pkt_type == BTINTEL_PCIE_HCI_EVT_PKT)
		ret = btintel_pcie_recv_event(hdev, skb);
	else
		ret = hci_recv_frame(hdev, skb);
	skb = NULL; /* skb is freed in the callee  */

exit_error:
	kfree_skb(skb);

	if (ret)
		hdev->stat.err_rx++;

	spin_unlock(&data->hci_rx_lock);

	return ret;
}

static void btintel_pcie_read_hwexp(struct btintel_pcie_data *data)
{
	int len, err, offset, pending;
	struct sk_buff *skb;
	u8 *buf, prefix[64];
	u32 addr, val;
	u16 pkt_len;

	struct tlv {
		u8	type;
		__le16	len;
		u8	val[];
	} __packed;

	struct tlv *tlv;

	switch (data->dmp_hdr.cnvi_top & 0xfff) {
	case BTINTEL_CNVI_BLAZARI:
	case BTINTEL_CNVI_BLAZARIW:
		/* only from step B0 onwards */
		if (INTEL_CNVX_TOP_STEP(data->dmp_hdr.cnvi_top) != 0x01)
			return;
		len = BTINTEL_PCIE_BLZR_HWEXP_SIZE; /* exception data length */
		addr = BTINTEL_PCIE_BLZR_HWEXP_DMP_ADDR;
	break;
	case BTINTEL_CNVI_SCP:
		len = BTINTEL_PCIE_SCP_HWEXP_SIZE;
		addr = BTINTEL_PCIE_SCP_HWEXP_DMP_ADDR;
	break;
	default:
		bt_dev_err(data->hdev, "Unsupported cnvi 0x%8.8x", data->dmp_hdr.cnvi_top);
		return;
	}

	buf = kzalloc(len, GFP_KERNEL);
	if (!buf)
		goto exit_on_error;

	btintel_pcie_mac_init(data);

	err = btintel_pcie_read_device_mem(data, buf, addr, len);
	if (err)
		goto exit_on_error;

	val = get_unaligned_le32(buf);
	if (val != BTINTEL_PCIE_MAGIC_NUM) {
		bt_dev_err(data->hdev, "Invalid exception dump signature: 0x%8.8x",
			   val);
		goto exit_on_error;
	}

	snprintf(prefix, sizeof(prefix), "Bluetooth: %s: ", bt_dev_name(data->hdev));

	offset = 4;
	do {
		pending = len - offset;
		if (pending < sizeof(*tlv))
			break;
		tlv = (struct tlv *)(buf + offset);

		/* If type == 0, then there are no more TLVs to be parsed */
		if (!tlv->type) {
			bt_dev_dbg(data->hdev, "Invalid TLV type 0");
			break;
		}
		pkt_len = le16_to_cpu(tlv->len);
		offset += sizeof(*tlv);
		pending = len - offset;
		if (pkt_len > pending)
			break;

		offset += pkt_len;

		 /* Only TLVs of type == 1 are HCI events, no need to process other
		  * TLVs
		  */
		if (tlv->type != 1)
			continue;

		bt_dev_dbg(data->hdev, "TLV packet length: %u", pkt_len);
		if (pkt_len > HCI_MAX_EVENT_SIZE)
			break;
		skb = bt_skb_alloc(pkt_len, GFP_KERNEL);
		if (!skb)
			goto exit_on_error;
		hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
		skb_put_data(skb, tlv->val, pkt_len);

		/* copy Intel specific pcie packet type */
		val = BTINTEL_PCIE_HCI_EVT_PKT;
		memcpy(skb_push(skb, BTINTEL_PCIE_HCI_TYPE_LEN), &val,
		       BTINTEL_PCIE_HCI_TYPE_LEN);

		print_hex_dump(KERN_DEBUG, prefix, DUMP_PREFIX_OFFSET, 16, 1,
			       tlv->val, pkt_len, false);

		btintel_pcie_recv_frame(data, skb);
	} while (offset < len);

exit_on_error:
	kfree(buf);
}

static void btintel_pcie_msix_hw_exp_handler(struct btintel_pcie_data *data)
{
	bt_dev_err(data->hdev, "Received hw exception interrupt");

	if (test_and_set_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags))
		return;

	if (test_and_set_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags))
		return;

	/* Trigger device core dump when there is HW  exception */
	if (!test_and_set_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags))
		data->dmp_hdr.trigger_reason = BTINTEL_PCIE_TRIGGER_REASON_FW_ASSERT;

	queue_work(data->workqueue, &data->rx_work);
}

static void btintel_pcie_rx_work(struct work_struct *work)
{
	struct btintel_pcie_data *data = container_of(work,
					struct btintel_pcie_data, rx_work);
	struct sk_buff *skb;

	if (test_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags)) {
		btintel_pcie_dump_traces(data->hdev);
		clear_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags);
	}

	if (test_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags)) {
		/* Unlike usb products, controller will not send hardware
		 * exception event on exception. Instead controller writes the
		 * hardware event to device memory along with optional debug
		 * events, raises MSIX and halts. Driver shall read the
		 * exception event from device memory and passes it stack for
		 * further processing.
		 */
		btintel_pcie_read_hwexp(data);
		clear_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags);
	}

	/* Process the sk_buf in queue and send to the HCI layer */
	while ((skb = skb_dequeue(&data->rx_skb_q))) {
		btintel_pcie_recv_frame(data, skb);
	}
}

/* create sk_buff with data and save it to queue and start RX work */
static int btintel_pcie_submit_rx_work(struct btintel_pcie_data *data, u8 status,
				       void *buf)
{
	int ret, len;
	struct rfh_hdr *rfh_hdr;
	struct sk_buff *skb;

	rfh_hdr = buf;

	len = rfh_hdr->packet_len;
	if (len <= 0) {
		ret = -EINVAL;
		goto resubmit;
	}

	/* Remove RFH header */
	buf += sizeof(*rfh_hdr);

	skb = alloc_skb(len, GFP_ATOMIC);
	if (!skb)
		goto resubmit;

	skb_put_data(skb, buf, len);
	skb_queue_tail(&data->rx_skb_q, skb);
	queue_work(data->workqueue, &data->rx_work);

resubmit:
	ret = btintel_pcie_submit_rx(data);

	return ret;
}

/* Handles the MSI-X interrupt for rx queue 1 which is for RX */
static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data)
{
	u16 cr_hia, cr_tia;
	struct rxq *rxq;
	struct urbd1 *urbd1;
	struct data_buf *buf;
	int ret;
	struct hci_dev *hdev = data->hdev;

	cr_hia = data->ia.cr_hia[BTINTEL_PCIE_RXQ_NUM];
	cr_tia = data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM];

	bt_dev_dbg(hdev, "RXQ: cr_hia: %u  cr_tia: %u", cr_hia, cr_tia);

	/* Check CR_TIA and CR_HIA for change */
	if (cr_tia == cr_hia)
		return;

	rxq = &data->rxq;

	/* The firmware sends multiple CD in a single MSI-X and it needs to
	 * process all received CDs in this interrupt.
	 */
	while (cr_tia != cr_hia) {
		urbd1 = &rxq->urbd1s[cr_tia];
		ipc_print_urbd1(data->hdev, urbd1, cr_tia);

		buf = &rxq->bufs[urbd1->frbd_tag];
		if (!buf) {
			bt_dev_err(hdev, "RXQ: failed to get the DMA buffer for %d",
				   urbd1->frbd_tag);
			return;
		}

		ret = btintel_pcie_submit_rx_work(data, urbd1->status,
						  buf->data);
		if (ret) {
			bt_dev_err(hdev, "RXQ: failed to submit rx request");
			return;
		}

		cr_tia = (cr_tia + 1) % rxq->count;
		data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM] = cr_tia;
		ipc_print_ia_ring(data->hdev, &data->ia, BTINTEL_PCIE_RXQ_NUM);
	}
}

static inline bool btintel_pcie_is_rxq_empty(struct btintel_pcie_data *data)
{
	return data->ia.cr_hia[BTINTEL_PCIE_RXQ_NUM] == data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM];
}

static inline bool btintel_pcie_is_txackq_empty(struct btintel_pcie_data *data)
{
	return data->ia.cr_tia[BTINTEL_PCIE_TXQ_NUM] == data->ia.cr_hia[BTINTEL_PCIE_TXQ_NUM];
}

static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
{
	struct msix_entry *entry = dev_id;
	struct btintel_pcie_data *data = btintel_pcie_get_data(entry);
	u32 intr_fh, intr_hw;

	spin_lock(&data->irq_lock);
	intr_fh = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_MSIX_FH_INT_CAUSES);
	intr_hw = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES);

	/* Clear causes registers to avoid being handling the same cause */
	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_FH_INT_CAUSES, intr_fh);
	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES, intr_hw);
	spin_unlock(&data->irq_lock);

	if (unlikely(!(intr_fh | intr_hw))) {
		/* Ignore interrupt, inta == 0 */
		return IRQ_NONE;
	}

	/* This interrupt is raised when there is an hardware exception */
	if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_HWEXP)
		btintel_pcie_msix_hw_exp_handler(data);

	if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP1)
		btintel_pcie_msix_gp1_handler(data);


	/* For TX */
	if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) {
		btintel_pcie_msix_tx_handle(data);
		if (!btintel_pcie_is_rxq_empty(data))
			btintel_pcie_msix_rx_handle(data);
	}

	/* For RX */
	if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1) {
		btintel_pcie_msix_rx_handle(data);
		if (!btintel_pcie_is_txackq_empty(data))
			btintel_pcie_msix_tx_handle(data);
	}

	/* This interrupt is triggered by the firmware after updating
	 * boot_stage register and image_response register
	 */
	if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0)
		btintel_pcie_msix_gp0_handler(data);

	/*
	 * Before sending the interrupt the HW disables it to prevent a nested
	 * interrupt. This is done by writing 1 to the corresponding bit in
	 * the mask register. After handling the interrupt, it should be
	 * re-enabled by clearing this bit. This register is defined as write 1
	 * clear (W1C) register, meaning that it's cleared by writing 1
	 * to the bit.
	 */
	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_AUTOMASK_ST,
			      BIT(entry->entry));

	return IRQ_HANDLED;
}

/* This function requests the irq for MSI-X and registers the handlers per irq.
 * Currently, it requests only 1 irq for all interrupt causes.
 */
static int btintel_pcie_setup_irq(struct btintel_pcie_data *data)
{
	int err;
	int num_irqs, i;

	for (i = 0; i < BTINTEL_PCIE_MSIX_VEC_MAX; i++)
		data->msix_entries[i].entry = i;

	num_irqs = pci_alloc_irq_vectors(data->pdev, BTINTEL_PCIE_MSIX_VEC_MIN,
					 BTINTEL_PCIE_MSIX_VEC_MAX, PCI_IRQ_MSIX);
	if (num_irqs < 0)
		return num_irqs;

	data->alloc_vecs = num_irqs;
	data->msix_enabled = 1;
	data->def_irq = 0;

	/* setup irq handler */
	for (i = 0; i < data->alloc_vecs; i++) {
		struct msix_entry *msix_entry;

		msix_entry = &data->msix_entries[i];
		msix_entry->vector = pci_irq_vector(data->pdev, i);

		err = devm_request_threaded_irq(&data->pdev->dev,
						msix_entry->vector,
						NULL,
						btintel_pcie_irq_msix_handler,
						IRQF_ONESHOT | IRQF_SHARED,
						KBUILD_MODNAME,
						msix_entry);
		if (err) {
			pci_free_irq_vectors(data->pdev);
			data->alloc_vecs = 0;
			return err;
		}
	}
	return 0;
}

struct btintel_pcie_causes_list {
	u32 cause;
	u32 mask_reg;
	u8 cause_num;
};

static struct btintel_pcie_causes_list causes_list[] = {
	{ BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0,	BTINTEL_PCIE_CSR_MSIX_FH_INT_MASK,	0x00 },
	{ BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1,	BTINTEL_PCIE_CSR_MSIX_FH_INT_MASK,	0x01 },
	{ BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0,	BTINTEL_PCIE_CSR_MSIX_HW_INT_MASK,	0x20 },
	{ BTINTEL_PCIE_MSIX_HW_INT_CAUSES_HWEXP, BTINTEL_PCIE_CSR_MSIX_HW_INT_MASK,	0x23 },
};

/* This function configures the interrupt masks for both HW_INT_CAUSES and
 * FH_INT_CAUSES which are meaningful to us.
 *
 * After resetting BT function via PCIE FLR or FUNC_CTRL reset, the driver
 * need to call this function again to configure since the masks
 * are reset to 0xFFFFFFFF after reset.
 */
static void btintel_pcie_config_msix(struct btintel_pcie_data *data)
{
	int i;
	int val = data->def_irq | BTINTEL_PCIE_MSIX_NON_AUTO_CLEAR_CAUSE;

	/* Set Non Auto Clear Cause */
	for (i = 0; i < ARRAY_SIZE(causes_list); i++) {
		btintel_pcie_wr_reg8(data,
				     BTINTEL_PCIE_CSR_MSIX_IVAR(causes_list[i].cause_num),
				     val);
		btintel_pcie_clr_reg_bits(data,
					  causes_list[i].mask_reg,
					  causes_list[i].cause);
	}

	/* Save the initial interrupt mask */
	data->fh_init_mask = ~btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_MSIX_FH_INT_MASK);
	data->hw_init_mask = ~btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_MSIX_HW_INT_MASK);
}

static int btintel_pcie_config_pcie(struct pci_dev *pdev,
				    struct btintel_pcie_data *data)
{
	int err;

	err = pcim_enable_device(pdev);
	if (err)
		return err;

	pci_set_master(pdev);

	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
	if (err) {
		err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
		if (err)
			return err;
	}

	data->base_addr = pcim_iomap_region(pdev, 0, KBUILD_MODNAME);
	if (IS_ERR(data->base_addr))
		return PTR_ERR(data->base_addr);

	err = btintel_pcie_setup_irq(data);
	if (err)
		return err;

	/* Configure MSI-X with causes list */
	btintel_pcie_config_msix(data);

	return 0;
}

static void btintel_pcie_init_ci(struct btintel_pcie_data *data,
				 struct ctx_info *ci)
{
	ci->version = 0x1;
	ci->size = sizeof(*ci);
	ci->config = 0x0000;
	ci->addr_cr_hia = data->ia.cr_hia_p_addr;
	ci->addr_tr_tia = data->ia.tr_tia_p_addr;
	ci->addr_cr_tia = data->ia.cr_tia_p_addr;
	ci->addr_tr_hia = data->ia.tr_hia_p_addr;
	ci->num_cr_ia = BTINTEL_PCIE_NUM_QUEUES;
	ci->num_tr_ia = BTINTEL_PCIE_NUM_QUEUES;
	ci->addr_urbdq0 = data->txq.urbd0s_p_addr;
	ci->addr_tfdq = data->txq.tfds_p_addr;
	ci->num_tfdq = data->txq.count;
	ci->num_urbdq0 = data->txq.count;
	ci->tfdq_db_vec = BTINTEL_PCIE_TXQ_NUM;
	ci->urbdq0_db_vec = BTINTEL_PCIE_TXQ_NUM;
	ci->rbd_size = BTINTEL_PCIE_RBD_SIZE_4K;
	ci->addr_frbdq = data->rxq.frbds_p_addr;
	ci->num_frbdq = data->rxq.count;
	ci->frbdq_db_vec = BTINTEL_PCIE_RXQ_NUM;
	ci->addr_urbdq1 = data->rxq.urbd1s_p_addr;
	ci->num_urbdq1 = data->rxq.count;
	ci->urbdq_db_vec = BTINTEL_PCIE_RXQ_NUM;

	ci->dbg_output_mode = 0x01;
	ci->dbgc_addr = data->dbgc.frag_p_addr;
	ci->dbgc_size = data->dbgc.frag_size;
	ci->dbg_preset = 0x00;
}

static void btintel_pcie_free_txq_bufs(struct btintel_pcie_data *data,
				       struct txq *txq)
{
	/* Free data buffers first */
	dma_free_coherent(&data->pdev->dev, txq->count * BTINTEL_PCIE_BUFFER_SIZE,
			  txq->buf_v_addr, txq->buf_p_addr);
	kfree(txq->bufs);
}

static int btintel_pcie_setup_txq_bufs(struct btintel_pcie_data *data,
				       struct txq *txq)
{
	int i;
	struct data_buf *buf;

	/* Allocate the same number of buffers as the descriptor */
	txq->bufs = kmalloc_objs(*buf, txq->count);
	if (!txq->bufs)
		return -ENOMEM;

	/* Allocate full chunk of data buffer for DMA first and do indexing and
	 * initialization next, so it can be freed easily
	 */
	txq->buf_v_addr = dma_alloc_coherent(&data->pdev->dev,
					     txq->count * BTINTEL_PCIE_BUFFER_SIZE,
					     &txq->buf_p_addr,
					     GFP_KERNEL | __GFP_NOWARN);
	if (!txq->buf_v_addr) {
		kfree(txq->bufs);
		return -ENOMEM;
	}

	/* Setup the allocated DMA buffer to bufs. Each data_buf should
	 * have virtual address and physical address
	 */
	for (i = 0; i < txq->count; i++) {
		buf = &txq->bufs[i];
		buf->data_p_addr = txq->buf_p_addr + (i * BTINTEL_PCIE_BUFFER_SIZE);
		buf->data = txq->buf_v_addr + (i * BTINTEL_PCIE_BUFFER_SIZE);
	}

	return 0;
}

static void btintel_pcie_free_rxq_bufs(struct btintel_pcie_data *data,
				       struct rxq *rxq)
{
	/* Free data buffers first */
	dma_free_coherent(&data->pdev->dev, rxq->count * BTINTEL_PCIE_BUFFER_SIZE,
			  rxq->buf_v_addr, rxq->buf_p_addr);
	kfree(rxq->bufs);
}

static int btintel_pcie_setup_rxq_bufs(struct btintel_pcie_data *data,
				       struct rxq *rxq)
{
	int i;
	struct data_buf *buf;

	/* Allocate the same number of buffers as the descriptor */
	rxq->bufs = kmalloc_objs(*buf, rxq->count);
	if (!rxq->bufs)
		return -ENOMEM;

	/* Allocate full chunk of data buffer for DMA first and do indexing and
	 * initialization next, so it can be freed easily
	 */
	rxq->buf_v_addr = dma_alloc_coherent(&data->pdev->dev,
					     rxq->count * BTINTEL_PCIE_BUFFER_SIZE,
					     &rxq->buf_p_addr,
					     GFP_KERNEL | __GFP_NOWARN);
	if (!rxq->buf_v_addr) {
		kfree(rxq->bufs);
		return -ENOMEM;
	}

	/* Setup the allocated DMA buffer to bufs. Each data_buf should
	 * have virtual address and physical address
	 */
	for (i = 0; i < rxq->count; i++) {
		buf = &rxq->bufs[i];
		buf->data_p_addr = rxq->buf_p_addr + (i * BTINTEL_PCIE_BUFFER_SIZE);
		buf->data = rxq->buf_v_addr + (i * BTINTEL_PCIE_BUFFER_SIZE);
	}

	return 0;
}

static void btintel_pcie_setup_ia(struct btintel_pcie_data *data,
				  dma_addr_t p_addr, void *v_addr,
				  struct ia *ia)
{
	/* TR Head Index Array */
	ia->tr_hia_p_addr = p_addr;
	ia->tr_hia = v_addr;

	/* TR Tail Index Array */
	ia->tr_tia_p_addr = p_addr + sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES;
	ia->tr_tia = v_addr + sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES;

	/* CR Head index Array */
	ia->cr_hia_p_addr = p_addr + (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 2);
	ia->cr_hia = v_addr + (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 2);

	/* CR Tail Index Array */
	ia->cr_tia_p_addr = p_addr + (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 3);
	ia->cr_tia = v_addr + (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 3);
}

static void btintel_pcie_free(struct btintel_pcie_data *data)
{
	btintel_pcie_free_rxq_bufs(data, &data->rxq);
	btintel_pcie_free_txq_bufs(data, &data->txq);

	dma_pool_free(data->dma_pool, data->dma_v_addr, data->dma_p_addr);
	dma_pool_destroy(data->dma_pool);
}

/* Allocate tx and rx queues, any related data structures and buffers.
 */
static int btintel_pcie_alloc(struct btintel_pcie_data *data)
{
	int err = 0;
	size_t total;
	dma_addr_t p_addr;
	void *v_addr;

	/* Allocate the chunk of DMA memory for descriptors, index array, and
	 * context information, instead of allocating individually.
	 * The DMA memory for data buffer is allocated while setting up the
	 * each queue.
	 *
	 * Total size is sum of the following
	 *  + size of TFD * Number of descriptors in queue
	 *  + size of URBD0 * Number of descriptors in queue
	 *  + size of FRBD * Number of descriptors in queue
	 *  + size of URBD1 * Number of descriptors in queue
	 *  + size of index * Number of queues(2) * type of index array(4)
	 *  + size of context information
	 */
	total = (sizeof(struct tfd) + sizeof(struct urbd0)) * BTINTEL_PCIE_TX_DESCS_COUNT;
	total += (sizeof(struct frbd) + sizeof(struct urbd1)) * BTINTEL_PCIE_RX_DESCS_COUNT;

	/* Add the sum of size of index array and size of ci struct */
	total += (sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4) + sizeof(struct ctx_info);

	/* Allocate DMA Pool */
	data->dma_pool = dma_pool_create(KBUILD_MODNAME, &data->pdev->dev,
					 total, BTINTEL_PCIE_DMA_POOL_ALIGNMENT, 0);
	if (!data->dma_pool) {
		err = -ENOMEM;
		goto exit_error;
	}

	v_addr = dma_pool_zalloc(data->dma_pool, GFP_KERNEL | __GFP_NOWARN,
				 &p_addr);
	if (!v_addr) {
		dma_pool_destroy(data->dma_pool);
		err = -ENOMEM;
		goto exit_error;
	}

	data->dma_p_addr = p_addr;
	data->dma_v_addr = v_addr;

	/* Setup descriptor count */
	data->txq.count = BTINTEL_PCIE_TX_DESCS_COUNT;
	data->rxq.count = BTINTEL_PCIE_RX_DESCS_COUNT;

	/* Setup tfds */
	data->txq.tfds_p_addr = p_addr;
	data->txq.tfds = v_addr;

	p_addr += (sizeof(struct tfd) * BTINTEL_PCIE_TX_DESCS_COUNT);
	v_addr += (sizeof(struct tfd) * BTINTEL_PCIE_TX_DESCS_COUNT);

	/* Setup urbd0 */
	data->txq.urbd0s_p_addr = p_addr;
	data->txq.urbd0s = v_addr;

	p_addr += (sizeof(struct urbd0) * BTINTEL_PCIE_TX_DESCS_COUNT);
	v_addr += (sizeof(struct urbd0) * BTINTEL_PCIE_TX_DESCS_COUNT);

	/* Setup FRBD*/
	data->rxq.frbds_p_addr = p_addr;
	data->rxq.frbds = v_addr;

	p_addr += (sizeof(struct frbd) * BTINTEL_PCIE_RX_DESCS_COUNT);
	v_addr += (sizeof(struct frbd) * BTINTEL_PCIE_RX_DESCS_COUNT);

	/* Setup urbd1 */
	data->rxq.urbd1s_p_addr = p_addr;
	data->rxq.urbd1s = v_addr;

	p_addr += (sizeof(struct urbd1) * BTINTEL_PCIE_RX_DESCS_COUNT);
	v_addr += (sizeof(struct urbd1) * BTINTEL_PCIE_RX_DESCS_COUNT);

	/* Setup data buffers for txq */
	err = btintel_pcie_setup_txq_bufs(data, &data->txq);
	if (err)
		goto exit_error_pool;

	/* Setup data buffers for rxq */
	err = btintel_pcie_setup_rxq_bufs(data, &data->rxq);
	if (err)
		goto exit_error_txq;

	/* Setup Index Array */
	btintel_pcie_setup_ia(data, p_addr, v_addr, &data->ia);

	/* Setup data buffers for dbgc */
	err = btintel_pcie_setup_dbgc(data);
	if (err)
		goto exit_error_txq;

	/* Setup Context Information */
	p_addr += sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4;
	v_addr += sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4;

	data->ci = v_addr;
	data->ci_p_addr = p_addr;

	/* Initialize the CI */
	btintel_pcie_init_ci(data, data->ci);

	return 0;

exit_error_txq:
	btintel_pcie_free_txq_bufs(data, &data->txq);
exit_error_pool:
	dma_pool_free(data->dma_pool, data->dma_v_addr, data->dma_p_addr);
	dma_pool_destroy(data->dma_pool);
exit_error:
	return err;
}

static int btintel_pcie_open(struct hci_dev *hdev)
{
	bt_dev_dbg(hdev, "");

	return 0;
}

static int btintel_pcie_close(struct hci_dev *hdev)
{
	bt_dev_dbg(hdev, "");

	return 0;
}

static int btintel_pcie_inject_cmd_complete(struct hci_dev *hdev, __u16 opcode)
{
	struct sk_buff *skb;
	struct hci_event_hdr *hdr;
	struct hci_ev_cmd_complete *evt;

	skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, GFP_KERNEL);
	if (!skb)
		return -ENOMEM;

	hdr = (struct hci_event_hdr *)skb_put(skb, sizeof(*hdr));
	hdr->evt = HCI_EV_CMD_COMPLETE;
	hdr->plen = sizeof(*evt) + 1;

	evt = (struct hci_ev_cmd_complete *)skb_put(skb, sizeof(*evt));
	evt->ncmd = 0x01;
	evt->opcode = cpu_to_le16(opcode);

	*(u8 *)skb_put(skb, 1) = 0x00;

	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;

	return hci_recv_frame(hdev, skb);
}

static int btintel_pcie_send_frame(struct hci_dev *hdev,
				       struct sk_buff *skb)
{
	struct btintel_pcie_data *data = hci_get_drvdata(hdev);
	struct hci_command_hdr *cmd;
	__u16 opcode = ~0;
	int ret;
	u32 type;

	if (test_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags))
		return -ENODEV;

	/* Due to the fw limitation, the type header of the packet should be
	 * 4 bytes unlike 1 byte for UART. In UART, the firmware can read
	 * the first byte to get the packet type and redirect the rest of data
	 * packet to the right handler.
	 *
	 * But for PCIe, THF(Transfer Flow Handler) fetches the 4 bytes of data
	 * from DMA memory and by the time it reads the first 4 bytes, it has
	 * already consumed some part of packet. Thus the packet type indicator
	 * for iBT PCIe is 4 bytes.
	 *
	 * Luckily, when HCI core creates the skb, it allocates 8 bytes of
	 * head room for profile and driver use, and before sending the data
	 * to the device, append the iBT PCIe packet type in the front.
	 */
	switch (hci_skb_pkt_type(skb)) {
	case HCI_COMMAND_PKT:
		type = BTINTEL_PCIE_HCI_CMD_PKT;
		cmd = (void *)skb->data;
		opcode = le16_to_cpu(cmd->opcode);
		if (btintel_test_flag(hdev, INTEL_BOOTLOADER)) {
			struct hci_command_hdr *cmd = (void *)skb->data;
			__u16 opcode = le16_to_cpu(cmd->opcode);

			/* When the BTINTEL_HCI_OP_RESET command is issued to
			 * boot into the operational firmware, it will actually
			 * not send a command complete event. To keep the flow
			 * control working inject that event here.
			 */
			if (opcode == BTINTEL_HCI_OP_RESET)
				btintel_pcie_inject_cmd_complete(hdev, opcode);
		}

		hdev->stat.cmd_tx++;
		break;
	case HCI_ACLDATA_PKT:
		type = BTINTEL_PCIE_HCI_ACL_PKT;
		hdev->stat.acl_tx++;
		break;
	case HCI_SCODATA_PKT:
		type = BTINTEL_PCIE_HCI_SCO_PKT;
		hdev->stat.sco_tx++;
		break;
	case HCI_ISODATA_PKT:
		type = BTINTEL_PCIE_HCI_ISO_PKT;
		break;
	default:
		bt_dev_err(hdev, "Unknown HCI packet type");
		return -EILSEQ;
	}

	ret = btintel_pcie_send_sync(data, skb, type, opcode);
	if (ret) {
		hdev->stat.err_tx++;
		bt_dev_err(hdev, "Failed to send frame (%d)", ret);
		goto exit_error;
	}

	hdev->stat.byte_tx += skb->len;
	kfree_skb(skb);

exit_error:
	return ret;
}

static void btintel_pcie_release_hdev(struct btintel_pcie_data *data)
{
	struct hci_dev *hdev;

	hdev = data->hdev;
	hci_unregister_dev(hdev);
	hci_free_dev(hdev);
	data->hdev = NULL;
}

static void btintel_pcie_disable_interrupts(struct btintel_pcie_data *data)
{
	spin_lock(&data->irq_lock);
	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_FH_INT_MASK, data->fh_init_mask);
	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_HW_INT_MASK, data->hw_init_mask);
	spin_unlock(&data->irq_lock);
}

static void btintel_pcie_enable_interrupts(struct btintel_pcie_data *data)
{
	spin_lock(&data->irq_lock);
	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_FH_INT_MASK, ~data->fh_init_mask);
	btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_HW_INT_MASK, ~data->hw_init_mask);
	spin_unlock(&data->irq_lock);
}

static void btintel_pcie_synchronize_irqs(struct btintel_pcie_data *data)
{
	for (int i = 0; i < data->alloc_vecs; i++)
		synchronize_irq(data->msix_entries[i].vector);
}

static int btintel_pcie_setup_internal(struct hci_dev *hdev)
{
	struct btintel_pcie_data *data = hci_get_drvdata(hdev);
	const u8 param[1] = { 0xFF };
	struct intel_version_tlv ver_tlv;
	struct sk_buff *skb;
	int err;

	BT_DBG("%s", hdev->name);

	skb = __hci_cmd_sync(hdev, 0xfc05, 1, param, HCI_CMD_TIMEOUT);
	if (IS_ERR(skb)) {
		bt_dev_err(hdev, "Reading Intel version command failed (%ld)",
			   PTR_ERR(skb));
		return PTR_ERR(skb);
	}

	/* Check the status */
	if (skb->data[0]) {
		bt_dev_err(hdev, "Intel Read Version command failed (%02x)",
			   skb->data[0]);
		err = -EIO;
		goto exit_error;
	}

	/* Apply the common HCI quirks for Intel device */
	hci_set_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER);
	hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
	hci_set_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_DIAG);

	/* Set up the quality report callback for Intel devices */
	hdev->set_quality_report = btintel_set_quality_report;

	memset(&ver_tlv, 0, sizeof(ver_tlv));
	/* For TLV type device, parse the tlv data */
	err = btintel_parse_version_tlv(hdev, &ver_tlv, skb);
	if (err) {
		bt_dev_err(hdev, "Failed to parse TLV version information");
		goto exit_error;
	}

	switch (INTEL_HW_PLATFORM(ver_tlv.cnvi_bt)) {
	case 0x37:
		break;
	default:
		bt_dev_err(hdev, "Unsupported Intel hardware platform (0x%2x)",
			   INTEL_HW_PLATFORM(ver_tlv.cnvi_bt));
		err = -EINVAL;
		goto exit_error;
	}

	/* Check for supported iBT hardware variants of this firmware
	 * loading method.
	 *
	 * This check has been put in place to ensure correct forward
	 * compatibility options when newer hardware variants come
	 * along.
	 */
	switch (INTEL_HW_VARIANT(ver_tlv.cnvi_bt)) {
	case 0x1e:	/* BzrI */
	case 0x1f:	/* ScP  */
	case 0x22:	/* BzrIW */
		/* Display version information of TLV type */
		btintel_version_info_tlv(hdev, &ver_tlv);

		/* Apply the device specific HCI quirks for TLV based devices
		 *
		 * All TLV based devices support WBS
		 */
		hci_set_quirk(hdev, HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);

		/* Setup MSFT Extension support */
		btintel_set_msft_opcode(hdev,
					INTEL_HW_VARIANT(ver_tlv.cnvi_bt));

		err = btintel_bootloader_setup_tlv(hdev, &ver_tlv);
		if (err)
			goto exit_error;
		break;
	default:
		bt_dev_err(hdev, "Unsupported Intel hw variant (%u)",
			   INTEL_HW_VARIANT(ver_tlv.cnvi_bt));
		err = -EINVAL;
		goto exit_error;
		break;
	}

	data->dmp_hdr.cnvi_top = ver_tlv.cnvi_top;
	data->dmp_hdr.cnvr_top = ver_tlv.cnvr_top;
	data->dmp_hdr.fw_timestamp = ver_tlv.timestamp;
	data->dmp_hdr.fw_build_type = ver_tlv.build_type;
	data->dmp_hdr.fw_build_num = ver_tlv.build_num;
	data->dmp_hdr.cnvi_bt = ver_tlv.cnvi_bt;

	if (ver_tlv.img_type == 0x02 || ver_tlv.img_type == 0x03)
		data->dmp_hdr.fw_git_sha1 = ver_tlv.git_sha1;

	btintel_print_fseq_info(hdev);
exit_error:
	kfree_skb(skb);

	return err;
}

static int btintel_pcie_setup(struct hci_dev *hdev)
{
	int err, fw_dl_retry = 0;
	struct btintel_pcie_data *data = hci_get_drvdata(hdev);

	while ((err = btintel_pcie_setup_internal(hdev)) && fw_dl_retry++ < 1) {
		bt_dev_err(hdev, "Firmware download retry count: %d",
			   fw_dl_retry);
		btintel_pcie_dump_debug_registers(hdev);
		btintel_pcie_disable_interrupts(data);
		btintel_pcie_synchronize_irqs(data);
		err = btintel_pcie_reset_bt(data);
		if (err) {
			bt_dev_err(hdev, "Failed to do shr reset: %d", err);
			break;
		}
		usleep_range(10000, 12000);
		btintel_pcie_reset_ia(data);
		btintel_pcie_enable_interrupts(data);
		btintel_pcie_config_msix(data);
		err = btintel_pcie_enable_bt(data);
		if (err) {
			bt_dev_err(hdev, "Failed to enable hardware: %d", err);
			break;
		}
		btintel_pcie_start_rx(data);
	}

	if (!err)
		set_bit(BTINTEL_PCIE_SETUP_DONE, &data->flags);
	return err;
}

static struct btintel_pcie_dev_recovery *
btintel_pcie_get_recovery(struct pci_dev *pdev, struct device *dev)
{
	struct btintel_pcie_dev_recovery *tmp, *data = NULL;
	const char *name = pci_name(pdev);
	const size_t name_len = strlen(name) + 1;
	struct hci_dev *hdev = to_hci_dev(dev);

	spin_lock(&btintel_pcie_recovery_lock);
	list_for_each_entry(tmp, &btintel_pcie_recovery_list, list) {
		if (strcmp(tmp->name, name))
			continue;
		data = tmp;
		break;
	}
	spin_unlock(&btintel_pcie_recovery_lock);

	if (data) {
		bt_dev_dbg(hdev, "Found restart data for BDF: %s", data->name);
		return data;
	}

	data = kzalloc_flex(*data, name, name_len, GFP_ATOMIC);
	if (!data)
		return NULL;

	strscpy(data->name, name, name_len);
	spin_lock(&btintel_pcie_recovery_lock);
	list_add_tail(&data->list, &btintel_pcie_recovery_list);
	spin_unlock(&btintel_pcie_recovery_lock);

	return data;
}

static void btintel_pcie_free_restart_list(void)
{
	struct btintel_pcie_dev_recovery *tmp;

	while ((tmp = list_first_entry_or_null(&btintel_pcie_recovery_list,
					       typeof(*tmp), list))) {
		list_del(&tmp->list);
		kfree(tmp);
	}
}

static void btintel_pcie_inc_recovery_count(struct pci_dev *pdev,
					    struct device *dev)
{
	struct btintel_pcie_dev_recovery *data;
	time64_t retry_window;

	data = btintel_pcie_get_recovery(pdev, dev);
	if (!data)
		return;

	retry_window = ktime_get_boottime_seconds() - data->last_error;
	if (data->count == 0) {
		data->last_error = ktime_get_boottime_seconds();
		data->count++;
	} else if (retry_window < BTINTEL_PCIE_RESET_WINDOW_SECS &&
		   data->count <= BTINTEL_PCIE_FLR_MAX_RETRY) {
		data->count++;
	} else if (retry_window > BTINTEL_PCIE_RESET_WINDOW_SECS) {
		data->last_error = 0;
		data->count = 0;
	}
}

static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data);

static void btintel_pcie_removal_work(struct work_struct *wk)
{
	struct btintel_pcie_removal *removal =
		container_of(wk, struct btintel_pcie_removal, work);
	struct pci_dev *pdev = removal->pdev;
	struct btintel_pcie_data *data;
	int err;

	pci_lock_rescan_remove();

	if (!pdev->bus)
		goto error;

	data = pci_get_drvdata(pdev);

	btintel_pcie_disable_interrupts(data);
	btintel_pcie_synchronize_irqs(data);

	flush_work(&data->rx_work);

	bt_dev_dbg(data->hdev, "Release bluetooth interface");
	btintel_pcie_release_hdev(data);

	err = pci_reset_function(pdev);
	if (err) {
		BT_ERR("Failed resetting the pcie device (%d)", err);
		goto error;
	}

	btintel_pcie_enable_interrupts(data);
	btintel_pcie_config_msix(data);

	err = btintel_pcie_enable_bt(data);
	if (err) {
		BT_ERR("Failed to enable bluetooth hardware after reset (%d)",
		       err);
		goto error;
	}

	btintel_pcie_reset_ia(data);
	btintel_pcie_start_rx(data);
	data->flags = 0;

	err = btintel_pcie_setup_hdev(data);
	if (err) {
		BT_ERR("Failed registering hdev (%d)", err);
		goto error;
	}
error:
	pci_dev_put(pdev);
	pci_unlock_rescan_remove();
	kfree(removal);
}

static void btintel_pcie_reset(struct hci_dev *hdev)
{
	struct btintel_pcie_removal *removal;
	struct btintel_pcie_data *data;

	data = hci_get_drvdata(hdev);

	if (!test_bit(BTINTEL_PCIE_SETUP_DONE, &data->flags))
		return;

	if (test_and_set_bit(BTINTEL_PCIE_RECOVERY_IN_PROGRESS, &data->flags))
		return;

	removal = kzalloc_obj(*removal, GFP_ATOMIC);
	if (!removal)
		return;

	removal->pdev = data->pdev;
	INIT_WORK(&removal->work, btintel_pcie_removal_work);
	pci_dev_get(removal->pdev);
	schedule_work(&removal->work);
}

static void btintel_pcie_hw_error(struct hci_dev *hdev, u8 code)
{
	struct btintel_pcie_dev_recovery *data;
	struct btintel_pcie_data *dev_data = hci_get_drvdata(hdev);
	struct pci_dev *pdev = dev_data->pdev;
	time64_t retry_window;

	if (code == 0x13) {
		bt_dev_err(hdev, "Encountered top exception");
		return;
	}

	data = btintel_pcie_get_recovery(pdev, &hdev->dev);
	if (!data)
		return;

	retry_window = ktime_get_boottime_seconds() - data->last_error;

	if (retry_window < BTINTEL_PCIE_RESET_WINDOW_SECS &&
	    data->count >= BTINTEL_PCIE_FLR_MAX_RETRY) {
		bt_dev_err(hdev, "Exhausted maximum: %d recovery attempts: %d",
			   BTINTEL_PCIE_FLR_MAX_RETRY, data->count);
		bt_dev_dbg(hdev, "Boot time: %lld seconds",
			   ktime_get_boottime_seconds());
		bt_dev_dbg(hdev, "last error at: %lld seconds",
			   data->last_error);
		return;
	}
	btintel_pcie_inc_recovery_count(pdev, &hdev->dev);
	btintel_pcie_reset(hdev);
}

static bool btintel_pcie_wakeup(struct hci_dev *hdev)
{
	struct btintel_pcie_data *data = hci_get_drvdata(hdev);

	return device_may_wakeup(&data->pdev->dev);
}

static const struct {
	u16 opcode;
	const char *desc;
} btintel_pcie_hci_drv_supported_commands[] = {
	/* Common commands */
	{ HCI_DRV_OP_READ_INFO, "Read Info" },
};

static int btintel_pcie_hci_drv_read_info(struct hci_dev *hdev, void *data,
					  u16 data_len)
{
	struct hci_drv_rp_read_info *rp;
	size_t rp_size;
	int err, i;
	u16 opcode, num_supported_commands =
		ARRAY_SIZE(btintel_pcie_hci_drv_supported_commands);

	rp_size = sizeof(*rp) + num_supported_commands * 2;

	rp = kmalloc(rp_size, GFP_KERNEL);
	if (!rp)
		return -ENOMEM;

	strscpy_pad(rp->driver_name, KBUILD_MODNAME);

	rp->num_supported_commands = cpu_to_le16(num_supported_commands);
	for (i = 0; i < num_supported_commands; i++) {
		opcode = btintel_pcie_hci_drv_supported_commands[i].opcode;
		bt_dev_dbg(hdev,
			    "Supported HCI Drv command (0x%02x|0x%04x): %s",
			    hci_opcode_ogf(opcode),
			    hci_opcode_ocf(opcode),
			    btintel_pcie_hci_drv_supported_commands[i].desc);
		rp->supported_commands[i] = cpu_to_le16(opcode);
	}

	err = hci_drv_cmd_complete(hdev, HCI_DRV_OP_READ_INFO,
				   HCI_DRV_STATUS_SUCCESS,
				   rp, rp_size);

	kfree(rp);
	return err;
}

static const struct hci_drv_handler btintel_pcie_hci_drv_common_handlers[] = {
	{ btintel_pcie_hci_drv_read_info,       HCI_DRV_READ_INFO_SIZE },
};

static const struct hci_drv_handler btintel_pcie_hci_drv_specific_handlers[] = {};

static struct hci_drv btintel_pcie_hci_drv = {
	.common_handler_count   = ARRAY_SIZE(btintel_pcie_hci_drv_common_handlers),
	.common_handlers        = btintel_pcie_hci_drv_common_handlers,
	.specific_handler_count = ARRAY_SIZE(btintel_pcie_hci_drv_specific_handlers),
	.specific_handlers      = btintel_pcie_hci_drv_specific_handlers,
};

static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data)
{
	int err;
	struct hci_dev *hdev;

	hdev = hci_alloc_dev_priv(sizeof(struct btintel_data));
	if (!hdev)
		return -ENOMEM;

	hdev->bus = HCI_PCI;
	hci_set_drvdata(hdev, data);

	data->hdev = hdev;
	SET_HCIDEV_DEV(hdev, &data->pdev->dev);

	hdev->manufacturer = 2;
	hdev->open = btintel_pcie_open;
	hdev->close = btintel_pcie_close;
	hdev->send = btintel_pcie_send_frame;
	hdev->setup = btintel_pcie_setup;
	hdev->shutdown = btintel_shutdown_combined;
	hdev->hw_error = btintel_pcie_hw_error;
	hdev->set_diag = btintel_set_diag;
	hdev->set_bdaddr = btintel_set_bdaddr;
	hdev->reset = btintel_pcie_reset;
	hdev->wakeup = btintel_pcie_wakeup;
	hdev->hci_drv = &btintel_pcie_hci_drv;

	err = hci_register_dev(hdev);
	if (err < 0) {
		BT_ERR("Failed to register to hdev (%d)", err);
		goto exit_error;
	}

	data->dmp_hdr.driver_name = KBUILD_MODNAME;
	return 0;

exit_error:
	hci_free_dev(hdev);
	return err;
}

static int btintel_pcie_probe(struct pci_dev *pdev,
			      const struct pci_device_id *ent)
{
	int err;
	struct btintel_pcie_data *data;

	if (!pdev)
		return -ENODEV;

	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->pdev = pdev;

	spin_lock_init(&data->irq_lock);
	spin_lock_init(&data->hci_rx_lock);

	init_waitqueue_head(&data->gp0_wait_q);
	data->gp0_received = false;

	init_waitqueue_head(&data->tx_wait_q);
	data->tx_wait_done = false;

	data->workqueue = alloc_ordered_workqueue(KBUILD_MODNAME, WQ_HIGHPRI);
	if (!data->workqueue)
		return -ENOMEM;

	skb_queue_head_init(&data->rx_skb_q);
	INIT_WORK(&data->rx_work, btintel_pcie_rx_work);

	data->boot_stage_cache = 0x00;
	data->img_resp_cache = 0x00;

	err = btintel_pcie_config_pcie(pdev, data);
	if (err)
		goto exit_error;

	pci_set_drvdata(pdev, data);

	err = btintel_pcie_alloc(data);
	if (err)
		goto exit_error;

	err = btintel_pcie_enable_bt(data);
	if (err)
		goto exit_error;

	/* CNV information (CNVi and CNVr) is in CSR */
	data->cnvi = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_HW_REV_REG);

	data->cnvr = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_RF_ID_REG);

	err = btintel_pcie_start_rx(data);
	if (err)
		goto exit_error;

	err = btintel_pcie_setup_hdev(data);
	if (err)
		goto exit_error;

	bt_dev_dbg(data->hdev, "cnvi: 0x%8.8x cnvr: 0x%8.8x", data->cnvi,
		   data->cnvr);
	return 0;

exit_error:
	/* reset device before exit */
	btintel_pcie_reset_bt(data);

	pci_clear_master(pdev);

	pci_set_drvdata(pdev, NULL);

	return err;
}

static void btintel_pcie_remove(struct pci_dev *pdev)
{
	struct btintel_pcie_data *data;

	data = pci_get_drvdata(pdev);

	btintel_pcie_disable_interrupts(data);

	btintel_pcie_synchronize_irqs(data);

	flush_work(&data->rx_work);

	btintel_pcie_reset_bt(data);
	for (int i = 0; i < data->alloc_vecs; i++) {
		struct msix_entry *msix_entry;

		msix_entry = &data->msix_entries[i];
		free_irq(msix_entry->vector, msix_entry);
	}

	pci_free_irq_vectors(pdev);

	btintel_pcie_release_hdev(data);

	destroy_workqueue(data->workqueue);

	btintel_pcie_free(data);

	pci_clear_master(pdev);

	pci_set_drvdata(pdev, NULL);
}

#ifdef CONFIG_DEV_COREDUMP
static void btintel_pcie_coredump(struct device *dev)
{
	struct  pci_dev *pdev = to_pci_dev(dev);
	struct btintel_pcie_data *data = pci_get_drvdata(pdev);

	if (test_and_set_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags))
		return;

	data->dmp_hdr.trigger_reason  = BTINTEL_PCIE_TRIGGER_REASON_USER_TRIGGER;
	queue_work(data->workqueue, &data->rx_work);
}
#endif

static int btintel_pcie_set_dxstate(struct btintel_pcie_data *data, u32 dxstate)
{
	int retry = 0, status;
	u32 dx_intr_timeout_ms = 200;

	do {
		data->gp0_received = false;

		btintel_pcie_wr_sleep_cntrl(data, dxstate);

		status = wait_event_timeout(data->gp0_wait_q, data->gp0_received,
			msecs_to_jiffies(dx_intr_timeout_ms));

		if (status)
			return 0;

		bt_dev_warn(data->hdev,
			   "Timeout (%u ms) on alive interrupt for D%d entry, retry count %d",
			   dx_intr_timeout_ms, dxstate, retry);

		/* clear gp0 cause */
		btintel_pcie_clr_reg_bits(data,
					  BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES,
					  BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0);

		/* A hardware bug may cause the alive interrupt to be missed.
		 * Check if the controller reached the expected state and retry
		 * the operation only if it hasn't.
		 */
		if (dxstate == BTINTEL_PCIE_STATE_D0) {
			if (btintel_pcie_in_d0(data))
				return 0;
		} else {
			if (btintel_pcie_in_d3(data))
				return 0;
		}

	} while (++retry < BTINTEL_PCIE_DX_TRANSITION_MAX_RETRIES);

	return -EBUSY;
}

static int btintel_pcie_suspend_late(struct device *dev, pm_message_t mesg)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct btintel_pcie_data *data;
	ktime_t start;
	u32 dxstate;
	int err;

	data = pci_get_drvdata(pdev);

	dxstate = (mesg.event == PM_EVENT_SUSPEND ?
		   BTINTEL_PCIE_STATE_D3_HOT : BTINTEL_PCIE_STATE_D3_COLD);

	data->pm_sx_event = mesg.event;

	start = ktime_get();

	/* Refer: 6.4.11.7 -> Platform power management */
	err = btintel_pcie_set_dxstate(data, dxstate);

	if (err)
		return err;

	bt_dev_dbg(data->hdev,
		   "device entered into d3 state from d0 in %lld us",
		   ktime_to_us(ktime_get() - start));
	return err;
}

static int btintel_pcie_suspend(struct device *dev)
{
	return btintel_pcie_suspend_late(dev, PMSG_SUSPEND);
}

static int btintel_pcie_hibernate(struct device *dev)
{
	return btintel_pcie_suspend_late(dev, PMSG_HIBERNATE);
}

static int btintel_pcie_freeze(struct device *dev)
{
	return btintel_pcie_suspend_late(dev, PMSG_FREEZE);
}

static int btintel_pcie_resume(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct btintel_pcie_data *data;
	ktime_t start;
	int err;

	data = pci_get_drvdata(pdev);
	data->gp0_received = false;

	start = ktime_get();

	/* When the system enters S4 (hibernate) mode, bluetooth device loses
	 * power, which results in the erasure of its loaded firmware.
	 * Consequently, function level reset (flr) is required on system
	 * resume to bring the controller back into an operational state by
	 * initiating a new firmware download.
	 */

	if (data->pm_sx_event == PM_EVENT_FREEZE ||
	    data->pm_sx_event == PM_EVENT_HIBERNATE) {
		set_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags);
		btintel_pcie_reset(data->hdev);
		return 0;
	}

	/* Refer: 6.4.11.7 -> Platform power management */
	err = btintel_pcie_set_dxstate(data, BTINTEL_PCIE_STATE_D0);

	if (err == 0) {
		bt_dev_dbg(data->hdev,
			   "device entered into d0 state from d3 in %lld us",
			   ktime_to_us(ktime_get() - start));
		return err;
	}

	/* Trigger function level reset if the controller is in error
	 * state during resume() to bring back the controller to
	 * operational mode
	 */

	data->boot_stage_cache = btintel_pcie_rd_reg32(data,
			BTINTEL_PCIE_CSR_BOOT_STAGE_REG);
	if (btintel_pcie_in_error(data) ||
			btintel_pcie_in_device_halt(data)) {
		bt_dev_err(data->hdev, "Controller in error state for D0 entry");
		if (!test_and_set_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS,
				      &data->flags)) {
			data->dmp_hdr.trigger_reason =
				BTINTEL_PCIE_TRIGGER_REASON_FW_ASSERT;
			queue_work(data->workqueue, &data->rx_work);
		}
		set_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags);
		btintel_pcie_reset(data->hdev);
	}
	return err;
}

static const struct dev_pm_ops btintel_pcie_pm_ops = {
	.suspend = btintel_pcie_suspend,
	.resume = btintel_pcie_resume,
	.freeze = btintel_pcie_freeze,
	.thaw = btintel_pcie_resume,
	.poweroff = btintel_pcie_hibernate,
	.restore = btintel_pcie_resume,
};

static struct pci_driver btintel_pcie_driver = {
	.name = KBUILD_MODNAME,
	.id_table = btintel_pcie_table,
	.probe = btintel_pcie_probe,
	.remove = btintel_pcie_remove,
	.driver.pm = pm_sleep_ptr(&btintel_pcie_pm_ops),
#ifdef CONFIG_DEV_COREDUMP
	.driver.coredump = btintel_pcie_coredump
#endif
};

static int __init btintel_pcie_init(void)
{
	return pci_register_driver(&btintel_pcie_driver);
}

static void __exit btintel_pcie_exit(void)
{
	pci_unregister_driver(&btintel_pcie_driver);
	btintel_pcie_free_restart_list();
}

module_init(btintel_pcie_init);
module_exit(btintel_pcie_exit);

MODULE_AUTHOR("Tedd Ho-Jeong An <tedd.an@intel.com>");
MODULE_DESCRIPTION("Intel Bluetooth PCIe transport driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
