C++程序  |  2848行  |  95.27 KB

/*
 * Copyright (C) 2012-2014 NXP Semiconductors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sys/stat.h>
#include <phNxpNciHal.h>
#include <phNxpNciHal_ext.h>
#include <phNxpNciHal_Dnld.h>
#include <phNxpNciHal_Adaptation.h>
#include <phTmlNfc.h>
#include <phDnldNfc.h>
#include <phDal4Nfc_messageQueueLib.h>
#include <phNxpLog.h>
#include <phNxpConfig.h>
#include <phNxpNciHal_NfcDepSWPrio.h>
#include <phNxpNciHal_Kovio.h>
/*********************** Global Variables *************************************/
#define PN547C2_CLOCK_SETTING
#undef  PN547C2_FACTORY_RESET_DEBUG
#define CORE_RES_STATUS_BYTE 3

/* Processing of ISO 15693 EOF */
extern uint8_t icode_send_eof;
extern uint8_t icode_detected;
static uint8_t cmd_icode_eof[] = { 0x00, 0x00, 0x00 };

/* FW download success flag */
static uint8_t fw_download_success = 0;

static uint8_t config_access = FALSE;
/* NCI HAL Control structure */
phNxpNciHal_Control_t nxpncihal_ctrl;

/* NXP Poll Profile structure */
phNxpNciProfile_Control_t nxpprofile_ctrl;

/* TML Context */
extern phTmlNfc_Context_t *gpphTmlNfc_Context;
extern void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result);
/* global variable to get FW version from NCI response*/
uint32_t wFwVerRsp;
/* External global variable to get FW version */
extern uint16_t wFwVer;

extern uint16_t fw_maj_ver;
extern uint16_t rom_version;
extern int send_to_upper_kovio;
extern int kovio_detected;
extern int disable_kovio;
#if(NFC_NXP_CHIP_TYPE != PN547C2)
extern uint8_t gRecFWDwnld;
static uint8_t gRecFwRetryCount; //variable to hold dummy FW recovery count
#endif
static uint8_t Rx_data[NCI_MAX_DATA_LEN];

#if(NFC_NXP_CHIP_TYPE == PN548C2)
uint8_t discovery_cmd[50] = { 0 };
uint8_t discovery_cmd_len = 0;
#endif
extern bool_t rf_deactive_cmd;
uint32_t timeoutTimerId = 0;
phNxpNciHal_Sem_t config_data;

phNxpNciClock_t phNxpNciClock={0, {0}, FALSE};

phNxpNciRfSetting_t phNxpNciRfSet={FALSE, {0} };

phNxpNciMwEepromArea_t phNxpNciMwEepromArea = {FALSE, {0} };

/**************** local methods used in this file only ************************/
static NFCSTATUS phNxpNciHal_fw_download(void);
static void phNxpNciHal_open_complete(NFCSTATUS status);
static void phNxpNciHal_write_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
static void phNxpNciHal_read_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
static void phNxpNciHal_close_complete(NFCSTATUS status);
static void phNxpNciHal_core_initialized_complete(NFCSTATUS status);
static void phNxpNciHal_pre_discover_complete(NFCSTATUS status);
static void phNxpNciHal_power_cycle_complete(NFCSTATUS status);
static void phNxpNciHal_kill_client_thread(phNxpNciHal_Control_t *p_nxpncihal_ctrl);
static void *phNxpNciHal_client_thread(void *arg);
static void phNxpNciHal_get_clk_freq(void);
static void phNxpNciHal_set_clock(void);
static void phNxpNciHal_check_factory_reset(void);
static void phNxpNciHal_print_res_status( uint8_t *p_rx_data, uint16_t *p_len);
static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void);
static void phNxpNciHal_enable_i2c_fragmentation();
static NFCSTATUS phNxpNciHal_get_mw_eeprom (void);
static NFCSTATUS phNxpNciHal_set_mw_eeprom (void);
static int phNxpNciHal_fw_mw_ver_check ();
NFCSTATUS phNxpNciHal_check_clock_config(void);
NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void);
#if(NFC_NXP_CHIP_TYPE != PN547C2)
static NFCSTATUS phNxpNciHalRFConfigCmdRecSequence ();
static NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus ();
#endif
int  check_config_parameter();

/******************************************************************************
 * Function         phNxpNciHal_client_thread
 *
 * Description      This function is a thread handler which handles all TML and
 *                  NCI messages.
 *
 * Returns          void
 *
 ******************************************************************************/
static void *phNxpNciHal_client_thread(void *arg)
{
    phNxpNciHal_Control_t *p_nxpncihal_ctrl = (phNxpNciHal_Control_t *) arg;
    phLibNfc_Message_t msg;

    NXPLOG_NCIHAL_D("thread started");

    p_nxpncihal_ctrl->thread_running = 1;

    while (p_nxpncihal_ctrl->thread_running == 1)
    {
        /* Fetch next message from the NFC stack message queue */
        if (phDal4Nfc_msgrcv(p_nxpncihal_ctrl->gDrvCfg.nClientId,
                &msg, 0, 0) == -1)
        {
            NXPLOG_NCIHAL_E("NFC client received bad message");
            continue;
        }

        if(p_nxpncihal_ctrl->thread_running == 0){
            break;
        }

        switch (msg.eMsgType)
        {
            case PH_LIBNFC_DEFERREDCALL_MSG:
            {
                phLibNfc_DeferredCall_t *deferCall =
                        (phLibNfc_DeferredCall_t *) (msg.pMsgData);

                REENTRANCE_LOCK();
                deferCall->pCallback(deferCall->pParameter);
                REENTRANCE_UNLOCK();

            break;
        }

        case NCI_HAL_OPEN_CPLT_MSG:
        {
            REENTRANCE_LOCK();
            if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
            {
                /* Send the event */
                (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT,
                        HAL_NFC_STATUS_OK);
            }
            REENTRANCE_UNLOCK();
            break;
        }

        case NCI_HAL_CLOSE_CPLT_MSG:
        {
            REENTRANCE_LOCK();
            if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
            {
                /* Send the event */
                (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_CLOSE_CPLT_EVT,
                        HAL_NFC_STATUS_OK);
                phNxpNciHal_kill_client_thread(&nxpncihal_ctrl);
            }
            REENTRANCE_UNLOCK();
            break;
        }

        case NCI_HAL_POST_INIT_CPLT_MSG:
        {
            REENTRANCE_LOCK();
            if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
            {
                /* Send the event */
                (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_POST_INIT_CPLT_EVT,
                        HAL_NFC_STATUS_OK);
            }
            REENTRANCE_UNLOCK();
            break;
        }

        case NCI_HAL_PRE_DISCOVER_CPLT_MSG:
        {
            REENTRANCE_LOCK();
            if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
            {
                /* Send the event */
                (*nxpncihal_ctrl.p_nfc_stack_cback)(
                        HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_OK);
            }
            REENTRANCE_UNLOCK();
            break;
        }

        case NCI_HAL_ERROR_MSG:
        {
            REENTRANCE_LOCK();
            if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
            {
                /* Send the event */
                (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ERROR_EVT,
                        HAL_NFC_STATUS_FAILED);
            }
            REENTRANCE_UNLOCK();
            break;
        }

        case NCI_HAL_RX_MSG:
        {
            REENTRANCE_LOCK();
            if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL)
            {
                (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
                        nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
            }
            REENTRANCE_UNLOCK();
            break;
        }
        }
    }

    NXPLOG_NCIHAL_D("NxpNciHal thread stopped");

    return NULL;
}

/******************************************************************************
 * Function         phNxpNciHal_kill_client_thread
 *
 * Description      This function safely kill the client thread and clean all
 *                  resources.
 *
 * Returns          void.
 *
 ******************************************************************************/
static void phNxpNciHal_kill_client_thread(phNxpNciHal_Control_t *p_nxpncihal_ctrl)
{
    NXPLOG_NCIHAL_D("Terminating phNxpNciHal client thread...");

    p_nxpncihal_ctrl->p_nfc_stack_cback = NULL;
    p_nxpncihal_ctrl->p_nfc_stack_data_cback = NULL;
    p_nxpncihal_ctrl->thread_running = 0;

    return;
}

/******************************************************************************
 * Function         phNxpNciHal_fw_download
 *
 * Description      This function download the PN54X secure firmware to IC. If
 *                  firmware version in Android filesystem and firmware in the
 *                  IC is same then firmware download will return with success
 *                  without downloading the firmware.
 *
 * Returns          NFCSTATUS_SUCCESS if firmware download successful
 *                  NFCSTATUS_FAILED in case of failure
 *
 ******************************************************************************/
static NFCSTATUS phNxpNciHal_fw_download(void)
{
    NFCSTATUS status = NFCSTATUS_FAILED;

    phNxpNciHal_get_clk_freq();
    status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
    if (NFCSTATUS_SUCCESS == status)
    {
        /* Set the obtained device handle to download module */
        phDnldNfc_SetHwDevHandle();
        NXPLOG_NCIHAL_D("Calling Seq handler for FW Download \n");
        status = phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal, nxpprofile_ctrl.bClkFreqVal);
        phDnldNfc_ReSetHwDevHandle();
    }
    else
    {
        status = NFCSTATUS_FAILED;
    }

    return status;
}

/******************************************************************************
 * Function         phNxpNciHal_CheckValidFwVersion
 *
 * Description      This function checks the valid FW for Mobile device.
 *                  If the FW doesn't belong the Mobile device it further
 *                  checks nxp config file to override.
 *
 * Returns          NFCSTATUS_SUCCESS if valid fw version found
 *                  NFCSTATUS_NOT_ALLOWED in case of FW not valid for mobile
 *                  device
 *
 ******************************************************************************/
static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void)
{
    NFCSTATUS status = NFCSTATUS_NOT_ALLOWED;
#if(NFC_NXP_CHIP_TYPE == PN551)
    const unsigned char sfw_mobile_major_no = 0x05;
#else
    const unsigned char sfw_mobile_major_no = 0x01;
#endif
    const unsigned char sfw_infra_major_no = 0x02;
    unsigned char ufw_current_major_no = 0x00;
    unsigned long num = 0;
    int isfound = 0;

    /* extract the firmware's major no */
    ufw_current_major_no = ((0x00FF) & (wFwVer >> 8U));

    NXPLOG_NCIHAL_D("%s current_major_no = 0x%x", __FUNCTION__,ufw_current_major_no );
    if ( ufw_current_major_no == sfw_mobile_major_no)
    {
        status = NFCSTATUS_SUCCESS;
    }
    else if (ufw_current_major_no == sfw_infra_major_no)
    {
        /* Check the nxp config file if still want to go for download */
        /* By default NAME_NXP_FW_PROTECION_OVERRIDE will not be defined in config file.
           If user really want to override the Infra firmware over mobile firmware, please
           put "NXP_FW_PROTECION_OVERRIDE=0x01" in libnfc-nxp.conf file.
           Please note once Infra firmware downloaded to Mobile device, The device
           can never be updated to Mobile firmware*/
        isfound = GetNxpNumValue(NAME_NXP_FW_PROTECION_OVERRIDE, &num, sizeof(num));
        if (isfound > 0)
        {
            if (num == 0x01)
            {
                NXPLOG_NCIHAL_D("Override Infra FW over Mobile");
                status = NFCSTATUS_SUCCESS;
            }
            else
            {
                NXPLOG_NCIHAL_D("Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE invalid value)");
            }
        }
        else
        {
            NXPLOG_NCIHAL_D("Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE not defiend)");
        }
    }
#if(NFC_NXP_CHIP_TYPE != PN547C2)
    else if (gRecFWDwnld == TRUE)
    {
        status = NFCSTATUS_SUCCESS;
    }
#endif
    else if (wFwVerRsp == 0)
    {
        NXPLOG_NCIHAL_E("FW Version not received by NCI command >>> Force Firmware download");
        status = NFCSTATUS_SUCCESS;
    }
    else
    {
        NXPLOG_NCIHAL_E("Wrong FW Version >>> Firmware download not allowed");
    }

    return status;
}

static void phNxpNciHal_get_clk_freq(void)
{
    unsigned long num = 0;
    int isfound = 0;

    nxpprofile_ctrl.bClkSrcVal = 0;
    nxpprofile_ctrl.bClkFreqVal = 0;
    nxpprofile_ctrl.bTimeout = 0;

    isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &num, sizeof(num));
    if (isfound > 0)
    {
        nxpprofile_ctrl.bClkSrcVal = num;
    }

    num = 0;
    isfound = 0;
    isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &num, sizeof(num));
    if (isfound > 0)
    {
        nxpprofile_ctrl.bClkFreqVal = num;
    }

    num = 0;
    isfound = 0;
    isfound = GetNxpNumValue(NAME_NXP_SYS_CLOCK_TO_CFG, &num, sizeof(num));
    if (isfound > 0)
    {
        nxpprofile_ctrl.bTimeout = num;
    }

    NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkSrcVal = 0x%x", nxpprofile_ctrl.bClkSrcVal);
    NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x", nxpprofile_ctrl.bClkFreqVal);
    NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x", nxpprofile_ctrl.bTimeout);

    if ((nxpprofile_ctrl.bClkSrcVal < CLK_SRC_XTAL) ||
            (nxpprofile_ctrl.bClkSrcVal > CLK_SRC_PLL))
    {
        NXPLOG_FWDNLD_E("Clock source value is wrong in config file, setting it as default");
        nxpprofile_ctrl.bClkSrcVal = NXP_SYS_CLK_SRC_SEL;
    }
    if ((nxpprofile_ctrl.bClkFreqVal < CLK_FREQ_13MHZ) ||
            (nxpprofile_ctrl.bClkFreqVal > CLK_FREQ_52MHZ))
    {
        NXPLOG_FWDNLD_E("Clock frequency value is wrong in config file, setting it as default");
        nxpprofile_ctrl.bClkFreqVal = NXP_SYS_CLK_FREQ_SEL;
    }
    if ((nxpprofile_ctrl.bTimeout < CLK_TO_CFG_DEF) || (nxpprofile_ctrl.bTimeout > CLK_TO_CFG_MAX))
    {
        NXPLOG_FWDNLD_E("Clock timeout value is wrong in config file, setting it as default");
        nxpprofile_ctrl.bTimeout = CLK_TO_CFG_DEF;
    }

}

/******************************************************************************
 * Function         phNxpNciHal_open
 *
 * Description      This function is called by libnfc-nci during the
 *                  initialization of the NFCC. It opens the physical connection
 *                  with NFCC (PN54X) and creates required client thread for
 *                  operation.
 *                  After open is complete, status is informed to libnfc-nci
 *                  through callback function.
 *
 * Returns          This function return NFCSTATUS_SUCCES (0) in case of success
 *                  In case of failure returns other failure value.
 *
 ******************************************************************************/
int phNxpNciHal_open(nfc_stack_callback_t *p_cback, nfc_stack_data_callback_t *p_data_cback)
{
    phOsalNfc_Config_t tOsalConfig;
    phTmlNfc_Config_t tTmlConfig;
    char *nfc_dev_node = NULL;
    const uint16_t max_len = 260;
    NFCSTATUS wConfigStatus = NFCSTATUS_SUCCESS;
    NFCSTATUS status = NFCSTATUS_SUCCESS;
    /*NCI_INIT_CMD*/
    static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
    /*NCI_RESET_CMD*/
    static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
    /* reset config cache */
    resetNxpConfig();

    int init_retry_cnt= 0;
    int8_t ret_val = 0x00;

    /* initialize trace level */
    phNxpLog_InitializeLogLevel();

    /*Create the timer for extns write response*/
    timeoutTimerId = phOsalNfc_Timer_Create();

    if (phNxpNciHal_init_monitor() == NULL)
    {
        NXPLOG_NCIHAL_E("Init monitor failed");
        return NFCSTATUS_FAILED;
    }

    CONCURRENCY_LOCK();

    memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
    memset(&tOsalConfig, 0x00, sizeof(tOsalConfig));
    memset(&tTmlConfig, 0x00, sizeof(tTmlConfig));
    memset (&nxpprofile_ctrl, 0, sizeof(phNxpNciProfile_Control_t));

    /* By default HAL status is HAL_STATUS_OPEN */
    nxpncihal_ctrl.halStatus = HAL_STATUS_OPEN;

    nxpncihal_ctrl.p_nfc_stack_cback = p_cback;
    nxpncihal_ctrl.p_nfc_stack_data_cback = p_data_cback;

    /* Read the nfc device node name */
    nfc_dev_node = (char*) malloc (max_len * sizeof (char *));
    if (nfc_dev_node == NULL)
    {
        NXPLOG_NCIHAL_E ("malloc of nfc_dev_node failed ");
        goto clean_and_return;
    }
    else if (!GetNxpStrValue (NAME_NXP_NFC_DEV_NODE, nfc_dev_node, sizeof (nfc_dev_node)))
    {
        NXPLOG_NCIHAL_E ("Invalid nfc device node name keeping the default device node /dev/pn54x");
        strcpy (nfc_dev_node, "/dev/pn54x");
    }

    /* Configure hardware link */
    nxpncihal_ctrl.gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
    nxpncihal_ctrl.gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C;/* For PN54X */
    tTmlConfig.pDevName = (int8_t *) nfc_dev_node;
    tOsalConfig.dwCallbackThreadId
    = (uintptr_t) nxpncihal_ctrl.gDrvCfg.nClientId;
    tOsalConfig.pLogFile = NULL;
    tTmlConfig.dwGetMsgThreadId = (uintptr_t) nxpncihal_ctrl.gDrvCfg.nClientId;

#if(NFC_NXP_CHIP_TYPE == PN548C2)
    memset (discovery_cmd, 0, sizeof(discovery_cmd));
    discovery_cmd_len = 0;
#endif

    /* Initialize TML layer */
    wConfigStatus = phTmlNfc_Init(&tTmlConfig);
    if (wConfigStatus != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
        goto clean_and_return;
    }
    else
    {
        if (nfc_dev_node != NULL)
        {
            free (nfc_dev_node);
            nfc_dev_node = NULL;
        }
    }

    /* Create the client thread */
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    ret_val = pthread_create (&nxpncihal_ctrl.client_thread, &attr,
            phNxpNciHal_client_thread, &nxpncihal_ctrl);
    pthread_attr_destroy (&attr);
    if (ret_val != 0)
    {
        NXPLOG_NCIHAL_E ("pthread_create failed");
        wConfigStatus = phTmlNfc_Shutdown ();
        goto clean_and_return;
    }

    CONCURRENCY_UNLOCK();

    /* call read pending */
    status = phTmlNfc_Read(
            nxpncihal_ctrl.p_cmd_data,
            NCI_MAX_DATA_LEN,
            (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
            NULL);
    if (status != NFCSTATUS_PENDING)
    {
        NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
        wConfigStatus = phTmlNfc_Shutdown();
        wConfigStatus = NFCSTATUS_FAILED;
        goto clean_and_return;
    }

init_retry:

    phNxpNciHal_ext_init();

    status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
    if((status != NFCSTATUS_SUCCESS) && (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT))
    {
        NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
        wConfigStatus = NFCSTATUS_FAILED;
        goto force_download;
    }
    else if(status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
        if(init_retry_cnt < 3) {
            init_retry_cnt++;
            (void)phNxpNciHal_power_cycle();
            goto init_retry;
        } else
            init_retry_cnt = 0;
        wConfigStatus = phTmlNfc_Shutdown();
        wConfigStatus = NFCSTATUS_FAILED;
        goto clean_and_return;
    }

    status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci),cmd_init_nci);
    if(status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_E ("NCI_CORE_INIT : Failed");
        if(init_retry_cnt < 3) {
            init_retry_cnt++;
            (void)phNxpNciHal_power_cycle();
            goto init_retry;
        } else
            init_retry_cnt = 0;
        wConfigStatus = phTmlNfc_Shutdown();
        wConfigStatus = NFCSTATUS_FAILED;
        goto clean_and_return;
    }
    phNxpNciHal_enable_i2c_fragmentation();
    /*Get FW version from device*/
    status = phDnldNfc_InitImgInfo();
    NXPLOG_NCIHAL_D ("FW version for FW file = 0x%x", wFwVer);
    NXPLOG_NCIHAL_D ("FW version from device = 0x%x", wFwVerRsp);
    if ((wFwVerRsp & 0x0000FFFF) == wFwVer)
    {
        NXPLOG_NCIHAL_D ("FW uptodate not required");
        phDnldNfc_ReSetHwDevHandle();
    }
    else
    {
force_download:
        if (wFwVerRsp == 0)
        {
            phDnldNfc_InitImgInfo();
        }
        if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion())
        {
            NXPLOG_NCIHAL_D ("FW update required");
            fw_download_success = 0;
            status = phNxpNciHal_fw_download();
            if (status != NFCSTATUS_SUCCESS)
            {
                if (NFCSTATUS_SUCCESS != phNxpNciHal_fw_mw_ver_check ())
                {
                    NXPLOG_NCIHAL_D ("Chip Version Middleware Version mismatch!!!!");
                    /* Abort any pending read and write */
                    phNxpNciHal_send_ext_cmd (sizeof (cmd_reset_nci), cmd_reset_nci);
                    phTmlNfc_ReadAbort ();
                    phTmlNfc_WriteAbort ();
                    phTmlNfc_Shutdown ();
                    wConfigStatus = NFCSTATUS_FAILED;
                    goto clean_and_return;
                }
                NXPLOG_NCIHAL_E ("FW Download failed - NFCC init will continue");
            }
            else
            {
                wConfigStatus = NFCSTATUS_SUCCESS;
                fw_download_success = 1;
                /* call read pending */
                status = phTmlNfc_Read(
                nxpncihal_ctrl.p_cmd_data,
                NCI_MAX_DATA_LEN,
                   (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
                        NULL);
                if (status != NFCSTATUS_PENDING)
                {
                    NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
                    wConfigStatus = phTmlNfc_Shutdown();
                    wConfigStatus = NFCSTATUS_FAILED;
                    goto clean_and_return;
                }
            }
        }
        else
        {
            if (wFwVerRsp == 0)
               phDnldNfc_ReSetHwDevHandle();
        }
    }
    /* Call open complete */
    phNxpNciHal_open_complete(wConfigStatus);

    return wConfigStatus;

    clean_and_return:
    CONCURRENCY_UNLOCK();
    if (nfc_dev_node != NULL)
    {
        free (nfc_dev_node);
        nfc_dev_node = NULL;
    }
    /* Report error status */
    (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT,
            HAL_NFC_STATUS_FAILED);

    nxpncihal_ctrl.p_nfc_stack_cback = NULL;
    nxpncihal_ctrl.p_nfc_stack_data_cback = NULL;
    phNxpNciHal_cleanup_monitor();
    nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
    return NFCSTATUS_FAILED;
}

/******************************************************************************
 * Function         phNxpNciHal_fw_mw_check
 *
 * Description      This function inform the status of phNxpNciHal_fw_mw_check
 *                  function to libnfc-nci.
 *
 * Returns          int.
 *
 ******************************************************************************/
int phNxpNciHal_fw_mw_ver_check()
{
    NFCSTATUS status = NFCSTATUS_FAILED;
    if(!strcmp (COMPILATION_MW, "PN551") && (rom_version == 0x10) && (fw_maj_ver == 0x05))
    {
        status = NFCSTATUS_SUCCESS;
    }
    else if (!strcmp (COMPILATION_MW, "PN548C2") && (rom_version == 0x10) && (fw_maj_ver == 0x01))
    {
        status = NFCSTATUS_SUCCESS;
    }
    else if (!strcmp (COMPILATION_MW, "PN547C2") && (rom_version == 0x08) && (fw_maj_ver == 0x01))
    {
        status = NFCSTATUS_SUCCESS;
    }
    return status;
}
/******************************************************************************
 * Function         phNxpNciHal_open_complete
 *
 * Description      This function inform the status of phNxpNciHal_open
 *                  function to libnfc-nci.
 *
 * Returns          void.
 *
 ******************************************************************************/
static void phNxpNciHal_open_complete(NFCSTATUS status)
{
    static phLibNfc_Message_t msg;

    if (status == NFCSTATUS_SUCCESS)
    {
        msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
        nxpncihal_ctrl.hal_open_status = TRUE;
    }
    else
    {
        msg.eMsgType = NCI_HAL_ERROR_MSG;
    }

    msg.pMsgData = NULL;
    msg.Size = 0;

    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
            (phLibNfc_Message_t *) &msg);

    return;
}

/******************************************************************************
 * Function         phNxpNciHal_write
 *
 * Description      This function write the data to NFCC through physical
 *                  interface (e.g. I2C) using the PN54X driver interface.
 *                  Before sending the data to NFCC, phNxpNciHal_write_ext
 *                  is called to check if there is any extension processing
 *                  is required for the NCI packet being sent out.
 *
 * Returns          It returns number of bytes successfully written to NFCC.
 *
 ******************************************************************************/
int phNxpNciHal_write(uint16_t data_len, const uint8_t *p_data)
{
    NFCSTATUS status = NFCSTATUS_FAILED;
    static phLibNfc_Message_t msg;

    /* Create local copy of cmd_data */
    memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
    nxpncihal_ctrl.cmd_len = data_len;
    if (nxpncihal_ctrl.cmd_len > NCI_MAX_DATA_LEN)
    {
        NXPLOG_NCIHAL_D ("cmd_len exceeds limit NCI_MAX_DATA_LEN");
        goto clean_and_return;
    }
#ifdef P2P_PRIO_LOGIC_HAL_IMP
    /* Specific logic to block RF disable when P2P priority logic is busy */
    if (p_data[0] == 0x21&&
        p_data[1] == 0x06 &&
        p_data[2] == 0x01 &&
        EnableP2P_PrioLogic == TRUE)
    {
        NXPLOG_NCIHAL_D ("P2P priority logic busy: Disable it.");
        phNxpNciHal_clean_P2P_Prio();
    }
#endif
    /* Specific logic to block RF disable when Kovio detection logic is active */
    if (p_data[0] == 0x21&&
        p_data[1] == 0x06 &&
        p_data[2] == 0x01)
    {
        rf_deactive_cmd = TRUE;
        if (kovio_detected == TRUE)
        {
            NXPLOG_NCIHAL_D ("Kovio detection logic is active: Set Flag to disable it.");
            disable_kovio = 0x01;
        }
    }

    /* Check for NXP ext before sending write */
    status = phNxpNciHal_write_ext(&nxpncihal_ctrl.cmd_len,
            nxpncihal_ctrl.p_cmd_data, &nxpncihal_ctrl.rsp_len,
            nxpncihal_ctrl.p_rsp_data);
    if (status != NFCSTATUS_SUCCESS)
    {
        /* Do not send packet to PN54X, send response directly */
        msg.eMsgType = NCI_HAL_RX_MSG;
        msg.pMsgData = NULL;
        msg.Size = 0;

        phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
                (phLibNfc_Message_t *) &msg);
        goto clean_and_return;
    }

    CONCURRENCY_LOCK();
    data_len = phNxpNciHal_write_unlocked(nxpncihal_ctrl.cmd_len,
            nxpncihal_ctrl.p_cmd_data);
    CONCURRENCY_UNLOCK();

    if (icode_send_eof == 1)
    {
        usleep (10000);
        icode_send_eof = 2;
        phNxpNciHal_send_ext_cmd (3, cmd_icode_eof);
    }

    clean_and_return:
    /* No data written */
    return data_len;
}

/******************************************************************************
 * Function         phNxpNciHal_write_unlocked
 *
 * Description      This is the actual function which is being called by
 *                  phNxpNciHal_write. This function writes the data to NFCC.
 *                  It waits till write callback provide the result of write
 *                  process.
 *
 * Returns          It returns number of bytes successfully written to NFCC.
 *
 ******************************************************************************/
int phNxpNciHal_write_unlocked(uint16_t data_len, const uint8_t *p_data)
{
    NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER;
    phNxpNciHal_Sem_t cb_data;
    nxpncihal_ctrl.retry_cnt = 0;
    static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00, 0xC7, 0xD4, 0x00, 0x00};

    /* Create the local semaphore */
    if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked Create cb data failed");
        data_len = 0;
        goto clean_and_return;
    }

    /* Create local copy of cmd_data */
    memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
    nxpncihal_ctrl.cmd_len = data_len;

    retry:

    data_len = nxpncihal_ctrl.cmd_len;

    status = phTmlNfc_Write( (uint8_t *) nxpncihal_ctrl.p_cmd_data,
            (uint16_t) nxpncihal_ctrl.cmd_len,
            (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_write_complete,
            (void *) &cb_data);
    if (status != NFCSTATUS_PENDING)
    {
        NXPLOG_NCIHAL_E("write_unlocked status error");
        data_len = 0;
        goto clean_and_return;
    }

    /* Wait for callback response */
    if (SEM_WAIT(cb_data))
    {
        NXPLOG_NCIHAL_E("write_unlocked semaphore error");
        data_len = 0;
        goto clean_and_return;
    }

    if (cb_data.status != NFCSTATUS_SUCCESS)
    {
        data_len = 0;
        if(nxpncihal_ctrl.retry_cnt++ < MAX_RETRY_COUNT)
        {
            NXPLOG_NCIHAL_E("write_unlocked failed - PN54X Maybe in Standby Mode - Retry");
            /* 1ms delay to give NFCC wake up delay */
            usleep(1000);
            goto retry;
        }
        else
        {

            NXPLOG_NCIHAL_E("write_unlocked failed - PN54X Maybe in Standby Mode (max count = 0x%x)", nxpncihal_ctrl.retry_cnt);

            status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);

            if(NFCSTATUS_SUCCESS == status)
            {
                NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
            }
            else
            {
                NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
            }
            if (nxpncihal_ctrl.p_nfc_stack_data_cback!= NULL &&
                nxpncihal_ctrl.p_rx_data!= NULL &&
                nxpncihal_ctrl.hal_open_status == TRUE)
            {
                NXPLOG_NCIHAL_D("Send the Core Reset NTF to upper layer, which will trigger the recovery\n");
                //Send the Core Reset NTF to upper layer, which will trigger the recovery.
                nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf);
                memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf));
                (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
            }
        }
    }

    clean_and_return:
    phNxpNciHal_cleanup_cb_data(&cb_data);
    return data_len;
}

/******************************************************************************
 * Function         phNxpNciHal_write_complete
 *
 * Description      This function handles write callback.
 *
 * Returns          void.
 *
 ******************************************************************************/
static void phNxpNciHal_write_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
{
    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;

    if (pInfo->wStatus == NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus);
    }
    else
    {
        NXPLOG_NCIHAL_E("write error status = 0x%x", pInfo->wStatus);
    }

    p_cb_data->status = pInfo->wStatus;

    SEM_POST(p_cb_data);

    return;
}

/******************************************************************************
 * Function         phNxpNciHal_read_complete
 *
 * Description      This function is called whenever there is an NCI packet
 *                  received from NFCC. It could be RSP or NTF packet. This
 *                  function provide the received NCI packet to libnfc-nci
 *                  using data callback of libnfc-nci.
 *                  There is a pending read called from each
 *                  phNxpNciHal_read_complete so each a packet received from
 *                  NFCC can be provide to libnfc-nci.
 *
 * Returns          void.
 *
 ******************************************************************************/
static void phNxpNciHal_read_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
{
    NFCSTATUS status = NFCSTATUS_FAILED;
    UNUSED(pContext);
    if(nxpncihal_ctrl.read_retry_cnt == 1)
    {
        nxpncihal_ctrl.read_retry_cnt = 0;
    }

    if (pInfo->wStatus == NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_D("read successful status = 0x%x", pInfo->wStatus);

        nxpncihal_ctrl.p_rx_data = pInfo->pBuff;
        nxpncihal_ctrl.rx_data_len = pInfo->wLength;

        status = phNxpNciHal_process_ext_rsp (nxpncihal_ctrl.p_rx_data, &nxpncihal_ctrl.rx_data_len);

        phNxpNciHal_print_res_status(nxpncihal_ctrl.p_rx_data,  &nxpncihal_ctrl.rx_data_len);
        /* Check if response should go to hal module only */
        if (nxpncihal_ctrl.hal_ext_enabled == 1
                && (nxpncihal_ctrl.p_rx_data[0x00] & 0xF0) == 0x40)
        {
            if(status == NFCSTATUS_FAILED)
            {
                NXPLOG_NCIHAL_D("enter into NFCC init recovery");
                nxpncihal_ctrl.ext_cb_data.status = status;
            }
            /* Unlock semaphore only for responses*/
            if ((nxpncihal_ctrl.p_rx_data[0x00] & 0xF0) == 0x40 ||
               ((icode_detected == TRUE) &&(icode_send_eof == 3)))
            {
                /* Unlock semaphore */
                SEM_POST (&(nxpncihal_ctrl.ext_cb_data));
            }
        }
        /* Read successful send the event to higher layer */
        else if ((nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) &&
                (status == NFCSTATUS_SUCCESS)&&(send_to_upper_kovio==1))
        {
            (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
                    nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
        }
    }
    else
    {
        NXPLOG_NCIHAL_E("read error status = 0x%x", pInfo->wStatus);
    }

    if(nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE)
    {
        return;
    }
    /* Read again because read must be pending always.*/
    status = phTmlNfc_Read(
            Rx_data,
            NCI_MAX_DATA_LEN,
            (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
            NULL);
    if (status != NFCSTATUS_PENDING)
    {
        NXPLOG_NCIHAL_E("read status error status = %x", status);
        /* TODO: Not sure how to handle this ? */
    }

    return;
}

void read_retry()
{
    /* Read again because read must be pending always.*/
    NFCSTATUS status = phTmlNfc_Read(
            Rx_data,
            NCI_MAX_DATA_LEN,
            (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
            NULL);
    if (status != NFCSTATUS_PENDING)
    {
        NXPLOG_NCIHAL_E("read status error status = %x", status);
        /* TODO: Not sure how to handle this ? */
    }
}
/******************************************************************************
 * Function         phNxpNciHal_core_initialized
 *
 * Description      This function is called by libnfc-nci after successful open
 *                  of NFCC. All proprietary setting for PN54X are done here.
 *                  After completion of proprietary settings notification is
 *                  provided to libnfc-nci through callback function.
 *
 * Returns          Always returns NFCSTATUS_SUCCESS (0).
 *
 ******************************************************************************/
int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params)
{
    NFCSTATUS status = NFCSTATUS_SUCCESS;
    static uint8_t p2p_listen_mode_routing_cmd[] = { 0x21, 0x01, 0x07, 0x00, 0x01,
                                                0x01, 0x03, 0x00, 0x01, 0x05 };

    uint8_t swp_full_pwr_mode_on_cmd[] = { 0x20, 0x02, 0x05, 0x01, 0xA0,
                                           0xF1,0x01,0x01 };

    static uint8_t android_l_aid_matching_mode_on_cmd[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x91, 0x01, 0x01};
    static uint8_t swp_switch_timeout_cmd[] = {0x20, 0x02, 0x06, 0x01, 0xA0, 0xF3, 0x02, 0x00, 0x00};

    uint8_t *buffer = NULL;
    long bufflen = 260;
    long retlen = 0;
    int isfound;
    /* Temp fix to re-apply the proper clock setting */
    int temp_fix = 1;
    unsigned long num = 0;
#if(NFC_NXP_CHIP_TYPE != PN547C2)
    //initialize dummy FW recovery variables
    gRecFwRetryCount = 0;
    gRecFWDwnld = 0;
#endif
    // recovery --start
    /*NCI_INIT_CMD*/
    static uint8_t cmd_init_nci[] = {0x20,0x01,0x00};
    /*NCI_RESET_CMD*/
    static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x00}; //keep configuration
    /* reset config cache */
    static uint8_t retry_core_init_cnt;

    if((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)) //initializing for recovery.
    {
retry_core_init:
        config_access = FALSE;
        if(buffer != NULL)
        {
            free(buffer);
            buffer = NULL;
        }
        if(retry_core_init_cnt > 3)
        {
            return NFCSTATUS_FAILED;
        }

        status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
        if(NFCSTATUS_SUCCESS == status) { NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n"); }
        else { NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n"); }

        status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
        if((status != NFCSTATUS_SUCCESS) && (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT))
        {
            NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
            retry_core_init_cnt++;
            goto retry_core_init;
        }
        else if(status != NFCSTATUS_SUCCESS)
        {
            NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
            retry_core_init_cnt++;
            goto retry_core_init;

        }

        if(*p_core_init_rsp_params == 2) {
            NXPLOG_NCIHAL_E(" Last command is CORE_RESET!!");
            goto invoke_callback;
        }

        status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci),cmd_init_nci);
        if(status != NFCSTATUS_SUCCESS)
        {
            NXPLOG_NCIHAL_E ("NCI_CORE_INIT : Failed");
            retry_core_init_cnt++;
            goto retry_core_init;
        }

        if(*p_core_init_rsp_params == 3) {
            NXPLOG_NCIHAL_E(" Last command is CORE_INIT!!");
            goto invoke_callback;
        }
    }
// recovery --end


    buffer = (uint8_t*) malloc(bufflen*sizeof(uint8_t));
    if(NULL == buffer)
    {
        return NFCSTATUS_FAILED;
    }
    config_access = TRUE;
    retlen = 0;
    isfound = GetNxpByteArrayValue(NAME_NXP_ACT_PROP_EXTN, (char *) buffer,
            bufflen, &retlen);
    if (retlen > 0) {
        /* NXP ACT Proprietary Ext */
        status = phNxpNciHal_send_ext_cmd(retlen, buffer);
        if (status != NFCSTATUS_SUCCESS) {
            NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
            retry_core_init_cnt++;
            goto retry_core_init;
        }
    }

    // Check if firmware download success
    status = phNxpNciHal_get_mw_eeprom ();
    if (status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_E ("NXP GET MW EEPROM AREA Proprietary Ext failed");
        retry_core_init_cnt++;
        goto retry_core_init;
    }

    //
    status = phNxpNciHal_check_clock_config();
    if (status != NFCSTATUS_SUCCESS) {
        NXPLOG_NCIHAL_E("phNxpNciHal_check_clock_config failed");
        retry_core_init_cnt++;
        goto retry_core_init;
    }

#ifdef PN547C2_CLOCK_SETTING
    if (isNxpConfigModified() || (fw_download_success == 1) || (phNxpNciClock.issetConfig)
#if(NFC_NXP_HFO_SETTINGS == TRUE)
        || temp_fix == 1
#endif
        )
    {
        //phNxpNciHal_get_clk_freq();
        phNxpNciHal_set_clock();
        phNxpNciClock.issetConfig = FALSE;
#if(NFC_NXP_HFO_SETTINGS == TRUE)
        if (temp_fix == 1 )
        {
            NXPLOG_NCIHAL_D("Applying Default Clock setting and DPLL register at power on");
            /*
            # A0, 0D, 06, 06, 83, 55, 2A, 04, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_GEAR_REG
            # A0, 0D, 06, 06, 82, 33, 14, 17, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_REG
            # A0, 0D, 06, 06, 84, AA, 85, 00, 80 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_FREQ_REG
            # A0, 0D, 06, 06, 81, 63, 00, 00, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_CONTROL_REG
            */
            static uint8_t cmd_dpll_set_reg_nci[] = {0x20, 0x02, 0x25, 0x04,
                                                                            0xA0, 0x0D, 0x06, 0x06, 0x83, 0x55, 0x2A, 0x04, 0x00,
                                                                            0xA0, 0x0D, 0x06, 0x06, 0x82, 0x33, 0x14, 0x17, 0x00,
                                                                            0xA0, 0x0D, 0x06, 0x06, 0x84, 0xAA, 0x85, 0x00, 0x80,
                                                                            0xA0, 0x0D, 0x06, 0x06, 0x81, 0x63, 0x00, 0x00, 0x00};

            status = phNxpNciHal_send_ext_cmd(sizeof(cmd_dpll_set_reg_nci), cmd_dpll_set_reg_nci);
            if (status != NFCSTATUS_SUCCESS) {
                NXPLOG_NCIHAL_E("NXP DPLL REG ACT Proprietary Ext failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
            /* reset the NFCC after applying the clock setting and DPLL setting */
            //phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
            temp_fix = 0;
            goto retry_core_init;
        }
#endif
    }
#endif

    phNxpNciHal_check_factory_reset();
    retlen = 0;
    config_access = TRUE;
    isfound = GetNxpByteArrayValue(NAME_NXP_NFC_PROFILE_EXTN, (char *) buffer,
            bufflen, &retlen);
    if (retlen > 0) {
        /* NXP ACT Proprietary Ext */
        status = phNxpNciHal_send_ext_cmd(retlen, buffer);
        if (status != NFCSTATUS_SUCCESS) {
            NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
            retry_core_init_cnt++;
            goto retry_core_init;
        }
    }

    if(isNxpConfigModified() || (fw_download_success == 1))
    {

        retlen = 0;
        fw_download_success = 0;

#if(NFC_NXP_CHIP_TYPE != PN547C2)
        NXPLOG_NCIHAL_D ("Performing TVDD Settings");
        isfound = GetNxpNumValue(NAME_NXP_EXT_TVDD_CFG, &num, sizeof(num));
        if (isfound > 0) {
            if(num == 1) {
                isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_1, (char *) buffer,
                        bufflen, &retlen);
                if (retlen > 0) {
                    status = phNxpNciHal_send_ext_cmd(retlen, buffer);
                    if (status != NFCSTATUS_SUCCESS) {
                        NXPLOG_NCIHAL_E("EXT TVDD CFG 1 Settings failed");
                        retry_core_init_cnt++;
                        goto retry_core_init;
                    }
                }
            }
            else if(num == 2) {
                isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_2, (char *) buffer,
                        bufflen, &retlen);
                    if (retlen > 0) {
                    status = phNxpNciHal_send_ext_cmd(retlen, buffer);
                    if (status != NFCSTATUS_SUCCESS) {
                        NXPLOG_NCIHAL_E("EXT TVDD CFG 2 Settings failed");
                        retry_core_init_cnt++;
                        goto retry_core_init;
                    }
                }
            }
            else if(num == 3) {
                isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_3, (char *) buffer,
                        bufflen, &retlen);
                    if (retlen > 0) {
                    status = phNxpNciHal_send_ext_cmd(retlen, buffer);
                    if (status != NFCSTATUS_SUCCESS) {
                        NXPLOG_NCIHAL_E("EXT TVDD CFG 3 Settings failed");
                        retry_core_init_cnt++;
                        goto retry_core_init;
                    }
                }
            }
            else {
                NXPLOG_NCIHAL_E("Wrong Configuration Value %ld", num);
            }

        }
#endif
        retlen = 0;
#if(NFC_NXP_CHIP_TYPE != PN547C2)
        config_access = FALSE;
#endif
        NXPLOG_NCIHAL_D ("Performing RF Settings BLK 1");
        isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_1, (char *) buffer,
                bufflen, &retlen);
        if (retlen > 0) {
            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
#if(NFC_NXP_CHIP_TYPE != PN547C2)
            if (status == NFCSTATUS_SUCCESS)
            {
                status = phNxpNciHal_CheckRFCmdRespStatus ();
                /*STATUS INVALID PARAM 0x09*/
                if (status == 0x09)
                {
                    phNxpNciHalRFConfigCmdRecSequence ();
                    retry_core_init_cnt++;
                    goto retry_core_init;
                }
            }
            else
#endif
            if (status != NFCSTATUS_SUCCESS) {
                NXPLOG_NCIHAL_E("RF Settings BLK 1 failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }
        retlen = 0;

        NXPLOG_NCIHAL_D ("Performing RF Settings BLK 2");
        isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_2, (char *) buffer,
                bufflen, &retlen);
        if (retlen > 0) {
            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
#if(NFC_NXP_CHIP_TYPE != PN547C2)
            if (status == NFCSTATUS_SUCCESS)
            {
                status = phNxpNciHal_CheckRFCmdRespStatus ();
                /*STATUS INVALID PARAM 0x09*/
                if (status == 0x09)
                {
                    phNxpNciHalRFConfigCmdRecSequence ();
                    retry_core_init_cnt++;
                    goto retry_core_init;
                }
            }
            else
#endif
            if (status != NFCSTATUS_SUCCESS) {
                NXPLOG_NCIHAL_E("RF Settings BLK 2 failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }
        retlen = 0;

        NXPLOG_NCIHAL_D ("Performing RF Settings BLK 3");
        isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_3, (char *) buffer,
                bufflen, &retlen);
        if (retlen > 0) {
            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
#if(NFC_NXP_CHIP_TYPE != PN547C2)
            if (status == NFCSTATUS_SUCCESS)
            {
                status = phNxpNciHal_CheckRFCmdRespStatus ();
                /*STATUS INVALID PARAM 0x09*/
                if (status == 0x09)
                {
                    phNxpNciHalRFConfigCmdRecSequence ();
                    retry_core_init_cnt++;
                    goto retry_core_init;
                }
            }
            else
#endif
            if (status != NFCSTATUS_SUCCESS) {
                NXPLOG_NCIHAL_E("RF Settings BLK 3 failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }
        retlen = 0;

        NXPLOG_NCIHAL_D ("Performing RF Settings BLK 4");
        isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_4, (char *) buffer,
                bufflen, &retlen);
        if (retlen > 0) {
            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
#if(NFC_NXP_CHIP_TYPE != PN547C2)
            if (status == NFCSTATUS_SUCCESS)
            {
                status = phNxpNciHal_CheckRFCmdRespStatus ();
                /*STATUS INVALID PARAM 0x09*/
                if (status == 0x09)
                {
                    phNxpNciHalRFConfigCmdRecSequence ();
                    retry_core_init_cnt++;
                    goto retry_core_init;
                }
            }
            else
#endif
            if (status != NFCSTATUS_SUCCESS) {
                NXPLOG_NCIHAL_E("RF Settings BLK 4 failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }
        retlen = 0;

        NXPLOG_NCIHAL_D ("Performing RF Settings BLK 5");
        isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_5, (char *) buffer,
                bufflen, &retlen);
        if (retlen > 0) {
            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
#if(NFC_NXP_CHIP_TYPE != PN547C2)
            if (status == NFCSTATUS_SUCCESS)
            {
                status = phNxpNciHal_CheckRFCmdRespStatus ();
                /*STATUS INVALID PARAM 0x09*/
                if (status == 0x09)
                {
                    phNxpNciHalRFConfigCmdRecSequence ();
                    retry_core_init_cnt++;
                    goto retry_core_init;
                }
            }
            else
#endif
            if (status != NFCSTATUS_SUCCESS) {
                NXPLOG_NCIHAL_E("RF Settings BLK 5 failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }
        retlen = 0;

        NXPLOG_NCIHAL_D ("Performing RF Settings BLK 6");
        isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_6, (char *) buffer,
                bufflen, &retlen);
        if (retlen > 0) {
            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
#if(NFC_NXP_CHIP_TYPE != PN547C2)
            if (status == NFCSTATUS_SUCCESS)
            {
                status = phNxpNciHal_CheckRFCmdRespStatus ();
                /*STATUS INVALID PARAM 0x09*/
                if (status == 0x09)
                {
                    phNxpNciHalRFConfigCmdRecSequence ();
                    retry_core_init_cnt++;
                    goto retry_core_init;
                }
            }
            else
#endif
            if (status != NFCSTATUS_SUCCESS) {
                NXPLOG_NCIHAL_E("RF Settings BLK 6 failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }
        retlen = 0;
#if(NFC_NXP_CHIP_TYPE != PN547C2)
        config_access = TRUE;
#endif
        NXPLOG_NCIHAL_D ("Performing NAME_NXP_CORE_CONF_EXTN Settings");
        isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF_EXTN,
                (char *) buffer, bufflen, &retlen);
        if (retlen > 0) {
            /* NXP ACT Proprietary Ext */
            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
            if (status != NFCSTATUS_SUCCESS) {
                NXPLOG_NCIHAL_E("NXP Core configuration failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }

        retlen = 0;

        isfound = GetNxpByteArrayValue(NAME_NXP_CORE_MFCKEY_SETTING,
                (char *) buffer, bufflen, &retlen);
        if (retlen > 0) {
            /* NXP ACT Proprietary Ext */
            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
            if (status != NFCSTATUS_SUCCESS) {
                NXPLOG_NCIHAL_E("Setting mifare keys failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }

        retlen = 0;
#if(NFC_NXP_CHIP_TYPE != PN547C2)
        config_access = FALSE;
#endif
        isfound = GetNxpByteArrayValue(NAME_NXP_CORE_RF_FIELD,
                (char *) buffer, bufflen, &retlen);
        if (retlen > 0) {
            /* NXP ACT Proprietary Ext */
            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
#if(NFC_NXP_CHIP_TYPE != PN547C2)
            if (status == NFCSTATUS_SUCCESS)
            {
                status = phNxpNciHal_CheckRFCmdRespStatus ();
                /*STATUS INVALID PARAM 0x09*/
                if (status == 0x09)
                {
                    phNxpNciHalRFConfigCmdRecSequence ();
                    retry_core_init_cnt++;
                    goto retry_core_init;
                }
            }
            else
#endif
            if (status != NFCSTATUS_SUCCESS) {
                NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }
#if(NFC_NXP_CHIP_TYPE != PN547C2)
        config_access = TRUE;
#endif

        retlen = 0;
#if(NFC_NXP_CHIP_TYPE != PN547C2)
        /* NXP SWP switch timeout Setting*/
        if(GetNxpNumValue(NAME_NXP_SWP_SWITCH_TIMEOUT, (void *)&retlen, sizeof(retlen)))
        {
            //Check the permissible range [0 - 60]
            if(0 <= retlen && retlen <= 60)
            {
                if( 0 < retlen)
                {
                    unsigned int timeout = retlen * 1000;
                    unsigned int timeoutHx = 0x0000;

                    char tmpbuffer[10] = {0};
                    snprintf ((char*)tmpbuffer, 10, "%04x", timeout);
                    sscanf ((char*)tmpbuffer,"%x", &timeoutHx);

                    swp_switch_timeout_cmd[7]= (timeoutHx & 0xFF);
                    swp_switch_timeout_cmd[8]= ((timeoutHx & 0xFF00) >> 8);
                }

                status = phNxpNciHal_send_ext_cmd (sizeof(swp_switch_timeout_cmd),
                                                          swp_switch_timeout_cmd);
                if (status != NFCSTATUS_SUCCESS)
                {
                    NXPLOG_NCIHAL_E ("SWP switch timeout Setting Failed");
                    retry_core_init_cnt++;
                    goto retry_core_init;
                }
            }
            else
            {
                NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed - out of range!");
            }

        }

        status = phNxpNciHal_china_tianjin_rf_setting();
        if (status != NFCSTATUS_SUCCESS)
        {
            NXPLOG_NCIHAL_E("phNxpNciHal_china_tianjin_rf_setting failed");
            return NFCSTATUS_FAILED;
        }
#endif
        // Update eeprom value
        status = phNxpNciHal_set_mw_eeprom ();
        if (status != NFCSTATUS_SUCCESS)
        {
            NXPLOG_NCIHAL_E ("NXP Update MW EEPROM Proprietary Ext failed");
        }
    }

    retlen = 0;

    isfound = GetNxpByteArrayValue(NAME_NXP_CORE_STANDBY, (char *) buffer,bufflen, &retlen);
    if (retlen > 0) {
        /* NXP ACT Proprietary Ext */
        status = phNxpNciHal_send_ext_cmd(retlen, buffer);
        if (status != NFCSTATUS_SUCCESS) {
            NXPLOG_NCIHAL_E("Stand by mode enable failed");
            retry_core_init_cnt++;
            goto retry_core_init;
        }
    }
    retlen = 0;

    isfound =  GetNxpByteArrayValue(NAME_NXP_CORE_CONF,(char *)buffer,bufflen,&retlen);
    if(retlen > 0)
    {
        /* NXP ACT Proprietary Ext */
        status = phNxpNciHal_send_ext_cmd(retlen,buffer);
        if (status != NFCSTATUS_SUCCESS)
        {
            NXPLOG_NCIHAL_E("Core Set Config failed");
            retry_core_init_cnt++;
            goto retry_core_init;
        }
    }

    config_access = FALSE;
    //if length of last command is 0 then only reset the P2P listen mode routing.
    if(p_core_init_rsp_params[35] == 0)
    {
        /* P2P listen mode routing */
        status = phNxpNciHal_send_ext_cmd (sizeof (p2p_listen_mode_routing_cmd), p2p_listen_mode_routing_cmd);
        if (status != NFCSTATUS_SUCCESS)
        {
            NXPLOG_NCIHAL_E("P2P listen mode routing failed");
            retry_core_init_cnt++;
            goto retry_core_init;
        }
    }

    retlen = 0;

    /* SWP FULL PWR MODE SETTING ON */
    if(GetNxpNumValue(NAME_NXP_SWP_FULL_PWR_ON, (void *)&retlen, sizeof(retlen)))
    {
        if(1 == retlen)
        {
            status = phNxpNciHal_send_ext_cmd (sizeof(swp_full_pwr_mode_on_cmd),
                                                      swp_full_pwr_mode_on_cmd);
            if (status != NFCSTATUS_SUCCESS)
            {
               NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING ON CMD FAILED");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }
        else
        {
            swp_full_pwr_mode_on_cmd[7]=0x00;
            status = phNxpNciHal_send_ext_cmd (sizeof(swp_full_pwr_mode_on_cmd),
                                                      swp_full_pwr_mode_on_cmd);
            if (status != NFCSTATUS_SUCCESS)
            {
                NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING OFF CMD FAILED");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }
    }

    /* Android L AID Matching Platform Setting*/
    if(GetNxpNumValue(NAME_AID_MATCHING_PLATFORM, (void *)&retlen, sizeof(retlen)))
    {
        if(1 == retlen)
        {
            status = phNxpNciHal_send_ext_cmd (sizeof(android_l_aid_matching_mode_on_cmd),
                    android_l_aid_matching_mode_on_cmd);
            if (status != NFCSTATUS_SUCCESS)
            {
               NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }
        else if (2 == retlen)
        {
            android_l_aid_matching_mode_on_cmd[7]=0x00;
            status = phNxpNciHal_send_ext_cmd (sizeof(android_l_aid_matching_mode_on_cmd),
                    android_l_aid_matching_mode_on_cmd);
            if (status != NFCSTATUS_SUCCESS)
            {
                NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }
        }
    }

    if((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4))
    {
        static phLibNfc_Message_t msg;
        uint16_t tmp_len = 0;
        uint8_t uicc_set_mode[] = {0x22, 0x01, 0x02, 0x02, 0x01};
        uint8_t set_screen_state[] = {0x2F, 0x15, 01, 00};      //SCREEN ON
        uint8_t nfcc_core_conn_create[] = {0x20, 0x04, 0x06, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01};
        uint8_t nfcc_mode_set_on[] = {0x22, 0x01, 0x02, 0x01, 0x01};

        NXPLOG_NCIHAL_E("Sending DH and NFCC core connection command as raw packet!!");
        status = phNxpNciHal_send_ext_cmd (sizeof(nfcc_core_conn_create), nfcc_core_conn_create);

        if (status != NFCSTATUS_SUCCESS)
        {
            NXPLOG_NCIHAL_E("Sending DH and NFCC core connection command as raw packet!! Failed");
            retry_core_init_cnt++;
            goto retry_core_init;
        }

        NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!!");
        status = phNxpNciHal_send_ext_cmd (sizeof(nfcc_mode_set_on), nfcc_mode_set_on);

        if (status != NFCSTATUS_SUCCESS)
        {
            NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!! Failed");
            retry_core_init_cnt++;
            goto retry_core_init;
        }

        NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!!");
        status = phNxpNciHal_send_ext_cmd (sizeof(uicc_set_mode),
                                      uicc_set_mode);
        if (status != NFCSTATUS_SUCCESS)
        {
            NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!! Failed");
            retry_core_init_cnt++;
            goto retry_core_init;
        }

        if(*(p_core_init_rsp_params + 1) == 1) // RF state is Discovery!!
        {
            NXPLOG_NCIHAL_E("Sending Set Screen ON State Command as raw packet!!");
            status = phNxpNciHal_send_ext_cmd (sizeof(set_screen_state),
                                          set_screen_state);
            if (status != NFCSTATUS_SUCCESS)
            {
                NXPLOG_NCIHAL_E("Sending Set Screen ON State Command as raw packet!! Failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }

            NXPLOG_NCIHAL_E("Sending discovery as raw packet!!");
            status = phNxpNciHal_send_ext_cmd (p_core_init_rsp_params[2],
                                                      (uint8_t *)&p_core_init_rsp_params[3]);
            if (status != NFCSTATUS_SUCCESS)
            {
                NXPLOG_NCIHAL_E("Sending discovery as raw packet Failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }

        }
        else
        {
            NXPLOG_NCIHAL_E("Sending Set Screen OFF State Command as raw packet!!");
            set_screen_state[3] = 0x01; //Screen OFF
            status = phNxpNciHal_send_ext_cmd (sizeof(set_screen_state),
                                          set_screen_state);
            if (status != NFCSTATUS_SUCCESS)
            {
                NXPLOG_NCIHAL_E("Sending Set Screen OFF State Command as raw packet!! Failed");
                retry_core_init_cnt++;
                goto retry_core_init;
            }

        }
        NXPLOG_NCIHAL_E("Sending last command for Recovery ");

        if(p_core_init_rsp_params[35] > 0)
        {  //if length of last command is 0 then it doesn't need to send last command.
            if( !(((p_core_init_rsp_params[36] == 0x21) && (p_core_init_rsp_params[37] == 0x03))
                && (*(p_core_init_rsp_params + 1) == 1)) &&
                    !((p_core_init_rsp_params[36] == 0x21) && (p_core_init_rsp_params[37] == 0x06) && (p_core_init_rsp_params[39] == 0x00) &&(*(p_core_init_rsp_params + 1) == 0x00)))
                //if last command is discovery and RF status is also discovery state, then it doesn't need to execute or similarly
                // if the last command is deactivate to idle and RF status is also idle , no need to execute the command .
            {
                tmp_len = p_core_init_rsp_params[35];

                /* Check for NXP ext before sending write */
                status = phNxpNciHal_write_ext(&tmp_len,
                        (uint8_t *)&p_core_init_rsp_params[36], &nxpncihal_ctrl.rsp_len,
                        nxpncihal_ctrl.p_rsp_data);
                if (status != NFCSTATUS_SUCCESS)
                {
                    if (buffer)
                    {
                        free (buffer);
                        buffer = NULL;
                    }
                    /* Do not send packet to PN54X, send response directly */
                    msg.eMsgType = NCI_HAL_RX_MSG;
                    msg.pMsgData = NULL;
                    msg.Size = 0;

                    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
                            (phLibNfc_Message_t *) &msg);
                    return NFCSTATUS_SUCCESS;
                }

                p_core_init_rsp_params[35] = (uint8_t)tmp_len;

                status = phNxpNciHal_send_ext_cmd (p_core_init_rsp_params[35],
                                                          (uint8_t *)&p_core_init_rsp_params[36]);
                if (status != NFCSTATUS_SUCCESS)
                {
                    NXPLOG_NCIHAL_E("Sending last command for Recovery Failed");
                    retry_core_init_cnt++;
                    goto retry_core_init;
                }
            }
        }
    }

    retry_core_init_cnt = 0;

    if(buffer)
    {
        free(buffer);
        buffer = NULL;
    }
#if(NFC_NXP_CHIP_TYPE != PN547C2)
    //initialize dummy FW recovery variables
    gRecFWDwnld = 0;
    gRecFwRetryCount = 0;
#endif
    if(!((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)))
        phNxpNciHal_core_initialized_complete(status);
    else
    {
invoke_callback:
        config_access = FALSE;
        if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL)
        {
            *p_core_init_rsp_params = 0;
            NXPLOG_NCIHAL_E("Invoking data callback!!");
            (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
                    nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
        }
    }

#ifdef PN547C2_CLOCK_SETTING
    if (isNxpConfigModified())
    {
        updateNxpConfigTimestamp();
    }
#endif
    return NFCSTATUS_SUCCESS;
}
#if(NFC_NXP_CHIP_TYPE != PN547C2)
/******************************************************************************
 * Function         phNxpNciHal_CheckRFCmdRespStatus
 *
 * Description      This function is called to check the resp status of
 *                  RF update commands.
 *
 * Returns          NFCSTATUS_SUCCESS           if successful,
 *                  NFCSTATUS_INVALID_PARAMETER if parameter is inavlid
 *                  NFCSTATUS_FAILED            if failed response
 *
 ******************************************************************************/
NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus ()
{
    NFCSTATUS status = NFCSTATUS_SUCCESS;
    static uint16_t INVALID_PARAM = 0x09;
    if ((nxpncihal_ctrl.rx_data_len > 0) && (nxpncihal_ctrl.p_rx_data[2] > 0))
    {
        if (nxpncihal_ctrl.p_rx_data[3] == 0x09)
        {
            status = INVALID_PARAM;
        }
        else if (nxpncihal_ctrl.p_rx_data[3] != NFCSTATUS_SUCCESS)
        {
            status = NFCSTATUS_FAILED;
        }
    }
    return status;
}
/******************************************************************************
 * Function         phNxpNciHalRFConfigCmdRecSequence
 *
 * Description      This function is called to handle dummy FW recovery sequence
 *                  Whenever RF settings are failed to apply with invalid param
 *                  response, recovery mechanism includes dummy firmware download
 *                  followed by firmware download and then config settings. The dummy
 *                  firmware changes the major number of the firmware inside NFCC.
 *                  Then actual firmware dowenload will be successful. This can be
 *                  retried maximum three times.
 *
 * Returns          Always returns NFCSTATUS_SUCCESS
 *
 ******************************************************************************/
NFCSTATUS phNxpNciHalRFConfigCmdRecSequence ()
{
    NFCSTATUS status = NFCSTATUS_SUCCESS;
    uint16_t recFWState = 1;
    gRecFWDwnld = TRUE;
    gRecFwRetryCount++;
    if (gRecFwRetryCount > 0x03)
    {
        NXPLOG_NCIHAL_D ("Max retry count for RF config FW recovery exceeded ");
        gRecFWDwnld = FALSE;
        return NFCSTATUS_FAILED;
    }
    do {
        status = phTmlNfc_IoCtl (phTmlNfc_e_ResetDevice);
        phDnldNfc_InitImgInfo ();
        if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion ())
        {
            fw_download_success = 0;
            status = phNxpNciHal_fw_download ();
            if (status == NFCSTATUS_SUCCESS)
            {
                fw_download_success = 1;
                status = phTmlNfc_Read(
                    nxpncihal_ctrl.p_cmd_data,
                    NCI_MAX_DATA_LEN,
                    (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
                    NULL);
                if (status != NFCSTATUS_PENDING)
                {
                    NXPLOG_NCIHAL_E ("TML Read status error status = %x", status);
                    phTmlNfc_Shutdown ();
                    status = NFCSTATUS_FAILED;
                    break;
                }
            }
            else
            {
                status = NFCSTATUS_FAILED;
                break;
            }
        }
        gRecFWDwnld = FALSE;
    }while (recFWState--);
    gRecFWDwnld = FALSE;
    return status;
}
#endif
/******************************************************************************
 * Function         phNxpNciHal_core_initialized_complete
 *
 * Description      This function is called when phNxpNciHal_core_initialized
 *                  complete all proprietary command exchanges. This function
 *                  informs libnfc-nci about completion of core initialize
 *                  and result of that through callback.
 *
 * Returns          void.
 *
 ******************************************************************************/
static void phNxpNciHal_core_initialized_complete(NFCSTATUS status)
{
    static phLibNfc_Message_t msg;

    if (status == NFCSTATUS_SUCCESS)
    {
        msg.eMsgType = NCI_HAL_POST_INIT_CPLT_MSG;
    }
    else
    {
        msg.eMsgType = NCI_HAL_ERROR_MSG;
    }
    msg.pMsgData = NULL;
    msg.Size = 0;

    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
            (phLibNfc_Message_t *) &msg);

    return;
}

/******************************************************************************
 * Function         phNxpNciHal_pre_discover
 *
 * Description      This function is called by libnfc-nci to perform any
 *                  proprietary exchange before RF discovery. When proprietary
 *                  exchange is over completion is informed to libnfc-nci
 *                  through phNxpNciHal_pre_discover_complete function.
 *
 * Returns          It always returns NFCSTATUS_SUCCESS (0).
 *
 ******************************************************************************/
int phNxpNciHal_pre_discover(void)
{
    /* Nothing to do here for initial version */
    return NFCSTATUS_SUCCESS;
}

/******************************************************************************
 * Function         phNxpNciHal_pre_discover_complete
 *
 * Description      This function informs libnfc-nci about completion and
 *                  status of phNxpNciHal_pre_discover through callback.
 *
 * Returns          void.
 *
 ******************************************************************************/
static void phNxpNciHal_pre_discover_complete(NFCSTATUS status)
{
    static phLibNfc_Message_t msg;

    if (status == NFCSTATUS_SUCCESS)
    {
        msg.eMsgType = NCI_HAL_PRE_DISCOVER_CPLT_MSG;
    }
    else
    {
        msg.eMsgType = NCI_HAL_ERROR_MSG;
    }
    msg.pMsgData = NULL;
    msg.Size = 0;

    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
            &msg);

    return;
}

/******************************************************************************
 * Function         phNxpNciHal_close
 *
 * Description      This function close the NFCC interface and free all
 *                  resources.This is called by libnfc-nci on NFC service stop.
 *
 * Returns          Always return NFCSTATUS_SUCCESS (0).
 *
 ******************************************************************************/
int phNxpNciHal_close(void)
{
    NFCSTATUS status;
    /*NCI_RESET_CMD*/
    static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x00};

    static uint8_t cmd_ce_disc_nci[] = {0x21,0x03,0x07,0x03,0x80,0x01,0x81,0x01,0x82,0x01};

    CONCURRENCY_LOCK();

    status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_disc_nci),cmd_ce_disc_nci);
    if(status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_E ("CMD_CE_DISC_NCI: Failed");
    }

    nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;

    status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
    if(status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
    }

    if (NULL != gpphTmlNfc_Context->pDevHandle)
    {
        phNxpNciHal_close_complete(NFCSTATUS_SUCCESS);
        /* Abort any pending read and write */
        status = phTmlNfc_ReadAbort();
        status = phTmlNfc_WriteAbort();

        phOsalNfc_Timer_Cleanup();

        status = phTmlNfc_Shutdown();

        phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);


        memset (&nxpncihal_ctrl, 0x00, sizeof (nxpncihal_ctrl));

        NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed");
    }

    CONCURRENCY_UNLOCK();

    phNxpNciHal_cleanup_monitor();

    /* Return success always */
    return NFCSTATUS_SUCCESS;
}

/******************************************************************************
 * Function         phNxpNciHal_close_complete
 *
 * Description      This function inform libnfc-nci about result of
 *                  phNxpNciHal_close.
 *
 * Returns          void.
 *
 ******************************************************************************/
void phNxpNciHal_close_complete(NFCSTATUS status)
{
    static phLibNfc_Message_t msg;

    if (status == NFCSTATUS_SUCCESS)
    {
        msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
    }
    else
    {
        msg.eMsgType = NCI_HAL_ERROR_MSG;
    }
    msg.pMsgData = NULL;
    msg.Size = 0;

    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
            &msg);

    return;
}
/******************************************************************************
 * Function         phNxpNciHal_notify_i2c_fragmentation
 *
 * Description      This function can be used by HAL to inform
 *                 libnfc-nci that i2c fragmentation is enabled/disabled
 *
 * Returns          void.
 *
 ******************************************************************************/
void phNxpNciHal_notify_i2c_fragmentation(void)
{
    if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
    {
        /*inform libnfc-nci that i2c fragmentation is enabled/disabled */
        (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT,
                HAL_NFC_STATUS_OK);
    }
}
/******************************************************************************
 * Function         phNxpNciHal_control_granted
 *
 * Description      Called by libnfc-nci when NFCC control is granted to HAL.
 *
 * Returns          Always returns NFCSTATUS_SUCCESS (0).
 *
 ******************************************************************************/
int phNxpNciHal_control_granted(void)
{
    /* Take the concurrency lock so no other calls from upper layer
     * will be allowed
     */
    CONCURRENCY_LOCK();

    if(NULL != nxpncihal_ctrl.p_control_granted_cback)
    {
        (*nxpncihal_ctrl.p_control_granted_cback)();
    }
    /* At the end concurrency unlock so calls from upper layer will
     * be allowed
     */
    CONCURRENCY_UNLOCK();
    return NFCSTATUS_SUCCESS;
}

/******************************************************************************
 * Function         phNxpNciHal_request_control
 *
 * Description      This function can be used by HAL to request control of
 *                  NFCC to libnfc-nci. When control is provided to HAL it is
 *                  notified through phNxpNciHal_control_granted.
 *
 * Returns          void.
 *
 ******************************************************************************/
void phNxpNciHal_request_control(void)
{
    if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
    {
        /* Request Control of NCI Controller from NCI NFC Stack */
        (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_REQUEST_CONTROL_EVT,
                HAL_NFC_STATUS_OK);
    }

    return;
}

/******************************************************************************
 * Function         phNxpNciHal_release_control
 *
 * Description      This function can be used by HAL to release the control of
 *                  NFCC back to libnfc-nci.
 *
 * Returns          void.
 *
 ******************************************************************************/
void phNxpNciHal_release_control(void)
{
    if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
    {
        /* Release Control of NCI Controller to NCI NFC Stack */
        (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_RELEASE_CONTROL_EVT,
                HAL_NFC_STATUS_OK);
    }

    return;
}

/******************************************************************************
 * Function         phNxpNciHal_power_cycle
 *
 * Description      This function is called by libnfc-nci when power cycling is
 *                  performed. When processing is complete it is notified to
 *                  libnfc-nci through phNxpNciHal_power_cycle_complete.
 *
 * Returns          Always return NFCSTATUS_SUCCESS (0).
 *
 ******************************************************************************/
int phNxpNciHal_power_cycle(void)
{
    NXPLOG_NCIHAL_D("Power Cycle");

    NFCSTATUS status = NFCSTATUS_FAILED;

    status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);

    if(NFCSTATUS_SUCCESS == status)
    {
        NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
    }
    else
    {
        NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
    }

    phNxpNciHal_power_cycle_complete(NFCSTATUS_SUCCESS);

    return NFCSTATUS_SUCCESS;
}

/******************************************************************************
 * Function         phNxpNciHal_power_cycle_complete
 *
 * Description      This function is called to provide the status of
 *                  phNxpNciHal_power_cycle to libnfc-nci through callback.
 *
 * Returns          void.
 *
 ******************************************************************************/
static void phNxpNciHal_power_cycle_complete(NFCSTATUS status)
{
    static phLibNfc_Message_t msg;

    if (status == NFCSTATUS_SUCCESS)
    {
        msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
    }
    else
    {
        msg.eMsgType = NCI_HAL_ERROR_MSG;
    }
    msg.pMsgData = NULL;
    msg.Size = 0;

    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
            &msg);

    return;
}

/******************************************************************************
 * Function         phNxpNciHal_get_mw_eeprom
 *
 * Description      This function is called to retreive data in mw eeprom area
 *
 * Returns          NFCSTATUS.
 *
 ******************************************************************************/
static NFCSTATUS phNxpNciHal_get_mw_eeprom (void)
{
    NFCSTATUS status = NFCSTATUS_SUCCESS;
    uint8_t retry_cnt = 0;
    static uint8_t get_mw_eeprom_cmd[] = { 0x20, 0x03,0x03, 0x01, 0xA0, 0x0F };
    uint8_t bConfig;

retry_send_ext:
    if (retry_cnt > 3)
    {
        return NFCSTATUS_FAILED;
    }

    phNxpNciMwEepromArea.isGetEepromArea = TRUE;
    status = phNxpNciHal_send_ext_cmd (sizeof(get_mw_eeprom_cmd), get_mw_eeprom_cmd);
    if (status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_E ("unable to get the mw eeprom data");
        phNxpNciMwEepromArea.isGetEepromArea = FALSE;
        retry_cnt++;
        goto retry_send_ext;
    }
    phNxpNciMwEepromArea.isGetEepromArea = FALSE;

    if (phNxpNciMwEepromArea.p_rx_data[12])
    {
        fw_download_success = 1;
    }
    return status;
}

/******************************************************************************
 * Function         phNxpNciHal_set_mw_eeprom
 *
 * Description      This function is called to update data in mw eeprom area
 *
 * Returns          void.
 *
 ******************************************************************************/
static NFCSTATUS phNxpNciHal_set_mw_eeprom (void)
{
    NFCSTATUS status = NFCSTATUS_SUCCESS;
    uint8_t retry_cnt = 0;
    uint8_t set_mw_eeprom_cmd[39] = {0};
    uint8_t cmd_header[] = { 0x20, 0x02,0x24, 0x01, 0xA0, 0x0F, 0x20 };

    memcpy (set_mw_eeprom_cmd, cmd_header, sizeof(cmd_header));
    phNxpNciMwEepromArea.p_rx_data[12] = 0;
    memcpy (set_mw_eeprom_cmd + sizeof(cmd_header), phNxpNciMwEepromArea.p_rx_data, sizeof(phNxpNciMwEepromArea.p_rx_data));

retry_send_ext:
    if (retry_cnt > 3)
    {
        return NFCSTATUS_FAILED;
    }

    status = phNxpNciHal_send_ext_cmd (sizeof(set_mw_eeprom_cmd), set_mw_eeprom_cmd);
    if (status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_E ("unable to update the mw eeprom data");
        retry_cnt++;
        goto retry_send_ext;
    }
    return status;
}

/******************************************************************************
 * Function         phNxpNciHal_set_clock
 *
 * Description      This function is called after successfull download
 *                  to apply the clock setting provided in config file
 *
 * Returns          void.
 *
 ******************************************************************************/
static void phNxpNciHal_set_clock(void)
{
    NFCSTATUS status = NFCSTATUS_FAILED;
    int retryCount = 0;

retrySetclock:
    phNxpNciClock.isClockSet = TRUE;
    if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL)
    {
        static uint8_t set_clock_cmd[] = {0x20, 0x02,0x09, 0x02, 0xA0, 0x03, 0x01, 0x11,
                                                               0xA0, 0x04, 0x01, 0x01};
        uint8_t param_clock_src = CLK_SRC_PLL;
        param_clock_src = param_clock_src << 3;

        if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ)
        {
            param_clock_src |= 0x00;
        }
        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ)
        {
            param_clock_src |= 0x01;
        }
        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ)
        {
            param_clock_src |= 0x02;
        }
        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ)
        {
            param_clock_src |= 0x03;
        }
        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ)
        {
            param_clock_src |= 0x04;
        }
        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ)
        {
            param_clock_src |= 0x05;
        }
        else
        {
            NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
            param_clock_src = 0x11;
        }

        set_clock_cmd[7] = param_clock_src;
        set_clock_cmd[11] = nxpprofile_ctrl.bTimeout;
        status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
        if (status != NFCSTATUS_SUCCESS)
        {
            NXPLOG_NCIHAL_E("PLL colck setting failed !!");
        }
    }
    else if(nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL)
    {
        static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x03, 0x01, 0x08};
        status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
        if (status != NFCSTATUS_SUCCESS)
        {
            NXPLOG_NCIHAL_E("XTAL colck setting failed !!");
        }
    }
    else
    {
        NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
    }

   // Checking for SET CONFG SUCCESS, re-send the command  if not.
    phNxpNciClock.isClockSet = FALSE;
    if(phNxpNciClock.p_rx_data[3]   != NFCSTATUS_SUCCESS )
    {
        if(retryCount++  < 3)
        {
            NXPLOG_NCIHAL_E("Set-clk failed retry again ");
            goto retrySetclock;
        }
        else
        {
            NXPLOG_NCIHAL_D("Set clk  failed -  max count = 0x%x exceeded ", retryCount);
//            NXPLOG_NCIHAL_E("Set Config is failed for Clock Due to elctrical disturbances, aborting the NFC process");
//            abort ();
       }
    }
}

/******************************************************************************
 * Function         phNxpNciHal_check_clock_config
 *
 * Description      This function is called after successfull download
 *                  to check if clock settings in config file and chip
 *                  is same
 *
 * Returns          void.
 *
 ******************************************************************************/
NFCSTATUS phNxpNciHal_check_clock_config(void)
{
    NFCSTATUS status = NFCSTATUS_SUCCESS;
    uint8_t param_clock_src;
    static uint8_t get_clock_cmd[] = {0x20, 0x03,0x07, 0x03, 0xA0, 0x02,
            0xA0, 0x03, 0xA0, 0x04};
    phNxpNciClock.isClockSet = TRUE;
    phNxpNciHal_get_clk_freq();
    status = phNxpNciHal_send_ext_cmd(sizeof(get_clock_cmd),get_clock_cmd);

    if(status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_E("unable to retrieve get_clk_src_sel");
        return status;
    }
    param_clock_src = check_config_parameter();
    if( phNxpNciClock.p_rx_data[12] == param_clock_src &&  phNxpNciClock.p_rx_data[16] == nxpprofile_ctrl.bTimeout)
    {
        phNxpNciClock.issetConfig = FALSE;
    }else {
        phNxpNciClock.issetConfig = TRUE;
    }
    phNxpNciClock.isClockSet = FALSE;

    return status;
}

/******************************************************************************
 * Function         phNxpNciHal_china_tianjin_rf_setting
 *
 * Description      This function is called to check RF Setting
 *
 * Returns          Status.
 *
 ******************************************************************************/
NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void)
{
    NFCSTATUS status = NFCSTATUS_SUCCESS;
    int isfound = 0;
    int rf_enable = FALSE;
    int rf_val = 0;
    int send_flag;
    uint8_t retry_cnt =0;
    int enable_bit =0;
    static uint8_t get_rf_cmd[] = {0x20, 0x03,0x03, 0x01, 0xA0, 0x85};

retry_send_ext:
    if(retry_cnt > 3)
    {
        return NFCSTATUS_FAILED;
    }
    send_flag = TRUE;
    phNxpNciRfSet.isGetRfSetting = TRUE;
    status = phNxpNciHal_send_ext_cmd(sizeof(get_rf_cmd),get_rf_cmd);
    if(status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_E("unable to get the RF setting");
        phNxpNciRfSet.isGetRfSetting = FALSE;
        retry_cnt++;
        goto retry_send_ext;
    }
    phNxpNciRfSet.isGetRfSetting = FALSE;
    if(phNxpNciRfSet.p_rx_data[3] != 0x00)
    {
        NXPLOG_NCIHAL_E("GET_CONFIG_RSP is FAILED for CHINA TIANJIN");
        return status;
    }
    rf_val = phNxpNciRfSet.p_rx_data[10];
    isfound = (GetNxpNumValue(NAME_NXP_CHINA_TIANJIN_RF_ENABLED, (void *)&rf_enable, sizeof(rf_enable)));
    if(isfound >0)
    {
        enable_bit = rf_val & 0x40;
        if((enable_bit != 0x40) && (rf_enable == 1))
        {
            phNxpNciRfSet.p_rx_data[10] |= 0x40;   // Enable if it is disabled
        }
        else if((enable_bit == 0x40) && (rf_enable == 0))
        {
            phNxpNciRfSet.p_rx_data[10] &= 0xBF;  // Disable if it is Enabled
        }
        else
        {
            send_flag = FALSE;  // No need to change in RF setting
        }

        if(send_flag == TRUE)
        {
            static uint8_t set_rf_cmd[] = {0x20, 0x02, 0x08, 0x01, 0xA0, 0x85, 0x04, 0x50, 0x08, 0x68, 0x00};
            memcpy(&set_rf_cmd[4],&phNxpNciRfSet.p_rx_data[5],7);
            status = phNxpNciHal_send_ext_cmd(sizeof(set_rf_cmd),set_rf_cmd);
            if(status != NFCSTATUS_SUCCESS)
            {
                NXPLOG_NCIHAL_E("unable to set the RF setting");
                retry_cnt++;
                goto retry_send_ext;
            }
        }
    }

    return status;
}

int  check_config_parameter()
{
    NFCSTATUS status = NFCSTATUS_FAILED;
    uint8_t param_clock_src = CLK_SRC_PLL;
    if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL)
    {
        param_clock_src = param_clock_src << 3;

        if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ)
        {
            param_clock_src |= 0x00;
        }
        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ)
        {
            param_clock_src |= 0x01;
        }
        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ)
        {
            param_clock_src |= 0x02;
        }
        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ)
        {
            param_clock_src |= 0x03;
        }
        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ)
        {
            param_clock_src |= 0x04;
        }
        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ)
        {
            param_clock_src |= 0x05;
        }
        else
        {
            NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
            param_clock_src = 0x11;
        }
    }
    else if(nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL)
    {
        param_clock_src = 0x08;

    }
    else
    {
        NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
    }
    return param_clock_src;
}
/******************************************************************************
 * Function         phNxpNciHal_enable_i2c_fragmentation
 *
 * Description      This function is called to process the response status
 *                  and print the status byte.
 *
 * Returns          void.
 *
 ******************************************************************************/
void phNxpNciHal_enable_i2c_fragmentation()
{
    NFCSTATUS status = NFCSTATUS_FAILED;
    static uint8_t fragmentation_enable_config_cmd[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x05, 0x01, 0x10};
    int isfound = 0;
    long i2c_status = 0x00;
    long config_i2c_vlaue = 0xff;
    /*NCI_RESET_CMD*/
    static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
    /*NCI_INIT_CMD*/
    static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
    static uint8_t get_i2c_fragmentation_cmd[] = {0x20, 0x03, 0x03, 0x01 ,0xA0 ,0x05};
    isfound = (GetNxpNumValue(NAME_NXP_I2C_FRAGMENTATION_ENABLED, (void *)&i2c_status, sizeof(i2c_status)));
    status = phNxpNciHal_send_ext_cmd(sizeof(get_i2c_fragmentation_cmd),get_i2c_fragmentation_cmd);
    if(status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_E("unable to retrieve  get_i2c_fragmentation_cmd");
    }
    else
    {
        if(nxpncihal_ctrl.p_rx_data[8] == 0x10)
        {
            config_i2c_vlaue = 0x01;
            phNxpNciHal_notify_i2c_fragmentation();
            phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
        }
        else if(nxpncihal_ctrl.p_rx_data[8] == 0x00)
        {
            config_i2c_vlaue = 0x00;
        }
        if( config_i2c_vlaue == i2c_status)
        {
            NXPLOG_NCIHAL_E("i2c_fragmentation_status existing");
        }
        else
        {
            if (i2c_status == 0x01)
            {
                /* NXP I2C fragmenation enabled*/
                status = phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd), fragmentation_enable_config_cmd);
                if (status != NFCSTATUS_SUCCESS)
                {
                    NXPLOG_NCIHAL_E("NXP fragmentation enable failed");
                }
            }
            else if (i2c_status == 0x00 || config_i2c_vlaue == 0xff)
            {
                fragmentation_enable_config_cmd[7] = 0x00;
                /* NXP I2C fragmentation disabled*/
                status = phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd), fragmentation_enable_config_cmd);
                if (status != NFCSTATUS_SUCCESS)
                {
                    NXPLOG_NCIHAL_E("NXP fragmentation disable failed");
                }
            }
            status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
            if(status != NFCSTATUS_SUCCESS)
            {
                NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
            }
            status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci),cmd_init_nci);
            if(status != NFCSTATUS_SUCCESS)
            {
                NXPLOG_NCIHAL_E ("NCI_CORE_INIT : Failed");
            }
            else if(i2c_status == 0x01)
            {
                phNxpNciHal_notify_i2c_fragmentation();
                phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
            }
        }
    }
}
/******************************************************************************
 * Function         phNxpNciHal_check_factory_reset
 *
 * Description      This function is called at init time to check
 *                  the presence of ese related info. If file are not
 *                  present set the SWP_INT_SESSION_ID_CFG to FF to
 *                  force the NFCEE to re-run its initialization sequence.
 *
 * Returns          void.
 *
 ******************************************************************************/
static void phNxpNciHal_check_factory_reset(void)
{
    struct stat st;
    int ret = 0;
    NFCSTATUS status = NFCSTATUS_FAILED;
    const char config_eseinfo_path[] = "/data/nfc/nfaStorage.bin1";
    static uint8_t reset_ese_session_identity_set[] = { 0x20, 0x02, 0x17, 0x02,
                                      0xA0, 0xEA, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                      0xA0, 0xEB, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
#ifdef PN547C2_FACTORY_RESET_DEBUG
    static uint8_t reset_ese_session_identity[] = { 0x20, 0x03, 0x05, 0x02,
                                          0xA0, 0xEA, 0xA0, 0xEB};
#endif
    if (stat(config_eseinfo_path, &st) == -1)
    {
        NXPLOG_NCIHAL_D("%s file not present = %s", __FUNCTION__, config_eseinfo_path);
        ret = -1;
    }
    else
    {
        ret = 0;
    }

    if(ret == -1)
    {
#ifdef PN547C2_FACTORY_RESET_DEBUG
        /* NXP ACT Proprietary Ext */
        status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity),
                                           reset_ese_session_identity);
        if (status != NFCSTATUS_SUCCESS) {
            NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed");
        }
#endif
        status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity_set),
                                           reset_ese_session_identity_set);
        if (status != NFCSTATUS_SUCCESS) {
            NXPLOG_NCIHAL_E("NXP reset_ese_session_identity_set command failed");
        }
#ifdef PN547C2_FACTORY_RESET_DEBUG
        /* NXP ACT Proprietary Ext */
        status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity),
                                           reset_ese_session_identity);
        if (status != NFCSTATUS_SUCCESS) {
            NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed");
        }
#endif

    }
}

/******************************************************************************
 * Function         phNxpNciHal_print_res_status
 *
 * Description      This function is called to process the response status
 *                  and print the status byte.
 *
 * Returns          void.
 *
 ******************************************************************************/
static void phNxpNciHal_print_res_status( uint8_t *p_rx_data, uint16_t *p_len)
{
    static uint8_t response_buf[][30] = {"STATUS_OK",
                                     "STATUS_REJECTED",
                                     "STATUS_RF_FRAME_CORRUPTED" ,
                                     "STATUS_FAILED" ,
                                     "STATUS_NOT_INITIALIZED" ,
                                     "STATUS_SYNTAX_ERROR",
                                     "STATUS_SEMANTIC_ERROR",
                                     "RFU",
                                     "RFU",
                                     "STATUS_INVALID_PARAM",
                                     "STATUS_MESSAGE_SIZE_EXCEEDED",
                                     "STATUS_UNDEFINED"};
    int status_byte;
    if(p_rx_data[0] == 0x40 && (p_rx_data[1] == 0x02 || p_rx_data[1] == 0x03))
    {
        if(p_rx_data[2] &&  p_rx_data[3]<=10)
        {
            status_byte = p_rx_data[CORE_RES_STATUS_BYTE];
            NXPLOG_NCIHAL_D("%s: response status =%s",__FUNCTION__,response_buf[status_byte]);
        }
        else
        {
            NXPLOG_NCIHAL_D("%s: response status =%s",__FUNCTION__,response_buf[11]);
        }
        if(phNxpNciClock.isClockSet)
        {
            int i;
            for(i=0; i<* p_len; i++)
            {
                phNxpNciClock.p_rx_data[i] = p_rx_data[i];
            }
        }

        else if(phNxpNciRfSet.isGetRfSetting)
        {
            int i;
            for(i=0; i<* p_len; i++)
            {
                phNxpNciRfSet.p_rx_data[i] = p_rx_data[i];
                //NXPLOG_NCIHAL_D("%s: response status =0x%x",__FUNCTION__,p_rx_data[i]);
            }
        }
        else if (phNxpNciMwEepromArea.isGetEepromArea)
        {
            int i;
            for (i = 8; i < *p_len; i++)
            {
                phNxpNciMwEepromArea.p_rx_data[i - 8] = p_rx_data[i];
            }
        }
    }

    if (p_rx_data[2] && (config_access == TRUE))
    {
        if (p_rx_data[3] != NFCSTATUS_SUCCESS)
        {
            NXPLOG_NCIHAL_W ("Invalid Data from config file . Aborting..");
            phNxpNciHal_close ();
        }
    }
}

#if(NFC_NXP_CHIP_TYPE == PN548C2)
NFCSTATUS phNxpNciHal_core_reset_recovery ()
{
    NFCSTATUS status = NFCSTATUS_FAILED;

    uint8_t buffer[260];
    long bufflen = 260;

    /*NCI_INIT_CMD*/
    static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
    /*NCI_RESET_CMD*/
    static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00}; //keep configuration

    /* reset config cache */
    uint8_t retry_core_init_cnt = 0;

    if (discovery_cmd_len == 0)
    {
        goto FAILURE;
    }
    NXPLOG_NCIHAL_D ("%s: recovery", __FUNCTION__);

retry_core_init:
    if (retry_core_init_cnt > 3)
    {
        goto FAILURE;
    }

    status = phTmlNfc_IoCtl (phTmlNfc_e_ResetDevice);
    if (status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
        goto FAILURE;
    }
    status = phNxpNciHal_send_ext_cmd (sizeof(cmd_reset_nci), cmd_reset_nci);
    if ((status != NFCSTATUS_SUCCESS) && (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT))
    {
        retry_core_init_cnt++;
        goto retry_core_init;
    }
    else if (status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_D ("NCI_CORE_RESET: Failed");
        retry_core_init_cnt++;
        goto retry_core_init;
    }
    status = phNxpNciHal_send_ext_cmd (sizeof(cmd_init_nci), cmd_init_nci);
    if (status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_D ("NCI_CORE_INIT : Failed");
        retry_core_init_cnt++;
        goto retry_core_init;
    }

    status = phNxpNciHal_send_ext_cmd (discovery_cmd_len, discovery_cmd);
    if (status != NFCSTATUS_SUCCESS)
    {
        NXPLOG_NCIHAL_D ("RF_DISCOVERY : Failed");
        retry_core_init_cnt++;
        goto retry_core_init;
    }

    return NFCSTATUS_SUCCESS;
FAILURE:
    abort ();
}

void phNxpNciHal_discovery_cmd_ext (uint8_t *p_cmd_data, uint16_t cmd_len)
{
    NXPLOG_NCIHAL_D ("phNxpNciHal_discovery_cmd_ext");
    if (cmd_len > 0 && cmd_len <= sizeof(discovery_cmd))
    {
        memcpy (discovery_cmd, p_cmd_data, cmd_len);
        discovery_cmd_len = cmd_len;
    }
}
#endif