/*
 * 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.
 */

#ifndef EXPORT_SYMTAB
#define EXPORT_SYMTAB
#endif

#include <osdep.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/if_arp.h>
#include <linux/mmc/card.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/sd.h>
#include "vos_cnss.h"
#include "wlan_hdd_main.h"
#include "wlan_nlink_common.h"
#include "bmi_msg.h" /* TARGET_TYPE_ */
#include "if_ath_sdio.h"
#include "vos_api.h"
#include "vos_sched.h"
#include "regtable.h"
#include "wlan_hdd_power.h"
#include "targaddrs.h"

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

#ifndef ATH_BUS_PM
#ifdef CONFIG_PM
#define ATH_BUS_PM
#endif /* CONFIG_PM */
#endif /* ATH_BUS_PM */

#ifndef offsetof
#define offsetof(type, field) ((adf_os_size_t)(&((type *)0)->field))
#endif

#define FW_IND_HELPER		0x8000

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

typedef void * hif_handle_t;
typedef void * hif_softc_t;

extern int hdd_wlan_startup(struct device *dev, void *hif_sc);
extern void __hdd_wlan_exit(void);

struct ath_hif_sdio_softc *sc = NULL;

#if defined(CONFIG_CNSS) && defined(HIF_SDIO)
static inline void *hif_get_virt_ramdump_mem(unsigned long *size)
{
	if (!sc)
		return NULL;

	return vos_get_virt_ramdump_mem(sc->dev, size);
}

static inline void hif_release_ramdump_mem(unsigned long *address)
{
}
#else
#ifndef TARGET_DUMP_FOR_NON_QC_PLATFORM
static inline void *hif_get_virt_ramdump_mem(unsigned long *size)
{
	void *addr;
	addr = ioremap(RAMDUMP_ADDR, RAMDUMP_SIZE);
	if (addr)
		*size = RAMDUMP_SIZE;
	return addr;
}

static inline void hif_release_ramdump_mem(unsigned long *address)
{
	if (address)
		iounmap(address);
}
#else
static inline void *hif_get_virt_ramdump_mem(unsigned long *size)
{
	size_t length = 0;
	int flags = GFP_KERNEL;

	length = DRAM_SIZE + IRAM_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_release_ramdump_mem(unsigned long *address)
{
	if (address != NULL)
		kfree(address);
}
#endif
#endif
static A_STATUS
ath_hif_sdio_probe(void *context, void *hif_handle)
{
    int ret = 0;
    struct ol_softc *ol_sc;
    HIF_DEVICE_OS_DEVICE_INFO os_dev_info;
    struct sdio_func *func = NULL;
    const struct sdio_device_id *id;
    u_int32_t target_type;
    ENTER();

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


    sc->hif_handle = hif_handle;
    HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE, &os_dev_info, sizeof(os_dev_info));

    sc->aps_osdev.device = os_dev_info.pOSDevice;
    sc->aps_osdev.bc.bc_bustype = HAL_BUS_TYPE_SDIO;
    spin_lock_init(&sc->target_lock);

    {
        /*
         * 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).
         *
         * TBDXXX: targetdef should not be global -- should be stored
         * in per-device struct so that we can support multiple
         * different Target types with a single Host driver.
         * The whole notion of an "hif type" -- (not as in the hif
         * module, but generic "Host Interface Type") is bizarre.
         * At first, one one expect it to be things like SDIO, USB, PCI.
         * But instead, it's an actual platform type. Inexplicably, the
         * values used for HIF platform types are *different* from the
         * values used for Target Types.
         */

#if defined(CONFIG_AR9888_SUPPORT)
        hif_register_tbl_attach(HIF_TYPE_AR9888);
        target_register_tbl_attach(TARGET_TYPE_AR9888);
        target_type = TARGET_TYPE_AR9888;
#elif defined(CONFIG_AR6320_SUPPORT)
        id = ((HIF_DEVICE*)hif_handle)->id;
        if (((id->device & MANUFACTURER_ID_AR6K_BASE_MASK) ==
             MANUFACTURER_ID_QCA9377_BASE) ||
            ((id->device & MANUFACTURER_ID_AR6K_BASE_MASK) ==
             MANUFACTURER_ID_QCA9379_BASE)) {
            hif_register_tbl_attach(HIF_TYPE_AR6320V2);
            target_register_tbl_attach(TARGET_TYPE_AR6320V2);
        } else if ((id->device & MANUFACTURER_ID_AR6K_BASE_MASK) == MANUFACTURER_ID_AR6320_BASE) {
            int ar6kid = id->device & MANUFACTURER_ID_AR6K_REV_MASK;
            if (ar6kid >= 1) {
                /* v2 or higher silicon */
                hif_register_tbl_attach(HIF_TYPE_AR6320V2);
                target_register_tbl_attach(TARGET_TYPE_AR6320V2);
            } else {
                /* legacy v1 silicon */
                hif_register_tbl_attach(HIF_TYPE_AR6320);
                target_register_tbl_attach(TARGET_TYPE_AR6320);
            }
        }
        target_type = TARGET_TYPE_AR6320;

#endif
    }
    func = ((HIF_DEVICE*)hif_handle)->func;
    sc->dev = &func->dev;

    ol_sc = A_MALLOC(sizeof(*ol_sc));
    if (!ol_sc){
           ret = -ENOMEM;
           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;
    ol_sc->enableuartprint = 1;
    ol_sc->enablefwlog = 0;
    ol_sc->enablesinglebinary = FALSE;
    ol_sc->max_no_of_peers = 1;

    ol_sc->hif_hdl = hif_handle;

    /* Get RAM dump memory address and size */
    ol_sc->ramdump_base = NULL;//hif_get_virt_ramdump_mem(&ol_sc->ramdump_size);
    if (ol_sc->ramdump_base == NULL || !ol_sc->ramdump_size) {
        VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_ERROR,
            "%s: Failed to get RAM dump memory address or size!\n",
            __func__);
    } else {
        VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_INFO,
            "%s: ramdump base 0x%pK size %d\n",
            __func__, ol_sc->ramdump_base, (int)ol_sc->ramdump_size);
    }
    init_waitqueue_head(&ol_sc->sc_osdev->event_queue);

    if (athdiag_procfs_init(sc) != 0) {
        VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_ERROR,
                "%s athdiag_procfs_init failed",__func__);
        ret =  A_ERROR;
        goto err_attach1;
    }
    ret = hif_init_adf_ctx(ol_sc);
    if (ret == 0) {
        if (vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL)) {
            ret = hdd_wlan_re_init(ol_sc);
            vos_set_logp_in_progress(VOS_MODULE_ID_HIF, FALSE);
        } else{
            ret = hdd_wlan_startup(&(func->dev), ol_sc);
        }
    }
    if ( ret ) {
        VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_FATAL," hdd_wlan_startup failed");
        goto err_attach2;
    }else{
        VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_INFO," hdd_wlan_startup success!");
    }

    return 0;

err_attach2:
    athdiag_procfs_remove();
    if (sc->ol_sc->ramdump_base)
        hif_release_ramdump_mem(sc->ol_sc->ramdump_base);
    hif_deinit_adf_ctx(ol_sc);
err_attach1:
    A_FREE(ol_sc);
err_attach:
    A_FREE(sc);
    sc = NULL;
err_alloc:
    return ret;
}

int
ol_ath_sdio_configure(hif_softc_t hif_sc, struct net_device *dev, hif_handle_t *hif_hdl)
{
    struct ath_hif_sdio_softc *sc = (struct ath_hif_sdio_softc *) hif_sc;
    int ret = 0;

    sc->aps_osdev.netdev = dev;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
    SET_MODULE_OWNER(dev);
#endif

    *hif_hdl = sc->hif_handle;

    return ret;
}

static A_STATUS
ath_hif_sdio_remove(void *context, void *hif_handle)
{
    ENTER();

    if (!sc) {
        VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_ERROR,
                  "Global SDIO context is NULL");
        return A_ERROR;
    }

    athdiag_procfs_remove();

    if (sc && sc->ol_sc && sc->ol_sc->ramdump_base)
        hif_release_ramdump_mem(sc->ol_sc->ramdump_base);

#ifndef REMOVE_PKT_LOG
    if (vos_get_conparam() != VOS_FTM_MODE &&
		!WLAN_IS_EPPING_ENABLED(vos_get_conparam())){
        if (sc && sc->ol_sc)
            pktlogmod_exit(sc->ol_sc);
    }
#endif

    //cleaning up the upper layers
    if (vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL)) {
        hdd_wlan_shutdown();
    } else {
        __hdd_wlan_exit();
    }
    if (sc && sc->ol_sc){
       hif_deinit_adf_ctx(sc->ol_sc);
       A_FREE(sc->ol_sc);
       sc->ol_sc = NULL;
    }
    if (sc) {
        A_FREE(sc);
        sc = NULL;
    }

    EXIT();
    return 0;
}

static A_STATUS
ath_hif_sdio_suspend(void *context)
{
	pr_debug("%s TODO\n", __func__);
	return 0;
}

static A_STATUS
ath_hif_sdio_resume(void *context)
{
	pr_debug("%s TODO\n", __func__);
	return 0;
}

static A_STATUS
ath_hif_sdio_power_change(void *context, A_UINT32 config)
{
    printk(KERN_INFO "ol_ath_sdio_power change TODO\n");
    return 0;
}

/*
 * Module glue.
 */
#include <linux/version.h>
static char *version = "HIF (Atheros/multi-bss)";
static char *dev_info = "ath_hif_sdio";

static int init_ath_hif_sdio(void)
{
    A_STATUS status;
    OSDRV_CALLBACKS osdrvCallbacks;
    ENTER();

    A_MEMZERO(&osdrvCallbacks,sizeof(osdrvCallbacks));
    osdrvCallbacks.deviceInsertedHandler = ath_hif_sdio_probe;
    osdrvCallbacks.deviceRemovedHandler = ath_hif_sdio_remove;
#ifdef CONFIG_PM
    osdrvCallbacks.deviceSuspendHandler = ath_hif_sdio_suspend;
    osdrvCallbacks.deviceResumeHandler = ath_hif_sdio_resume;
    osdrvCallbacks.devicePowerChangeHandler = ath_hif_sdio_power_change;
#endif

    VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_INFO,"%s %d",__func__,__LINE__);
    status = HIFInit(&osdrvCallbacks);
    if(status != A_OK){
       VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_FATAL, "%s HIFInit failed!",__func__);
        return -ENODEV;
    }

    printk(KERN_INFO "%s: %s\n", dev_info, version);

    return 0;
}

int hif_register_driver(void)
{
   int status = 0;
   ENTER();
   status = init_ath_hif_sdio();
   EXIT("status = %d", status);
   return status;

}

void hif_unregister_driver(void)
{
   ENTER();
   HIFShutDownDevice(NULL);
   EXIT();
   return ;
}

int hif_init_adf_ctx(void *ol_sc)
{
   adf_os_device_t adf_ctx;
   v_CONTEXT_t pVosContext = NULL;
   struct ol_softc *ol_sc_local = (struct ol_softc *)ol_sc;
   struct ath_hif_sdio_softc *hif_sc = ol_sc_local->hif_sc;
   ENTER();
   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->dev = hif_sc->aps_osdev.device;
   ol_sc_local->adf_dev = adf_ctx;
   ((VosContextType*)(pVosContext))->adf_ctx = adf_ctx;
   EXIT();
   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;
   }
}

/* 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;
   ENTER();
   sc->pdev_txrx_handle = txrx_handle;
}

void hif_disable_isr(void *ol_sc)
{
   ENTER("- dummy function!");
}

void
HIFSetTargetSleep(HIF_DEVICE *hif_device, A_BOOL sleep_ok, A_BOOL wait_for_it)
{
   ENTER("- dummy function!");
}

void
HIFCancelDeferredTargetSleep(HIF_DEVICE *hif_device)
{
    ENTER("- dummy function!");

}

/* Function to reset SoC */
void hif_reset_soc(void *ol_sc)
{
    ENTER("- dummy function!");
}

void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision)
{
    struct ol_softc *ol_sc_local = (struct ol_softc *)ol_sc;
    A_UINT32 chip_id = 0;
    A_STATUS rv;
    rv = HIFDiagReadAccess(ol_sc_local->hif_hdl,
             (CHIP_ID_ADDRESS | RTC_SOC_BASE_ADDRESS), &chip_id);
    if (rv != A_OK) {
        pr_warn("%s[%d]: get chip id fail\n", __func__, __LINE__);
        ol_sc_local->target_revision = -1;
    } else {
        ol_sc_local->target_revision =
            CHIP_ID_REVISION_GET(chip_id);
    }
    *version = ol_sc_local->target_version;
    *revision = ol_sc_local->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;
}

/**
 * hif_sdio_check_fw_reg() - Check wether a self recovery is needed
 * @ol_sc: os layser software context
 *
 * For scenario such as AXI error, cold reset is needed to recover FW.
 * FW will set FW_IND_HELPER in such a scenario.
 *
 */
int hif_sdio_check_fw_reg(void * ol_sc)
{
	int ret = 1;
	unsigned int addr = 0;
	unsigned int fw_indication = 0;
	struct ol_softc *scn = (struct ol_softc *) ol_sc;

	addr = host_interest_item_address(scn->target_type,
					offsetof(struct host_interest_s,
					hi_option_flag2));

	if (HIFDiagReadMem(scn->hif_hdl, addr,
				(unsigned char *)&fw_indication,
				4) != A_OK) {
		printk("%s Get fw indication failed\n", __func__);
		return -ENOENT;
	}

	printk("%s: fw indication is 0x%x.\n", __func__, fw_indication);

	if (fw_indication & FW_IND_HELPER)
		ret = 0;

	return ret;
}
