611 lines
21 KiB
C++
611 lines
21 KiB
C++
/*
|
|
* Copyright 2021 NXP
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#if (NXP_NFC_RECOVERY == TRUE)
|
|
|
|
#include "phNxpNciHal_Recovery.h"
|
|
|
|
#include <phDnldNfc.h>
|
|
#include <phNfcStatus.h>
|
|
#include <phNfcTypes.h>
|
|
#include <phNxpLog.h>
|
|
#include <phNxpNciHal.h>
|
|
#include <phNxpNciHal_Dnld.h>
|
|
#include <phNxpNciHal_ext.h>
|
|
#include <phOsalNfc_Timer.h>
|
|
#include <phTmlNfc.h>
|
|
#undef property_set
|
|
#undef PROPERTY_VALUE_MAX
|
|
#undef property_get
|
|
#include <cutils/properties.h>
|
|
#define MAX_CORE_RESET 3
|
|
|
|
extern phNxpNciProfile_Control_t nxpprofile_ctrl;
|
|
extern phNxpNciHal_Control_t nxpncihal_ctrl;
|
|
extern phTmlNfc_Context_t* gpphTmlNfc_Context;
|
|
extern void* phNxpNciHal_client_thread(void* arg);
|
|
|
|
static void phnxpNciHal_partialClose();
|
|
static NFCSTATUS phnxpNciHal_partialOpen();
|
|
|
|
// property name for storing boot time init status
|
|
const char* halInitProperty = "vendor.nfc.min_firmware";
|
|
|
|
/******************************************************************************
|
|
* Function getHalInitStatus
|
|
*
|
|
* Description Get property whether it is boot init/not
|
|
*
|
|
* Parameters Parameter to return the hal status is boot init/not.
|
|
*
|
|
* Returns None
|
|
*
|
|
******************************************************************************/
|
|
static void getHalInitStatus(char* halInitStatus) {
|
|
NXPLOG_NCIHAL_D("Enter : %s", __func__);
|
|
if (property_get(halInitProperty, halInitStatus, "Boot-time") != 0) {
|
|
NXPLOG_NCIHAL_E("Error in property_get : %s", __func__);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function setHalInitStatus
|
|
*
|
|
* Description To set property as per input whether it is boot init/not
|
|
*
|
|
* Parameters status to be updated in property
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
static void setHalInitStatus(const char* status) {
|
|
NXPLOG_NCIHAL_E("Enter : %s", __func__);
|
|
if (property_set(halInitProperty, status) != 0) {
|
|
NXPLOG_NCIHAL_E("Error in property_set : %s", __func__);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function phNxpNciHal_read_callback
|
|
*
|
|
* Description Callback function for read request to tml reader thread
|
|
*
|
|
* Parameters pContext - context value passed while callback register
|
|
* pInfo - Information which contains status and response
|
|
* buffers.
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
static void phNxpNciHal_read_callback(void* pContext,
|
|
phTmlNfc_TransactInfo_t* pInfo) {
|
|
UNUSED_PROP(pContext);
|
|
if (pInfo != NULL) {
|
|
NXPLOG_NCIHAL_E("%s Status %d", __func__, pInfo->wStatus);
|
|
if (pInfo->wStatus == NFCSTATUS_SUCCESS) {
|
|
nxpncihal_ctrl.p_rx_data = pInfo->pBuff;
|
|
nxpncihal_ctrl.rx_data_len = pInfo->wLength;
|
|
}
|
|
nxpncihal_ctrl.ext_cb_data.status = pInfo->wStatus;
|
|
} else {
|
|
nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_FAILED;
|
|
}
|
|
SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function phNxpNciHal_write_callback
|
|
*
|
|
* Description Callback function for write request to tml writer thread
|
|
*
|
|
* Parameters pContext - context value passed while callback register
|
|
* pInfo - Information which contains status and response
|
|
* buffers.
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
static void phNxpNciHal_write_callback(void* pContext,
|
|
phTmlNfc_TransactInfo_t* pInfo) {
|
|
UNUSED_PROP(pContext);
|
|
if (pInfo != NULL) {
|
|
if (pInfo->wStatus != NFCSTATUS_SUCCESS) {
|
|
NXPLOG_NCIHAL_E("write error status = 0x%x", pInfo->wStatus);
|
|
}
|
|
nxpncihal_ctrl.ext_cb_data.status = pInfo->wStatus;
|
|
} else {
|
|
nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_FAILED;
|
|
}
|
|
SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function phNxpNciHal_semWaitTimeout
|
|
*
|
|
* Description Helper function for global sem wait with timeout value
|
|
*
|
|
* Parameters timeout - wait timeout in nanoseconds
|
|
*
|
|
* Returns NFCSTATUS
|
|
*
|
|
******************************************************************************/
|
|
static NFCSTATUS phNxpNciHal_semWaitTimeout(long timeout) {
|
|
NFCSTATUS status = NFCSTATUS_FAILED;
|
|
int retVal = 0;
|
|
struct timespec ts;
|
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
ts.tv_nsec += timeout;
|
|
ts.tv_sec += ts.tv_nsec / 1000000000;
|
|
ts.tv_nsec %= 1000000000;
|
|
while ((retVal = sem_timedwait_monotonic_np(&nxpncihal_ctrl.ext_cb_data.sem, &ts)) == -1 &&
|
|
errno == EINTR) {
|
|
continue; /* Restart if interrupted by handler */
|
|
}
|
|
if (retVal == -1 && errno != ETIMEDOUT) {
|
|
NXPLOG_NCIHAL_E("%s : sem_timedwait failed : errno = 0x%x", __func__,
|
|
errno);
|
|
}
|
|
if (retVal != -1) {
|
|
status = nxpncihal_ctrl.ext_cb_data.status;
|
|
} else if (errno == ETIMEDOUT && retVal == -1) {
|
|
NXPLOG_NCIHAL_E("%s :timed out errno = 0x%x", __func__, errno);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function phNxpNciHal_writeCmd
|
|
*
|
|
* Description Helper function to write command to NFCC
|
|
*
|
|
* Parameters timeout - wait timeout in nanoseconds
|
|
*
|
|
* Returns NFCSTATUS
|
|
*
|
|
******************************************************************************/
|
|
static NFCSTATUS phNxpNciHal_writeCmd(uint16_t data_len, const uint8_t* p_data,
|
|
long timeout) {
|
|
NFCSTATUS status = NFCSTATUS_FAILED;
|
|
const char context[] = "RecoveryWrite";
|
|
|
|
if (p_data == NULL) {
|
|
NXPLOG_NCIHAL_E("Invalid Command Buffer");
|
|
return NFCSTATUS_INVALID_PARAMETER;
|
|
}
|
|
/* Create local copy of cmd_data */
|
|
memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
|
|
nxpncihal_ctrl.cmd_len = data_len;
|
|
status = phTmlNfc_Write(
|
|
(uint8_t*)nxpncihal_ctrl.p_cmd_data, (uint16_t)nxpncihal_ctrl.cmd_len,
|
|
(pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_write_callback,
|
|
(void*)context);
|
|
if (status == NFCSTATUS_PENDING) {
|
|
return phNxpNciHal_semWaitTimeout(timeout);
|
|
}
|
|
NXPLOG_NCIHAL_E("tml write request failed");
|
|
return status;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function phNxpNciHal_ReadResponse
|
|
*
|
|
* Description Helper function to read response from NFCC
|
|
*
|
|
* Parameters len - response buffer len
|
|
* rsp_buffer - Ptr to the response buffer
|
|
* timeout - wait timeout in nanoseconds
|
|
*
|
|
* Returns NFCSTATUS
|
|
*
|
|
******************************************************************************/
|
|
static NFCSTATUS phNxpNciHal_ReadResponse(uint16_t* len, uint8_t** rsp_buffer,
|
|
long timeout) {
|
|
NFCSTATUS status = NFCSTATUS_FAILED;
|
|
const char context[] = "RecoveryRead";
|
|
|
|
if (len == NULL) {
|
|
NXPLOG_NCIHAL_E("%s Invalid Parameters", __func__);
|
|
return NFCSTATUS_INVALID_PARAMETER;
|
|
}
|
|
status = phTmlNfc_Read(
|
|
nxpncihal_ctrl.p_rsp_data, NCI_MAX_DATA_LEN,
|
|
(pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_callback,
|
|
(void*)context);
|
|
if (phNxpNciHal_semWaitTimeout(timeout) == NFCSTATUS_SUCCESS) {
|
|
if (nxpncihal_ctrl.p_rx_data != NULL && nxpncihal_ctrl.rx_data_len > 0) {
|
|
*rsp_buffer = nxpncihal_ctrl.p_rx_data;
|
|
*len = nxpncihal_ctrl.rx_data_len;
|
|
status = NFCSTATUS_SUCCESS;
|
|
} else
|
|
status = NFCSTATUS_FAILED;
|
|
}
|
|
return status;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function phNxpNciHal_readNFCCClockCfgValues
|
|
*
|
|
* Description Helper function to read clock configuration from
|
|
* nfcc configuration file and stores value in global strcture
|
|
*
|
|
* Returns void
|
|
*
|
|
******************************************************************************/
|
|
static void phNxpNciHal_readNFCCClockCfgValues(void) {
|
|
unsigned long num = 0;
|
|
int isfound = 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;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function phNxpNciHal_determineChipType
|
|
*
|
|
* Description Helper function to determine the chip info in nci mode
|
|
* from NCI command and stores value in global strcture
|
|
*
|
|
* Returns bool
|
|
*
|
|
******************************************************************************/
|
|
static bool phNxpNciHal_determineChipType(void) {
|
|
const uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
|
|
uint8_t* rsp_buffer = NULL;
|
|
uint16_t rsp_len = 0;
|
|
uint8_t retry = 0;
|
|
bool status = false;
|
|
|
|
do {
|
|
if ((phNxpNciHal_writeCmd(sizeof(cmd_reset_nci), cmd_reset_nci,
|
|
WRITE_TIMEOUT_NS) != NFCSTATUS_SUCCESS)) {
|
|
NXPLOG_NCIHAL_E("NCI_CORE_RESET Write Failure ");
|
|
break;
|
|
}
|
|
// 10ms delay for first core reset response to avoid nfcc standby
|
|
usleep(NCI_RESET_RESP_READ_DELAY_US);
|
|
if ((phNxpNciHal_ReadResponse(&rsp_len, &rsp_buffer,
|
|
RESPONSE_READ_TIMEOUT_NS) !=
|
|
NFCSTATUS_SUCCESS) ||
|
|
(rsp_buffer == NULL)) {
|
|
NXPLOG_NCIHAL_E("NCI_CORE_RESET read response failed");
|
|
break;
|
|
}
|
|
if (rsp_buffer[NCI_RSP_IDX] == NCI_MSG_RSP) {
|
|
if ((phNxpNciHal_ReadResponse(&rsp_len, &rsp_buffer,
|
|
RESPONSE_READ_TIMEOUT_NS) !=
|
|
NFCSTATUS_SUCCESS) ||
|
|
(rsp_buffer == NULL)) {
|
|
NXPLOG_NCIHAL_E("NCI_CORE_RESET NTF read failed");
|
|
break;
|
|
}
|
|
if (rsp_buffer[NCI_RSP_IDX] == NCI_MSG_NTF) {
|
|
phNxpNciHal_configFeatureList(rsp_buffer, rsp_len);
|
|
status = true;
|
|
break;
|
|
}
|
|
} else {
|
|
NXPLOG_NCIHAL_E("NCI_CORE_RESPONSE Wrong Status");
|
|
}
|
|
} while (retry++ < MAX_CORE_RESET);
|
|
return status;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function phNxpNciHal_isSessionClosed
|
|
*
|
|
* Description Helper function to determine download session state
|
|
*
|
|
* Returns true means session closed
|
|
*
|
|
******************************************************************************/
|
|
bool phNxpNciHal_isSessionClosed(void) {
|
|
const uint8_t get_session_cmd[] = {0x00, 0x04, 0xF2, 0x00,
|
|
0x00, 0x00, 0xF5, 0x33};
|
|
uint8_t* rsp_buffer = NULL;
|
|
uint16_t rsp_len = 0;
|
|
|
|
if ((phNxpNciHal_writeCmd(sizeof(get_session_cmd), get_session_cmd,
|
|
WRITE_TIMEOUT_NS) == NFCSTATUS_SUCCESS)) {
|
|
if ((phNxpNciHal_ReadResponse(&rsp_len, &rsp_buffer,
|
|
RESPONSE_READ_TIMEOUT_NS) !=
|
|
NFCSTATUS_SUCCESS) ||
|
|
(rsp_buffer == NULL)) {
|
|
NXPLOG_NCIHAL_E("Get Session read response failed");
|
|
} else if (rsp_buffer[DL_RSP_STAT_IDX] == DL_MSG_STAT_RSP &&
|
|
rsp_buffer[DL_RSP_IDX] == DL_MSG_RSP) {
|
|
if (rsp_buffer[DL_RSP_SESS_IDX] == DL_SESSION_CLOSE_TAG) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function phNxpNciHal_determineChipTypeDlMode
|
|
*
|
|
* Description Helper function to determine the chip info in download mode
|
|
* from get version command and stores value in global strcture
|
|
*
|
|
* Returns bool
|
|
*
|
|
******************************************************************************/
|
|
static bool phNxpNciHal_determineChipTypeDlMode(void) {
|
|
const uint8_t get_version_cmd[] = {0x00, 0x04, 0xF1, 0x00,
|
|
0x00, 0x00, 0x6E, 0xEF};
|
|
uint8_t* rsp_buffer = NULL;
|
|
uint16_t rsp_len = 0;
|
|
|
|
if ((phNxpNciHal_writeCmd(sizeof(get_version_cmd), get_version_cmd,
|
|
WRITE_TIMEOUT_NS) == NFCSTATUS_SUCCESS)) {
|
|
if ((phNxpNciHal_ReadResponse(&rsp_len, &rsp_buffer,
|
|
RESPONSE_READ_TIMEOUT_NS) !=
|
|
NFCSTATUS_SUCCESS) ||
|
|
(rsp_buffer == NULL)) {
|
|
NXPLOG_NCIHAL_E("Get Version read response failed");
|
|
} else if (rsp_buffer[DL_RSP_STAT_IDX] == DL_MSG_STAT_RSP &&
|
|
rsp_buffer[DL_RSP_IDX] == DL_MSG_RSP) {
|
|
phNxpNciHal_configFeatureList(rsp_buffer, rsp_len);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function phNxpNciHal_RecoverFWTearDown
|
|
*
|
|
* Description Function to determine the NFCC state and recovery using
|
|
* minimal fw download.
|
|
*
|
|
* Parameters None
|
|
*
|
|
* Returns SUCCESS if recovery is successful else FAIL.
|
|
*
|
|
******************************************************************************/
|
|
void phNxpNciHal_RecoverFWTearDown(void) {
|
|
uint8_t nfcc_recovery_support = 0x00;
|
|
// status post boot completed
|
|
const char* status = "Boot-completed";
|
|
char halInitStatus[PROPERTY_VALUE_MAX] = {0};
|
|
|
|
NXPLOG_NCIHAL_D("phNxpNciHal_RecoverFWTearDown(): enter \n");
|
|
if (!GetNxpNumValue(NAME_NXP_NFCC_RECOVERY_SUPPORT, &nfcc_recovery_support,
|
|
sizeof(nfcc_recovery_support))) {
|
|
NXPLOG_NCIHAL_E("Failed to read NXP_NFC_RECOVERY_SUPPORT config :");
|
|
}
|
|
if (nfcc_recovery_support == 0x00) {
|
|
NXPLOG_NCIHAL_D("NFCC Recovery not supported");
|
|
return;
|
|
}
|
|
|
|
// If this is not boot time invocation return
|
|
getHalInitStatus(halInitStatus);
|
|
if (strncmp(halInitStatus, status, PROPERTY_VALUE_MAX) == 0) {
|
|
NXPLOG_NCIHAL_D("Not boot time, skip minimal FW download");
|
|
return;
|
|
} else {
|
|
NXPLOG_NCIHAL_D("boot time, check minimal FW download required");
|
|
}
|
|
|
|
if (phnxpNciHal_partialOpen() != NFCSTATUS_SUCCESS) {
|
|
NXPLOG_NCIHAL_E("Failed to Initialize Partial HAL for NFCC recovery \n");
|
|
return;
|
|
}
|
|
if (phTmlNfc_IoCtl(phTmlNfc_e_PowerReset) != NFCSTATUS_SUCCESS) {
|
|
NXPLOG_NCIHAL_E("Failed to Perform VEN RESET \n");
|
|
phnxpNciHal_partialClose();
|
|
return;
|
|
}
|
|
if (phNxpNciHal_determineChipType()) {
|
|
NXPLOG_NCIHAL_D("Recovery not required \n");
|
|
phnxpNciHal_partialClose();
|
|
setHalInitStatus(status);
|
|
return;
|
|
}
|
|
if (phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadModeWithVenRst) !=
|
|
NFCSTATUS_SUCCESS) {
|
|
NXPLOG_NCIHAL_E("Enable Download mode failed");
|
|
phnxpNciHal_partialClose();
|
|
setHalInitStatus(status);
|
|
return;
|
|
}
|
|
|
|
phTmlNfc_EnableFwDnldMode(true);
|
|
nxpncihal_ctrl.fwdnld_mode_reqd = TRUE;
|
|
bool bEnableNormalMode = true;
|
|
if (!phNxpNciHal_determineChipTypeDlMode()) {
|
|
NXPLOG_NCIHAL_E("Not able to determine chiptype");
|
|
} else if (nfcFL.chipType != sn100u) {
|
|
NXPLOG_NCIHAL_E("Recovery not supported for chiptype (%d)", nfcFL.chipType);
|
|
} else if (phNxpNciHal_isSessionClosed()) {
|
|
NXPLOG_NCIHAL_D("FW Dnld session is closed");
|
|
} else if (phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal,
|
|
nxpprofile_ctrl.bClkFreqVal, 0,
|
|
true) != NFCSTATUS_SUCCESS) {
|
|
NXPLOG_NCIHAL_E("Minimal FW Update failed \n");
|
|
} else {
|
|
/* In the success case, the phNxpNciHal_fw_download_seq() will enable normal
|
|
* mode */
|
|
bEnableNormalMode = false;
|
|
}
|
|
if (bEnableNormalMode) {
|
|
phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
|
|
}
|
|
phTmlNfc_IoCtl(phTmlNfc_e_PowerReset);
|
|
phnxpNciHal_partialClose();
|
|
// Minimal FW not required in this boot session
|
|
setHalInitStatus(status);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function phnxpNciHal_partialOpenCleanUp
|
|
*
|
|
* Description Helper function to cleanUp the Memory and flags from
|
|
* phnxpNciHal_partialOpen
|
|
*
|
|
* Parameters nfc_dev_node - dev node to be freed
|
|
*
|
|
* Returns NFCSTATUS
|
|
*******************************************************************************/
|
|
static int phnxpNciHal_partialOpenCleanUp(char* nfc_dev_node) {
|
|
if (nfc_dev_node != NULL) {
|
|
free(nfc_dev_node);
|
|
nfc_dev_node = NULL;
|
|
}
|
|
/* Report error status */
|
|
phNxpNciHal_cleanup_monitor();
|
|
nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
|
|
return NFCSTATUS_FAILED;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function phnxpNciHal_partialOpen
|
|
*
|
|
* Description Initialize the Minimal HAL
|
|
*
|
|
* Parameters none
|
|
*
|
|
* Returns NFCSTATUS
|
|
*******************************************************************************/
|
|
static NFCSTATUS phnxpNciHal_partialOpen(void) {
|
|
phOsalNfc_Config_t tOsalConfig;
|
|
phTmlNfc_Config_t tTmlConfig;
|
|
char* nfc_dev_node = NULL;
|
|
|
|
NXPLOG_NCIHAL_D("phnxpNciHal_partialOpen(): enter");
|
|
if (nxpncihal_ctrl.halStatus == HAL_STATUS_MIN_OPEN) {
|
|
NXPLOG_NCIHAL_D("phNxpNciHal: already open");
|
|
return NFCSTATUS_SUCCESS;
|
|
}
|
|
/* initialize trace level */
|
|
phNxpLog_InitializeLogLevel();
|
|
if (phNxpNciHal_init_monitor() == NULL) {
|
|
NXPLOG_NCIHAL_E("Init monitor failed");
|
|
return NFCSTATUS_FAILED;
|
|
}
|
|
/* Create the local semaphore */
|
|
if (phNxpNciHal_init_cb_data(&nxpncihal_ctrl.ext_cb_data, NULL) !=
|
|
NFCSTATUS_SUCCESS) {
|
|
NXPLOG_NCIHAL_D("Create ext_cb_data failed");
|
|
return NFCSTATUS_FAILED;
|
|
}
|
|
CONCURRENCY_LOCK();
|
|
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;
|
|
|
|
/*nci version NCI_VERSION_2_0 version by default for SN100 chip type*/
|
|
nxpncihal_ctrl.nci_info.nci_version = NCI_VERSION_2_0;
|
|
/* Read the nfc device node name */
|
|
nfc_dev_node = (char*)malloc(NXP_MAX_CONFIG_STRING_LEN * sizeof(char));
|
|
if (nfc_dev_node == NULL) {
|
|
NXPLOG_NCIHAL_D("malloc of nfc_dev_node failed ");
|
|
CONCURRENCY_UNLOCK();
|
|
return phnxpNciHal_partialOpenCleanUp(nfc_dev_node);
|
|
} else if (!GetNxpStrValue(NAME_NXP_NFC_DEV_NODE, nfc_dev_node,
|
|
NXP_MAX_CONFIG_STRING_LEN)) {
|
|
NXPLOG_NCIHAL_D(
|
|
"Invalid nfc device node name keeping the default device node "
|
|
"/dev/pn54x");
|
|
strlcpy(nfc_dev_node, "/dev/pn54x",
|
|
(NXP_MAX_CONFIG_STRING_LEN * sizeof(char)));
|
|
}
|
|
/* 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;
|
|
|
|
/* Set Default Fragment Length */
|
|
tTmlConfig.fragment_len = NCI_CMDRESP_MAX_BUFF_SIZE_PN557;
|
|
|
|
/* Initialize TML layer */
|
|
if (phTmlNfc_Init(&tTmlConfig) != NFCSTATUS_SUCCESS) {
|
|
NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
|
|
CONCURRENCY_UNLOCK();
|
|
return phnxpNciHal_partialOpenCleanUp(nfc_dev_node);
|
|
} else {
|
|
if (nfc_dev_node != NULL) {
|
|
free(nfc_dev_node);
|
|
nfc_dev_node = NULL;
|
|
}
|
|
}
|
|
/* Create the client thread */
|
|
if (pthread_create(&nxpncihal_ctrl.client_thread, NULL,
|
|
phNxpNciHal_client_thread, &nxpncihal_ctrl) != 0) {
|
|
NXPLOG_NCIHAL_E("pthread_create failed");
|
|
if (phTmlNfc_Shutdown_CleanUp() != NFCSTATUS_SUCCESS) {
|
|
NXPLOG_NCIHAL_E("phTmlNfc_Shutdown_CleanUp: Failed");
|
|
}
|
|
CONCURRENCY_UNLOCK();
|
|
return phnxpNciHal_partialOpenCleanUp(nfc_dev_node);
|
|
}
|
|
phNxpNciHal_readNFCCClockCfgValues();
|
|
CONCURRENCY_UNLOCK();
|
|
return NFCSTATUS_SUCCESS;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Function phnxpNciHal_partialClose
|
|
*
|
|
* Description close the Minimal HAL
|
|
*
|
|
* Parameters none
|
|
*
|
|
* Returns void
|
|
*******************************************************************************/
|
|
static void phnxpNciHal_partialClose(void) {
|
|
NFCSTATUS status = NFCSTATUS_SUCCESS;
|
|
phLibNfc_Message_t msg;
|
|
nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
|
|
|
|
if (NULL != gpphTmlNfc_Context->pDevHandle) {
|
|
msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
|
|
msg.pMsgData = NULL;
|
|
msg.Size = 0;
|
|
phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
|
|
/* Abort any pending read and write */
|
|
status = phTmlNfc_ReadAbort();
|
|
status = phTmlNfc_WriteAbort();
|
|
status = phTmlNfc_Shutdown();
|
|
if (0 != pthread_join(nxpncihal_ctrl.client_thread, (void**)NULL)) {
|
|
NXPLOG_TML_E("Fail to kill client thread!");
|
|
}
|
|
phTmlNfc_CleanUp();
|
|
phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
|
|
phNxpNciHal_cleanup_cb_data(&nxpncihal_ctrl.ext_cb_data);
|
|
memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
|
|
NXPLOG_NCIHAL_D("phnxpNciHal_partialClose - phOsalNfc_DeInit completed");
|
|
}
|
|
CONCURRENCY_UNLOCK();
|
|
phNxpNciHal_cleanup_monitor();
|
|
}
|
|
|
|
#endif
|