diff options
Diffstat (limited to 'pn54x/hal/phNxpNciHal.c')
-rw-r--r-- | pn54x/hal/phNxpNciHal.c | 2653 |
1 files changed, 2653 insertions, 0 deletions
diff --git a/pn54x/hal/phNxpNciHal.c b/pn54x/hal/phNxpNciHal.c new file mode 100644 index 0000000..5a799d5 --- /dev/null +++ b/pn54x/hal/phNxpNciHal.c @@ -0,0 +1,2653 @@ +/* + * 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 <phDal4Nfc_messageQueueLib.h> +#include <phDnldNfc.h> +#include <phNxpConfig.h> +#include <phNxpLog.h> +#include <phNxpNciHal.h> +#include <phNxpNciHal_Adaptation.h> +#include <phNxpNciHal_Dnld.h> +#include <phNxpNciHal_NfcDepSWPrio.h> +#include <phNxpNciHal_ext.h> +#include <phTmlNfc.h> +#include <sys/stat.h> +/*********************** Global Variables *************************************/ +#define PN547C2_CLOCK_SETTING +#undef PN547C2_FACTORY_RESET_DEBUG +#define CORE_RES_STATUS_BYTE 3 +/* FW Mobile major number */ +#define FW_MOBILE_MAJOR_NUMBER_PN553 0x01 +#define FW_MOBILE_MAJOR_NUMBER_PN81A 0x02 +#define FW_MOBILE_MAJOR_NUMBER_PN551 0x05 +#define FW_MOBILE_MAJOR_NUMBER_PN48AD 0x01 + +#if (NFC_NXP_CHIP_TYPE == PN551) +#define FW_MOBILE_MAJOR_NUMBER FW_MOBILE_MAJOR_NUMBER_PN551 +#elif (NFC_NXP_CHIP_TYPE == PN553) +#define FW_MOBILE_MAJOR_NUMBER FW_MOBILE_MAJOR_NUMBER_PN553 +#else +#define FW_MOBILE_MAJOR_NUMBER FW_MOBILE_MAJOR_NUMBER_PN48AD +#endif +/* 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; +static uint8_t config_success = true; +/* 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; +#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 +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; + /*NCI_RESET_CMD*/ + static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00}; + + 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); + if (status != NFCSTATUS_SUCCESS) { + /* Abort any pending read and write */ + phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci); + phTmlNfc_ReadAbort(); + phTmlNfc_WriteAbort(); + } + 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; + 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 == FW_MOBILE_MAJOR_NUMBER) || + ((ufw_current_major_no == FW_MOBILE_MAJOR_NUMBER_PN81A && + (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0))) +#if (NFC_NXP_CHIP_TYPE == PN553) + || ((rom_version == 0x00) && + (ufw_current_major_no == FW_MOBILE_MAJOR_NUMBER_PN81A)) +#endif + ) + + { + status = NFCSTATUS_SUCCESS; + } else if (ufw_current_major_no == sfw_infra_major_no) { + if (rom_version == FW_MOBILE_ROM_VERSION_PN553 && + nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) { + NXPLOG_NCIHAL_D(" PN81A allow Fw download with major number = 0x%x", + ufw_current_major_no); + status = NFCSTATUS_SUCCESS; + } else { + /* 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 " + "defined)"); + } + } + } +#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}; + /*NCI2_0_INIT_CMD*/ + static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00}; + if (nxpncihal_ctrl.halStatus == HAL_STATUS_OPEN) { + NXPLOG_NCIHAL_E("phNxpNciHal_open already open"); + return NFCSTATUS_SUCCESS; + } + /* 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; + /*nci version NCI_VERSION_UNKNOWN version by default*/ + nxpncihal_ctrl.nci_info.nci_version = NCI_VERSION_UNKNOWN; + /* 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_nci2_0), cmd_init_nci2_0); + if (status == NFCSTATUS_SUCCESS) { + if (nxpncihal_ctrl.nci_info.nci_version != NCI_VERSION_2_0) { + NXPLOG_NCIHAL_E("Chip is in NCI1.0 mode reset the chip again"); + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci); + if (status == NFCSTATUS_SUCCESS) { + if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) { + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), + cmd_init_nci2_0); + } else { + 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_E("FW version for FW file = 0x%x", wFwVer); + NXPLOG_NCIHAL_E("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!!!!"); + phOsalNfc_Timer_Cleanup(); + 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, "PN553")) && + (rom_version == FW_MOBILE_ROM_VERSION_PN553) && + (fw_maj_ver == 0x01 || fw_maj_ver == 0x02)) { + status = NFCSTATUS_SUCCESS; + } else if (!strcmp(COMPILATION_MW, "PN551") && + (rom_version == FW_MOBILE_ROM_VERSION_PN551) && + (fw_maj_ver == 0x05)) { + status = NFCSTATUS_SUCCESS; + } else if (!strcmp(COMPILATION_MW, "PN548C2") && + (rom_version == FW_MOBILE_ROM_VERSION_PN548AD) && + (fw_maj_ver == 0x01)) { + status = NFCSTATUS_SUCCESS; + } else if (!strcmp(COMPILATION_MW, "PN547C2") && + (rom_version == FW_MOBILE_ROM_VERSION_PN547C2) && + (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; + if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) { + return NFCSTATUS_FAILED; + } + /* 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 + + /* 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"); + /* 10ms delay to give NFCC wake up delay */ + usleep(1000 * 10); + 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 == TRUE && + (nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_RSP) { + 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] & NCI_MT_MASK) == NCI_MT_RSP || + ((icode_detected == true) && (icode_send_eof == 3))) { + /* Unlock semaphore */ + SEM_POST(&(nxpncihal_ctrl.ext_cb_data)); + } + } // Notification Checking + else if ((nxpncihal_ctrl.hal_ext_enabled == TRUE) && + ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_NTF) && + (nxpncihal_ctrl.nci_info.wait_for_ntf == TRUE)) { + /* Unlock semaphore waiting for only ntf*/ + SEM_POST(&(nxpncihal_ctrl.ext_cb_data)); + nxpncihal_ctrl.nci_info.wait_for_ntf = FALSE; + } + /* Read successful send the event to higher layer */ + else if ((nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) && + (status == NFCSTATUS_SUCCESS)) { + (*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 && + nxpncihal_ctrl.nci_info.wait_for_ntf == FALSE) { + NXPLOG_NCIHAL_E(" Ignoring read , HAL close triggered"); + 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}; + config_success = true; + 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 + static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00}; + /* reset config cache */ + static uint8_t retry_core_init_cnt; + if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) { + return NFCSTATUS_FAILED; + } + 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; + } + if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) { + status = + phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0); + } else { + 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 recovery mode and length of last command is 0 then only reset the P2P + // listen mode routing. + if ((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4) && + 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); + } + } + + if (config_success == false) return NFCSTATUS_FAILED; +#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); + phOsalNfc_Timer_Cleanup(); + phTmlNfc_Shutdown(); + 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}; + + if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) { + NXPLOG_NCIHAL_E("phNxpNciHal_close is already closed, ignoring close"); + return NFCSTATUS_FAILED; + } + 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; + if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) { + NXPLOG_NCIHAL_D("Power Cycle failed due to hal status not open"); + 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"); + } + + 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}; +#if (NFC_NXP_CHIP_TYPE == PN553) + uint8_t param_clock_src = 0x00; +#else + uint8_t param_clock_src = CLK_SRC_PLL; + param_clock_src = param_clock_src << 3; +#endif + + 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"); +#if (NFC_NXP_CHIP_TYPE == PN553) + param_clock_src = 0x01; +#else + param_clock_src = 0x11; +#endif + } + + 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) { +#if (NFC_NXP_CHIP_TYPE != PN553) + param_clock_src = param_clock_src << 3; +#endif + 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 cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 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"); + } + if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) { + status = + phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0); + } else { + 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", __func__, 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", __func__, + response_buf[status_byte]); + } else { + NXPLOG_NCIHAL_D("%s: response status =%s", __func__, 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",__func__,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."); + config_success = false; + } + } +} + +#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 + static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00}; + /* reset config cache */ + uint8_t retry_core_init_cnt = 0; + + if (discovery_cmd_len == 0) { + goto FAILURE; + } + NXPLOG_NCIHAL_D("%s: recovery", __func__); + +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; + } + if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) { + status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0); + } else { + 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 |