//------------------------------------------------------------------------------
// Copyright (c) 2004-2010 Atheros Communications Inc.
// All rights reserved.
//
// 
//
// 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.
//
//
//
// Author(s): ="Atheros"
//------------------------------------------------------------------------------

#include "ar6000_drv.h"

#ifdef HTC_RAW_INTERFACE

static void
ar6000_htc_raw_read_cb(void *Context, HTC_PACKET *pPacket)
{
    AR_SOFTC_T        *ar = (AR_SOFTC_T *)Context;
    raw_htc_buffer    *busy;
    HTC_RAW_STREAM_ID streamID; 
    AR_RAW_HTC_T *arRaw = ar->arRawHtc;

    busy = (raw_htc_buffer *)pPacket->pPktContext;
    A_ASSERT(busy != NULL);

    if (pPacket->Status == A_ECANCELED) {
        /*
         * HTC provides A_ECANCELED status when it doesn't want to be refilled
         * (probably due to a shutdown)
         */
        return;
    }

    streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
    A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
    if(streamID == HTC_RAW_STREAM_NOT_MAPPED) {
        return; /* in case panic_on_assert==0 */
    }
    
#ifdef CF
   if (down_trylock(&arRaw->raw_htc_read_sem[streamID])) {
#else
    if (down_interruptible(&arRaw->raw_htc_read_sem[streamID])) {
#endif /* CF */
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
    }

    A_ASSERT((pPacket->Status != A_OK) || 
             (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN)));

    busy->length = pPacket->ActualLength + HTC_HEADER_LEN;
    busy->currPtr = HTC_HEADER_LEN;
    arRaw->read_buffer_available[streamID] = TRUE;
    //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("raw read cb:  0x%X 0x%X \n", busy->currPtr,busy->length);
    up(&arRaw->raw_htc_read_sem[streamID]);

    /* Signal the waiting process */
    AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) read process\n", streamID));
    wake_up_interruptible(&arRaw->raw_htc_read_queue[streamID]);
}

static void
ar6000_htc_raw_write_cb(void *Context, HTC_PACKET *pPacket)
{
    AR_SOFTC_T          *ar = (AR_SOFTC_T  *)Context;
    raw_htc_buffer      *free;
    HTC_RAW_STREAM_ID   streamID;
    AR_RAW_HTC_T *arRaw = ar->arRawHtc;
    
    free = (raw_htc_buffer *)pPacket->pPktContext;
    A_ASSERT(free != NULL);

    if (pPacket->Status == A_ECANCELED) {
        /*
         * HTC provides A_ECANCELED status when it doesn't want to be refilled
         * (probably due to a shutdown)
         */
        return;
    }

    streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
    A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
    if(streamID == HTC_RAW_STREAM_NOT_MAPPED) {
        return; /* in case panic_on_assert==0 */
    }
#ifdef CF
    if (down_trylock(&arRaw->raw_htc_write_sem[streamID])) {
#else
    if (down_interruptible(&arRaw->raw_htc_write_sem[streamID])) {
#endif
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
    }

    A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN));

    free->length = 0;
    arRaw->write_buffer_available[streamID] = TRUE;
    up(&arRaw->raw_htc_write_sem[streamID]);

    /* Signal the waiting process */
    AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) write process\n", streamID));
    wake_up_interruptible(&arRaw->raw_htc_write_queue[streamID]);
}

/* connect to a service */
static A_STATUS ar6000_connect_raw_service(AR_SOFTC_T        *ar,
                                           HTC_RAW_STREAM_ID StreamID)
{
    A_STATUS                 status;
    HTC_SERVICE_CONNECT_RESP response;
    A_UINT8                  streamNo;
    HTC_SERVICE_CONNECT_REQ  connect;
    
    do {      
        
        A_MEMZERO(&connect,sizeof(connect));
            /* pass the stream ID as meta data to the RAW streams service */
        streamNo = (A_UINT8)StreamID;
        connect.pMetaData = &streamNo;
        connect.MetaDataLength = sizeof(A_UINT8);
            /* these fields are the same for all endpoints */
        connect.EpCallbacks.pContext = ar;
        connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb;   
        connect.EpCallbacks.EpRecv = ar6000_htc_raw_read_cb;   
            /* simple interface, we don't need these optional callbacks */      
        connect.EpCallbacks.EpRecvRefill = NULL;
        connect.EpCallbacks.EpSendFull = NULL;
        connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM;  
        
            /* connect to the raw streams service, we may be able to get 1 or more
             * connections, depending on WHAT is running on the target */
        connect.ServiceID = HTC_RAW_STREAMS_SVC;
        
        A_MEMZERO(&response,sizeof(response));
        
            /* try to connect to the raw stream, it is okay if this fails with 
             * status HTC_SERVICE_NO_MORE_EP */
        status = HTCConnectService(ar->arHtcTarget, 
                                   &connect,
                                   &response);
        
        if (A_FAILED(status)) {
            if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC RAW , No more streams allowed \n"));
                status = A_OK;    
            }
            break;    
        }

            /* set endpoint mapping for the RAW HTC streams */
        arSetRawStream2EndpointIDMap(ar,StreamID,response.Endpoint);

        AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("HTC RAW : stream ID: %d, endpoint: %d\n", 
                        StreamID, arRawStream2EndpointID(ar,StreamID)));
        
    } while (FALSE);
    
    return status;
}

int ar6000_htc_raw_open(AR_SOFTC_T *ar)
{
    A_STATUS status;
    int streamID, endPt, count2;
    raw_htc_buffer *buffer;
    HTC_SERVICE_ID servicepriority;
    AR_RAW_HTC_T *arRaw = ar->arRawHtc;
    if (!arRaw) {
        arRaw = ar->arRawHtc = A_MALLOC(sizeof(AR_RAW_HTC_T));
        if (arRaw) {
            A_MEMZERO(arRaw, sizeof(AR_RAW_HTC_T));
        }
    }
    A_ASSERT(ar->arHtcTarget != NULL);
    if (!arRaw) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Faile to allocate memory for HTC RAW interface\n"));
        return -ENOMEM;
    }
    /* wait for target */
    status = HTCWaitTarget(ar->arHtcTarget);

    if (A_FAILED(status)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTCWaitTarget failed (%d)\n", status));
        return -ENODEV;
    }

    for (endPt = 0; endPt < ENDPOINT_MAX; endPt++) {
        arRaw->arEp2RawMapping[endPt] = HTC_RAW_STREAM_NOT_MAPPED;
    }

    for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) {
        /* Initialize the data structures */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
        sema_init(&arRaw->raw_htc_read_sem[streamID], 1);
        sema_init(&arRaw->raw_htc_write_sem[streamID], 1);
#else
        init_MUTEX(&arRaw->raw_htc_read_sem[streamID]);
        init_MUTEX(&arRaw->raw_htc_write_sem[streamID]);
#endif
        init_waitqueue_head(&arRaw->raw_htc_read_queue[streamID]);
        init_waitqueue_head(&arRaw->raw_htc_write_queue[streamID]);

        /* try to connect to the raw service */
        status = ar6000_connect_raw_service(ar,streamID);

        if (A_FAILED(status)) {
            break;
        }

        if (arRawStream2EndpointID(ar,streamID) == 0) {
            break;
        }

        for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) {
            /* Initialize the receive buffers */
            buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
            memset(buffer, 0, sizeof(raw_htc_buffer));
            buffer = &arRaw->raw_htc_read_buffer[streamID][count2];
            memset(buffer, 0, sizeof(raw_htc_buffer));

            SET_HTC_PACKET_INFO_RX_REFILL(&buffer->HTCPacket,
                                          buffer,
                                          buffer->data,
                                          HTC_RAW_BUFFER_SIZE,
                                          arRawStream2EndpointID(ar,streamID));

            /* Queue buffers to HTC for receive */
            if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != A_OK)
            {
                BMIInit();
                return -EIO;
            }
        }

        for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) {
            /* Initialize the receive buffers */
            buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
            memset(buffer, 0, sizeof(raw_htc_buffer));
        }

        arRaw->read_buffer_available[streamID] = FALSE;
        arRaw->write_buffer_available[streamID] = TRUE;
    }

    if (A_FAILED(status)) {
        return -EIO;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("HTC RAW, number of streams the target supports: %d \n", streamID));

    servicepriority = HTC_RAW_STREAMS_SVC;  /* only 1 */

    /* set callbacks and priority list */
    HTCSetCreditDistribution(ar->arHtcTarget,
                             ar,
                             NULL,  /* use default */
                             NULL,  /* use default */
                             &servicepriority,
                             1);

    /* Start the HTC component */
    if ((status = HTCStart(ar->arHtcTarget)) != A_OK) {
        BMIInit();
        return -EIO;
    }

    (ar)->arRawIfInit = TRUE;

    return 0;
}

int ar6000_htc_raw_close(AR_SOFTC_T *ar)
{
    A_PRINTF("ar6000_htc_raw_close called \n");
    HTCStop(ar->arHtcTarget);
    
        /* reset the device */
    ar6000_reset_device(ar->arHifDevice, ar->arTargetType, TRUE, FALSE);
    /* Initialize the BMI component */
    BMIInit();

    return 0;
}

raw_htc_buffer *
get_filled_buffer(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID)
{
    int count;
    raw_htc_buffer *busy;
    AR_RAW_HTC_T *arRaw = ar->arRawHtc;

    /* Check for data */
    for (count = 0; count < RAW_HTC_READ_BUFFERS_NUM; count ++) {
        busy = &arRaw->raw_htc_read_buffer[StreamID][count];
        if (busy->length) {
            break;
        }
    }
    if (busy->length) {
        arRaw->read_buffer_available[StreamID] = TRUE;
    } else {
        arRaw->read_buffer_available[StreamID] = FALSE;
    }

    return busy;
}

ssize_t ar6000_htc_raw_read(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID, 
                            char __user *buffer, size_t length)
{
    int readPtr;
    raw_htc_buffer *busy;
    AR_RAW_HTC_T *arRaw = ar->arRawHtc;

    if (arRawStream2EndpointID(ar,StreamID) == 0) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
        return -EFAULT;    
    }
    
    if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
        return -ERESTARTSYS;
    }

    busy = get_filled_buffer(ar,StreamID);
    while (!arRaw->read_buffer_available[StreamID]) {
        up(&arRaw->raw_htc_read_sem[StreamID]);

        /* Wait for the data */
        AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) read process\n", StreamID));
        if (wait_event_interruptible(arRaw->raw_htc_read_queue[StreamID],
                                     arRaw->read_buffer_available[StreamID]))
        {
            return -EINTR;
        }
        if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
            return -ERESTARTSYS;
        }
        busy = get_filled_buffer(ar,StreamID);
    }

    /* Read the data */
    readPtr = busy->currPtr;
    if (length > busy->length - HTC_HEADER_LEN) {
        length = busy->length - HTC_HEADER_LEN;
    }
    if (copy_to_user(buffer, &busy->data[readPtr], length)) {
        up(&arRaw->raw_htc_read_sem[StreamID]);
        return -EFAULT;
    }

    busy->currPtr += length;
        
    if (busy->currPtr == busy->length)
    {    
        busy->currPtr = 0;
        busy->length = 0;        
        HTC_PACKET_RESET_RX(&busy->HTCPacket);                                          
        //AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("raw read ioctl:  ep for packet:%d \n", busy->HTCPacket.Endpoint));
        HTCAddReceivePkt(ar->arHtcTarget, &busy->HTCPacket);
    }
    arRaw->read_buffer_available[StreamID] = FALSE;
    up(&arRaw->raw_htc_read_sem[StreamID]);

    return length;
}

static raw_htc_buffer *
get_free_buffer(AR_SOFTC_T *ar, HTC_ENDPOINT_ID StreamID)
{
    int count;
    raw_htc_buffer *free;
    AR_RAW_HTC_T *arRaw = ar->arRawHtc;

    free = NULL;
    for (count = 0; count < RAW_HTC_WRITE_BUFFERS_NUM; count ++) {
        free = &arRaw->raw_htc_write_buffer[StreamID][count];
        if (free->length == 0) {
            break;
        }
    }
    if (!free->length) {
        arRaw->write_buffer_available[StreamID] = TRUE;
    } else {
        arRaw->write_buffer_available[StreamID] = FALSE;
    }

    return free;
}

ssize_t ar6000_htc_raw_write(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID,
                     char __user *buffer, size_t length)
{
    int writePtr;
    raw_htc_buffer *free;
    AR_RAW_HTC_T *arRaw = ar->arRawHtc;
    if (arRawStream2EndpointID(ar,StreamID) == 0) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
        return -EFAULT;    
    }
    
    if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
        return -ERESTARTSYS;
    }

    /* Search for a free buffer */
    free = get_free_buffer(ar,StreamID);

    /* Check if there is space to write else wait */
    while (!arRaw->write_buffer_available[StreamID]) {
        up(&arRaw->raw_htc_write_sem[StreamID]);

        /* Wait for buffer to become free */
        AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) write process\n", StreamID));
        if (wait_event_interruptible(arRaw->raw_htc_write_queue[StreamID],
                                     arRaw->write_buffer_available[StreamID]))
        {
            return -EINTR;
        }
        if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
            return -ERESTARTSYS;
        }
        free = get_free_buffer(ar,StreamID);
    }

    /* Send the data */
    writePtr = HTC_HEADER_LEN;
    if (length > (HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN)) {
        length = HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN;
    }

    if (copy_from_user(&free->data[writePtr], buffer, length)) {
        up(&arRaw->raw_htc_read_sem[StreamID]);
        return -EFAULT;
    }

    free->length = length;
        
    SET_HTC_PACKET_INFO_TX(&free->HTCPacket,
                           free,
                           &free->data[writePtr],
                           length,
                           arRawStream2EndpointID(ar,StreamID),
                           AR6K_DATA_PKT_TAG);
    
    HTCSendPkt(ar->arHtcTarget,&free->HTCPacket);
    
    arRaw->write_buffer_available[StreamID] = FALSE;
    up(&arRaw->raw_htc_write_sem[StreamID]);

    return length;
}
#endif /* HTC_RAW_INTERFACE */
