/*
 * Copyright (c) 2013-2014,2016-2018 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.
 */

#define ATH_MODULE_NAME hif
#include <linux/kthread.h>
#include "a_debug.h"

#include <adf_os_types.h>
#include <adf_os_dma.h>
#include <adf_os_timer.h>
#include <adf_os_time.h>
#include <adf_os_lock.h>
#include <adf_os_io.h>
#include <adf_os_mem.h>
#include <adf_os_module.h>
#include <adf_os_util.h>
#include <adf_os_stdtypes.h>
#include <adf_os_defer.h>
#include <adf_os_atomic.h>
#include <adf_nbuf.h>
#include <athdefs.h>
#include <adf_net_types.h>
#include <a_types.h>
#include <athdefs.h>
#include <a_osapi.h>
#include <hif.h>
#include <htc_services.h>
#include <htc_internal.h>
#include "hif_sdio_internal.h"
#include "if_ath_sdio.h"
#include "regtable.h"
#include "vos_sched.h"

/* under HL SDIO, with Interface Memory support, we have the following
 * reasons to support 2 mboxs: a) we need place different buffers in different
 * mempool, for example, data using Interface Memory, desc and other using
 * DRAM, they need different SDIO mbox channels; b) currently, tx mempool in
 * LL case is seperated from main mempool, the structure (descs at the beginning
 * of every pool buffer) is different, because they only need store tx desc from host.
 * To align with LL case, we also need 2 mbox support just as PCIe LL cases.
 */

A_UINT8 HIFDevMapPipeToMailBox(HIF_SDIO_DEVICE *pDev, A_UINT8 pipeid)
{
    // TODO: temp version, should not hardcoded here, will be updated after HIF design
    if (2 == pipeid || 3 == pipeid)
        return 1;
    else if (0 == pipeid || 1 == pipeid)
        return 0;
    else {
        printk("%s:--------------------pipeid=%d,should not happen\n",__func__,pipeid);
        adf_os_assert(0);
        return INVALID_MAILBOX_NUMBER;
    }
}

A_UINT8 HIFDevMapMailBoxToPipe(HIF_SDIO_DEVICE *pDev, A_UINT8 mboxIndex,
        A_BOOL upload)
{
    // TODO: temp version, should not hardcoded here, will be updated after HIF design
    if (mboxIndex == 0) {
        return upload ? 1 : 0;
    } else if (mboxIndex == 1) {
        return upload ? 3 : 2;
    } else {
        printk("%s:--------------------mboxIndex=%d,upload=%d,should not happen\n",__func__,mboxIndex,upload);
        adf_os_assert(0);
        return 0xff;
    }
}

A_STATUS HIFDevMapServiceToPipe(HIF_SDIO_DEVICE *pDev, A_UINT16 ServiceId,
        A_UINT8 *ULPipe, A_UINT8 *DLPipe, A_BOOL SwapMapping)
{
    A_STATUS status = EOK;
    switch (ServiceId) {
    case HTT_DATA_MSG_SVC:
        if (SwapMapping) {
            *ULPipe = 1;
            *DLPipe = 0;
        } else {
            *ULPipe = 3;
            *DLPipe = 2;
        }
        break;

    case HTC_CTRL_RSVD_SVC:
    case HTC_RAW_STREAMS_SVC:
        *ULPipe = 1;
        *DLPipe = 0;
        break;

    case WMI_DATA_BE_SVC:
    case WMI_DATA_BK_SVC:
    case WMI_DATA_VI_SVC:
    case WMI_DATA_VO_SVC:
        *ULPipe = 1;
        *DLPipe = 0;
        break;

    case WMI_CONTROL_SVC:
        if (SwapMapping) {
            *ULPipe = 3;
            *DLPipe = 2;
        } else {
            *ULPipe = 1;
            *DLPipe = 0;
        }
        break;

    default:
        status = !EOK;
        break;
    }
    return status;
}

HTC_PACKET *HIFDevAllocRxBuffer(HIF_SDIO_DEVICE *pDev, size_t length)
{
    HTC_PACKET *pPacket;
    adf_nbuf_t netbuf;
    A_UINT32 bufsize = 0, headsize = 0;

    bufsize = length + HIF_SDIO_RX_DATA_OFFSET;
    headsize = sizeof(HTC_PACKET);
    netbuf = adf_nbuf_alloc(NULL, bufsize + headsize, 0, 4, FALSE);
    if (netbuf == NULL) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("(%s)Allocate netbuf failed\n", __FUNCTION__));
        return NULL;
    }
    pPacket = (HTC_PACKET *) adf_nbuf_data(netbuf);
    adf_nbuf_reserve(netbuf, headsize);

    SET_HTC_PACKET_INFO_RX_REFILL(pPacket,
            pDev,
            adf_nbuf_data(netbuf),
            bufsize,
            ENDPOINT_0);
    SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, netbuf);
    return pPacket;
}

#ifdef HIF_RX_THREAD
/**
 * rx_completion_sem_init() - initialize rx completion semaphore
 * @device:  device handle.
 *
 * Initialize semaphore for RX completion thread's synchronization.
 *
 * Return: None.
 */
static inline void rx_completion_sem_init(HIF_SDIO_DEVICE *pDev)
{
	spin_lock_init(&pDev->pRecvTask->rx_bundle_lock);
	spin_lock_init(&pDev->pRecvTask->rx_sync_completion_lock);
	sema_init(&pDev->pRecvTask->sem_rx_completion, 0);
}
extern int rx_completion_task(void *param);

/**
 * hif_start_tx_completion_thread() - Create and start the RX compl thread
 * @pDev:   pDev handle.
 *
 * This function will create the rx completion thread.
 *
 * Return: A_OK     thread created.
 *         A_ERROR  thread not created.
 */
static inline int hif_start_rx_completion_thread(HIF_SDIO_DEVICE *pDev)
{
#ifdef CONFIG_PERF_NON_QC_PLATFORM
    struct sched_param param = {.sched_priority = 99};
#endif
	if (!pDev->pRecvTask->rx_completion_task) {
		pDev->pRecvTask->rx_completion_shutdown = 0;
		pDev->pRecvTask->rx_completion_task = kthread_create(rx_completion_task,
			(void *)pDev,	"AR6K RxCompletion");
#ifdef CONFIG_PERF_NON_QC_PLATFORM
                sched_setscheduler(pDev->pRecvTask->rx_completion_task, SCHED_FIFO, &param);
#endif
		if (IS_ERR(pDev->pRecvTask->rx_completion_task)) {
			pDev->pRecvTask->rx_completion_shutdown = 1;
			AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
			("AR6000: fail to create rx_comple task\n"));
			pDev->pRecvTask->rx_completion_task = NULL;
			return A_ERROR;
		}
		AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
			("AR6000: start rx_comple task\n"));
		wake_up_process(pDev->pRecvTask->rx_completion_task);
	}
	return A_OK;
}

/*
 * hif_stop_rx_completion_thread() - Destroy the rx compl thread
 * @pDev: pDev handle.
 *
 * This function will destroy the RX completion thread.
 *
 * Return: None.
 */
static inline void hif_stop_rx_completion_thread(HIF_SDIO_DEVICE *pDev)
{
    HTC_PACKET *pPacket;
    if (pDev->pRecvTask->rx_completion_task) {
        init_completion(&pDev->pRecvTask->rx_completion_exit);
        pDev->pRecvTask->rx_completion_shutdown = 1;
        up(&pDev->pRecvTask->sem_rx_completion);
        wait_for_completion(&pDev->pRecvTask->rx_completion_exit);
        pDev->pRecvTask->rx_completion_task = NULL;
        sema_init(&pDev->pRecvTask->sem_rx_completion, 0);
    }
    while(!HTC_QUEUE_EMPTY(&pDev->pRecvTask->rxAllocQueue)) {
        pPacket = HTC_PACKET_DEQUEUE(&pDev->pRecvTask->rxAllocQueue);
        if(pPacket == NULL)
            break;
        adf_nbuf_free(pPacket->pNetBufContext);
    }
}
struct hif_recv_task gRecvTask;
#endif

HIF_SDIO_DEVICE* HIFDevCreate(HIF_DEVICE *hif_device,
        MSG_BASED_HIF_CALLBACKS *callbacks,
        void *target)
{
    A_STATUS status;
    HIF_SDIO_DEVICE *pDev;

    pDev = A_MALLOC(sizeof(HIF_SDIO_DEVICE));
    if (!pDev) {
        A_ASSERT(FALSE);
        return NULL;
    }

    A_MEMZERO(pDev, sizeof(HIF_SDIO_DEVICE));
    A_MUTEX_INIT(&pDev->Lock);
    A_MUTEX_INIT(&pDev->TxLock);
    A_MUTEX_INIT(&pDev->RxLock);

    pDev->HIFDevice = hif_device;
    pDev->pTarget = target;
#ifdef HIF_RX_THREAD
    pDev->pRecvTask = &gRecvTask;
    pDev->pRecvTask->rx_completion_task = NULL;
    rx_completion_sem_init(pDev);
    INIT_HTC_PACKET_QUEUE(&pDev->pRecvTask->rxBundleQueue);
    INIT_HTC_PACKET_QUEUE(&pDev->pRecvTask->rxSyncCompletionQueue);
    hif_start_rx_completion_thread(pDev);
    spin_lock_init(&pDev->pRecvTask->rx_alloc_lock);
    INIT_HTC_PACKET_QUEUE(&pDev->pRecvTask->rxAllocQueue);
#endif

    status = HIFConfigureDevice(hif_device,
            HIF_DEVICE_SET_HTC_CONTEXT,
            (void*) pDev,
            sizeof(pDev));
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("(%s)HIF_DEVICE_SET_HTC_CONTEXT failed!!!\n", __FUNCTION__));
    }

    A_MEMCPY(&pDev->hif_callbacks, callbacks, sizeof(*callbacks));

    return pDev;
}

void HIFDevDestroy(HIF_SDIO_DEVICE *pDev)
{
    A_STATUS status;
#ifdef HIF_RX_THREAD
    hif_stop_rx_completion_thread(pDev);
#endif
    status = HIFConfigureDevice(pDev->HIFDevice,
            HIF_DEVICE_SET_HTC_CONTEXT,
            (void*) NULL,
            0);
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("(%s)HIF_DEVICE_SET_HTC_CONTEXT failed!!!\n", __FUNCTION__));
    }
    A_FREE(pDev);
}

HIF_SDIO_DEVICE *HIFDevFromHIF(HIF_DEVICE *hif_device)
{
    HIF_SDIO_DEVICE *pDev = NULL;
    A_STATUS status;
    status = HIFConfigureDevice(hif_device,
            HIF_DEVICE_GET_HTC_CONTEXT,
            (void**) &pDev,
            sizeof(HIF_SDIO_DEVICE));
    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("(%s)HTC_SDIO_CONTEXT is NULL!!!\n", __FUNCTION__));
    }
    return pDev;
}

A_STATUS HIFDevDisableInterrupts(HIF_SDIO_DEVICE *pDev)
{
    MBOX_IRQ_ENABLE_REGISTERS regs;
    A_STATUS    status = A_OK;
    ENTER();

    LOCK_HIF_DEV(pDev);
    /* Disable all interrupts */
    pDev->IrqEnableRegisters.int_status_enable = 0;
    pDev->IrqEnableRegisters.cpu_int_status_enable = 0;
    pDev->IrqEnableRegisters.error_status_enable = 0;
    pDev->IrqEnableRegisters.counter_int_status_enable = 0;
    /* copy into our temp area */
    A_MEMCPY(&regs,
            &pDev->IrqEnableRegisters,
            sizeof(pDev->IrqEnableRegisters));

    UNLOCK_HIF_DEV(pDev);

    /* always synchronous */
    status = HIFReadWrite(pDev->HIFDevice,
            INT_STATUS_ENABLE_ADDRESS,
            (A_UCHAR *)&regs,
            sizeof(MBOX_IRQ_ENABLE_REGISTERS),
            HIF_WR_SYNC_BYTE_INC,
            NULL);

    if (status != A_OK) {
        /* Can't write it for some reason */
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to update interrupt control registers err: %d", status));
    }

    /* mask the host controller interrupts */
    HIFMaskInterrupt(pDev->HIFDevice);
    EXIT("status :%d",status);
    return status;
}

A_STATUS HIFDevEnableInterrupts(HIF_SDIO_DEVICE *pDev)
{
    A_STATUS status;
    MBOX_IRQ_ENABLE_REGISTERS regs;
    ENTER();


    /* for good measure, make sure interrupt are disabled before unmasking at the HIF
     * layer.
     * The rationale here is that between device insertion (where we clear the interrupts the first time)
     * and when HTC is finally ready to handle interrupts, other software can perform target "soft" resets.
     * The AR6K interrupt enables reset back to an "enabled" state when this happens.
     *  */
    HIFDevDisableInterrupts(pDev);

    /* Unmask the host controller interrupts */
    HIFUnMaskInterrupt(pDev->HIFDevice);

    LOCK_HIF_DEV(pDev);

    /* Enable all the interrupts except for the internal AR6000 CPU interrupt */
    pDev->IrqEnableRegisters.int_status_enable =
            INT_STATUS_ENABLE_ERROR_SET(0x01) | INT_STATUS_ENABLE_CPU_SET(0x01)
                    | INT_STATUS_ENABLE_COUNTER_SET(0x01);

    pDev->IrqEnableRegisters.int_status_enable |=
            INT_STATUS_ENABLE_MBOX_DATA_SET(0x01) | INT_STATUS_ENABLE_MBOX_DATA_SET(0x02); // enable 2 mboxs INT

    /* Set up the CPU Interrupt Status Register, enable CPU sourced interrupt #0, #1
     * #0 is used for report assertion from target
     * #1 is used for inform host that credit arrived
     * */
    pDev->IrqEnableRegisters.cpu_int_status_enable = 0x03;

    /* Set up the Error Interrupt Status Register */
    pDev->IrqEnableRegisters.error_status_enable =
            (ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01)
                    | ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01)) >> 16;

    /* Set up the Counter Interrupt Status Register (only for debug interrupt to catch fatal errors) */
    pDev->IrqEnableRegisters.counter_int_status_enable =
            (COUNTER_INT_STATUS_ENABLE_BIT_SET(AR6K_TARGET_DEBUG_INTR_MASK)) >> 24;

    /* copy into our temp area */
    A_MEMCPY(&regs,
            &pDev->IrqEnableRegisters,
            sizeof(MBOX_IRQ_ENABLE_REGISTERS));

    UNLOCK_HIF_DEV(pDev);


    /* always synchronous */
    status = HIFReadWrite(pDev->HIFDevice,
            INT_STATUS_ENABLE_ADDRESS,
            (A_UCHAR *)&regs,
            sizeof(MBOX_IRQ_ENABLE_REGISTERS),
            HIF_WR_SYNC_BYTE_INC,
            NULL);

    if (status != A_OK) {
        /* Can't write it for some reason */
        AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
                ("Failed to update interrupt control registers err: %d\n", status));

    }
    EXIT();
    return status;
}

A_STATUS HIFDevSetup(HIF_SDIO_DEVICE *pDev)
{
    A_STATUS status;
    A_UINT32 blocksizes[MAILBOX_COUNT];
    HTC_CALLBACKS htcCallbacks;
    HIF_DEVICE *hif_device = pDev->HIFDevice;

    ENTER();

    status = HIFConfigureDevice(hif_device,
            HIF_DEVICE_GET_MBOX_ADDR,
            &pDev->MailBoxInfo,
            sizeof(pDev->MailBoxInfo));

    if (status != A_OK) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("(%s)HIF_DEVICE_GET_MBOX_ADDR failed!!!\n", __FUNCTION__));
        A_ASSERT(FALSE);
    }

    status = HIFConfigureDevice(hif_device,
            HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
            blocksizes,
            sizeof(blocksizes));
    if (status != A_OK) {
        AR_DEBUG_PRINTF( ATH_DEBUG_ERR,
                ("(%s)HIF_DEVICE_GET_MBOX_BLOCK_SIZE failed!!!\n", __FUNCTION__));
        A_ASSERT(FALSE);
    }

    pDev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE];
    pDev->BlockMask = pDev->BlockSize - 1;
    A_ASSERT((pDev->BlockSize & pDev->BlockMask) == 0);

    /* assume we can process HIF interrupt events asynchronously */
    pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC;

    /* see if the HIF layer overrides this assumption */
    HIFConfigureDevice(hif_device,
            HIF_DEVICE_GET_IRQ_PROC_MODE,
            &pDev->HifIRQProcessingMode,
            sizeof(pDev->HifIRQProcessingMode));

    switch (pDev->HifIRQProcessingMode) {
    case HIF_DEVICE_IRQ_SYNC_ONLY:
        AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
                ("HIF Interrupt processing is SYNC ONLY\n"));
        /* see if HIF layer wants HTC to yield */
        HIFConfigureDevice(hif_device,
                HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
                &pDev->HifIRQYieldParams,
                sizeof(pDev->HifIRQYieldParams));

        if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) {
            AR_DEBUG_PRINTF( ATH_DEBUG_WARN,
                    ("HIF requests that DSR yield per %d RECV packets \n", pDev->HifIRQYieldParams.RecvPacketYieldCount));
            pDev->DSRCanYield = TRUE;
        }
        break;
    case HIF_DEVICE_IRQ_ASYNC_SYNC:
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
                ("HIF Interrupt processing is ASYNC and SYNC\n"));
        break;
    default:
        A_ASSERT(FALSE);
        break;
    }

    pDev->HifMaskUmaskRecvEvent = NULL;

    /* see if the HIF layer implements the mask/unmask recv events function  */
    HIFConfigureDevice(hif_device,
            HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
            &pDev->HifMaskUmaskRecvEvent,
            sizeof(pDev->HifMaskUmaskRecvEvent));

    status = HIFDevDisableInterrupts(pDev);

    A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS));
    /* the device layer handles these */
    htcCallbacks.rwCompletionHandler = HIFDevRWCompletionHandler;
    htcCallbacks.dsrHandler = HIFDevDsrHandler;
    htcCallbacks.context = pDev;
    status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks);

    EXIT();
    return status;
}

