/*
 * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */



#include <osdep.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/if_arp.h>
#include "if_pci.h"
#include "hif_msg_based.h"
#include "hif_pci.h"
#include "copy_engine_api.h"
#include "copy_engine_internal.h"
#include "bmi_msg.h" /* TARGET_TYPE_ */
#include "regtable.h"
#include "ol_fw.h"
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <osapi_linux.h>
#include "vos_api.h"
#include "vos_sched.h"
#include "wma_api.h"
#include "wma.h"
#include "adf_os_atomic.h"
#include "wlan_hdd_power.h"
#include "wlan_hdd_main.h"
#include "vos_cnss.h"
#include "epping_main.h"

#ifndef REMOVE_PKT_LOG
#include "ol_txrx_types.h"
#include "pktlog_ac_api.h"
#include "pktlog_ac.h"
#endif

#define AR9888_DEVICE_ID (0x003c)
#define AR6320_DEVICE_ID (0x003e)
#define QCA9379_DEVICE_ID (0x0042)
#define QCA9379_DEVICE_REV_ID (0x0043)
#define AR6320_FW_1_1  (0x11)
#define AR6320_FW_1_3  (0x13)
#define AR6320_FW_2_0  (0x20)
#define AR6320_FW_3_0  (0x30)
#define AR6320_FW_3_2  (0x32)
#define QCA9379_FW_3_2  (0x31)

#ifdef CONFIG_SLUB_DEBUG_ON
#define MAX_NUM_OF_RECEIVES 400 /* Maximum number of Rx buf to process before*
                                   break out in SLUB debug builds */
#else
#define MAX_NUM_OF_RECEIVES 1000 /* Maximum number of Rx buf to process before break out */
#endif

#define PCIE_WAKE_TIMEOUT 1000 /* Maximum ms timeout for host to wake up target */
#define RAMDUMP_EVENT_TIMEOUT 2500
#define MAX_REG_READ_RETRIES 10

unsigned int msienable = 1;
module_param(msienable, int, S_IRUSR | S_IRGRP | S_IROTH);

int hif_pci_configure(struct hif_pci_softc *sc, hif_handle_t *hif_hdl);
void hif_nointrs(struct hif_pci_softc *sc);
static int __hif_pci_suspend(struct pci_dev *, pm_message_t, bool);
static int __hif_pci_resume(struct pci_dev *, bool);

static void print_config_soc_reg(struct hif_pci_softc *sc)
{
	A_UINT16 val;
	A_UINT32 bar0;

	pci_read_config_word(sc->pdev, PCI_VENDOR_ID, &val);
	pr_err("%s: PCI Vendor ID = 0x%04x\n", __func__, val);

	pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &val);
	pr_err("%s: PCI Device ID = 0x%04x\n", __func__, val);

	pci_read_config_word(sc->pdev, PCI_COMMAND, &val);
	pr_err("%s: PCI Command = 0x%04x\n", __func__, val);

	pci_read_config_word(sc->pdev, PCI_STATUS, &val);
	pr_err("%s: PCI Status = 0x%04x\n", __func__, val);

	pci_read_config_dword(sc->pdev, PCI_BASE_ADDRESS_0, &bar0);
	pr_err("%s: PCI BAR0 = 0x%08x\n", __func__, bar0);

	pr_err("%s: RTC_STATE_ADDRESS = 0x%08x, "
		"PCIE_SOC_WAKE_ADDRESS = 0x%08x\n", __func__,
		A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS
			+ RTC_STATE_ADDRESS),
		A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS
			+ PCIE_SOC_WAKE_ADDRESS));

	pr_err("%s: 0x80008 = 0x%08x, 0x8000c = 0x%08x, "
		"0x80010 = 0x%08x,\n0x80014 = 0x%08x, 0x80018 = 0x%08x, "
		"0x8001c = 0x%08x\n", __func__,
		A_PCI_READ32(sc->mem + 0x80008),
		A_PCI_READ32(sc->mem + 0x8000c),
		A_PCI_READ32(sc->mem + 0x80010),
		A_PCI_READ32(sc->mem + 0x80014),
		A_PCI_READ32(sc->mem + 0x80018),
		A_PCI_READ32(sc->mem + 0x8001c));
};

static struct pci_device_id hif_pci_id_table[] = {
	{ 0x168c, 0x003c, PCI_ANY_ID, PCI_ANY_ID },
	{ 0x168c, 0x003e, PCI_ANY_ID, PCI_ANY_ID },
	{ 0x168c, 0x0042, PCI_ANY_ID, PCI_ANY_ID },
	{ 0x168c, 0x0043, PCI_ANY_ID, PCI_ANY_ID },
	{ 0 }
};

/* HIF IRQ History */
typedef enum {
	HIF_IRQ,
	HIF_IRQ_END,
	HIF_TASKLET,
	HIF_TASKLET_END,
	HIF_CRASH,
	HIF_SUSPEND_START,
	HIF_SUSPEND_AFTER_WOW,
	HIF_SUSPEND_END,
	HIF_RESUME,
} hif_irq_type;

#ifdef CONFIG_SLUB_DEBUG_ON
typedef struct {
	hif_irq_type type;
	A_UINT64 time;
	A_UINT32 irq_summary;
	A_UINT32 fw_indicator;
	A_UINT32 irq_enable;
	A_UINT32 irq_cause;
	A_UINT32 irq_clear;
} hif_irq_history;

#define HIF_IRQ_HISTORY_MAX 1024
adf_os_atomic_t g_hif_irq_history_idx;
hif_irq_history hif_irq_history_buffer[HIF_IRQ_HISTORY_MAX];

static void hif_irq_record(hif_irq_type type, struct hif_pci_softc *sc)
{
	struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device;
	A_target_id_t targid = hif_state->targid;

	int record_index = get_next_record_index(
			&g_hif_irq_history_idx, HIF_IRQ_HISTORY_MAX);

	if (HIFTargetSleepStateAdjust(hif_state->targid, FALSE, TRUE) < 0) {
		adf_os_mem_zero(&hif_irq_history_buffer[record_index],
				sizeof(hif_irq_history));
		goto out;
	}

	hif_irq_history_buffer[record_index].irq_summary =
			CE_INTERRUPT_SUMMARY(targid);
	hif_irq_history_buffer[record_index].fw_indicator =
			A_TARGET_READ(targid, hif_state->fw_indicator_address);
	hif_irq_history_buffer[record_index].irq_enable =
			A_PCI_READ32(sc->mem + SOC_CORE_BASE_ADDRESS +
				PCIE_INTR_ENABLE_ADDRESS);
	hif_irq_history_buffer[record_index].irq_cause =
			A_PCI_READ32(sc->mem + SOC_CORE_BASE_ADDRESS +
				PCIE_INTR_CAUSE_ADDRESS);
	hif_irq_history_buffer[record_index].irq_clear =
			A_PCI_READ32(sc->mem + SOC_CORE_BASE_ADDRESS +
				PCIE_INTR_CLR_ADDRESS);

	HIFTargetSleepStateAdjust(hif_state->targid, TRUE, FALSE);

out:
	hif_irq_history_buffer[record_index].type = type;
	hif_irq_history_buffer[record_index].time = adf_get_boottime();

}

/**
 * hif_irq_record_index_init() - initialize the hif irq index
 *
 * initialize the hif irq record index.
 * Return: none
 */
static void hif_irq_record_index_init(void)
{
	adf_os_atomic_init(&g_hif_irq_history_idx);
}

#else
static void hif_irq_record(hif_irq_type type, struct hif_pci_softc *sc) {};
static void hif_irq_record_index_init(void) {};
#endif

#ifndef REMOVE_PKT_LOG
struct ol_pl_os_dep_funcs *g_ol_pl_os_dep_funcs = NULL;
#endif

/* Setting SOC_GLOBAL_RESET during driver unload causes intermittent PCIe data bus error
 * As workaround for this issue - changing the reset sequence to use TargetCPU warm reset
 * instead of SOC_GLOBAL_RESET
 */
#define CPU_WARM_RESET_WAR

/*
 * Top-level interrupt handler for all PCI interrupts from a Target.
 * When a block of MSI interrupts is allocated, this top-level handler
 * is not used; instead, we directly call the correct sub-handler.
 */
static irqreturn_t
hif_pci_interrupt_handler(int irq, void *arg)
{
    struct hif_pci_softc *sc = (struct hif_pci_softc *) arg;
    struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device;
    volatile int tmp;

    if (sc->hif_init_done == TRUE) {
        adf_os_spin_lock_irqsave(&hif_state->suspend_lock);
    }

    if (LEGACY_INTERRUPTS(sc)) {

        if (sc->hif_init_done == TRUE) {
            if (Q_TARGET_ACCESS_BEGIN(hif_state->targid) < 0) {
                adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock);
                return IRQ_HANDLED;
            }

            hif_irq_record(HIF_IRQ, sc);
        }

        /* Clear Legacy PCI line interrupts */
        /* IMPORTANT: INTR_CLR regiser has to be set after INTR_ENABLE is set to 0, */
        /*            otherwise interrupt can not be really cleared */
        A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS), 0);
        A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_CLR_ADDRESS), PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
        /* IMPORTANT: this extra read transaction is required to flush the posted write buffer */
        tmp = A_PCI_READ32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS));

        if (tmp == 0xdeadbeef) {
            pr_err("BUG(%s): SoC returns 0xdeadbeef!!\n", __func__);
            print_config_soc_reg(sc);
            VOS_BUG(0);
        }

        if (sc->hif_init_done == TRUE) {
            if (Q_TARGET_ACCESS_END(hif_state->targid) < 0) {
                adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock);
                return IRQ_HANDLED;
            }
        }
    }
    /* TBDXXX: Add support for WMAC */

    sc->irq_event = irq;
    adf_os_atomic_set(&sc->tasklet_from_intr, 1);
    tasklet_schedule(&sc->intr_tq);

    if (sc->hif_init_done == TRUE) {
        hif_irq_record(HIF_IRQ_END, sc);
        adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock);
    }
    return IRQ_HANDLED;
}

static irqreturn_t
hif_pci_msi_fw_handler(int irq, void *arg)
{
    struct hif_pci_softc *sc = (struct hif_pci_softc *) arg;

    (irqreturn_t)HIF_fw_interrupt_handler(sc->irq_event, sc);

    return IRQ_HANDLED;
}

bool
hif_pci_targ_is_awake(struct hif_pci_softc *sc, void *__iomem *mem)
{
    A_UINT32 val;

    if(sc->recovery)
        return false;

    val = A_PCI_READ32(mem + PCIE_LOCAL_BASE_ADDRESS + RTC_STATE_ADDRESS);
    return (RTC_STATE_V_GET(val) == RTC_STATE_V_ON);
}

bool hif_pci_targ_is_present(A_target_id_t targetid, void *__iomem *mem)
{
    return 1; /* FIX THIS */
}

bool hif_max_num_receives_reached(unsigned int count)
{
    if (WLAN_IS_EPPING_ENABLED(vos_get_conparam()))
        return (count > 120);
    else
        return (count > MAX_NUM_OF_RECEIVES);
}

int hif_init_adf_ctx(void *ol_sc)
{
    v_CONTEXT_t pVosContext = NULL;
    adf_os_device_t adf_ctx;
    struct ol_softc *sc = (struct ol_softc *)ol_sc;
    struct hif_pci_softc *hif_sc = sc->hif_sc;

    pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);

    if(pVosContext == NULL) {
       return -EFAULT;
    }
    adf_ctx = vos_mem_malloc(sizeof(*adf_ctx));
    if (!adf_ctx) {
        return -ENOMEM;
    }
    vos_mem_zero(adf_ctx, sizeof(*adf_ctx));
    adf_ctx->drv = &hif_sc->aps_osdev;
    adf_ctx->drv_hdl = hif_sc->aps_osdev.bdev;
    adf_ctx->dev = hif_sc->aps_osdev.device;
    sc->adf_dev = adf_ctx;
    ((VosContextType*)(pVosContext))->adf_ctx = adf_ctx;
    return 0;
}

void hif_deinit_adf_ctx(void *ol_sc)
{
    struct ol_softc *sc = (struct ol_softc *)ol_sc;

    if (sc == NULL)
        return;
    if (sc->adf_dev) {
        v_CONTEXT_t pVosContext = NULL;

        pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
        vos_mem_free(sc->adf_dev);
        sc->adf_dev = NULL;
        if (pVosContext)
            ((VosContextType*)(pVosContext))->adf_ctx = NULL;
    }
}

#define A_PCIE_LOCAL_REG_READ(mem, addr) \
        A_PCI_READ32((char *)(mem) + PCIE_LOCAL_BASE_ADDRESS + (A_UINT32)(addr))

#define A_PCIE_LOCAL_REG_WRITE(mem, addr, val) \
        A_PCI_WRITE32(((char *)(mem) + PCIE_LOCAL_BASE_ADDRESS + (A_UINT32)(addr)), (val))

#define ATH_PCI_RESET_WAIT_MAX 10 /* Ms */
static void
hif_pci_device_reset(struct hif_pci_softc *sc)
{
    void __iomem *mem = sc->mem;
    int i;
    u_int32_t val;

    if (!sc->hostdef)
        return;

    /* NB: Don't check resetok here.  This form of reset is integral to correct operation. */

    if (!SOC_GLOBAL_RESET_ADDRESS) {
        return;
    }

    if (!mem) {
        return;
    }

    printk("Reset Device \n");

    /*
     * NB: If we try to write SOC_GLOBAL_RESET_ADDRESS without first
     * writing WAKE_V, the Target may scribble over Host memory!
     */
    A_PCIE_LOCAL_REG_WRITE(mem, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK);
    for (i=0; i<ATH_PCI_RESET_WAIT_MAX; i++) {
        if (hif_pci_targ_is_awake(sc, mem)) {
            break;
        }

        A_MDELAY(1);
    }

    /* Put Target, including PCIe, into RESET. */
    val = A_PCIE_LOCAL_REG_READ(mem, SOC_GLOBAL_RESET_ADDRESS);
    val |= 1;
    A_PCIE_LOCAL_REG_WRITE(mem, SOC_GLOBAL_RESET_ADDRESS, val);
    for (i=0; i<ATH_PCI_RESET_WAIT_MAX; i++) {
        if (A_PCIE_LOCAL_REG_READ(mem, RTC_STATE_ADDRESS) & RTC_STATE_COLD_RESET_MASK) {
            break;
        }

        A_MDELAY(1);
    }

    /* Pull Target, including PCIe, out of RESET. */
    val &= ~1;
    A_PCIE_LOCAL_REG_WRITE(mem, SOC_GLOBAL_RESET_ADDRESS, val);
    for (i=0; i<ATH_PCI_RESET_WAIT_MAX; i++) {
        if (!(A_PCIE_LOCAL_REG_READ(mem, RTC_STATE_ADDRESS) & RTC_STATE_COLD_RESET_MASK)) {
            break;
        }

        A_MDELAY(1);
    }

    A_PCIE_LOCAL_REG_WRITE(mem, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
}


/* CPU warm reset function
 * Steps:
 *	1. Disable all pending interrupts - so no pending interrupts on WARM reset
 *	2. Clear the FW_INDICATOR_ADDRESS -so Traget CPU intializes FW correctly on WARM reset
 *      3. Clear TARGET CPU LF timer interrupt
 *      4. Reset all CEs to clear any pending CE tarnsactions
 *      5. Warm reset CPU
 */
void
hif_pci_device_warm_reset(struct hif_pci_softc *sc)
{
    void __iomem *mem = sc->mem;
    int i;
    u_int32_t val;
    u_int32_t fw_indicator;

    /* NB: Don't check resetok here.  This form of reset is integral to correct operation. */

    if (!mem) {
        return;
    }

    printk("Target Warm Reset\n");

    /*
     * NB: If we try to write SOC_GLOBAL_RESET_ADDRESS without first
     * writing WAKE_V, the Target may scribble over Host memory!
     */
    A_PCIE_LOCAL_REG_WRITE(mem, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK);
    for (i=0; i<ATH_PCI_RESET_WAIT_MAX; i++) {
        if (hif_pci_targ_is_awake(sc, mem)) {
            break;
        }
        A_MDELAY(1);
    }

    /*
     * Disable Pending interrupts
     */
    val = A_PCI_READ32(mem + (SOC_CORE_BASE_ADDRESS | PCIE_INTR_CAUSE_ADDRESS));
    printk("Host Intr Cause reg 0x%x : value : 0x%x \n", (SOC_CORE_BASE_ADDRESS | PCIE_INTR_CAUSE_ADDRESS), val);
    /* Target CPU Intr Cause */
    val = A_PCI_READ32(mem + (SOC_CORE_BASE_ADDRESS | CPU_INTR_ADDRESS));
    printk("Target CPU Intr Cause 0x%x \n", val);

    val = A_PCI_READ32(mem + (SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS));
    A_PCI_WRITE32((mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS)), 0);
    A_PCI_WRITE32((mem+(SOC_CORE_BASE_ADDRESS+PCIE_INTR_CLR_ADDRESS)), 0xffffffff);

    A_MDELAY(100);

    /* Clear FW_INDICATOR_ADDRESS */
    fw_indicator = A_PCI_READ32(mem + FW_INDICATOR_ADDRESS);
    A_PCI_WRITE32(mem+FW_INDICATOR_ADDRESS, 0);

    /* Clear Target LF Timer interrupts */
    val = A_PCI_READ32(mem + (RTC_SOC_BASE_ADDRESS + SOC_LF_TIMER_CONTROL0_ADDRESS));
    printk("addr 0x%x :  0x%x \n", (RTC_SOC_BASE_ADDRESS + SOC_LF_TIMER_CONTROL0_ADDRESS), val);
    val &= ~SOC_LF_TIMER_CONTROL0_ENABLE_MASK;
    A_PCI_WRITE32(mem+(RTC_SOC_BASE_ADDRESS + SOC_LF_TIMER_CONTROL0_ADDRESS), val);

    /* Reset CE */
    val = A_PCI_READ32(mem + (RTC_SOC_BASE_ADDRESS | SOC_RESET_CONTROL_ADDRESS));
    val |= SOC_RESET_CONTROL_CE_RST_MASK;
    A_PCI_WRITE32((mem+(RTC_SOC_BASE_ADDRESS | SOC_RESET_CONTROL_ADDRESS)), val);
    val = A_PCI_READ32(mem + (RTC_SOC_BASE_ADDRESS | SOC_RESET_CONTROL_ADDRESS));
    A_MDELAY(10);

    /* CE unreset */
    val &= ~SOC_RESET_CONTROL_CE_RST_MASK;
    A_PCI_WRITE32(mem+(RTC_SOC_BASE_ADDRESS | SOC_RESET_CONTROL_ADDRESS), val);
    val = A_PCI_READ32(mem + (RTC_SOC_BASE_ADDRESS | SOC_RESET_CONTROL_ADDRESS));
    A_MDELAY(10);

    /* Read Target CPU Intr Cause */
    val = A_PCI_READ32(mem + (SOC_CORE_BASE_ADDRESS | CPU_INTR_ADDRESS));
    printk("Target CPU Intr Cause after CE reset 0x%x \n", val);

    /* CPU warm RESET */
    val = A_PCI_READ32(mem + (RTC_SOC_BASE_ADDRESS | SOC_RESET_CONTROL_ADDRESS));
    val |= SOC_RESET_CONTROL_CPU_WARM_RST_MASK;
    A_PCI_WRITE32(mem+(RTC_SOC_BASE_ADDRESS | SOC_RESET_CONTROL_ADDRESS), val);
    val = A_PCI_READ32(mem + (RTC_SOC_BASE_ADDRESS | SOC_RESET_CONTROL_ADDRESS));
    printk("RESET_CONTROL after cpu warm reset 0x%x \n", val);

    A_MDELAY(100);
    printk("Target Warm reset complete\n");

}

/**
 * hif_pci_set_ram_config_reg() - sets target RAM configuration register
 * @sc:                           pointer of hif_pci_softc context
 * @config:                       value to be wrote to the register
 *
 * This function will write the given value to target RAM configuration
 * register which is bit[23-20] of target CPU inbound address in order to
 * provide correct address mapping.
 *
 * Return: 0 for success or reasons for failure
 */
int hif_pci_set_ram_config_reg(struct hif_pci_softc *sc, uint32_t config)
{
	struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device;
	A_target_id_t targid = hif_state->targid;
	void __iomem *mem = sc->mem;
	uint32_t val;

	A_TARGET_ACCESS_BEGIN_RET(targid);
	A_PCI_WRITE32(mem + SOC_CORE_BASE_ADDRESS +
			FW_RAM_CONFIG_ADDRESS, config);
	val = A_PCI_READ32(mem + SOC_CORE_BASE_ADDRESS +
			FW_RAM_CONFIG_ADDRESS);
	if (val != config) {
		pr_err("%s: Failed to set RAM config reg from 0x%x to 0x%x\n",
			__func__, val, config);
		A_TARGET_ACCESS_END_RET(targid);
		return -EACCES;
	}
	A_TARGET_ACCESS_END_RET(targid);
	return 0;
}

int hif_pci_check_fw_reg(struct hif_pci_softc *sc)
{
    struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device;
    A_target_id_t targid = hif_state->targid;
    void __iomem *mem = sc->mem;
    u_int32_t val;

    A_TARGET_ACCESS_BEGIN_RET(targid);
    val = A_PCI_READ32(mem + FW_INDICATOR_ADDRESS);
    A_TARGET_ACCESS_END_RET(targid);

    printk("%s: FW_INDICATOR register is 0x%x\n", __func__, val);

    if (val & FW_IND_HELPER)
        return 0;

    return 1;
}

int hif_pci_check_soc_status(struct hif_pci_softc *sc)
{
    u_int16_t device_id;
    u_int32_t val;
    u_int16_t timeout_count = 0;

    /* Check device ID from PCIe configuration space for link status */
    pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &device_id);
    if(device_id != sc->devid) {
        printk(KERN_ERR "PCIe link is down!\n");
        return -EACCES;
    }

    /* Check PCIe local register for bar/memory access */
    val = A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS +
                       RTC_STATE_ADDRESS);
    printk("RTC_STATE_ADDRESS is %08x\n", val);

    /* Try to wake up taget if it sleeps */
    A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS +
                  PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK);
    printk("PCIE_SOC_WAKE_ADDRESS is %08x\n",
           A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS +
                        PCIE_SOC_WAKE_ADDRESS));

    /* Check if taget can be woken up */
    while(!hif_pci_targ_is_awake(sc, sc->mem)) {
        if(timeout_count >= PCIE_WAKE_TIMEOUT) {
            printk(KERN_ERR "Target cannot be woken up! "
                "RTC_STATE_ADDRESS is %08x, PCIE_SOC_WAKE_ADDRESS is %08x\n",
                A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS +
                RTC_STATE_ADDRESS), A_PCI_READ32(sc->mem +
                PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS));
            return -EACCES;
        }

        A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS +
                      PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK);

        A_MDELAY(100);
        timeout_count += 100;
    }

    /* Check Power register for SoC internal bus issues */
    val = A_PCI_READ32(sc->mem + RTC_SOC_BASE_ADDRESS + SOC_POWER_REG_OFFSET);
    printk("Power register is %08x\n", val);

    return EOK;
}

void dump_CE_debug_register(struct hif_pci_softc *sc)
{
    struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device;
    A_target_id_t targid = hif_state->targid;
    void __iomem *mem = sc->mem;
    u_int32_t val, i, j;
    u_int32_t wrapper_idx[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    u_int32_t ce_base;

    A_TARGET_ACCESS_BEGIN(targid);

    /* DEBUG_INPUT_SEL_SRC = 0x6 */
    val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_INPUT_SEL_OFFSET);
    val &= ~WLAN_DEBUG_INPUT_SEL_SRC_MASK;
    val |= WLAN_DEBUG_INPUT_SEL_SRC_SET(0x6);
    A_PCI_WRITE32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_INPUT_SEL_OFFSET, val);

    /* DEBUG_CONTROL_ENABLE = 0x1 */
    val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_CONTROL_OFFSET);
    val &= ~WLAN_DEBUG_CONTROL_ENABLE_MASK;
    val |= WLAN_DEBUG_CONTROL_ENABLE_SET(0x1);
    A_PCI_WRITE32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_CONTROL_OFFSET, val);

    printk("Debug: inputsel: %x dbgctrl: %x\n",
        A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_INPUT_SEL_OFFSET),
        A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_CONTROL_OFFSET));

    printk("Debug CE: \n");
    /* Loop CE debug output */
    /* AMBA_DEBUG_BUS_SEL = 0xc */
    val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET);
    val &= ~AMBA_DEBUG_BUS_SEL_MASK;
    val |= AMBA_DEBUG_BUS_SEL_SET(0xc);
    A_PCI_WRITE32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET, val);

    for (i = 0; i < sizeof(wrapper_idx)/sizeof(A_UINT32); i++) {
        /* For (i=1,2,3,4,8,9) write CE_WRAPPER_DEBUG_SEL = i */
        val = A_PCI_READ32(mem + CE_WRAPPER_BASE_ADDRESS +
                           CE_WRAPPER_DEBUG_OFFSET);
        val &= ~CE_WRAPPER_DEBUG_SEL_MASK;
        val |= CE_WRAPPER_DEBUG_SEL_SET(wrapper_idx[i]);
        A_PCI_WRITE32(mem + CE_WRAPPER_BASE_ADDRESS +
                      CE_WRAPPER_DEBUG_OFFSET, val);

        printk("ce wrapper: %d amdbg: %x cewdbg: %x\n", wrapper_idx[i],
            A_PCI_READ32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET),
            A_PCI_READ32(mem + CE_WRAPPER_BASE_ADDRESS +
                         CE_WRAPPER_DEBUG_OFFSET));

        if (wrapper_idx[i] <= 7) {
            for (j = 0; j <= 5; j++) {
                ce_base = CE_BASE_ADDRESS(wrapper_idx[i]);
                /* For (j=0~5) write CE_DEBUG_SEL = j */
                val = A_PCI_READ32(mem + ce_base + CE_DEBUG_OFFSET);
                val &= ~CE_DEBUG_SEL_MASK;
                val |= CE_DEBUG_SEL_SET(j);
                A_PCI_WRITE32(mem + ce_base + CE_DEBUG_OFFSET, val);

                /* read (@gpio_athr_wlan_reg) WLAN_DEBUG_OUT_DATA */
                val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS +
                                   WLAN_DEBUG_OUT_OFFSET);
                val = WLAN_DEBUG_OUT_DATA_GET(val);

                printk("    module%d: cedbg: %x out: %x\n", j,
                    A_PCI_READ32(mem + ce_base + CE_DEBUG_OFFSET), val);
            }
        } else {
            /* read (@gpio_athr_wlan_reg) WLAN_DEBUG_OUT_DATA */
            val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_OUT_OFFSET);
            val = WLAN_DEBUG_OUT_DATA_GET(val);

            printk("    out: %x\n", val);
        }
    }

    printk("Debug PCIe: \n");
    /* Loop PCIe debug output */
    /* Write AMBA_DEBUG_BUS_SEL = 0x1c */
    val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET);
    val &= ~AMBA_DEBUG_BUS_SEL_MASK;
    val |= AMBA_DEBUG_BUS_SEL_SET(0x1c);
    A_PCI_WRITE32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET, val);

    for (i = 0; i <= 8; i++) {
        /* For (i=1~8) write AMBA_DEBUG_BUS_PCIE_DEBUG_SEL = i */
        val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET);
        val &= ~AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_MASK;
        val |= AMBA_DEBUG_BUS_PCIE_DEBUG_SEL_SET(i);
        A_PCI_WRITE32(mem + GPIO_BASE_ADDRESS + AMBA_DEBUG_BUS_OFFSET, val);

        /* read (@gpio_athr_wlan_reg) WLAN_DEBUG_OUT_DATA */
        val = A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_OUT_OFFSET);
        val = WLAN_DEBUG_OUT_DATA_GET(val);

        printk("amdbg: %x out: %x %x\n",
            A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_OUT_OFFSET), val,
            A_PCI_READ32(mem + GPIO_BASE_ADDRESS + WLAN_DEBUG_OUT_OFFSET));
    }

    A_TARGET_ACCESS_END(targid);
}

/*
 * Handler for a per-engine interrupt on a PARTICULAR CE.
 * This is used in cases where each CE has a private
 * MSI interrupt.
 */
static irqreturn_t
CE_per_engine_handler(int irq, void *arg)
{
    struct hif_pci_softc *sc = (struct hif_pci_softc *) arg;
    int CE_id = irq - MSI_ASSIGN_CE_INITIAL;

    /*
     * NOTE: We are able to derive CE_id from irq because we
     * use a one-to-one mapping for CE's 0..5.
     * CE's 6 & 7 do not use interrupts at all.
     *
     * This mapping must be kept in sync with the mapping
     * used by firmware.
     */

    CE_per_engine_service(sc, CE_id);

    return IRQ_HANDLED;
}

#ifdef CONFIG_SLUB_DEBUG_ON

/* worker thread to schedule wlan_tasklet in SLUB debug build */
static void reschedule_tasklet_work_handler(struct work_struct *recovery)
{
  void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);
  struct ol_softc *scn =  vos_get_context(VOS_MODULE_ID_HIF, vos_context);
  struct hif_pci_softc *sc;

  if (NULL == scn){
         printk(KERN_ERR "%s: tasklet scn is null\n", __func__);
         return;
   }

   sc = scn->hif_sc;

   if (sc->hif_init_done == FALSE) {
         printk(KERN_ERR "%s: wlan driver is unloaded\n", __func__);
         return;
   }

   tasklet_schedule(&sc->intr_tq);
   return;
}

static DECLARE_WORK(reschedule_tasklet_work, reschedule_tasklet_work_handler);

#endif


static void
wlan_tasklet(unsigned long data)
{
    struct hif_pci_softc *sc = (struct hif_pci_softc *) data;
    struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device;
    volatile int tmp;
    bool hif_init_done = sc->hif_init_done;
    A_target_id_t targid = hif_state->targid;

    if (hif_init_done == FALSE) {
         goto irq_handled;
    }

#ifdef FEATURE_WLAN_D0WOW
    if (adf_os_atomic_read(&sc->wow_done) && !adf_os_atomic_read(&sc->in_d0wow))
#else
    if (adf_os_atomic_read(&sc->wow_done))
#endif
         goto irq_handled;

    hif_irq_record(HIF_TASKLET, sc);

    adf_os_atomic_set(&sc->ce_suspend, 0);

    (irqreturn_t)HIF_fw_interrupt_handler(sc->irq_event, sc);
    if (sc->ol_sc->target_status == OL_TRGET_STATUS_RESET)
         goto irq_handled;

    CE_per_engine_service_any(sc->irq_event, sc);
    adf_os_atomic_set(&sc->tasklet_from_intr, 1);
    if (CE_get_rx_pending(sc)) {
        if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL)) {
            pr_err("%s: Load/Unload in Progress\n", __func__);
            goto end;
        }
        if (vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL)) {
            pr_err("%s: LOGP in progress\n", __func__);
            goto end;
        }

        /*
         * There are frames pending, schedule tasklet to process them.
         * Enable the interrupt only when there is no pending frames in
         * any of the Copy Engine pipes.
         */
#ifdef CONFIG_SLUB_DEBUG_ON
        schedule_work(&reschedule_tasklet_work);
#else
        tasklet_schedule(&sc->intr_tq);
#endif

end:
        adf_os_atomic_set(&sc->ce_suspend, 1);
        return;
    }

    if(!LEGACY_INTERRUPTS(sc) && CE_INTERRUPT_SUMMARY(targid)) {
	if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL))
		goto msiend;

	if (vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL))
		goto msiend;

	tasklet_schedule(&sc->intr_tq);
msiend:
	adf_os_atomic_set(&sc->ce_suspend, 1);
	return;
    }

irq_handled:
    /* use cached value for hif_init_done to prevent
     * unlocking an unlocked spinlock if hif init finishes
     * while this tasklet is running
     */
    if (hif_init_done == TRUE)
        adf_os_spin_lock_irqsave(&hif_state->suspend_lock);

    if (LEGACY_INTERRUPTS(sc) && (sc->ol_sc->target_status !=
                                  OL_TRGET_STATUS_RESET) &&
           (!adf_os_atomic_read(&sc->pci_link_suspended))) {

        if (hif_init_done == TRUE) {
            if(HIFTargetSleepStateAdjust(hif_state->targid, FALSE, TRUE) < 0) {
                adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock);
                return;
            }
        }

        /* Enable Legacy PCI line interrupts */
        A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS),
		    PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
        /* IMPORTANT: this extra read transaction is required to flush the posted write buffer */
        tmp = A_PCI_READ32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS));

        if (hif_init_done == TRUE) {
             HIF_fw_interrupt_handler(sc->irq_event, sc);
             if(HIFTargetSleepStateAdjust(hif_state->targid, TRUE, FALSE) < 0) {
                   adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock);
                   return;
               }
        }
    }

    if (hif_init_done == TRUE) {
        hif_irq_record(HIF_TASKLET_END, sc);
        adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock);
    }

    adf_os_atomic_set(&sc->ce_suspend, 1);
}

#define ATH_PCI_PROBE_RETRY_MAX 3

#ifdef FEATURE_RUNTIME_PM
static void hif_pci_pm_work(struct work_struct *work)
{
	struct hif_pci_softc *sc = container_of(work, struct hif_pci_softc,
			pm_work);
	struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device;
	MSG_BASED_HIF_CALLBACKS *msg_callbacks;

	pr_debug("%s: Resume HTT & WMI Service in runtime_pm state %d\n",
			__func__, atomic_read(&sc->pm_state));

	msg_callbacks = &hif_state->msg_callbacks_current;

	msg_callbacks->txResumeAllHandler(msg_callbacks->Context);
}

#ifdef WLAN_OPEN_SOURCE
static int hif_pci_autopm_debugfs_show(struct seq_file *s, void *data)
{
#define HIF_PCI_AUTOPM_STATS(_s, _sc, _name) \
	seq_printf(_s, "%30s: %u\n", #_name, _sc->pm_stats._name)
	struct hif_pci_softc *sc = s->private;
	static const char *autopm_state[] = {"NONE", "ON", "INPROGRESS",
						"SUSPENDED"};
	unsigned int msecs_age;
	int pm_state = atomic_read(&sc->pm_state);
	unsigned long timer_expires;
	struct hif_pm_runtime_context *ctx;

	seq_printf(s, "%30s: %s\n", "Runtime PM state",
			autopm_state[pm_state]);
	seq_printf(s, "%30s: %pf\n", "Last Resume Caller",
			sc->pm_stats.last_resume_caller);

	if (pm_state == HIF_PM_RUNTIME_STATE_SUSPENDED) {
		msecs_age = jiffies_to_msecs(jiffies - sc->pm_stats.suspend_jiffies);
		seq_printf(s, "%30s: %d.%03ds\n", "Suspended Since",
				msecs_age / 1000, msecs_age % 1000);
	}

	seq_printf(s, "%30s: %d\n", "PM Usage count",
			atomic_read(&sc->dev->power.usage_count));

	seq_printf(s, "%30s: %u\n", "prevent_suspend_cnt",
				sc->prevent_suspend_cnt);

	HIF_PCI_AUTOPM_STATS(s, sc, suspended);
	HIF_PCI_AUTOPM_STATS(s, sc, suspend_err);
	HIF_PCI_AUTOPM_STATS(s, sc, resumed);
	HIF_PCI_AUTOPM_STATS(s, sc, runtime_get);
	HIF_PCI_AUTOPM_STATS(s, sc, runtime_put);
	HIF_PCI_AUTOPM_STATS(s, sc, request_resume);
	HIF_PCI_AUTOPM_STATS(s, sc, prevent_suspend);
	HIF_PCI_AUTOPM_STATS(s, sc, allow_suspend);
	HIF_PCI_AUTOPM_STATS(s, sc, prevent_suspend_timeout);
	HIF_PCI_AUTOPM_STATS(s, sc, allow_suspend_timeout);
	HIF_PCI_AUTOPM_STATS(s, sc, runtime_get_err);
	timer_expires = sc->runtime_timer_expires;
	if (timer_expires > 0) {
		msecs_age = jiffies_to_msecs(timer_expires - jiffies);
		seq_printf(s, "%30s: %d.%03ds\n", "Prevent suspend timeout",
				msecs_age / 1000, msecs_age % 1000);
	}

	spin_lock_bh(&sc->runtime_lock);
	if (list_empty(&sc->prevent_suspend_list)) {
		spin_unlock_bh(&sc->runtime_lock);
		return 0;
	}

	seq_printf(s, "%30s: ", "Active Wakeup_Sources");
	list_for_each_entry(ctx, &sc->prevent_suspend_list, list) {
		seq_printf(s, "%s", ctx->name);
		if (ctx->timeout)
			seq_printf(s, "(%d ms)", ctx->timeout);
		seq_puts(s, " ");
	}
	seq_puts(s, "\n");
	spin_unlock_bh(&sc->runtime_lock);

	return 0;
#undef HIF_PCI_AUTOPM_STATS
}

static int hif_pci_autopm_open(struct inode *inode, struct file *file)
{
	return single_open(file, hif_pci_autopm_debugfs_show, inode->i_private);
}

#ifdef FEATURE_RUNTIME_PM_UNIT_TEST
/*
 * This is global runtime context just for unit test framework.
 * This context should not be used for other purpose.
 */

#define MAX_RUNTIME_DEBUG_CONTEXT 4
static struct hif_pm_runtime_context rpm_data[MAX_RUNTIME_DEBUG_CONTEXT];

/**
 * hif_pm_test() - Calls the API's per context
 * @sc:	ol_softc context
 * @context: Runtime PM context
 * @fn:	function Tag
 * @delay: delay to add before executing the runtime API
 *
 * This API's calls the runtime API's based on the passed
 * function tag value and adds the dealy before calling them
 *
 * Return: void
 */
static void hif_pm_test(struct ol_softc *sc,
			struct hif_pm_runtime_context *context,
			const char *fn, uint32_t delay)
{
	char func = *fn;

	pr_info("%s func:%c delay:%d ctx:%s\n", __func__,
		func, delay, context ? context->name : "NULL");

	switch (func) {
	case 'A':
		msleep(delay * 1000);
		hif_pm_runtime_allow_suspend(sc, context);
		break;
	case 'P':
		msleep(delay * 1000);
		hif_pm_runtime_prevent_suspend(sc, context);
		break;
	case 'T':
		hif_pm_runtime_prevent_suspend_timeout(sc, context,
							delay * 1000);
		break;
	default:
		break;
	}
}

/**
 * hif_get_context() - Returns the context for unit test framework
 * @c: value to choose the gloabl context for testing the runtime API's
 *
 * Return: void
 */

static void *hif_get_context(char *c)
{
	unsigned int val;

	if (kstrtou32(c, 0, &val))
		return NULL;

	switch (val) {
	case 1:
		rpm_data[0].name = "context_1";
		break;
	case 2:
		rpm_data[1].name = "context_2";
		break;
	case 3:
		rpm_data[2].name = "context_3";
		break;
	case 4:
		rpm_data[3].name = "context_4";
		break;
	default:
		return NULL;
	}
	return &rpm_data[val-1];
}

/**
 * hif_runtime_test_init() - Initialize the test framework
 * @sc:	Global hif context
 * Return: void
 */
void hif_runtime_test_init(struct hif_pci_softc *sc)
{
	int i;
	struct hif_pm_runtime_context *ctx = NULL, *tmp;

	for (i = 0; i < MAX_RUNTIME_DEBUG_CONTEXT; i++) {
		ctx = &rpm_data[i];
		ctx->active = false;
		ctx->name = NULL;
		list_for_each_entry_safe(ctx, tmp,
				&sc->prevent_suspend_list, list) {
			list_del(&ctx->list);
		}
	}
}

/**
 * hif_pci_autopm_write() - Unit Test API to verify the Runtime PM API's
 *
 * Usage: "Context=API:Delay:....;Context=API:Delay;"
 * Context Can be from 1 to 4.
 * API can be one of the following
 * T - Prevent Suspend Timeout Version
 * P - Prevent_suspend
 * A - Allow Suspend
 * Delay in sec
 * Delimiters:
 * "=" - Seperates context from the API calls
 * ":" - Seperates API's/Delay
 * ";" - Seperates two context.
 *
 * eg: echo "1=T:5:A:2:P:1;2=T:5;1=A:1;2=A:0" > /d/cnss_runtime_pm
 * In the above example:
 * 1=T:4:A:2:P:1 --> This is sequence of calls with context 1
 * 2=T:5 --> Context 2 is used here
 * 1=A:1 --> Context 1 can be used to allow the prevented suspend in context 1
 * 2=A:0 --> Relax the runtime suspend from context 2.
 *
 * Only to be used by developers to verify if any changes done in future.
 */

static ssize_t hif_pci_autopm_write(struct file *fp, const char __user *buf,
				size_t count, loff_t *off)
{
	struct hif_pci_softc *hif_sc;
	struct ol_softc *sc;
	char *fmtp, *pattern, *func, *ctxp, *ctx, *data;
	uint32_t val;
	struct hif_pm_runtime_context *context = NULL;

	hif_sc = ((struct seq_file *)fp->private_data)->private;
	if (!hif_sc)
		return -EINVAL;

	sc = hif_sc->ol_sc;

	pattern = adf_os_mem_alloc(NULL, count);
	if (!pattern)
		return -ENOMEM;

	if (copy_from_user(pattern, buf, count)) {
		adf_os_mem_free(pattern);
		return -EFAULT;
	}

	hif_runtime_test_init(hif_sc);

	ctxp = pattern;
	while (ctxp) {
		ctx = strsep(&ctxp, ";");
		while (ctx) {
			data = strsep(&ctx, "=");
			context = hif_get_context(data);
			fmtp = strsep(&ctx, "=");
			while (fmtp) {
				func = strsep(&fmtp, ":");
				if (kstrtou32(strsep(&fmtp, ":"), 0, &val)) {
					adf_os_mem_free(pattern);
					return -EFAULT;
				}
				hif_pm_test(sc, context, func, val);
			}
		}
	}
	adf_os_mem_free(pattern);
	return count;
}
#else
#define HIF_ENABLE_AUTO_PM	1
#define HIF_DISABLE_AUTO_PM	0
static bool dynamic_auto_pm_state = HIF_ENABLE_AUTO_PM;

static ssize_t hif_pci_enable_disable_autopm(struct file *fp, const char __user
					     *buf, size_t count, loff_t *off)
{
	int enable_auto_pm;
	struct seq_file *s;
	struct hif_pci_softc *hif_sc;
	int ret;
	struct hif_pm_runtime_context *ctx;
	struct ol_softc *sc;

	s = (struct seq_file *)fp->private_data;
	hif_sc = s->private;

	if (!hif_sc)
		return -EINVAL;

	sscanf(buf, "%d", &enable_auto_pm);

	if ((enable_auto_pm != HIF_ENABLE_AUTO_PM) && (enable_auto_pm !=
	    HIF_DISABLE_AUTO_PM)) {
		pr_err("%s: I/P is invalid:%d Valid: Enable(1), Disable(0)\n",
		       __func__, enable_auto_pm);
		return -EINVAL;
	}

	ctx = hif_sc->dynamic_ctx;
	sc = hif_sc->ol_sc;

	ret = enable_auto_pm ? hif_pm_runtime_allow_suspend(sc, ctx) :
		hif_pm_runtime_prevent_suspend(sc, ctx);

	if (ret)
		return ret;

	pr_info("%s: enable_auto_pm:%d ret:%d \n", __func__, enable_auto_pm,
		ret);

	dynamic_auto_pm_state = enable_auto_pm;

	return count;
}
#endif

static const struct file_operations hif_pci_autopm_fops = {
	.owner		= THIS_MODULE,
	.open		= hif_pci_autopm_open,
	.release	= single_release,
	.read		= seq_read,
	.llseek		= seq_lseek,
#ifdef FEATURE_RUNTIME_PM_UNIT_TEST
	.write		= hif_pci_autopm_write,
#else
	.write		= hif_pci_enable_disable_autopm,
#endif
};
#endif /*WLAN_OPEN_SOURCE*/

static int __hif_pci_runtime_suspend(struct pci_dev *pdev)
{
	struct hif_pci_softc *sc = NULL;
	void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);
	pm_message_t state = { .event = PM_EVENT_SUSPEND };
	v_VOID_t *temp_module;
	ol_txrx_pdev_handle txrx_pdev;
	int ret = -EBUSY, test = 0;

	if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL)) {
		pr_err("%s: Load/Unload in Progress\n", __func__);
		goto end;
	}

	if (vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL)) {
		pr_err("%s: LOGP in progress\n", __func__);
		goto end;
	}

	sc = pci_get_drvdata(pdev);
	if (!sc) {
		pr_err("%s: sc is NULL!\n", __func__);
		goto end;
	}

	adf_os_atomic_set(&sc->pm_state, HIF_PM_RUNTIME_STATE_INPROGRESS);

	txrx_pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos_context);
	if (!txrx_pdev) {
		pr_err("%s: txrx_pdev is NULL\n", __func__);
		goto out;
	}

	if ((test = ol_txrx_get_tx_pending(txrx_pdev)) ||
		 ol_txrx_get_queue_status(txrx_pdev)) {
		pr_err("%s: txrx pending(%d), get: %u, put: %u\n", __func__,
				test,
				sc->pm_stats.runtime_get,
				sc->pm_stats.runtime_put);
		goto out;
	}

	temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos_context);
	if (!temp_module) {
		pr_err("%s: WDA module is NULL\n", __func__);
		goto out;
	}

	if (wma_check_scan_in_progress(temp_module)) {
		pr_err("%s: Scan in Progress. Aborting runtime suspend\n",
				__func__);
		goto out;
	}

#ifdef FEATURE_WLAN_D0WOW
	if (wma_get_client_count(temp_module)) {
		pr_err("%s: Runtime PM not supported when clients are connected\n",
				__func__);
		goto out;
	}
#endif

	ret = wma_runtime_suspend_req(temp_module);
	if (ret) {
		pr_err("%s: Runtime Offloads configuration failed: %d\n",
				__func__, ret);
		goto out;
	}

	ret = __hif_pci_suspend(pdev, state, true);
	if (ret) {
		pr_err("%s: pci_suspend failed: %d\n", __func__, ret);
		goto suspend_fail;
	}

	ret = vos_auto_suspend();

	if (ret) {
		ret = -EAGAIN;
		goto suspend_fail;
	}

	adf_os_atomic_set(&sc->pm_state, HIF_PM_RUNTIME_STATE_SUSPENDED);
	sc->pm_stats.suspended++;
	sc->pm_stats.suspend_jiffies = jiffies;

	return 0;

suspend_fail:
	wma_runtime_resume_req(temp_module);
out:
	adf_os_atomic_set(&sc->pm_state, HIF_PM_RUNTIME_STATE_ON);
	sc->pm_stats.suspend_err++;
	hif_pm_runtime_mark_last_busy(sc->dev);
end:
	ASSERT(ret == -EAGAIN || ret == -EBUSY);
	return ret;
}

static int hif_pci_runtime_suspend(struct pci_dev *pdev)
{
	int ret = 0;
	vos_ssr_protect(__func__);
	ret = __hif_pci_runtime_suspend(pdev);
	vos_ssr_unprotect(__func__);

	return ret;
}

static int __hif_pci_runtime_resume(struct pci_dev *pdev)
{
	struct hif_pci_softc *sc = pci_get_drvdata(pdev);
	void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);
	int ret = 0;
	v_VOID_t * temp_module;

	adf_os_atomic_set(&sc->pm_state, HIF_PM_RUNTIME_STATE_INPROGRESS);

	temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos_context);
	if (!temp_module) {
		pr_err("%s: WDA module is NULL\n", __func__);
		goto out;
	}

#ifdef FEATURE_WLAN_D0WOW
	if (wma_get_client_count(temp_module)) {
		pr_err("%s: Runtime PM not supported when clients are connected\n",
				__func__);
		ASSERT(0);

		ret = -EINVAL;
		goto out;
	}
#endif
	ret = vos_auto_resume();

	if (ret) {
		pr_err("%s: Failed to resume PCIe link: %d\n", __func__, ret);
		goto out;
	}

	ret = __hif_pci_resume(pdev, true);

	if (ret) {
		hif_pci_runtime_pm_warn(sc, "Link Resume Failed");
		return ret;
	}

	ret = wma_runtime_resume_req(temp_module);
	if (ret)
		goto out;

	adf_os_atomic_set(&sc->pm_state, HIF_PM_RUNTIME_STATE_ON);
	hif_pm_runtime_mark_last_busy(sc->dev);
	sc->pm_stats.resumed++;

	schedule_work(&sc->pm_work);

	return 0;
out:
	/* In Resume we should never fail */
	hif_pci_runtime_pm_warn(sc, "Runtime Resume Failed");
	/* skip VOS_BUG if SSR is already in progress */
	if (!vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL))
		VOS_BUG(0);
	return ret;
}

static int hif_pci_runtime_resume(struct pci_dev *pdev)
{
	int ret = 0;

	vos_ssr_protect(__func__);
	ret = __hif_pci_runtime_resume(pdev);
	vos_ssr_unprotect(__func__);

	return ret;
}

/* TODO: Change this to dev_pm_ops */
struct cnss_wlan_runtime_ops runtime_pm_ops = {
	.runtime_suspend = hif_pci_runtime_suspend,
	.runtime_resume = hif_pci_runtime_resume,
};

#ifdef WLAN_OPEN_SOURCE
#ifdef FEATURE_RUNTIME_PM_UNIT_TEST
static void hif_dynamic_auto_pm_init(struct hif_pci_softc *sc)
{
}
static void hif_dynaic_auto_pm_deinit(struct hif_pci_softc *sc)
{
}
#else /* else FEATURE_RUNTIME_PM_UNIT_TEST */
static void hif_dynamic_auto_pm_init(struct hif_pci_softc *sc)
{
	sc->dynamic_ctx = hif_runtime_pm_prevent_suspend_init("dynamic_ctx");

	if (!dynamic_auto_pm_state)
		hif_pm_runtime_prevent_suspend(sc->ol_sc, sc->dynamic_ctx);
}
static void hif_dynaic_auto_pm_deinit(struct hif_pci_softc *sc)
{
	hif_runtime_pm_prevent_suspend_deinit(sc->dynamic_ctx);
}
#endif /* END FEATURE_RUNTIME_PM_UNIT_TEST */

static inline void hif_pci_pm_debugfs(struct hif_pci_softc *sc, bool init)
{
	if (init) {
		sc->pm_dentry = debugfs_create_file("cnss_runtime_pm",
						S_IRUSR, NULL, sc,
						&hif_pci_autopm_fops);
		hif_dynamic_auto_pm_init(sc);
	} else {
		hif_dynaic_auto_pm_deinit(sc);
		debugfs_remove(sc->pm_dentry);
	}
}
#else
static inline void hif_pci_pm_debugfs(struct hif_pci_softc *sc, bool init)
{

}
#endif

static void hif_pci_pm_runtime_pre_init(struct hif_pci_softc *sc)
{
	spin_lock_init(&sc->runtime_lock);
	setup_timer(&sc->runtime_timer, hif_pci_runtime_pm_timeout_fn,
			(unsigned long)sc);

	adf_os_atomic_init(&sc->pm_state);
	adf_os_atomic_set(&sc->pm_state, HIF_PM_RUNTIME_STATE_NONE);
	INIT_LIST_HEAD(&sc->prevent_suspend_list);
}

static void hif_pci_pm_runtime_init(struct hif_pci_softc *sc)
{
	struct ol_softc *ol_sc;

	ol_sc = sc->ol_sc;

	if (!ol_sc->enable_runtime_pm) {
		pr_info("%s: RUNTIME PM is disabled in ini\n", __func__);
		return;
	}

	if (vos_get_conparam() == VOS_FTM_MODE ||
		WLAN_IS_EPPING_ENABLED(vos_get_conparam())) {
		pr_info("%s: RUNTIME PM is disabled for FTM/EPPING mode\n",
				__func__);
		return;
	}

	pr_info("%s: Enabling RUNTIME PM, Delay: %d ms\n", __func__,
			ol_sc->runtime_pm_delay);

	vos_init_work(&sc->pm_work, hif_pci_pm_work);
	vos_runtime_init(sc->dev, ol_sc->runtime_pm_delay);
	adf_os_atomic_set(&sc->pm_state, HIF_PM_RUNTIME_STATE_ON);
	hif_pci_pm_debugfs(sc, true);
}

static void hif_pci_pm_runtime_exit(struct hif_pci_softc *sc)
{
	struct ol_softc *ol_sc = sc->ol_sc;

	if (!ol_sc->enable_runtime_pm)
		return;

	if (vos_get_conparam() == VOS_FTM_MODE ||
		WLAN_IS_EPPING_ENABLED(vos_get_conparam()))
		return;

	hif_pm_runtime_resume(sc->dev);

	vos_runtime_exit(sc->dev);
	adf_os_atomic_set(&sc->pm_state, HIF_PM_RUNTIME_STATE_NONE);

	hif_pci_pm_debugfs(sc, false);
	del_timer_sync(&sc->runtime_timer);
	vos_flush_work(&sc->pm_work);
}

/**
 * hif_pci_pm_runtime_post_exit() - API to check the sanity of Runtime PM
 * @sc:	hif_pci_softc context
 *
 * API is used to check if any mismatch in runtime usage count and
 * to ensure we fix it before driver unload.
 * Ideally the conditions in this API shouldn't hit
 * This prevention is needed to ensure Runtime PM wont be disabled
 * for ever with mismatch in usage count.
 *
 * Return: void
 */
static void hif_pci_pm_runtime_post_exit(struct hif_pci_softc *sc)
{
	struct hif_pm_runtime_context *ctx, *tmp;

	/*
	 * The usage_count should be one at this state, as all the
	 * HTT/WMI pkts should get tx complete and driver should
	 * will increment the usage count to 1 to prevent any suspend
	 */
	if (atomic_read(&sc->dev->power.usage_count) != 1)
		hif_pci_runtime_pm_warn(sc, "Driver UnLoading");
	else
		return;

	spin_lock_bh(&sc->runtime_lock);
	list_for_each_entry_safe(ctx, tmp, &sc->prevent_suspend_list, list) {
		spin_unlock_bh(&sc->runtime_lock);
		hif_runtime_pm_prevent_suspend_deinit(ctx);
		spin_lock_bh(&sc->runtime_lock);
	}
	spin_unlock_bh(&sc->runtime_lock);
	/*
	 * This is totally a preventive measure to ensure Runtime PM
	 * isn't disabled for life time.
	 * To debug such scenarios, we can set dev->power.disable_depth > 0
	 * or set dev->power.runtime_error. So Runtime PM callbacks won't
	 * get called.
	 * When usage_count is negative, kernel Runtime PM framework continues
	 * to call runtime suspend, and we may see weird issues.
	 */
	if (atomic_read(&sc->dev->power.usage_count) <= 0)
		atomic_set(&sc->dev->power.usage_count, 1);

	while (atomic_read(&sc->dev->power.usage_count) != 1)
		pm_runtime_put_noidle(sc->dev);
}

/**
 * hif_pci_pm_runtime_ssr_post_exit() - Empty the prevent suspend list on SSR
 * @sc: hif_pci context
 *
 * API is used to empty the runtime pm prevent suspend list.
 *
 * Return: void
 */
static void hif_pci_pm_runtime_ssr_post_exit(struct hif_pci_softc *sc)
{
	struct hif_pm_runtime_context *ctx, *tmp;

	spin_lock_bh(&sc->runtime_lock);
	list_for_each_entry_safe(ctx, tmp, &sc->prevent_suspend_list, list) {
		hif_pm_ssr_runtime_allow_suspend(sc, ctx);
	}
	spin_unlock_bh(&sc->runtime_lock);
}

#else
static inline void hif_pci_pm_runtime_init(struct hif_pci_softc *sc) { }
static inline void hif_pci_pm_runtime_pre_init(struct hif_pci_softc *sc) { }
static inline void hif_pci_pm_runtime_exit(struct hif_pci_softc *sc) { }
static inline void hif_pci_pm_runtime_post_exit(struct hif_pci_softc *sc) { }
static inline void
hif_pci_pm_runtime_ssr_post_exit(struct hif_pci_softc *sc) { }
#endif

#ifdef CONFIG_NON_QC_PLATFORM_PCI
static inline void *hif_pci_get_virt_ramdump_mem(unsigned long *size)
{
	size_t length = 0;
	int flags = GFP_KERNEL;

	length = DRAM_SIZE + IRAM1_SIZE + IRAM2_SIZE + AXI_SIZE + REG_SIZE;

	if (size != NULL)
		*size = (unsigned long)length;

	if (in_interrupt() || irqs_disabled() || in_atomic())
		flags = GFP_ATOMIC;

	return kzalloc(length, flags);
}

static inline void hif_pci_release_ramdump_mem(unsigned long *address)
{
	if (address != NULL)
		kfree(address);
}
#endif

int
hif_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
    void __iomem *mem;
    int ret = 0;
    u_int32_t hif_type, target_type;
    struct hif_pci_softc *sc;
    struct ol_softc *ol_sc;
    int probe_again = 0;
    u_int16_t device_id;
    u_int16_t revision_id;
    u_int32_t lcr_val;
    static int devid = 0;

    printk(KERN_INFO "%s:, con_mode= 0x%x\n", __func__, vos_get_conparam());

again:
    ret = 0;

    /* CLD driver only support one instance */
    if (devid)
	return -EIO;

#define BAR_NUM 0
    /*
     * Without any knowledge of the Host, the Target
     * may have been reset or power cycled and its
     * Config Space may no longer reflect the PCI
     * address space that was assigned earlier
     * by the PCI infrastructure.  Refresh it now.
     */
     /*WAR for EV#117307, if PCI link is down, return from probe() */
     pci_read_config_word(pdev,PCI_DEVICE_ID,&device_id);
     printk("PCI device id is %04x :%04x\n",device_id,id->device);
     if(device_id != id->device)  {
	printk(KERN_ERR "ath: PCI link is down.\n");
	/* pci link is down, so returing with error code */
	return -EIO;
     }

    /* FIXME: temp. commenting out assign_resource
     * call for dev_attach to work on 2.6.38 kernel
     */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) && !defined(__LINUX_ARM_ARCH__)
    if (pci_assign_resource(pdev, BAR_NUM)) {
        printk(KERN_ERR "ath: cannot assign PCI space\n");
        return -EIO;
    }
#endif

    if (pci_enable_device(pdev)) {
        printk(KERN_ERR "ath: cannot enable PCI device\n");
        return -EIO;
    }

#define BAR_NUM 0
    /* Request MMIO resources */
    ret = pci_request_region(pdev, BAR_NUM, "ath");
    if (ret) {
        dev_err(&pdev->dev, "ath: PCI MMIO reservation error\n");
        ret = -EIO;
        goto err_region;
    }
#ifdef CONFIG_ARM_LPAE
    /* if CONFIG_ARM_LPAE is enabled, we have to set 64 bits mask
     * for 32 bits device also. */
    ret =  pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
    if (ret) {
        printk(KERN_ERR "ath: Cannot enable 64-bit pci DMA\n");
        goto err_dma;
    }
    ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
    if (ret) {
        printk(KERN_ERR "ath: Cannot enable 64-bit consistent DMA\n");
        goto err_dma;
    }
#else
    ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
    if (ret) {
        printk(KERN_ERR "ath: Cannot enable 32-bit pci DMA\n");
        goto err_dma;
    }
    ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
    if (ret) {
        printk(KERN_ERR "%s: Cannot enable 32-bit consistent DMA!\n",
               __func__);
        goto err_dma;
    }
#endif

#ifdef DISABLE_L1SS_STATES
    pci_read_config_dword(pdev, 0x188, &lcr_val);
    pci_write_config_dword(pdev, 0x188, (lcr_val & ~0x0000000f));
#endif

    /* Set bus master bit in PCI_COMMAND to enable DMA */
    pci_set_master(pdev);

    /* Temporary FIX: disable ASPM on peregrine. Will be removed after the OTP is programmed */
    pci_read_config_dword(pdev, 0x80, &lcr_val);
    pci_write_config_dword(pdev, 0x80, (lcr_val & 0xffffff00));

    /* Arrange for access to Target SoC registers. */
    mem = pci_iomap(pdev, BAR_NUM, 0);
    if (!mem) {
        printk(KERN_ERR "ath: PCI iomap error\n") ;
        ret = -EIO;
        goto err_iomap;
    }

    /* Disable asynchronous suspend */
    device_disable_async_suspend(&pdev->dev);

    sc = A_MALLOC(sizeof(*sc));
    if (!sc) {
        ret = -ENOMEM;
        goto err_alloc;
    }

    OS_MEMZERO(sc, sizeof(*sc));
    sc->mem = mem;
    sc->mem_len = pci_resource_len(pdev, BAR_NUM);
    sc->pdev = pdev;
    sc->dev = &pdev->dev;

    sc->aps_osdev.bdev = pdev;
    sc->aps_osdev.device = &pdev->dev;
    sc->aps_osdev.bc.bc_handle = (void *)mem;
    sc->aps_osdev.bc.bc_bustype = HAL_BUS_TYPE_PCI;
    sc->devid = id->device;

    adf_os_spinlock_init(&sc->target_lock);

    sc->cacheline_sz = dma_get_cache_alignment();

    pci_read_config_word(pdev, 0x08, &revision_id);

    switch (id->device) {
    case AR9888_DEVICE_ID:
        hif_type = HIF_TYPE_AR9888;
        target_type = TARGET_TYPE_AR9888;
        break;

    case AR6320_DEVICE_ID:
    case QCA9379_DEVICE_ID:
    case QCA9379_DEVICE_REV_ID:
        switch(revision_id) {
        case AR6320_FW_1_1:
        case AR6320_FW_1_3:
            hif_type = HIF_TYPE_AR6320;
            target_type = TARGET_TYPE_AR6320;
            break;

        case AR6320_FW_2_0:
        case AR6320_FW_3_0:
        case AR6320_FW_3_2:
        case QCA9379_FW_3_2:
            hif_type = HIF_TYPE_AR6320V2;
            target_type = TARGET_TYPE_AR6320V2;
            break;

        default:
            printk(KERN_ERR "unsupported revision id %x\n", id->device);
            ret = -ENODEV;
            goto err_tgtstate;
        }
        break;

    default:
        printk(KERN_ERR "unsupported device id\n");
        ret = -ENODEV;
        goto err_tgtstate;
    }
    /*
     * Attach Target register table.  This is needed early on --
     * even before BMI -- since PCI and HIF initialization (and BMI init)
     * directly access Target registers (e.g. CE registers).
     */

    hif_register_tbl_attach(sc, hif_type);
    target_register_tbl_attach(sc, target_type);
    {
        A_UINT32 fw_indicator;
#if PCIE_BAR0_READY_CHECKING
        int wait_limit = 200;
#endif
        int targ_awake_limit = 500;

        /*
         * Verify that the Target was started cleanly.
         *
         * The case where this is most likely is with an AUX-powered
         * Target and a Host in WoW mode. If the Host crashes,
         * loses power, or is restarted (without unloading the driver)
         * then the Target is left (aux) powered and running.  On a
         * subsequent driver load, the Target is in an unexpected state.
         * We try to catch that here in order to reset the Target and
         * retry the probe.
         */
        A_PCI_WRITE32(mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK);
        while (!hif_pci_targ_is_awake(sc, mem)) {
            if (0 == targ_awake_limit) {
                printk(KERN_ERR "%s: target awake timeout\n", __func__);
                ret = -EAGAIN;
                goto err_tgtstate;
            }
            A_MDELAY(1);
            targ_awake_limit--;
        }

#if PCIE_BAR0_READY_CHECKING
        /* Synchronization point: wait the BAR0 is configured */
        while (wait_limit-- &&
            !(A_PCI_READ32(mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_RDY_STATUS_ADDRESS) \
             & PCIE_SOC_RDY_STATUS_BAR_MASK)) {
            A_MDELAY(10);
        }
        if (wait_limit < 0) {
            /* AR6320v1 doesn't support checking of BAR0 configuration,
               takes one sec to wait BAR0 ready */
            printk(KERN_INFO "AR6320v1 waits two sec for BAR0 ready.\n");
        }
#endif

        fw_indicator = A_PCI_READ32(mem + FW_INDICATOR_ADDRESS);
        A_PCI_WRITE32(mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);

        if (fw_indicator & FW_IND_INITIALIZED) {
            probe_again++;
            printk(KERN_ERR "ath: Target is in an unknown state. Resetting (attempt %d).\n", probe_again);
            /* hif_pci_device_reset, below, will reset the target */
            ret = -EIO;
            goto err_tgtstate;
        }
    }

    ol_sc = A_MALLOC(sizeof(*ol_sc));
    if (!ol_sc)
	    goto err_attach;
    OS_MEMZERO(ol_sc, sizeof(*ol_sc));
    ol_sc->sc_osdev = &sc->aps_osdev;
    ol_sc->hif_sc = (void *)sc;
    sc->ol_sc = ol_sc;
    ol_sc->target_type = target_type;

    hif_pci_pm_runtime_pre_init(sc);

    if (hif_pci_configure(sc, &ol_sc->hif_hdl))
	    goto err_config;

    ol_sc->enableuartprint = 0;
    ol_sc->enablefwlog = 0;
#ifdef QCA_SINGLE_BINARY_SUPPORT
    ol_sc->enablesinglebinary = TRUE;
#else
    ol_sc->enablesinglebinary = FALSE;
#endif
    ol_sc->max_no_of_peers = 1;

#ifdef CONFIG_NON_QC_PLATFORM_PCI
    ol_sc->ramdump_base = hif_pci_get_virt_ramdump_mem(&ol_sc->ramdump_size);
#else
    /* Get RAM dump memory address and size */
    ol_sc->ramdump_base = vos_get_virt_ramdump_mem(&pdev->dev,
                                             &ol_sc->ramdump_size);

#endif
    if (ol_sc->ramdump_base == NULL || !ol_sc->ramdump_size) {
        pr_info("%s: Failed to get RAM dump memory address or size!\n",
                __func__);
    } else {
        pr_info("%s: ramdump base 0x%p size %d\n", __func__,
		ol_sc->ramdump_base, (int)ol_sc->ramdump_size);
    }

    adf_os_atomic_init(&sc->tasklet_from_intr);
    adf_os_atomic_init(&sc->wow_done);
#ifdef FEATURE_WLAN_D0WOW
    adf_os_atomic_init(&sc->in_d0wow);
#endif
    adf_os_atomic_init(&sc->ce_suspend);
    adf_os_atomic_init(&sc->pci_link_suspended);
    hif_irq_record_index_init();
    init_waitqueue_head(&ol_sc->sc_osdev->event_queue);

    ret = hif_init_adf_ctx(ol_sc);
    if (ret == 0) {
        sc->hdd_startup_reinit_flag = true;
        ret = hdd_wlan_startup(&pdev->dev, ol_sc);
        sc->hdd_startup_reinit_flag = false;
    }

    if (ret) {
        hif_disable_isr(ol_sc);
        HIFShutDownDevice(ol_sc->hif_hdl);
        goto err_config;
    }

    /* Re-enable ASPM after firmware/OTP download is complete */
    pci_write_config_dword(pdev, 0x80, lcr_val);

    hif_pci_pm_runtime_init(sc);
    devid++;

    return 0;

err_config:
#ifdef CONFIG_NON_QC_PLATFORM_PCI
    if (sc && sc->ol_sc && sc->ol_sc->ramdump_base)
        hif_pci_release_ramdump_mem(sc->ol_sc->ramdump_base);
#endif
    hif_deinit_adf_ctx(ol_sc);
    A_FREE(ol_sc);
err_attach:
    ret = -EIO;
err_tgtstate:
    pci_set_drvdata(pdev, NULL);
    hif_pci_device_reset(sc);
    A_FREE(sc);
err_alloc:
    /* call HIF PCI free here */
    printk("%s: HIF PCI Free needs to happen here \n", __func__);
    pci_iounmap(pdev, mem);
err_iomap:
    pci_clear_master(pdev);
err_dma:
    pci_release_region(pdev, BAR_NUM);
err_region:
    pci_disable_device(pdev);

    if (probe_again && (probe_again <= ATH_PCI_PROBE_RETRY_MAX)) {
        int delay_time;

        /*
         * We can get here after a Host crash or power fail when
         * the Target has aux power.  We just did a device_reset,
         * so we need to delay a short while before we try to
         * reinitialize.  Typically only one retry with the smallest
         * delay is needed.  Target should never need more than a 100Ms
         * delay; that would not conform to the PCIe std.
         */

        printk(KERN_INFO "pci reprobe.\n");
        delay_time = max(100, 10 * (probe_again * probe_again)); /* 10, 40, 90, 100, 100, ... */
        A_MDELAY(delay_time);
        goto again;
    }
    return ret;
}

/* This function will be called when SSR frame work wants to
 * power up WLAN host driver when SSR happens. Most of this
 * function is duplicated from hif_pci_probe().
 */
#ifdef HIF_PCI
int hif_pci_reinit(struct pci_dev *pdev, const struct pci_device_id *id)
{
    void __iomem *mem;
    struct hif_pci_softc *sc;
    struct ol_softc *ol_sc;
    int probe_again = 0;
    int ret = 0;
    u_int16_t device_id;
    u_int32_t hif_type;
    u_int32_t target_type;
    u_int32_t lcr_val;
    u_int16_t revision_id;

again:
    ret = 0;

    if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL) &&
        !vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) {
        printk("%s: Load/unload is in progress and SSR is not,"
               "ignore SSR reinit...\n", __func__);
        return 0;
    }

#define BAR_NUM 0
    /*
     * Without any knowledge of the Host, the Target
     * may have been reset or power cycled and its
     * Config Space may no longer reflect the PCI
     * address space that was assigned earlier
     * by the PCI infrastructure.  Refresh it now.
     */
    /* If PCI link is down, return from reinit() */
    pci_read_config_word(pdev,PCI_DEVICE_ID,&device_id);
    printk("PCI device id is %04x :%04x\n", device_id, id->device);
    if (device_id != id->device)  {
        printk(KERN_ERR "%s: PCI link is down!\n", __func__);
        /* PCI link is down, so return with error code. */
        return -EIO;
    }

    /* FIXME: Commenting out assign_resource
     * call for dev_attach to work on 2.6.38 kernel
     */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) && !defined(__LINUX_ARM_ARCH__)
    if (pci_assign_resource(pdev, BAR_NUM)) {
        printk(KERN_ERR "%s: Cannot assign PCI space!\n", __func__);
        return -EIO;
    }
#endif

    if (pci_enable_device(pdev)) {
        printk(KERN_ERR "%s: Cannot enable PCI device!\n", __func__);
        return -EIO;
    }

    /* Request MMIO resources */
    ret = pci_request_region(pdev, BAR_NUM, "ath");
    if (ret) {
        dev_err(&pdev->dev, "%s: PCI MMIO reservation error!\n", __func__);
        ret = -EIO;
        goto err_region;
    }

#ifdef CONFIG_ARM_LPAE
    /* if CONFIG_ARM_LPAE is enabled, we have to set 64 bits mask
     * for 32 bits device also. */
    ret =  pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
    if (ret) {
        printk(KERN_ERR "ath: Cannot enable 64-bit pci DMA\n");
        goto err_dma;
    }
    ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
    if (ret) {
        printk(KERN_ERR "ath: Cannot enable 64-bit consistent DMA\n");
        goto err_dma;
    }
#else
    ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
    if (ret) {
        printk(KERN_ERR "ath: Cannot enable 32-bit pci DMA\n");
        goto err_dma;
    }
    ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
    if (ret) {
        printk(KERN_ERR "%s: Cannot enable 32-bit consistent DMA!\n",
               __func__);
        goto err_dma;
    }
#endif

#ifdef DISABLE_L1SS_STATES
    pci_read_config_dword(pdev, 0x188, &lcr_val);
    pci_write_config_dword(pdev, 0x188, (lcr_val & ~0x0000000f));
#endif

    /* Set bus master bit in PCI_COMMAND to enable DMA */
    pci_set_master(pdev);

    /* Temporary FIX: disable ASPM. Will be removed after
       the OTP is programmed. */
    pci_read_config_dword(pdev, 0x80, &lcr_val);
    pci_write_config_dword(pdev, 0x80, (lcr_val & 0xffffff00));

    /* Arrange for access to Target SoC registers */
    mem = pci_iomap(pdev, BAR_NUM, 0);
    if (!mem) {
        printk(KERN_ERR "%s: PCI iomap error!\n", __func__) ;
        ret = -EIO;
        goto err_iomap;
    }

    /* Disable asynchronous suspend */
    device_disable_async_suspend(&pdev->dev);

    sc = A_MALLOC(sizeof(*sc));
    if (!sc) {
        ret = -ENOMEM;
        goto err_alloc;
    }

    OS_MEMZERO(sc, sizeof(*sc));
    sc->mem = mem;
    sc->pdev = pdev;
    sc->dev = &pdev->dev;
    sc->aps_osdev.bdev = pdev;
    sc->aps_osdev.device = &pdev->dev;
    sc->aps_osdev.bc.bc_handle = (void *)mem;
    sc->aps_osdev.bc.bc_bustype = HAL_BUS_TYPE_PCI;
    sc->devid = id->device;

    adf_os_spinlock_init(&sc->target_lock);

    sc->cacheline_sz = dma_get_cache_alignment();
    pci_read_config_word(pdev, 0x08, &revision_id);

    switch (id->device) {
    case AR9888_DEVICE_ID:
        hif_type = HIF_TYPE_AR9888;
        target_type = TARGET_TYPE_AR9888;
        break;

    case AR6320_DEVICE_ID:
    case QCA9379_DEVICE_ID:
    case QCA9379_DEVICE_REV_ID:
        switch(revision_id) {
        case AR6320_FW_1_1:
        case AR6320_FW_1_3:
            hif_type = HIF_TYPE_AR6320;
            target_type = TARGET_TYPE_AR6320;
            break;

        case AR6320_FW_2_0:
        case AR6320_FW_3_0:
        case AR6320_FW_3_2:
        case QCA9379_FW_3_2:
            hif_type = HIF_TYPE_AR6320V2;
            target_type = TARGET_TYPE_AR6320V2;
            break;

        default:
            printk(KERN_ERR "unsupported revision id %x\n", id->device);
            ret = -ENODEV;
            goto err_tgtstate;
        }
        break;

    default:
        printk(KERN_ERR "%s: Unsupported device ID!\n", __func__);
        ret = -ENODEV;
        goto err_tgtstate;
    }

    /*
     * Attach Target register table. This is needed early on --
     * even before BMI -- since PCI and HIF initialization (and BMI init)
     * directly access Target registers (e.g. CE registers).
     */

    hif_register_tbl_attach(sc, hif_type);
    target_register_tbl_attach(sc, target_type);
    {
        A_UINT32 fw_indicator;
#if PCIE_BAR0_READY_CHECKING
        int wait_limit = 200;
#endif

        /*
         * Verify that the Target was started cleanly.
         *
         * The case where this is most likely is with an AUX-powered
         * Target and a Host in WoW mode. If the Host crashes,
         * loses power, or is restarted (without unloading the driver)
         * then the Target is left (aux) powered and running. On a
         * subsequent driver load, the Target is in an unexpected state.
         * We try to catch that here in order to reset the Target and
         * retry the probe.
         */
        A_PCI_WRITE32(mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS,
                      PCIE_SOC_WAKE_V_MASK);
        while (!hif_pci_targ_is_awake(sc, mem)) {
            ;
        }

#if PCIE_BAR0_READY_CHECKING
        /* Synchronization point: wait the BAR0 is configured. */
        while (wait_limit-- &&
            !(A_PCI_READ32(mem + PCIE_LOCAL_BASE_ADDRESS +
            PCIE_SOC_RDY_STATUS_ADDRESS) & PCIE_SOC_RDY_STATUS_BAR_MASK)) {
            A_MDELAY(10);
        }
        if (wait_limit < 0) {
            /* AR6320v1 doesn't support checking of BAR0 configuration,
               takes one sec to wait BAR0 ready. */
            printk(KERN_INFO "AR6320v1 waits two sec for BAR0 ready.\n");
        }
#endif

        fw_indicator = A_PCI_READ32(mem + FW_INDICATOR_ADDRESS);
        A_PCI_WRITE32(mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS,
                      PCIE_SOC_WAKE_RESET);

        if (fw_indicator & FW_IND_INITIALIZED) {
            probe_again++;
            printk(KERN_ERR "%s: Target is in an unknown state. "
                   "Resetting (attempt %d).\n", __func__, probe_again);
            /* hif_pci_device_reset, below will reset the target. */
            ret = -EIO;
            goto err_tgtstate;
        }
    }

    ol_sc = A_MALLOC(sizeof(*ol_sc));
    if (!ol_sc)
        goto err_attach;

    OS_MEMZERO(ol_sc, sizeof(*ol_sc));
    ol_sc->sc_osdev = &sc->aps_osdev;
    ol_sc->hif_sc = (void *)sc;
    sc->ol_sc = ol_sc;
    ol_sc->target_type = target_type;

    hif_pci_pm_runtime_pre_init(sc);

    if (hif_pci_configure(sc, &ol_sc->hif_hdl))
        goto err_config;

    ol_sc->enableuartprint = 0;
    ol_sc->enablefwlog = 0;
#ifdef QCA_SINGLE_BINARY_SUPPORT
    ol_sc->enablesinglebinary = TRUE;
#else
    ol_sc->enablesinglebinary = FALSE;
#endif
    ol_sc->max_no_of_peers = 1;

    /* Get RAM dump memory address and size */
#ifdef CONFIG_NON_QC_PLATFORM_PCI
    ol_sc->ramdump_base = hif_pci_get_virt_ramdump_mem(&ol_sc->ramdump_size);
#else
    ol_sc->ramdump_base = vos_get_virt_ramdump_mem(&pdev->dev,
                                             &ol_sc->ramdump_size);

#endif
    if (ol_sc->ramdump_base == NULL || !ol_sc->ramdump_size) {
        pr_info("%s: Failed to get RAM dump memory address or size!\n",
                __func__);
    }

    adf_os_atomic_init(&sc->tasklet_from_intr);
    adf_os_atomic_init(&sc->wow_done);
#ifdef FEATURE_WLAN_D0WOW
    adf_os_atomic_init(&sc->in_d0wow);
#endif
    adf_os_atomic_init(&sc->ce_suspend);
    adf_os_atomic_init(&sc->pci_link_suspended);

    init_waitqueue_head(&ol_sc->sc_osdev->event_queue);

    ret = hif_init_adf_ctx(ol_sc);
    if (ret == 0) {
        sc->hdd_startup_reinit_flag = true;
        if (VOS_STATUS_SUCCESS == hdd_wlan_re_init(ol_sc))
            ret = 0;
        sc->hdd_startup_reinit_flag = false;
    }

    /* Re-enable ASPM after firmware/OTP download is complete */
    pci_write_config_dword(pdev, 0x80, lcr_val);

    if (ret) {
        hif_disable_isr(ol_sc);
        HIFShutDownDevice(ol_sc->hif_hdl);
        goto err_config;
    }

    hif_pci_pm_runtime_init(sc);

    vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
    printk("%s: WLAN host driver reinitiation completed!\n", __func__);
    return 0;

err_config:
#ifdef CONFIG_NON_QC_PLATFORM_PCI
    if (sc && sc->ol_sc && sc->ol_sc->ramdump_base)
        hif_pci_release_ramdump_mem(sc->ol_sc->ramdump_base);
#endif
    hif_deinit_adf_ctx(ol_sc);
    A_FREE(ol_sc);
err_attach:
    ret = -EIO;
err_tgtstate:
    pci_set_drvdata(pdev, NULL);
    hif_pci_device_reset(sc);
    A_FREE(sc);
err_alloc:
    /* Call HIF PCI free here */
    printk("%s: HIF PCI free needs to happen here.\n", __func__);
    pci_iounmap(pdev, mem);
err_iomap:
    pci_clear_master(pdev);
err_dma:
    pci_release_region(pdev, BAR_NUM);
err_region:
    pci_disable_device(pdev);

    if (probe_again && (probe_again <= ATH_PCI_PROBE_RETRY_MAX)) {
        int delay_time;

        /*
         * We can get here after a Host crash or power fail when
         * the Target has aux power. We just did a device_reset,
         * so we need to delay a short while before we try to
         * reinitialize. Typically only one retry with the smallest
         * delay is needed. Target should never need more than a 100Ms
         * delay; that would not conform to the PCIe std.
         */

        printk(KERN_INFO "%s: PCI rereinit\n", __func__);
        /* 10, 40, 90, 100, 100, ... */
        delay_time = max(100, 10 * (probe_again * probe_again));
        A_MDELAY(delay_time);
        goto again;
    }

    return ret;
}
#endif

void hif_pci_notify_handler(struct pci_dev *pdev, int state)
{
   if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam())) {
       int ret = 0;
       ret = hdd_wlan_notify_modem_power_state(state);
       if (ret < 0)
          printk(KERN_ERR "%s: Fail to send notify\n", __func__);
   }
}

void
hif_nointrs(struct hif_pci_softc *sc)
{
    int i;

    if (sc->hdd_startup_reinit_flag) {
        pr_err("%s: WARN: In HDD startup or reinit\n", __func__);
        return;
    }

    if (!sc->pdev) {
        pr_err("%s: pdev is NULL\n", __func__);
        return;
    }
    if (sc->num_msi_intrs > 0) {
        /* MSI interrupt(s) */
        for (i = 0; i < sc->num_msi_intrs; i++) {
            free_irq(sc->pdev->irq + i, sc);
        }
        sc->num_msi_intrs = 0;
    } else {
        /* Legacy PCI line interrupt */
        free_irq(sc->pdev->irq, sc);
    }
}

int
hif_pci_configure(struct hif_pci_softc *sc, hif_handle_t *hif_hdl)
{
    int ret = 0;
    int num_msi_desired;
    u_int32_t val;

    BUG_ON(pci_get_drvdata(sc->pdev) != NULL);
    pci_set_drvdata(sc->pdev, sc);

    tasklet_init(&sc->intr_tq, wlan_tasklet, (unsigned long)sc);

	/*
	 * Interrupt Management is divided into these scenarios :
	 * A) We wish to use MSI and Multiple MSI is supported and we
	 *    are able to obtain the number of MSI interrupts desired
	 *    (best performance)
	 * B) We wish to use MSI and Single MSI is supported and we are
	 *    able to obtain a single MSI interrupt
	 * C) We don't want to use MSI or MSI is not supported and we
	 *    are able to obtain a legacy interrupt
	 * D) Failure
	 */
#if defined(FORCE_LEGACY_PCI_INTERRUPTS)
    num_msi_desired = 0; /* Use legacy PCI line interrupts rather than MSI */
#else
    num_msi_desired = MSI_NUM_REQUEST; /* Multiple MSI */
    if (!msienable) {
        num_msi_desired = 0;
    }
#endif

    printk("\n %s : num_desired MSI set to %d\n", __func__, num_msi_desired);

    if (num_msi_desired > 1) {
        int i;
        int rv;

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)) || defined(WITH_BACKPORTS)
        rv = pci_alloc_irq_vectors(sc->pdev, MSI_NUM_REQUEST, MSI_NUM_REQUEST, PCI_IRQ_MSI);
#else
        rv = pci_enable_msi_block(sc->pdev, MSI_NUM_REQUEST);
#endif

	if (rv == 0) { /* successfully allocated all MSI interrupts */
		/*
		 * TBDXXX: This path not yet tested,
		 * since Linux x86 does not currently
		 * support "Multiple MSIs".
		 */
		sc->num_msi_intrs = MSI_NUM_REQUEST;
		ret = request_irq(sc->pdev->irq+MSI_ASSIGN_FW, hif_pci_msi_fw_handler,
				  IRQF_SHARED, "wlan_pci", sc);
		if(ret) {
			dev_err(&sc->pdev->dev, "request_irq failed\n");
			goto err_intr;
		}
		for (i=MSI_ASSIGN_CE_INITIAL; i<=MSI_ASSIGN_CE_MAX; i++) {
			ret = request_irq(sc->pdev->irq+i, CE_per_engine_handler, IRQF_SHARED,
					  "wlan_pci", sc);
			if(ret) {
				dev_err(&sc->pdev->dev, "request_irq failed\n");
				goto err_intr;
			}
		}
	} else {
            if (rv < 0) {
                /* Can't get any MSI -- try for legacy line interrupts */
                num_msi_desired = 0;
            } else {
                /* Can't get enough MSI interrupts -- try for just 1 */
                printk("\n %s : Can't allocate requested number of MSI, just use 1\n", __func__);
                num_msi_desired = 1;
            }
        }
    }

    if (num_msi_desired == 1) {
        /*
         * We are here because either the platform only supports
         * single MSI OR because we couldn't get all the MSI interrupts
         * that we wanted so we fall back to a single MSI.
         */
        if (pci_enable_msi(sc->pdev) < 0) {
            printk(KERN_ERR "ath: single MSI interrupt allocation failed\n");
            /* Try for legacy PCI line interrupts */
            num_msi_desired = 0;
        } else {
            /* Use a single Host-side MSI interrupt handler for all interrupts */
            num_msi_desired = 1;
        }
    }

    if ( num_msi_desired <= 1) {
	    /* We are here because we want to multiplex a single host interrupt among all
	     * Target interrupt sources
	     */
	    ret = request_irq(sc->pdev->irq, hif_pci_interrupt_handler, IRQF_SHARED,
			      "wlan_pci", sc);
	    if(ret) {
		    dev_err(&sc->pdev->dev, "request_irq failed\n");
		    goto err_intr;
	    }

    }
#if CONFIG_PCIE_64BIT_MSI
    {
        struct ol_ath_softc_net80211 *scn = sc->scn;
        u_int8_t MSI_flag;
        u_int32_t reg;

#define OL_ATH_PCI_MSI_POS        0x50
#define MSI_MAGIC_RDY_MASK  0x00000001
#define MSI_MAGIC_EN_MASK   0x80000000

        pci_read_config_byte(sc->pdev, OL_ATH_PCI_MSI_POS + PCI_MSI_FLAGS, &MSI_flag);
        if (MSI_flag & PCI_MSI_FLAGS_ENABLE) {
            A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK);
            while (!ath_pci_targ_is_awake(sc->mem)) {
                ;
            }
            scn->MSI_magic = OS_MALLOC_CONSISTENT(scn->sc_osdev, 4, &scn->MSI_magic_dma, \
                             OS_GET_DMA_MEM_CONTEXT(scn, MSI_dmacontext), 0);
            A_PCI_WRITE32(sc->mem + SOC_PCIE_BASE_ADDRESS + MSI_MAGIC_ADR_ADDRESS,
                          scn->MSI_magic_dma);
            reg = A_PCI_READ32(sc->mem + SOC_PCIE_BASE_ADDRESS + MSI_MAGIC_ADDRESS);
            A_PCI_WRITE32(sc->mem + SOC_PCIE_BASE_ADDRESS + MSI_MAGIC_ADDRESS, reg | MSI_MAGIC_RDY_MASK);

            A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
        }
    }
#endif

    if(num_msi_desired == 0) {
        printk("\n Using PCI Legacy Interrupt\n");

        /* Make sure to wake the Target before enabling Legacy Interrupt */
        A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS,
                      PCIE_SOC_WAKE_V_MASK);
        while (!hif_pci_targ_is_awake(sc, sc->mem)) {
                ;
        }
        /* Use Legacy PCI Interrupts */
        /*
         * A potential race occurs here: The CORE_BASE write depends on
         * target correctly decoding AXI address but host won't know
         * when target writes BAR to CORE_CTRL. This write might get lost
         * if target has NOT written BAR. For now, fix the race by repeating
         * the write in below synchronization checking.
         */
        A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS |
                      PCIE_INTR_ENABLE_ADDRESS),
                      PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
        A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS,
                      PCIE_SOC_WAKE_RESET);
    }

    sc->num_msi_intrs = num_msi_desired;
    sc->ce_count = CE_COUNT;

    { /* Synchronization point: Wait for Target to finish initialization before we proceed. */
        int wait_limit = 1000; /* 10 sec */

        /* Make sure to wake Target before accessing Target memory */
        A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK);
        while (!hif_pci_targ_is_awake(sc, sc->mem)) {
                ;
        }
        while (wait_limit-- && !(A_PCI_READ32(sc->mem + FW_INDICATOR_ADDRESS) & FW_IND_INITIALIZED)) {
            if (num_msi_desired == 0) {
                /* Fix potential race by repeating CORE_BASE writes */
                A_PCI_WRITE32(sc->mem + (SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS),
                      PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
            }
            A_MDELAY(10);
        }

        if (wait_limit < 0) {
            printk(KERN_ERR "ath: %s: TARGET STALLED: .\n", __FUNCTION__);
            A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
            ret = -EIO;
            goto err_stalled;
        }
        A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
    }

    if (HIF_PCIDeviceProbed(sc)) {
            printk(KERN_ERR "ath: %s: Target probe failed.\n", __FUNCTION__);
            ret = -EIO;
            goto err_stalled;
    }

    *hif_hdl = sc->hif_device;

    /*
     * Flag to avoid potential unallocated memory access from MSI
     * interrupt handler which could get scheduled as soon as MSI
     * is enabled, i.e to take care of the race due to the order
     * in where MSI is enabled before the memory, that will be
     * in interrupt handlers, is allocated.
     */
    sc->hif_init_done = TRUE;
    return 0;

err_stalled:
    /* Read Target CPU Intr Cause for debug */
    val = A_PCI_READ32(sc->mem + (SOC_CORE_BASE_ADDRESS | CPU_INTR_ADDRESS));
    printk("ERROR: Target Stalled : Target CPU Intr Cause 0x%x \n", val);
    hif_nointrs(sc);
err_intr:
    if (num_msi_desired) {
	pci_free_irq_vectors(sc->pdev);
    }
    pci_set_drvdata(sc->pdev, NULL);

    return ret;
}

void
hif_pci_remove(struct pci_dev *pdev)
{
    struct hif_pci_softc *sc = pci_get_drvdata(pdev);
    struct ol_softc *scn;
    void __iomem *mem;

    /* Attach did not succeed, all resources have been
     * freed in error handler
     */
    if (!sc)
        return;

    scn = sc->ol_sc;

#ifdef CONFIG_NON_QC_PLATFORM_PCI
    if (sc && sc->ol_sc && sc->ol_sc->ramdump_base)
        hif_pci_release_ramdump_mem(sc->ol_sc->ramdump_base);
#endif
#ifndef REMOVE_PKT_LOG
    if (vos_get_conparam() != VOS_FTM_MODE &&
        !WLAN_IS_EPPING_ENABLED(vos_get_conparam()))
        pktlogmod_exit(scn);
#endif

    hif_pci_pm_runtime_exit(sc);

    __hdd_wlan_exit();

    mem = (void __iomem *)sc->mem;

    pci_free_irq_vectors(pdev);

    hif_dump_pipe_debug_count(sc->hif_device);

    hif_pci_pm_runtime_post_exit(sc);
    hif_deinit_adf_ctx(scn);
    A_FREE(scn);
    A_FREE(sc->hif_device);
    A_FREE(sc);
    pci_set_drvdata(pdev, NULL);
    pci_iounmap(pdev, mem);
    pci_release_region(pdev, BAR_NUM);
    pci_clear_master(pdev);
    pci_disable_device(pdev);
    printk(KERN_INFO "pci_remove\n");
}

/* This function will be called when SSR framework wants to
 * shutdown WLAN host driver when SSR happens. Most of this
 * function is duplicated from hif_pci_remove().
 */
#ifdef HIF_PCI
void hif_pci_shutdown(struct pci_dev *pdev)
{
    void __iomem *mem;
    struct hif_pci_softc *sc;
    struct ol_softc *scn;
    struct HIF_CE_state *hif_state;

    sc = pci_get_drvdata(pdev);
    /* Attach did not succeed, all resources have been
     * freed in error handler.
     */
    if (!sc)
        return;

    hif_state = (struct HIF_CE_state *)sc->hif_device;

    if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL)) {
        printk("Load/unload in progress, ignore SSR shutdown\n");
        vos_set_logp_in_progress(VOS_MODULE_ID_HIF, FALSE);
        return;
    }
    /* this is for cases, where shutdown invoked from CNSS */
    vos_set_logp_in_progress(VOS_MODULE_ID_HIF, TRUE);
    vos_set_shutdown_in_progress(VOS_MODULE_ID_HIF, TRUE);

    if (!vos_is_ssr_ready(__func__))
        pr_info("Host driver is not ready for SSR, attempting anyway\n");

    scn = sc->ol_sc;

    hif_disable_isr(scn);
    adf_os_spin_lock_irqsave(&hif_state->suspend_lock);
    if (!adf_os_atomic_read(&sc->pci_link_suspended))
        hif_pci_device_reset(sc);
    adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock);

#ifndef REMOVE_PKT_LOG
    if (vos_get_conparam() != VOS_FTM_MODE &&
        !WLAN_IS_EPPING_ENABLED(vos_get_conparam()))
        pktlogmod_exit(scn);
#endif

    hif_pci_pm_runtime_exit(sc);

    hif_dump_pipe_debug_count(sc->hif_device);

    if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()))
        hdd_wlan_shutdown();

    mem = (void __iomem *)sc->mem;

    pci_free_irq_vectors(pdev);

    hif_pci_pm_runtime_ssr_post_exit(sc);
    hif_deinit_adf_ctx(scn);
    A_FREE(scn);
    A_FREE(sc->hif_device);
    A_FREE(sc);
    pci_set_drvdata(pdev, NULL);
    pci_iounmap(pdev, mem);
    pci_release_region(pdev, BAR_NUM);
    pci_clear_master(pdev);
    pci_disable_device(pdev);
    vos_set_shutdown_in_progress(VOS_MODULE_ID_HIF, FALSE);

    printk("%s: WLAN host driver shutting down completed!\n", __func__);
}

#ifdef TARGET_RAMDUMP_AFTER_KERNEL_PANIC
#ifdef FEATURE_RUNTIME_PM
static bool is_hif_runtime_active(struct hif_pci_softc *sc)
{
	int pm_state = adf_os_atomic_read(&sc->pm_state);

	if (pm_state  == HIF_PM_RUNTIME_STATE_ON ||
	    pm_state == HIF_PM_RUNTIME_STATE_NONE)
		return true;

	return false;
}
#else /* ELSE FEATURE_RUNTIME_PM */
static bool is_hif_runtime_active(struct hif_pci_softc *sc)
{
	return true;
}
#endif /* END FEATURE_RUNTIME_PM */

#ifdef WLAN_DEBUG
static void hif_dump_soc_and_ce_registers(struct hif_pci_softc *sc)
{
	int ret;
	struct ol_softc *scn = sc->ol_sc;

	ret = hif_pci_check_soc_status(sc);

	if (ret) {
		pr_err("%s: SOC wakeup Failed\n", __func__);
		return;
	}

	ret = dump_CE_register(scn);

	if (ret) {
		pr_err("%s: Failed to dump Copy Engine Registers\n", __func__);
		return;
	}

	dump_CE_debug_register(sc);
}
#else
static void hif_dump_soc_and_ce_registers(struct hif_pci_softc *sc)
{
}
#endif

static void hif_dump_crash_debug_info(struct hif_pci_softc *sc)
{
	struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device;
	struct ol_softc *scn = sc->ol_sc;
	int ret;
	tp_wma_handle wma_handle;
	void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);

	if (!hif_state)
		return;
	if (vos_context == NULL) {
		pr_err("%s: vos context is null\n", __func__);
		return;
	}
	wma_handle = (tp_wma_handle) vos_get_context(
			VOS_MODULE_ID_WDA, vos_context);
	if (wma_handle == NULL) {
		pr_err("%s: wma_handle is null\n", __func__);
		return;
	}

	/*
	 * When kernel panic happen, if WiFi FW is still active,
	 * it may cause NOC errors/memory corruption when dumping
	 * target DRAM/IRAM, to avoid this, inject a fw crash first.
	 * send crash_inject to FW directly, because we are now
	 * in an atomic context, and preempt has been disabled,
	 * MCThread won't be scheduled at the moment, at the same
	 * time, TargetFailure event wont't be received after inject
	 * crash due to the same reason
	 */
	ret = wma_crash_inject(wma_handle, 1, 0);

	adf_os_spin_lock_irqsave(&hif_state->suspend_lock);
	hif_irq_record(HIF_CRASH, sc);
	hif_dump_soc_and_ce_registers(sc);
	if (ret) {
		pr_err("%s: failed to send crash inject - %d\n",
				__func__, ret);
		goto out;
	}

	ret = ol_copy_ramdump(scn);

	if (ret) {
		pr_err("%s: Failed to Copy Target Memory to Host DDR\n",
		       __func__);
		goto out;
	}

	pr_info("%s: RAM dump collecting completed!\n", __func__);
out:
	adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock);
}

void hif_pci_crash_shutdown(struct pci_dev *pdev)
{
	struct hif_pci_softc *sc;
	struct ol_softc *scn;

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

	scn = sc->ol_sc;
	if (!scn)
		return;

	if (OL_TRGET_STATUS_RESET == scn->target_status) {
		pr_info("%s: Target is already asserted, ignore!\n", __func__);
		return;
	}

	if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL)) {
		if (!vos_is_load_in_progress(VOS_MODULE_ID_VOSS, NULL)) {
			pr_info("%s: Load/unload is in progress, ignore!\n",
				__func__);
			return;
		}
	}

	if (is_hif_runtime_active(sc))
		hif_dump_crash_debug_info(sc);
	else
		pr_info("%s: Runtime Suspended; Ramdump Collection disabled\n",
			__func__);

	pr_info("%s: Crash Shutdown Complete\n", __func__);
}
#else /* TARGET_RAMDUMP_AFTER_KERNEL_PANIC */
void hif_pci_crash_shutdown(struct pci_dev *pdev)
{
	pr_info("%s: QCA Ramdump Collected Disabled!\n", __func__);
}
#endif
#endif

#define OL_ATH_PCI_PM_CONTROL 0x44

/**
 * hif_disable_tasklet_noclient() - API to disable tasklet in D3WOW
 * @sc: HIF Context
 * @wma_hdl: WMA Handle
 *
 * This API allows to disable the tasklet in D3-wow
 * cases.
 *
 * Return: None
 */
static void hif_disable_tasklet_noclient(struct hif_pci_softc *sc,
			void *wma_hdl)
{
	if (!wma_get_client_count(wma_hdl)) {
		tasklet_disable(&sc->intr_tq);
		pr_debug("%s: tasklet disabled\n", __func__);
	}
}

/**
 * hif_enable_tasklet_noclient() - API to enable tasklet in D3WOW
 * @sc: HIF Context
 * @wma_hdl: WMA Handle
 *
 * This API allows to enable the tasklet in D3-wow
 * cases.
 *
 * Return: None
 */
static void hif_enable_tasklet_noclient(struct hif_pci_softc *sc, void *wma_hdl)
{
	if (!wma_get_client_count(wma_hdl)) {
		tasklet_enable(&sc->intr_tq);
		pr_debug("%s: tasklet disabled\n", __func__);
	}
}

static int
__hif_pci_suspend(struct pci_dev *pdev, pm_message_t state, bool runtime_pm)
{
    struct hif_pci_softc *sc = pci_get_drvdata(pdev);
    void *vos = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);
    ol_txrx_pdev_handle txrx_pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos);
    struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device;
    A_target_id_t targid = hif_state->targid;
    u32 tx_drain_wait_cnt = 0;
    u32 val;
    u32 ce_drain_wait_cnt = 0;
    v_VOID_t * temp_module;
    u32 tmp;
    int ret = -EBUSY;

    hif_irq_record(HIF_SUSPEND_START, sc);

    if (vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL))
        return ret;

    if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL))
        return ret;

    if (!txrx_pdev) {
        printk("%s: txrx_pdev is NULL\n", __func__);
        goto out;
    }
    /* Wait for pending tx completion */
    while (ol_txrx_get_tx_pending(txrx_pdev) ||
           ol_txrx_get_queue_status(txrx_pdev)) {
        msleep(OL_ATH_TX_DRAIN_WAIT_DELAY);
        if (++tx_drain_wait_cnt > OL_ATH_TX_DRAIN_WAIT_CNT) {
            printk("%s: tx frames are pending\n", __func__);
            ol_txrx_dump_tx_desc(txrx_pdev);
            goto out;
        }
    }

    /* No need to send WMI_PDEV_SUSPEND_CMDID to FW if WOW is enabled */
    temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos);
    if (!temp_module) {
        printk("%s: WDA module is NULL\n", __func__);
        goto out;
    }

    if (wma_check_scan_in_progress(temp_module)) {
        printk("%s: Scan in progress. Aborting suspend%s\n", __func__,
                runtime_pm ? " for runtime PM" : "");
        goto out;
    }

    if (wma_is_wow_mode_selected(temp_module)) {
          if(wma_enable_wow_in_fw(temp_module, runtime_pm))
            goto out;
    } else {
          if (wma_suspend_target(temp_module, 0))
            goto out;
    }

    while (!adf_os_atomic_read(&sc->ce_suspend)) {
        if (++ce_drain_wait_cnt > HIF_CE_DRAIN_WAIT_CNT) {
            printk("%s: CE still not done with access: \n", __func__);
            adf_os_atomic_set(&sc->wow_done, 0);

            if (!wma_is_wow_mode_selected(temp_module)) {
               wma_resume_target(temp_module, runtime_pm);
               goto out;
            }
            else {
               wma_disable_wow_in_fw(temp_module, runtime_pm);
               goto out;
            }
        }
        pr_debug("%s: Waiting for CE to finish access: \n", __func__);
        msleep(10);
    }

    hif_disable_tasklet_noclient(sc, temp_module);
    hif_irq_record(HIF_SUSPEND_AFTER_WOW, sc);

#ifdef FEATURE_WLAN_D0WOW
    if (wma_get_client_count(temp_module)) {
        if (enable_irq_wake(pdev->irq)) {
            pr_err("%s: Fail to enable wake IRQ!\n", __func__);
            ret = -EAGAIN;
            goto out;
        }

        pr_debug("%s: Suspend completes (D0WOW)\n", __func__);
        HIFCancelDeferredTargetSleep(sc->hif_device);
        ret = 0;
        goto out;
    }
#endif

    /* Wakeup ROME to disable PCIe interrupts */
    if (HIFTargetSleepStateAdjust(targid, FALSE, TRUE) < 0)
        goto out;

    /* Acquire lock to access shared register */
    adf_os_spin_lock_irqsave(&hif_state->suspend_lock);
    A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS), 0);
    A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_CLR_ADDRESS),
                  PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
    /* IMPORTANT: this extra read transaction is required to flush the posted write buffer */
    tmp = A_PCI_READ32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS));
    if (tmp == 0xffffffff) {
         printk(KERN_ERR "%s: PCIe pcie link is down\n", __func__);
         VOS_ASSERT(0);
    }

    hif_irq_record(HIF_SUSPEND_END, sc);

    /* Put ROME to sleep */
    if (HIFTargetSleepStateAdjust(targid, TRUE, FALSE) < 0) {
        adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock);
        goto out;
    }
    /* Stop the HIF Sleep Timer */
    HIFCancelDeferredTargetSleep(sc->hif_device);

    adf_os_atomic_set(&sc->pci_link_suspended, 1);
    adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock);

    /* Keep PCIe bus driver's shadow memory intact */
    vos_pcie_shadow_control(pdev, FALSE);

    if (runtime_pm)
	    goto skip;

    pci_read_config_dword(pdev, OL_ATH_PCI_PM_CONTROL, &val);
    if ((val & 0x000000ff) != 0x3) {
        pci_save_state(pdev);
        pci_disable_device(pdev);
        pci_write_config_dword(pdev, OL_ATH_PCI_PM_CONTROL, (val & 0xffffff00) | 0x03);
    }

skip:
    pr_debug("%s: Suspend completes%s in%s mode event:%d device_state:%d\n",
                   __func__, runtime_pm ? " for runtime pm" : "",
                   wma_is_wow_mode_selected(temp_module) ? " wow" : " pdev",
                   state.event, val);
    pr_debug("%s: Suspend completes%s\n", __func__,
            runtime_pm ? " for runtime pm" : "");

    ret = 0;

out:
    return ret;
}

static int hif_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
    int ret;

    vos_ssr_protect(__func__);

    ret = __hif_pci_suspend(pdev, state, false);

    vos_ssr_unprotect(__func__);

    return ret;
}

/**
 * __hif_check_link_status() - API to check if PCIe link is active/not
 *
 * @pdev: PCIe device structure
 *
 * API reads the PCIe config space to verify if PCIe link training is
 * successful or not.
 *
 * Return: Success/Failure
 */
static int __hif_check_link_status(struct pci_dev *pdev)
{
	uint16_t dev_id;
	struct hif_pci_softc *sc = pci_get_drvdata(pdev);

	if (!sc) {
		pr_err("%s: HIF Bus Context is Invalid\n", __func__);
		return -EINVAL;
	}

	pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &dev_id);

	if (dev_id == sc->devid)
		return 0;

	pr_err("%s: Invalid PCIe Config Space; PCIe link down dev_id:0x%04x\n",
	       __func__, dev_id);
	sc->recovery = true;
	vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE);
	vos_wlan_pci_link_down();
	return -EACCES;
}

static int
__hif_pci_resume(struct pci_dev *pdev, bool runtime_pm)
{
    struct hif_pci_softc *sc = pci_get_drvdata(pdev);
    void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);
    struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device;
    A_target_id_t targid = hif_state->targid;
    u32 val;
    int err = 0;
    v_VOID_t * temp_module;
    u32 tmp;
    int retry = 0;

    if (vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL))
        return err;

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

    adf_os_atomic_set(&sc->pci_link_suspended, 0);
    adf_os_atomic_set(&sc->wow_done, 0);

    /* Enable Legacy PCI line interrupts */
    if (HIFTargetSleepStateAdjust(targid, FALSE, TRUE) < 0)
        goto out;
    for (;;) {
        A_PCI_WRITE32(sc->mem +
                     (SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS),
                      PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
        /*
         * IMPORTANT: this extra read transaction is required to
         * flush the posted write buffer
         */

        tmp = A_PCI_READ32(sc->mem +
                          (SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS));

        if (tmp != 0xffffffff)
            break;

        if (retry > MAX_REG_READ_RETRIES) {
            pr_err("%s: PCIe link is possible down!\n", __func__);
            print_config_soc_reg(sc);
            adf_os_atomic_set(&sc->pci_link_suspended, 1);
            adf_os_atomic_set(&sc->wow_done, 1);
            sc->recovery = true;
            vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE);
            vos_wlan_pci_link_down();
            return -EACCES;
        }

        A_MDELAY(1);
        retry++;
    }

    hif_irq_record(HIF_RESUME, sc);

    if (HIFTargetSleepStateAdjust(targid, TRUE, FALSE) < 0)
        goto out;

    if (runtime_pm)
	    goto skip;

    err = pci_enable_device(pdev);
    if (err)
    {
        printk("\n%s %d : pci_enable_device returned failure %d\n",
           __func__, __LINE__, err);
        goto out;
    }

    pci_read_config_dword(pdev, OL_ATH_PCI_PM_CONTROL, &val);
    if ((val & 0x000000ff) != 0) {
        pci_restore_state(pdev);
        pci_write_config_dword(pdev, OL_ATH_PCI_PM_CONTROL, val & 0xffffff00);

        /*
         * Suspend/Resume resets the PCI configuration space, so we have to
         * re-disable the RETRY_TIMEOUT register (0x41) to keep
         * PCI Tx retries from interfering with C3 CPU state
         *
         */
        pci_read_config_dword(pdev, 0x40, &val);

        if ((val & 0x0000ff00) != 0)
            pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
    }

    /* Set bus master bit in PCI_COMMAND to enable DMA */
    pci_set_master(pdev);

skip:
#ifdef HIF_PCI
    /* Keep PCIe bus driver's shadow memory intact */
    vos_pcie_shadow_control(pdev, TRUE);
#endif

#ifdef DISABLE_L1SS_STATES
    pci_read_config_dword(pdev, 0x188, &val);
    pci_write_config_dword(pdev, 0x188, (val & ~0x0000000f));
#endif

    /* No need to send WMI_PDEV_RESUME_CMDID to FW if WOW is enabled */
    temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos_context);
    if (!temp_module) {
        printk("%s: WDA module is NULL\n", __func__);
        goto out;
    }

    hif_enable_tasklet_noclient(sc, temp_module);

    if (!wma_is_wow_mode_selected(temp_module))
        err = wma_resume_target(temp_module, runtime_pm);
    else
        err = wma_disable_wow_in_fw(temp_module, runtime_pm);

#ifdef FEATURE_WLAN_D0WOW
    if (wma_get_client_count(temp_module)) {
        if (disable_irq_wake(pdev->irq)) {
            pr_err("%s: Fail to disable wake IRQ!\n", __func__);
            err = -1;
            goto out;
        }
    }
#endif

    pr_debug("%s: Resume completes%s in%s mode\n", __func__,
                runtime_pm ? " for runtime pm" : "",
                wma_is_wow_mode_selected(temp_module) ? " wow" : " pdev");
out:
    if (err) {
        pr_err("%s: resume failed err:%d\n", __func__, err);
        return (-1);
    }

    return (0);
}

static int
hif_pci_resume(struct pci_dev *pdev)
{
    int ret;

    vos_ssr_protect(__func__);

    ret = __hif_pci_resume(pdev, false);

    vos_ssr_unprotect(__func__);

    return ret;
}

/* routine to modify the initial buffer count to be allocated on an os
 * platform basis. Platform owner will need to modify this as needed
 */
adf_os_size_t initBufferCount(adf_os_size_t maxSize)
{
    return maxSize;
}

#ifdef CONFIG_CNSS
struct cnss_wlan_driver cnss_wlan_drv_id = {
    .name       = "hif_pci",
    .id_table   = hif_pci_id_table,
    .probe      = hif_pci_probe,
    .remove     = hif_pci_remove,
    .reinit     = hif_pci_reinit,
    .shutdown   = hif_pci_shutdown,
    .crash_shutdown = hif_pci_crash_shutdown,
    .modem_status   = hif_pci_notify_handler,
#ifdef ATH_BUS_PM
    .suspend    = hif_pci_suspend,
    .resume     = hif_pci_resume,
#ifdef FEATURE_RUNTIME_PM
    .runtime_ops = &runtime_pm_ops,
#endif
#endif
};
#else
MODULE_DEVICE_TABLE(pci, hif_pci_id_table);
struct pci_driver hif_pci_drv_id = {
    .name       = "hif_pci",
    .id_table   = hif_pci_id_table,
    .probe      = hif_pci_probe,
    .remove     = hif_pci_remove,
#ifdef ATH_BUS_PM
    .suspend    = hif_pci_suspend,
    .resume     = hif_pci_resume,
#endif
};
#endif

int hif_register_driver(void)
{
#ifdef CONFIG_CNSS
    return cnss_wlan_register_driver(&cnss_wlan_drv_id);
#else
    return pci_register_driver(&hif_pci_drv_id);
#endif
}

void hif_unregister_driver(void)
{
#ifdef CONFIG_CNSS
	cnss_wlan_unregister_driver(&cnss_wlan_drv_id);
#else
	pci_unregister_driver(&hif_pci_drv_id);
#endif
}

/* Function to set the TXRX handle in the ol_sc context */
void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle)
{
	struct ol_softc *sc = (struct ol_softc *)ol_sc;
	sc->pdev_txrx_handle = txrx_handle;
}

void hif_disable_isr(void *ol_sc)
{
	struct ol_softc *sc = (struct ol_softc *)ol_sc;
	struct hif_pci_softc *hif_sc = sc->hif_sc;
	struct ol_softc *scn;
	if (hif_sc->hdd_startup_reinit_flag) {
		pr_err("%s: WARN: in HDD starrtup or reinit function\n",
			__func__);
		return;
	}
	scn = hif_sc->ol_sc;
	hif_nointrs(hif_sc);
#if CONFIG_PCIE_64BIT_MSI
	OS_FREE_CONSISTENT(scn->sc_osdev, 4, scn->MSI_magic, scn->MSI_magic_dma,
                       OS_GET_DMA_MEM_CONTEXT(scn, MSI_dmacontext));
	scn->MSI_magic = NULL;
	scn->MSI_magic_dma = 0;
#endif
	/* Cancel the pending tasklet */
	tasklet_kill(&hif_sc->intr_tq);
}

/* Function to reset SoC */
void hif_reset_soc(void *ol_sc)
{
	struct ol_softc *scn = (struct ol_softc *)ol_sc;
	struct hif_pci_softc *sc = scn->hif_sc;

#if defined(CPU_WARM_RESET_WAR)
	/* Currently CPU warm reset sequence is tested only for AR9888_REV2
	* Need to enable for AR9888_REV1 once CPU warm reset sequence is
	* verified for AR9888_REV1
	*/
	if (scn->target_version == AR9888_REV2_VERSION) {
		hif_pci_device_warm_reset(sc);
	}
	else {
		hif_pci_device_reset(sc);
	}
#else
	hif_pci_device_reset(sc);
#endif
}

void hif_disable_aspm(void)
{
	u_int32_t lcr_val = 0;
	void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);
	struct ol_softc *scn =  vos_get_context(VOS_MODULE_ID_HIF, vos_context);
	struct hif_pci_softc *sc;

	if (NULL == scn)
	{
		printk(KERN_ERR "%s: Could not disable ASPM scn is null\n", __func__);
		return;
	}

	sc = scn->hif_sc;

	/* Disable ASPM when pkt log is enabled */
	pci_read_config_dword(sc->pdev, 0x80, &lcr_val);
	pci_write_config_dword(sc->pdev, 0x80, (lcr_val & 0xffffff00));
}

void hif_pci_save_htc_htt_config_endpoint(int htc_endpoint)
{
    void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);
    struct ol_softc *scn =  vos_get_context(VOS_MODULE_ID_HIF, vos_context);

    if (!scn || !scn->hif_sc) {
        printk(KERN_ERR "%s: error: scn or scn->hif_sc is NULL!\n", __func__);
        return;
    }

    scn->hif_sc->htc_endpoint = htc_endpoint;
}

void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision)
{
    *version = ((struct ol_softc *)ol_sc)->target_version;
    *revision = ((struct ol_softc *)ol_sc)->target_revision;
}

void hif_set_fw_info(void *ol_sc, u32 target_fw_version)
{
    ((struct ol_softc *)ol_sc)->target_fw_version = target_fw_version;
}

#ifdef IPA_UC_OFFLOAD
/* Micro controller needs PCI BAR address to access CE register */
void hif_read_bar(struct hif_pci_softc *sc, u32 *bar_value)
{
    pci_read_config_dword(sc->pdev, 0x10, bar_value);
    *bar_value = pci_resource_start(sc->pdev, 0);
}
#endif /* IPA_UC_OFFLOAD */

#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
void wlan_hif_pci_suspend(void)
{
    void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);
    struct ol_softc *scn =  vos_get_context(VOS_MODULE_ID_HIF, vos_context);
    pm_message_t state;

    if (!scn || !scn->hif_sc) {
        printk(KERN_ERR "%s: error: scn or scn->hif_sc is NULL!\n", __func__);
        return;
    }
    state.event = PM_EVENT_SUSPEND;
    hif_pci_suspend(scn->hif_sc->pdev, state);
}
#endif
