/*
 * Copyright (c) 2004-2010 Atheros Communications Inc.
 * All rights reserved.
 *
 * This file implements the Atheros PS and patch downloaded for HCI UART Transport driver.
 * This file can be used for HCI SDIO transport implementation for AR6002 with HCI_TRANSPORT_SDIO
 * defined.
 *
 *
 * ar3kcpsconfig.c
 *
 *
 *
 * The software source and binaries included in this development package are
 * licensed, not sold. You, or your company, received the package under one
 * or more license agreements. The rights granted to you are specifically
 * listed in these license agreement(s). All other rights remain with Atheros
 * Communications, Inc., its subsidiaries, or the respective owner including
 * those listed on the included copyright notices..  Distribution of any
 * portion of this package must be in strict compliance with the license
 * agreement(s) terms.
 *
 *
 *
 */



#include "ar3kpsconfig.h"
#ifndef HCI_TRANSPORT_SDIO
#include "hci_ath.h"
#include "hci_uart.h"
#endif /* #ifndef HCI_TRANSPORT_SDIO */

#define MAX_FW_PATH_LEN             50
#define MAX_BDADDR_FORMAT_LENGTH    30

/*
 *  Structure used to send HCI packet, hci packet length and device info 
 *  together as parameter to PSThread.
 */
typedef struct {

    PSCmdPacket *HciCmdList;
    A_UINT32  num_packets;
    AR3K_CONFIG_INFO *dev;
}HciCommandListParam;

A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig,
                                           A_UINT8          *pHCICommand,
                                           int              CmdLength,
                                           A_UINT8          **ppEventBuffer,
                                           A_UINT8          **ppBufferToFree);

A_UINT32  Rom_Version;
A_UINT32  Build_Version;
extern A_BOOL BDADDR;

A_STATUS getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code);
A_STATUS ReadVersionInfo(AR3K_CONFIG_INFO *pConfig);
#ifndef HCI_TRANSPORT_SDIO

DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent);
DECLARE_WAIT_QUEUE_HEAD(HciEvent);
A_UCHAR *HciEventpacket;
rwlock_t syncLock;
wait_queue_t Eventwait;

int PSHciWritepacket(struct hci_dev*,A_UCHAR* Data, A_UINT32 len);
extern char *bdaddr;
#endif /* HCI_TRANSPORT_SDIO */

A_STATUS write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type);

int PSSendOps(void *arg);

#ifdef BT_PS_DEBUG
void Hci_log(A_UCHAR * log_string,A_UCHAR *data,A_UINT32 len)
{
    int i;
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s : ",log_string));
    for (i = 0; i < len; i++) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("0x%02x ", data[i]));
    }
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n...................................\n"));
}
#else
#define Hci_log(string,data,len)
#endif /* BT_PS_DEBUG */




A_STATUS AthPSInitialize(AR3K_CONFIG_INFO *hdev)
{
    A_STATUS status = A_OK;
    if(hdev == NULL) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Device handle received\n"));
        return A_ERROR;
    }

#ifndef HCI_TRANSPORT_SDIO
    DECLARE_WAITQUEUE(wait, current);
#endif /* HCI_TRANSPORT_SDIO */
    

#ifdef HCI_TRANSPORT_SDIO
    status = PSSendOps((void*)hdev);
#else
    if(InitPSState(hdev) == -1) {
        return A_ERROR;
    }
    allow_signal(SIGKILL);
    add_wait_queue(&PsCompleteEvent,&wait);
    set_current_state(TASK_INTERRUPTIBLE);
    if(!kernel_thread(PSSendOps,(void*)hdev,CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Kthread Failed\n"));
        remove_wait_queue(&PsCompleteEvent,&wait);
        return A_ERROR;
    }
    wait_event_interruptible(PsCompleteEvent,(PSTagMode == FALSE));
    set_current_state(TASK_RUNNING);
    remove_wait_queue(&PsCompleteEvent,&wait);

#endif /* HCI_TRANSPORT_SDIO */


    return status;
    
}

int PSSendOps(void *arg) 
{
    int i;
    int status = 0;
    PSCmdPacket *HciCmdList; /* List storing the commands */
    const struct firmware* firmware;
    A_UINT32 numCmds;
    A_UINT8 *event;
    A_UINT8 *bufferToFree;
    struct hci_dev *device;
    A_UCHAR *buffer;
    A_UINT32 len;
    A_UINT32 DevType;
    A_UCHAR *PsFileName;
    A_UCHAR *patchFileName;
    A_UCHAR *path = NULL;
    A_UCHAR *config_path = NULL;
    A_UCHAR config_bdaddr[MAX_BDADDR_FORMAT_LENGTH];
    AR3K_CONFIG_INFO *hdev = (AR3K_CONFIG_INFO*)arg;
    struct device *firmwareDev = NULL;
    status = 0;
    HciCmdList = NULL;
#ifdef HCI_TRANSPORT_SDIO
    device = hdev->pBtStackHCIDev; 
    firmwareDev = device->parent;
#else 
    device = hdev;
    firmwareDev = &device->dev;
    AthEnableSyncCommandOp(TRUE);    
#endif /* HCI_TRANSPORT_SDIO */
    /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different.
     */

    path =(A_UCHAR *)A_MALLOC(MAX_FW_PATH_LEN);
    if(path == NULL) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for path\n", MAX_FW_PATH_LEN));
        goto complete;
    }
    config_path = (A_UCHAR *) A_MALLOC(MAX_FW_PATH_LEN);
    if(config_path == NULL) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for config_path\n", MAX_FW_PATH_LEN));
        goto complete;
    }

    if(A_ERROR == getDeviceType(hdev,&DevType)) {
        status = 1;
        goto complete;
    }
    if(A_ERROR == ReadVersionInfo(hdev)) {
        status = 1;
        goto complete;
    }

    patchFileName = PATCH_FILE;
    snprintf(path, MAX_FW_PATH_LEN, "%s/%xcoex/",CONFIG_PATH,Rom_Version);
    if(DevType){
        if(DevType == 0xdeadc0de){
	        PsFileName =  PS_ASIC_FILE;
	    } else{
    		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x  \n",Rom_Version,Build_Version));
                if((Rom_Version == 0x99999999) && (Build_Version == 1)){
                        
    			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n"));
    			patchFileName = NULL;
		}
	        PsFileName =  PS_FPGA_FILE;
	    }
    }
    else{
	    PsFileName =  PS_ASIC_FILE;
    }

    snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,PsFileName);
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,config_path));
    /* Read the PS file to a dynamically allocated buffer */
    if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
        status = 1;
        goto complete;

    }
    if(NULL == firmware || firmware->size == 0) {
        status = 1;
        goto complete;
    }
    buffer = (A_UCHAR *)A_MALLOC(firmware->size);
    if(buffer != NULL) {
    /* Copy the read file to a local Dynamic buffer */
        memcpy(buffer,firmware->data,firmware->size);
        len = firmware->size;
        A_RELEASE_FIRMWARE(firmware);
        /* Parse the PS buffer to a global variable */
        status = AthDoParsePS(buffer,len);
        A_FREE(buffer);
    } else {
        A_RELEASE_FIRMWARE(firmware);
    }


    /* Read the patch file to a dynamically allocated buffer */
	if(patchFileName != NULL)
                snprintf(config_path,
                         MAX_FW_PATH_LEN, "%s%s",path,patchFileName);
	else {
        	status = 0;
	}
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
    if((patchFileName == NULL) || (A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
        /* 
         *  It is not necessary that Patch file be available, continue with PS Operations if.
         *  failed.
         */
        status = 0;

    } else {
        if(NULL == firmware || firmware->size == 0) {
            status = 0;
        } else {
            buffer = (A_UCHAR *)A_MALLOC(firmware->size);
            if(buffer != NULL) {
                /* Copy the read file to a local Dynamic buffer */
                memcpy(buffer,firmware->data,firmware->size);
                len = firmware->size;
                A_RELEASE_FIRMWARE(firmware);
                /* parse and store the Patch file contents to a global variables */
                status = AthDoParsePatch(buffer,len);
                A_FREE(buffer);
            } else {
                A_RELEASE_FIRMWARE(firmware);
            }
        }
    }

    /* Create an HCI command list from the parsed PS and patch information */
    AthCreateCommandList(&HciCmdList,&numCmds);

    /* Form the parameter for PSSendOps() API */
 

    /*
     * First Send the CRC packet, 
     * We have to continue with the PS operations only if the CRC packet has been replied with 
     * a Command complete event with status Error.
     */

    if(SendHCICommandWaitCommandComplete
    (hdev,
    HciCmdList[0].Hcipacket,
    HciCmdList[0].packetLen,
    &event,
    &bufferToFree) == A_OK) {
        if(ReadPSEvent(event) == A_OK) { /* Exit if the status is success */
            if(bufferToFree != NULL) {
                A_FREE(bufferToFree);
                }
	
#ifndef HCI_TRANSPORT_SDIO
			if(bdaddr && bdaddr[0] !='\0') {
				write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
			}
#endif 
               status = 1;
               goto complete;
        }
        if(bufferToFree != NULL) {
               A_FREE(bufferToFree);
        }
    } else {
        status = 0;
        goto complete;
    }
 
    for(i = 1; i <numCmds; i++) {
    
        if(SendHCICommandWaitCommandComplete
        (hdev,
        HciCmdList[i].Hcipacket,
        HciCmdList[i].packetLen,
        &event,
        &bufferToFree) == A_OK) {
            if(ReadPSEvent(event) != A_OK) { /* Exit if the status is success */
                if(bufferToFree != NULL) {
                    A_FREE(bufferToFree);
                    }
                   status = 1;
                    goto complete;
            }
            if(bufferToFree != NULL) {
                   A_FREE(bufferToFree);
            }
        } else {
            status = 0;
            goto complete;
        }
    }
#ifdef HCI_TRANSPORT_SDIO
	if(BDADDR == FALSE)
		if(hdev->bdaddr[0] !=0x00 ||
		   hdev->bdaddr[1] !=0x00 ||
		   hdev->bdaddr[2] !=0x00 ||
		   hdev->bdaddr[3] !=0x00 ||
		   hdev->bdaddr[4] !=0x00 ||
		   hdev->bdaddr[5] !=0x00)
			write_bdaddr(hdev,hdev->bdaddr,BDADDR_TYPE_HEX);

#ifndef HCI_TRANSPORT_SDIO

	if(bdaddr && bdaddr[0] != '\0') {
		write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
	} else
#endif /* HCI_TRANSPORT_SDIO */
    /* Write BDADDR Read from OTP here */



#endif

	{
		 /* Read Contents of BDADDR file if user has not provided any option */
        snprintf(config_path,MAX_FW_PATH_LEN, "%s%s",path,BDADDR_FILE);
    	AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
    	if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
        	AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
        	status = 1;
        	goto complete;
    	}
    	if(NULL == firmware || firmware->size == 0) {
        	status = 1;
        	goto complete;
    	}
        len = (firmware->size > MAX_BDADDR_FORMAT_LENGTH)? MAX_BDADDR_FORMAT_LENGTH: firmware->size;
	memcpy(config_bdaddr, firmware->data,len);
	config_bdaddr[len] = '\0';
	write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING);
       	A_RELEASE_FIRMWARE(firmware);
	}
complete:
#ifndef HCI_TRANSPORT_SDIO
    AthEnableSyncCommandOp(FALSE);    
    PSTagMode = FALSE;
    wake_up_interruptible(&PsCompleteEvent);
#endif /* HCI_TRANSPORT_SDIO */
    if(NULL != HciCmdList) {
        AthFreeCommandList(&HciCmdList,numCmds);
    }
    if(path) {
        A_FREE(path);
    }
    if(config_path) {
        A_FREE(config_path);
    }
    return status;
}
#ifndef HCI_TRANSPORT_SDIO
/*
 *  This API is used to send the HCI command to controller and return
 *  with a HCI Command Complete event.
 *  For HCI SDIO transport, this will be internally defined. 
 */
A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig,
                                           A_UINT8          *pHCICommand,
                                           int              CmdLength,
                                           A_UINT8          **ppEventBuffer,
                                           A_UINT8          **ppBufferToFree)
{
    if(CmdLength == 0) {
        return A_ERROR;
    }
    Hci_log("COM Write -->",pHCICommand,CmdLength);
    PSAcked = FALSE;
    if(PSHciWritepacket(pConfig,pHCICommand,CmdLength) == 0) {
        /* If the controller is not available, return Error */
        return A_ERROR;
    }
    //add_timer(&psCmdTimer);
    wait_event_interruptible(HciEvent,(PSAcked == TRUE));
    if(NULL != HciEventpacket) {
        *ppEventBuffer = HciEventpacket;
        *ppBufferToFree = HciEventpacket;
    } else {
        /* Did not get an event from controller. return error */
        *ppBufferToFree = NULL;
        return A_ERROR;
    }

    return A_OK;
}
#endif /* HCI_TRANSPORT_SDIO */

A_STATUS ReadPSEvent(A_UCHAR* Data){
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" PS Event %x %x %x\n",Data[4],Data[5],Data[3]));
                                
    if(Data[4] == 0xFC && Data[5] == 0x00)
    {
         switch(Data[3]){
             case 0x0B:
                     return A_OK;
                 break;
                 case 0x0C:
                    /* Change Baudrate */
                        return A_OK;    
                 break;  
                 case 0x04:
                     return A_OK;
                 break;  
		case 0x1E:
			Rom_Version = Data[9];
			Rom_Version = ((Rom_Version << 8) |Data[8]);
			Rom_Version = ((Rom_Version << 8) |Data[7]);
			Rom_Version = ((Rom_Version << 8) |Data[6]);

			Build_Version = Data[13];
			Build_Version = ((Build_Version << 8) |Data[12]);
			Build_Version = ((Build_Version << 8) |Data[11]);
			Build_Version = ((Build_Version << 8) |Data[10]);
			return A_OK;
		break;

        
                }
    }                       
        
    return A_ERROR;           
}
int str2ba(unsigned char *str_bdaddr,unsigned char *bdaddr)
{
	unsigned char bdbyte[3];
	unsigned char *str_byte = str_bdaddr;
	int i,j;
	unsigned char colon_present = 0;

	if(NULL != strstr(str_bdaddr,":")) {
		colon_present = 1;
	}


	bdbyte[2] = '\0';

	for( i = 0,j = 5; i < 6; i++, j--) {
		bdbyte[0] = str_byte[0];
		bdbyte[1] = str_byte[1];
		bdaddr[j] = A_STRTOL(bdbyte,NULL,16);
		if(colon_present == 1) {
			str_byte+=3;
		} else {
			str_byte+=2;
		}
	}
	return 0; 
}

A_STATUS write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type)
{
	A_UCHAR bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01, 
							0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

    A_UINT8 *event;
    A_UINT8 *bufferToFree = NULL;
    A_STATUS result = A_ERROR;
	int inc,outc;

	if (type == BDADDR_TYPE_STRING)
		str2ba(bdaddr,&bdaddr_cmd[7]);
	else {
		/* Bdaddr has to be sent as LAP first */
		for(inc = 5 ,outc = 7; inc >=0; inc--, outc++)
			bdaddr_cmd[outc] = bdaddr[inc];
	}

    if(A_OK == SendHCICommandWaitCommandComplete(pConfig,bdaddr_cmd,
												sizeof(bdaddr_cmd),
												&event,&bufferToFree)) {

        if(event[4] == 0xFC && event[5] == 0x00){
               if(event[3] == 0x0B){
                result = A_OK;
            }
        }

    }
    if(bufferToFree != NULL) {
        A_FREE(bufferToFree);
   }
    return result;

}
A_STATUS ReadVersionInfo(AR3K_CONFIG_INFO *pConfig)
{
    A_UINT8   hciCommand[] =  {0x1E,0xfc,0x00};
    A_UINT8 *event;
    A_UINT8 *bufferToFree = NULL;
    A_STATUS result = A_ERROR;
    if(A_OK == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
	result = ReadPSEvent(event);

    }
    if(bufferToFree != NULL) {
        A_FREE(bufferToFree);
   }
    return result;
}
A_STATUS getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code)
{
    A_UINT8   hciCommand[] =  {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04};
    A_UINT8 *event;
    A_UINT8 *bufferToFree = NULL;
    A_UINT32 reg;
    A_STATUS result = A_ERROR;
    *code = 0;
    hciCommand[3] = (A_UINT8)(FPGA_REGISTER & 0xFF);
    hciCommand[4] = (A_UINT8)((FPGA_REGISTER >> 8) & 0xFF);
    hciCommand[5] = (A_UINT8)((FPGA_REGISTER >> 16) & 0xFF);
    hciCommand[6] = (A_UINT8)((FPGA_REGISTER >> 24) & 0xFF); 
    if(A_OK == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {

        if(event[4] == 0xFC && event[5] == 0x00){
               switch(event[3]){
                case 0x05:
                reg = event[9];
                reg = ((reg << 8) |event[8]);
                reg = ((reg << 8) |event[7]);
                reg = ((reg << 8) |event[6]);
                *code = reg;
                result = A_OK;

                break;
                case 0x06:
                    //Sleep(500);
                break;
            }
        }

    }
    if(bufferToFree != NULL) {
        A_FREE(bufferToFree);
   }
    return result;
}


