summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoranil.hiranniah <anil.hiranniah@nxp.com>2018-05-10 18:56:29 +0530
committerRuchi Kandoi <kandoiruchi@google.com>2018-05-14 16:22:11 +0000
commitaf6caa669b871bd44f372ceaf73e369da3088171 (patch)
tree693cb78a20845c348aa9eb7b682ab7f3f06c1279
parentb1a2fd7c86a343be909e9799dd60d73be075ab5c (diff)
downloadandroid_hardware_nxp_nfc-af6caa669b871bd44f372ceaf73e369da3088171.tar.gz
android_hardware_nxp_nfc-af6caa669b871bd44f372ceaf73e369da3088171.tar.bz2
android_hardware_nxp_nfc-af6caa669b871bd44f372ceaf73e369da3088171.zip
Fix FW Download read buffer corruption issue
Protect readInfo parameter updates by mutex. Update Readcomplete callback before and after FW Download. Bug: 77936959 Test: FW Download, NFC Enable, Disable & VTS Test. Change-Id: I69382ccb17e6f3429d252b8264f5c6143d223d20 (cherry picked from commit 6cd5592587f3c260cc422689184671f5a320e388)
-rwxr-xr-xhalimpl/dnld/phDnldNfc_Internal.cc8
-rwxr-xr-xhalimpl/hal/phNxpNciHal.cc156
-rwxr-xr-xhalimpl/tml/phTmlNfc.cc36
-rw-r--r--[-rwxr-xr-x]halimpl/tml/phTmlNfc.h3
4 files changed, 130 insertions, 73 deletions
diff --git a/halimpl/dnld/phDnldNfc_Internal.cc b/halimpl/dnld/phDnldNfc_Internal.cc
index f5cbb3a..887abe6 100755
--- a/halimpl/dnld/phDnldNfc_Internal.cc
+++ b/halimpl/dnld/phDnldNfc_Internal.cc
@@ -201,7 +201,13 @@ static void phDnldNfc_ProcessSeqState(void* pContext,
switch (pDlCtxt->tCurrState) {
case phDnldNfc_StateInit: {
NXPLOG_FWDNLD_D("Initializing Sequence..");
-
+ wStatus = phTmlNfc_UpdateReadCompleteCallback (
+ (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessSeqState);
+ if (NFCSTATUS_SUCCESS != wStatus) {
+ NXPLOG_FWDNLD_D(
+ "Registering phDnldNfc_ProcessSeqState for readComplete "
+ "Failed!!");
+ }
if (0 == (pDlCtxt->TimerInfo.dwRspTimerId)) {
TimerId = phOsalNfc_Timer_Create();
diff --git a/halimpl/hal/phNxpNciHal.cc b/halimpl/hal/phNxpNciHal.cc
index b616798..27d38c1 100755
--- a/halimpl/hal/phNxpNciHal.cc
+++ b/halimpl/hal/phNxpNciHal.cc
@@ -296,15 +296,40 @@ static void phNxpNciHal_kill_client_thread(
*
* Returns NFCSTATUS_SUCCESS if firmware download successful
* NFCSTATUS_FAILED in case of failure
+ * NFCSTATUS_REJECTED if FW version is invalid or if hardware
+ * criteria is not matching
*
******************************************************************************/
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) {
+ if (NFCSTATUS_SUCCESS != phNxpNciHal_CheckValidFwVersion()) {
+ return NFCSTATUS_REJECTED;
+ }
+
+ nfc_nci_IoctlInOutData_t data;
+ memset(&data, 0x00, sizeof(nfc_nci_IoctlInOutData_t));
+ data.inp.level = 0x03; // ioctl call arg value to get eSE power GPIO value = 0x03
+ int ese_gpio_value = phNxpNciHal_ioctl(HAL_NFC_GET_SPM_STATUS, &data);
+ NXPLOG_NCIHAL_D("eSE Power GPIO value = %d", ese_gpio_value);
+ if (ese_gpio_value != 0) {
+ NXPLOG_NCIHAL_E("FW download denied while SPI in use, Continue NFC init");
+ return NFCSTATUS_REJECTED;
+ }
+ nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_UNKNOWN;
+ phNxpNciHal_gpio_restore(GPIO_STORE);
+
+ int fw_retry_count = 0;
+ NFCSTATUS status = NFCSTATUS_REJECTED;
+ NXPLOG_NCIHAL_D("Starting FW update");
+ do {
+ fw_download_success = 0;
+ phNxpNciHal_get_clk_freq();
+ status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
+ if (NFCSTATUS_SUCCESS != status) {
+ fw_retry_count++;
+ NXPLOG_NCIHAL_D("Retrying: FW download");
+ continue;
+ }
+
if (nxpncihal_ctrl.bIsForceFwDwnld) {
status = phNxpNciHal_getChipInfoInFwDnldMode();
if (status != NFCSTATUS_SUCCESS) {
@@ -313,21 +338,55 @@ static NFCSTATUS phNxpNciHal_fw_download(void) {
}
nxpncihal_ctrl.bIsForceFwDwnld = false;
}
+
/* 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();
+ fw_retry_count++;
+ NXPLOG_NCIHAL_D("Retrying: FW download");
+ }
+ } while((fw_retry_count < 3) && (status != NFCSTATUS_SUCCESS));
+
+ 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();
+ status = NFCSTATUS_FAILED;
+ } else {
+ NXPLOG_NCIHAL_E("FW download failed, Continue NFCC init");
}
- phDnldNfc_ReSetHwDevHandle();
} else {
- status = NFCSTATUS_FAILED;
+ status = NFCSTATUS_SUCCESS;
+ fw_download_success = 1;
}
+
+ /*Keep Read Pending on I2C*/
+ NFCSTATUS readRestoreStatus = NFCSTATUS_FAILED;
+ readRestoreStatus = phTmlNfc_Read(
+ nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN,
+ (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
+ if (readRestoreStatus != NFCSTATUS_PENDING) {
+ NXPLOG_NCIHAL_E("TML Read status error status = %x", readRestoreStatus);
+ readRestoreStatus = phTmlNfc_Shutdown();
+ if (readRestoreStatus != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("TML Shutdown failed. Status = %x", readRestoreStatus);
+ }
+ }
+ phDnldNfc_ReSetHwDevHandle();
+
+ if (status == NFCSTATUS_SUCCESS) {
+ status = phNxpNciHal_nfcc_core_reset_init();
+ if (status == NFCSTATUS_SUCCESS) {
+ phNxpNciHal_gpio_restore(GPIO_RESTORE);
+ } else {
+ NXPLOG_NCIHAL_E("Failed to restore GPIO values!!!\n");
+ }
+ }
+
return status;
}
@@ -495,7 +554,6 @@ int phNxpNciHal_MinOpen (){
resetNxpConfig();
int init_retry_cnt = 0;
- int fw_retry_count = 0;
int8_t ret_val = 0x00;
phNxpNciHal_initialize_debug_enabled_flag();
@@ -610,16 +668,16 @@ init_retry:
goto clean_and_return;
}
- if(nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
+ 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 && (nfcFL.chipType == pn557)) {
+ if (status == NFCSTATUS_SUCCESS && (nfcFL.chipType == pn557)) {
NXPLOG_NCIHAL_E("Chip is in NCI1.0 mode reset the chip to 2.0 mode");
status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
- if(status == NFCSTATUS_SUCCESS) {
+ if (status == NFCSTATUS_SUCCESS) {
status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
- if(status == NFCSTATUS_SUCCESS) {
+ if (status == NFCSTATUS_SUCCESS) {
goto init_retry;
}
}
@@ -646,60 +704,18 @@ init_retry:
NXPLOG_NCIHAL_D("FW update not required");
phDnldNfc_ReSetHwDevHandle();
} else {
- nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_UNKNOWN;
- phNxpNciHal_gpio_restore(GPIO_STORE);
force_download:
- if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion()) {
- NXPLOG_NCIHAL_D("FW update required");
- fw_download_success = 0;
- nfc_nci_IoctlInOutData_t data;
- memset(&data, 0x00, sizeof(nfc_nci_IoctlInOutData_t));
- data.inp.level = 0x03; /* ioctl call arg value to get eSE power GPIO value = 0x03 */
- int ese_gpio_value = phNxpNciHal_ioctl(HAL_NFC_GET_SPM_STATUS, &data);
- NXPLOG_NCIHAL_D("eSE Power GPIO value = %d", ese_gpio_value);
- if(ese_gpio_value == 0) {
- status = phNxpNciHal_fw_download();
- if ((fw_retry_count < 3) && (status != NFCSTATUS_SUCCESS)) {
- fw_retry_count++;
- NXPLOG_NCIHAL_D("Retrying: FW download");
- goto force_download;
- }
- else 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;
- } else {
- NXPLOG_NCIHAL_E("FW download failed, Continue NFCC init");
- }
- } 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();
- }
-
- status = phNxpNciHal_nfcc_core_reset_init();
- if(status == NFCSTATUS_SUCCESS) {
- phNxpNciHal_gpio_restore(GPIO_RESTORE);
- } else {
- NXPLOG_NCIHAL_E("Failed to restore GPIO values!!!\n");
- }
- } else {
- NXPLOG_NCIHAL_E("FW download denied while SPI in use, Continue NFC init");
- }
+ status = phNxpNciHal_fw_download();
+ if (NFCSTATUS_FAILED == status){
+ wConfigStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ NXPLOG_NCIHAL_D("FW download Failed");
+ } else if (NFCSTATUS_REJECTED == status) {
+ wConfigStatus = NFCSTATUS_SUCCESS;
+ NXPLOG_NCIHAL_D("FW download Rejected. Continuiing Nfc Init");
+ } else {
+ wConfigStatus = NFCSTATUS_SUCCESS;
+ NXPLOG_NCIHAL_D("FW download Success");
}
}
diff --git a/halimpl/tml/phTmlNfc.cc b/halimpl/tml/phTmlNfc.cc
index 57fff2a..87ec71f 100755
--- a/halimpl/tml/phTmlNfc.cc
+++ b/halimpl/tml/phTmlNfc.cc
@@ -112,8 +112,10 @@ NFCSTATUS phTmlNfc_Init(pphTmlNfc_Config_t pConfig) {
gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
gpphTmlNfc_Context->tReadInfo.bThreadBusy = false;
gpphTmlNfc_Context->tWriteInfo.bThreadBusy = false;
-
- if (0 != sem_init(&gpphTmlNfc_Context->rxSemaphore, 0, 0)) {
+ if (pthread_mutex_init(&gpphTmlNfc_Context->readInfoUpdateMutex,
+ NULL) == -1) {
+ wInitStatus = NFCSTATUS_FAILED;
+ } else if (0 != sem_init(&gpphTmlNfc_Context->rxSemaphore, 0, 0)) {
wInitStatus = NFCSTATUS_FAILED;
} else if (0 != sem_init(&gpphTmlNfc_Context->txSemaphore, 0, 0)) {
wInitStatus = NFCSTATUS_FAILED;
@@ -337,6 +339,7 @@ static void * phTmlNfc_TmlThread(void* pParam) {
NXPLOG_TML_E("Numer of bytes read exceeds the limit 260.....\n");
sem_post(&gpphTmlNfc_Context->rxSemaphore);
} else {
+ pthread_mutex_lock(&gpphTmlNfc_Context->readInfoUpdateMutex);
memcpy(gpphTmlNfc_Context->tReadInfo.pBuffer, temp, dwNoBytesWrRd);
NXPLOG_TML_D("PN54X - I2C Read successful.....\n");
@@ -381,6 +384,7 @@ static void * phTmlNfc_TmlThread(void* pParam) {
tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
tMsg.pMsgData = &tDeferredInfo;
tMsg.Size = sizeof(tDeferredInfo);
+ pthread_mutex_unlock(&gpphTmlNfc_Context->readInfoUpdateMutex);
NXPLOG_TML_D("PN54X - Posting read message.....\n");
phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg);
}
@@ -593,6 +597,7 @@ NFCSTATUS phTmlNfc_Shutdown(void) {
usleep(1000);
sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
usleep(1000);
+ pthread_mutex_destroy(&gpphTmlNfc_Context->readInfoUpdateMutex);
if (0 != pthread_join(gpphTmlNfc_Context->readerThread, (void**)NULL)) {
NXPLOG_TML_E("Fail to kill reader thread!");
}
@@ -689,6 +694,30 @@ NFCSTATUS phTmlNfc_Write(uint8_t* pBuffer, uint16_t wLength,
/*******************************************************************************
**
+** Function phTmlNfc_UpdateReadCompleteCallback
+**
+** Description Updates the callback to be invoked after read completed
+**
+** Parameters pTmlReadComplete - pointer to the function to be invoked
+** upon completion of read operation
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - if TmlNfc context available
+** NFCSTATUS_FAILED - otherwise
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_UpdateReadCompleteCallback (
+ pphTmlNfc_TransactCompletionCb_t pTmlReadComplete) {
+ NFCSTATUS wStatus = NFCSTATUS_FAILED;
+ if ((NULL != gpphTmlNfc_Context) && (NULL != pTmlReadComplete)) {
+ gpphTmlNfc_Context->tReadInfo.pThread_Callback = pTmlReadComplete;
+ wStatus = NFCSTATUS_SUCCESS;
+ }
+ return wStatus;
+}
+
+/*******************************************************************************
+**
** Function phTmlNfc_Read
**
** Description Asynchronously reads data from the driver
@@ -722,6 +751,7 @@ NFCSTATUS phTmlNfc_Read(uint8_t* pBuffer, uint16_t wLength,
if ((gpphTmlNfc_Context->pDevHandle != NULL) && (NULL != pBuffer) &&
(PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlReadComplete)) {
if (!gpphTmlNfc_Context->tReadInfo.bThreadBusy) {
+ pthread_mutex_lock(&gpphTmlNfc_Context->readInfoUpdateMutex);
/* Setting the flag marks beginning of a Read Operation */
gpphTmlNfc_Context->tReadInfo.bThreadBusy = true;
/* Copy the buffer, length and Callback function,
@@ -735,6 +765,8 @@ NFCSTATUS phTmlNfc_Read(uint8_t* pBuffer, uint16_t wLength,
/* Set event to invoke Reader Thread */
gpphTmlNfc_Context->tReadInfo.bEnable = 1;
+ pthread_mutex_unlock(&gpphTmlNfc_Context->readInfoUpdateMutex);
+
sem_post(&gpphTmlNfc_Context->rxSemaphore);
} else {
wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY);
diff --git a/halimpl/tml/phTmlNfc.h b/halimpl/tml/phTmlNfc.h
index 3955354..03cde41 100755..100644
--- a/halimpl/tml/phTmlNfc.h
+++ b/halimpl/tml/phTmlNfc.h
@@ -161,6 +161,7 @@ typedef struct phTmlNfc_Context {
sem_t txSemaphore; /* Lock/Aquire txRx Semaphore */
sem_t postMsgSemaphore; /* Semaphore to post message atomically by Reader &
writer thread */
+ pthread_mutex_t readInfoUpdateMutex; /*Mutex to synchronize read Info update*/
} phTmlNfc_Context_t;
/*
@@ -218,6 +219,8 @@ NFCSTATUS phTmlNfc_Read(uint8_t* pBuffer, uint16_t wLength,
NFCSTATUS phTmlNfc_WriteAbort(void);
NFCSTATUS phTmlNfc_ReadAbort(void);
NFCSTATUS phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode);
+NFCSTATUS phTmlNfc_UpdateReadCompleteCallback (
+ pphTmlNfc_TransactCompletionCb_t pTmlReadComplete);
void phTmlNfc_DeferredCall(uintptr_t dwThreadId,
phLibNfc_Message_t* ptWorkerMsg);
void phTmlNfc_ConfigNciPktReTx(phTmlNfc_ConfigRetrans_t eConfig,