diff options
| author | anil.hiranniah <anil.hiranniah@nxp.com> | 2018-05-10 18:56:29 +0530 |
|---|---|---|
| committer | Ruchi Kandoi <kandoiruchi@google.com> | 2018-05-14 16:22:11 +0000 |
| commit | af6caa669b871bd44f372ceaf73e369da3088171 (patch) | |
| tree | 693cb78a20845c348aa9eb7b682ab7f3f06c1279 | |
| parent | b1a2fd7c86a343be909e9799dd60d73be075ab5c (diff) | |
| download | android_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-x | halimpl/dnld/phDnldNfc_Internal.cc | 8 | ||||
| -rwxr-xr-x | halimpl/hal/phNxpNciHal.cc | 156 | ||||
| -rwxr-xr-x | halimpl/tml/phTmlNfc.cc | 36 | ||||
| -rw-r--r--[-rwxr-xr-x] | halimpl/tml/phTmlNfc.h | 3 |
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, |
