/*
 * Copyright (c) 2013-2016 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/usb.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/if_arp.h>
#include <linux/usb/hcd.h>
#include "if_usb.h"
#include "hif_usb_internal.h"
#include "bmi_msg.h"		/* TARGET_TYPE_ */
#include "regtable.h"
#include "ol_fw.h"
#include <osapi_linux.h>
#include "vos_api.h"
#include "wma_api.h"
#include "wlan_hdd_main.h"
#include "epping_main.h"
#include "vos_sched.h"

#ifndef REMOVE_PKT_LOG
#include "ol_txrx_types.h"
#include "pktlog_ac_api.h"
#include "pktlog_ac.h"
#endif
#define VENDOR_ATHR             0x0CF3
#define AR9888_DEVICE_ID (0x003c)
#define AR6320_DEVICE_ID (0x9378)
#define DELAY_FOR_TARGET_READY 200	/* 200ms */
#define DELAY_INT_FOR_HDD_REMOVE 200	/* 200ms */
#define HIFDiagWriteCOLDRESET(hifdevice) HIFDiagWriteAccess(sc->hif_device, \
				(ROME_USB_SOC_RESET_CONTROL_COLD_RST_LSB | \
				ROME_USB_RTC_SOC_BASE_ADDRESS), \
				SOC_RESET_CONTROL_COLD_RST_SET(1))

unsigned int msienable;
module_param(msienable, int, 0644);
#define HIF_USB_UNLOAD_TIMEOUT		(2*HZ)
enum hif_usb_drv_unload_state {
	HIF_USB_UNLOAD_STATE_NULL = 0,
	HIF_USB_UNLOAD_STATE_DRV_DEREG,
	HIF_USB_UNLOAD_STATE_TARGET_RESET,
	HIF_USB_UNLOAD_STATE_DEV_DISCONNECTED,
};

static int hif_usb_unload_dev_num = -1;
static wait_queue_head_t hif_usb_unload_event_wq;
static atomic_t hif_usb_unload_state;
struct hif_usb_softc *usb_sc = NULL;
static int hif_usb_resume(struct usb_interface *interface);

static int
hif_usb_configure(struct hif_usb_softc *sc, hif_handle_t *hif_hdl,
		  struct usb_interface *interface)
{
	int ret = 0;
	struct usb_device *dev = interface_to_usbdev(interface);

	if (HIF_USBDeviceInserted(interface, sc)) {
		pr_err("ath: %s: Target probe failed.\n", __func__);
		ret = -EIO;
		goto err_stalled;
	}

	if (athdiag_procfs_init(sc) != 0) {
		pr_err("athdiag_procfs_init failed\n");
		return A_ERROR;
	}
	hif_usb_unload_dev_num = dev->devnum;
	*hif_hdl = sc->hif_device;
	return 0;

err_stalled:

	return ret;
}

static void hif_nointrs(struct hif_usb_softc *sc)
{
}

static int hif_usb_reboot(struct notifier_block *nb, unsigned long val,
			     void *v)
{
	struct hif_usb_softc *sc;
	sc = container_of(nb, struct hif_usb_softc, reboot_notifier);
	/* do cold reset */
	HIFDiagWriteCOLDRESET(sc->hif_device);
	return NOTIFY_DONE;
}

/*
 * Disable lpm feature of usb2.0.
 */
static int hif_usb_disable_lpm(struct usb_device *udev)
{
	struct usb_hcd *hcd;
	int ret = -EPERM;
	pr_info("Enter:%s,Line:%d\n", __func__, __LINE__);
	if (!udev || !udev->bus) {
		pr_err("Invalid input parameters\n");
	} else {
		hcd = bus_to_hcd(udev->bus);
		if (udev->usb2_hw_lpm_enabled) {
			if (hcd->driver->set_usb2_hw_lpm) {
				ret = hcd->driver->set_usb2_hw_lpm(hcd,
							udev, FALSE);
				if (!ret) {
					udev->usb2_hw_lpm_enabled = FALSE;
					udev->usb2_hw_lpm_capable = FALSE;
					pr_info("%s: LPM is disabled\n",
								__func__);
				} else {
					pr_info("%s: Fail to disable LPM\n",
								__func__);
				}
			} else {
				pr_info("%s: hcd doesn't support LPM\n",
							__func__);
			}
		} else {
			pr_info("%s: LPM isn't enabled\n", __func__);
		}
	}

	pr_info("Exit:%s,Line:%d\n", __func__, __LINE__);
	return ret;
}

static int
hif_usb_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
	int ret = 0;
	struct hif_usb_softc *sc;
	struct ol_softc *ol_sc;
	struct usb_device *pdev = interface_to_usbdev(interface);
	int vendor_id, product_id;

	pr_info("hif_usb_probe\n");
	usb_get_dev(pdev);
	vendor_id = le16_to_cpu(pdev->descriptor.idVendor);
	product_id = le16_to_cpu(pdev->descriptor.idProduct);

	ret = 0;

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

	OS_MEMZERO(sc, sizeof(*sc));
	sc->pdev = (void *)pdev;
	sc->dev = &pdev->dev;

	sc->aps_osdev.bdev = pdev;
	sc->aps_osdev.device = &pdev->dev;
	sc->aps_osdev.bc.bc_bustype = HAL_BUS_TYPE_AHB;
	sc->devid = id->idProduct;

	adf_os_spinlock_init(&sc->target_lock);

	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;

	if ((usb_control_msg(pdev, usb_sndctrlpipe(pdev, 0),
			     USB_REQ_SET_CONFIGURATION, 0, 1, 0, NULL, 0,
			     HZ)) < 0) {
		pr_info("%s[%d]\n\r", __func__, __LINE__);
	}
	usb_set_interface(pdev, 0, 0);
	/* disable lpm to avoid usb2.0 probe timeout */
	hif_usb_disable_lpm(pdev);

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

	ol_sc->enableuartprint = 1;
	ol_sc->enablefwlog = 0;
	ol_sc->enablesinglebinary = FALSE;
	ol_sc->max_no_of_peers = 1;

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

	ret = hif_init_adf_ctx(ol_sc);
	if (ret == 0)
		ret = hdd_wlan_startup(&pdev->dev, ol_sc);
	if (ret) {
		hif_nointrs(sc);
		if (sc->hif_device != NULL) {
			((HIF_DEVICE_USB *)(sc->hif_device))->sc = NULL;
		}
		athdiag_procfs_remove();
		goto err_config;
	}
	atomic_set(&sc->hdd_removed, -1);
	atomic_set(&sc->hdd_removed_processing, 0);
	sc->hdd_removed_wait_cnt = 0;

	sc->interface = interface;
	sc->reboot_notifier.notifier_call = hif_usb_reboot;
	register_reboot_notifier(&sc->reboot_notifier);

	usb_sc = sc;
	return 0;

err_config:
	hif_deinit_adf_ctx(ol_sc);
	HIFDiagWriteCOLDRESET(sc->hif_device);
	A_FREE(ol_sc);
err_attach:
	ret = -EIO;
	usb_sc = NULL;
	A_FREE(sc);
err_alloc:
	usb_put_dev(pdev);

	return ret;
}

static void hif_usb_remove(struct usb_interface *interface)
{
	HIF_DEVICE_USB *device = usb_get_intfdata(interface);
	struct usb_device *udev = interface_to_usbdev(interface);
	struct hif_usb_softc *sc = device->sc;
	struct ol_softc *scn;

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

	pr_info("Try to remove hif_usb!\n");

	/* wait __hdd_wlan_exit until finished and no more than 4 seconds*/
	while(atomic_read(&usb_sc->hdd_removed_processing) == 1 &&
			usb_sc->hdd_removed_wait_cnt < 20) {
		set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(msecs_to_jiffies(DELAY_INT_FOR_HDD_REMOVE));
		set_current_state(TASK_RUNNING);
		usb_sc->hdd_removed_wait_cnt ++;
	}
	atomic_set(&usb_sc->hdd_removed_processing, 1);
	vos_set_shutdown_in_progress(VOS_MODULE_ID_HIF, TRUE);

	/* disable lpm to avoid following cold reset will
	 *cause xHCI U1/U2 timeout
	 */
	usb_disable_lpm(udev);

	/* wait for disable lpm */
	set_current_state(TASK_INTERRUPTIBLE);
	schedule_timeout(msecs_to_jiffies(DELAY_FOR_TARGET_READY));
	set_current_state(TASK_RUNNING);

	/* do cold reset */
	HIFDiagWriteCOLDRESET(sc->hif_device);

	unregister_reboot_notifier(&sc->reboot_notifier);
	usb_put_dev(interface_to_usbdev(interface));
	if (atomic_read(&hif_usb_unload_state) ==
			HIF_USB_UNLOAD_STATE_DRV_DEREG)
		atomic_set(&hif_usb_unload_state,
			   HIF_USB_UNLOAD_STATE_TARGET_RESET);
	scn = sc->ol_sc;

        /* The logp is set by target failure's ol_ramdump_handler.
         * Coldreset occurs and do this disconnect cb, try to issue
         * offline uevent to restart driver.
         */
        if (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) {
                /* dispatch 'offline' uevent to restart module */
                kobject_uevent(&scn->adf_dev->dev->kobj, KOBJ_OFFLINE);
                vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
        }

	if (atomic_inc_and_test(&usb_sc->hdd_removed)) {
#ifndef REMOVE_PKT_LOG
		if (vos_get_conparam() != VOS_FTM_MODE &&
			!WLAN_IS_EPPING_ENABLED(vos_get_conparam()))
			pktlogmod_exit(scn);
#endif
		__hdd_wlan_exit();
		pr_info("Exit HDD wlan... done by %s\n", __func__);
	}

	hif_nointrs(sc);
	HIF_USBDeviceDetached(interface, 1);
	vos_set_shutdown_in_progress(VOS_MODULE_ID_HIF, FALSE);
	atomic_set(&usb_sc->hdd_removed_processing, 0);
	hif_deinit_adf_ctx(scn);
	A_FREE(scn);
	A_FREE(sc);
	usb_sc = NULL;
	pr_info("hif_usb_remove!!!!!!\n");
}

#ifdef WLAN_LINK_UMAC_SUSPEND_WITH_BUS_SUSPEND
void hdd_suspend_wlan(void (*callback) (void *callbackContext),
		      void *callbackContext);
#endif

static int hif_usb_suspend(struct usb_interface *interface, pm_message_t state)
{
	HIF_DEVICE_USB *device = usb_get_intfdata(interface);
	struct hif_usb_softc *sc = device->sc;
	void *vos = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);
	v_VOID_t * temp_module;

	printk("Enter:%s,Line:%d\n", __func__,__LINE__);

	temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos);
	if (!temp_module) {
		printk("%s: WDA module is NULL\n", __func__);
		return (-1);
	}

	if (wma_check_scan_in_progress(temp_module)) {
		printk("%s: Scan in progress. Aborting suspend\n", __func__);
		return (-1);
	}

	sc->suspend_state = 1;
	usb_hif_flush_all(device);

	printk("Exit:%s,Line:%d\n", __func__,__LINE__);
	return 0;
}

#ifdef WLAN_LINK_UMAC_SUSPEND_WITH_BUS_SUSPEND
void hdd_resume_wlan(void);
#endif

static int hif_usb_resume(struct usb_interface *interface)
{
	HIF_DEVICE_USB *device = usb_get_intfdata(interface);
	struct hif_usb_softc *sc = device->sc;
	void *vos = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);
	v_VOID_t * temp_module;

	printk("Enter:%s,Line:%d\n", __func__,__LINE__);
	temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos);
	if (!temp_module) {
		printk("%s: WDA module is NULL\n", __func__);
		return (-1);
	}

	sc->suspend_state = 0;
	usb_hif_start_recv_pipes(device);

#ifdef USB_HIF_TEST_INTERRUPT_IN
	usb_hif_post_recv_transfers(&device->pipes[HIF_RX_INT_PIPE],
				    HIF_USB_RX_BUFFER_SIZE);
#endif
	printk("Exit:%s,Line:%d\n", __func__,__LINE__);
	return 0;
}

static int hif_usb_reset_resume(struct usb_interface *intf)
{
	HIF_DEVICE_USB *device = usb_get_intfdata(intf);
	struct hif_usb_softc *sc = device->sc;

	printk("Enter:%s,Line:%d \n\r", __func__,__LINE__);
	HIFDiagWriteCOLDRESET(sc->hif_device);
	printk("Exit:%s,Line:%d \n\r", __func__,__LINE__);
	return 0;
}

static struct usb_device_id hif_usb_id_table[] = {
	{USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ATHR, 0x9378, 0xFF, 0xFF, 0xFF)},
	{USB_DEVICE_AND_INTERFACE_INFO(VENDOR_ATHR, 0x9379, 0xFF, 0xFF, 0xFF)},
	{}			/* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, hif_usb_id_table);
struct usb_driver hif_usb_drv_id = {

	.name = "hif_usb",
	.id_table = hif_usb_id_table,
	.probe = hif_usb_probe,
	.disconnect = hif_usb_remove,
#ifdef ATH_BUS_PM
	.suspend = hif_usb_suspend,
	.resume = hif_usb_resume,
	.reset_resume = hif_usb_reset_resume,
#endif
	.supports_autosuspend = true,
};

int hif_init_adf_ctx(void *ol_sc)
{
	adf_os_device_t adf_ctx;
	v_CONTEXT_t pVosContext = NULL;
	struct ol_softc *sc = (struct ol_softc *)ol_sc;
	struct hif_usb_softc *hif_sc = (struct hif_usb_softc *)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;
	}
}

static int hif_usb_dev_notify(struct notifier_block *nb,
				 unsigned long action, void *dev)
{
	struct usb_device *udev;
	int ret = NOTIFY_DONE;

	if (action != USB_DEVICE_REMOVE)
		goto done;

	udev = (struct usb_device *) dev;
	if (hif_usb_unload_dev_num != udev->devnum)
		goto done;

	if (atomic_read(&hif_usb_unload_state) ==
			HIF_USB_UNLOAD_STATE_TARGET_RESET) {
		atomic_set(&hif_usb_unload_state,
			   HIF_USB_UNLOAD_STATE_DEV_DISCONNECTED);
		wake_up(&hif_usb_unload_event_wq);
	}

done:
	return ret;
}

static struct notifier_block hif_usb_dev_nb = {
	.notifier_call = hif_usb_dev_notify,
};
static int is_usb_driver_register = 0;
int hif_register_driver(void)
{
	int status = 0;
	int probe_wait_cnt = 0;
	is_usb_driver_register = 1;
	init_waitqueue_head(&hif_usb_unload_event_wq);
	atomic_set(&hif_usb_unload_state, HIF_USB_UNLOAD_STATE_NULL);
	usb_register_notify(&hif_usb_dev_nb);
	status = usb_register(&hif_usb_drv_id);

	/* wait for usb probe done, 2s at most*/
	while(!usb_sc && probe_wait_cnt < 10) {
		A_MSLEEP(200);
		probe_wait_cnt++;
	}

	if (usb_sc && status == 0)
		return 0;
	else
		return -1;
}

void hif_unregister_driver(void)
{
	if (is_usb_driver_register) {
		long timeleft = 0;
		pr_info("Try to unregister hif_driver\n");
		if (usb_sc != NULL) {
			/* wait __hdd_wlan_exit until finished and no more than
			 * 4 seconds
			 */
			while(usb_sc &&
				atomic_read(&usb_sc->hdd_removed_processing) == 1 &&
				usb_sc->hdd_removed_wait_cnt < 20) {
				usb_sc->hdd_removed_wait_cnt ++;
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(msecs_to_jiffies(
						DELAY_INT_FOR_HDD_REMOVE));
				set_current_state(TASK_RUNNING);
			}

			/* usb_sc is freed by hif_usb_remove */
			if (!usb_sc)
				goto deregister;

			atomic_set(&usb_sc->hdd_removed_processing, 1);

			if (usb_sc->suspend_state) {
				hif_usb_resume(usb_sc->interface);
			}

			if (atomic_inc_and_test(&usb_sc->hdd_removed)) {
#ifndef REMOVE_PKT_LOG
				if (vos_get_conparam() != VOS_FTM_MODE &&
					!WLAN_IS_EPPING_ENABLED(vos_get_conparam()))
					pktlogmod_exit(usb_sc->ol_sc);
#endif
				__hdd_wlan_exit();
				pr_info("Exit HDD wlan... done by %s\n", __func__);
			}
			atomic_set(&usb_sc->hdd_removed_processing, 0);
		}

deregister:
		is_usb_driver_register = 0;
		atomic_set(&hif_usb_unload_state,
			   HIF_USB_UNLOAD_STATE_DRV_DEREG);
		usb_deregister(&hif_usb_drv_id);
		if (atomic_read(&hif_usb_unload_state) !=
				HIF_USB_UNLOAD_STATE_TARGET_RESET)
			goto finish;
		timeleft = wait_event_interruptible_timeout(
				hif_usb_unload_event_wq,
				atomic_read(&hif_usb_unload_state) ==
				HIF_USB_UNLOAD_STATE_DEV_DISCONNECTED,
				HIF_USB_UNLOAD_TIMEOUT);
		if (timeleft <= 0)
			pr_err("Fail to wait from DRV_DEREG to DISCONNECT,"
				"timeleft = %ld \n\r",
				timeleft);
finish:
		usb_unregister_notify(&hif_usb_dev_nb);
		pr_info("hif_unregister_driver!!!!!!\n");
	}
}

/* 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)
{
	/* TODO */
}

/* Function to reset SoC */
void hif_reset_soc(void *ol_sc)
{
	/* TODO */
}

void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision)
{
	u_int32_t hif_type, target_type;
	A_STATUS rv;
	A_INT32 ret = 0;
	A_UINT32 chip_id;
	struct hif_usb_softc *sc;

	sc = ((struct ol_softc *)ol_sc)->hif_sc;
	if (sc->hostdef == NULL && sc->targetdef == NULL) {
		switch (((struct ol_softc *)ol_sc)->target_type)
		{
			case TARGET_TYPE_AR6320:
				switch(((struct ol_softc *)ol_sc)->target_version) {
					case AR6320_REV1_VERSION:
					case AR6320_REV1_1_VERSION:
					case AR6320_REV1_3_VERSION:
						hif_type = HIF_TYPE_AR6320;
						target_type = TARGET_TYPE_AR6320;
						break;
					case AR6320_REV2_1_VERSION:
					case AR6320_REV3_VERSION:
					case AR6320_REV3_2_VERSION:
					case QCA9377_REV1_1_VERSION:
					case QCA9379_REV1_VERSION:
						hif_type = HIF_TYPE_AR6320V2;
						target_type = TARGET_TYPE_AR6320V2;
						break;
					default:
						ret = -1;
						break;
				}
				break;
			default:
				ret = -1;
				break;
		}

		if (!ret) {
			/* assign target register table if we find corresponding type */
			hif_register_tbl_attach(sc, hif_type);
			target_register_tbl_attach(sc, target_type);
			/* read the chip revision*/
			rv = HIFDiagReadAccess(sc->hif_device, (CHIP_ID_ADDRESS | RTC_SOC_BASE_ADDRESS), &chip_id);
			if (rv != A_OK) {
				pr_err("ath: HIF_PCIDeviceProbed get chip id val (%d)\n", rv);
			}
			((struct ol_softc *)ol_sc)->target_revision = CHIP_ID_REVISION_GET(chip_id);
		}
	}

	/* we need to get chip revision here */
	*version = ((struct ol_softc *)ol_sc)->target_version;
	/* Chip version should be supported, set to 0 for now */
	*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;
}

MODULE_LICENSE("Dual BSD/GPL");
