From 6e5fb233746387ce0ad1f9865c237e9ce8b45b40 Mon Sep 17 00:00:00 2001 From: Jizhou Liao Date: Fri, 25 Sep 2015 02:11:07 -0700 Subject: Fix fail to wirte RF parameters Whenever receive invalid param respons during RF parameter update, this recovery mechanism includes dummy firmware download followed by firmware download and then re-update RF parameters. Change-Id: I8e47a86ff98a9ca8c30be52c231fd284cd825f4d --- halimpl/pn54x/common/phNfcStatus.h | 8 ++ halimpl/pn54x/dnld/phDnldNfc.c | 95 ++++++++++++- halimpl/pn54x/dnld/phDnldNfc.h | 3 + halimpl/pn54x/dnld/phDnldNfc_Internal.c | 8 +- halimpl/pn54x/dnld/phNxpNciHal_Dnld.c | 37 ++++- halimpl/pn54x/hal/phNxpNciHal.c | 230 +++++++++++++++++++++++++++++++- 6 files changed, 366 insertions(+), 15 deletions(-) diff --git a/halimpl/pn54x/common/phNfcStatus.h b/halimpl/pn54x/common/phNfcStatus.h index fb1d818..5d6c81d 100644 --- a/halimpl/pn54x/common/phNfcStatus.h +++ b/halimpl/pn54x/common/phNfcStatus.h @@ -182,6 +182,14 @@ */ #define NFCSTATUS_NOT_ALLOWED (0x003A) +/* + * FW version error while performing FW download, + * FW major version mismatch (cannot downgrade FW major version) or FW version already upto date + * User may be trying to flash Mobile FW on top of Infra FW, which is not allowed + * Download appropriate version of FW + */ +#define NFCSTATUS_FW_VERSION_ERROR (0x003C) + /* * The system is busy with the previous operation. */ diff --git a/halimpl/pn54x/dnld/phDnldNfc.c b/halimpl/pn54x/dnld/phDnldNfc.c index 512b186..a77f136 100644 --- a/halimpl/pn54x/dnld/phDnldNfc.c +++ b/halimpl/pn54x/dnld/phDnldNfc.c @@ -28,6 +28,9 @@ static void *pFwLibHandle; /* Global firmware lib handle used in this file only */ uint16_t wMwVer = 0; /* Middleware version no */ uint16_t wFwVer = 0; /* Firmware version no */ +#if(NFC_NXP_CHIP_TYPE == PN548C2) +uint8_t gRecFWDwnld; // flag set to true to indicate dummy FW download +#endif static pphDnldNfc_DlContext_t gpphDnldContext = NULL; /* Download contex */ static pphDnldNfc_RspCb_t UserCb; /* Upper layer call back function */ static void* UserCtxt; /* Pointer to upper layer context */ @@ -869,7 +872,12 @@ NFCSTATUS phDnldNfc_InitImgInfo(void) phDnldNfc_SetHwDevHandle(); /* load the library and get the image info pointer */ - wStatus = phDnldNfc_LoadFW(FW_LIB_PATH, &pImageInfo, &ImageInfoLen); +#if(NFC_NXP_CHIP_TYPE == PN548C2) + if (gRecFWDwnld == TRUE) + wStatus = phDnldNfc_LoadRecoveryFW (FW_LIB_PATH, &pImageInfo, &ImageInfoLen); + else +#endif + wStatus = phDnldNfc_LoadFW (FW_LIB_PATH, &pImageInfo, &ImageInfoLen); NXPLOG_FWDNLD_D("FW Image Length - ImageInfoLen %d",ImageInfoLen); NXPLOG_FWDNLD_D("FW Image Info Pointer - pImageInfo %x",(uintptr_t)pImageInfo); @@ -939,9 +947,12 @@ NFCSTATUS phDnldNfc_LoadRecInfo(void) /* if memory is not allocated then allocate memory for donwload context structure */ phDnldNfc_SetHwDevHandle(); - - wStatus = phDnldNfc_LoadFW(PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen); - +#if(NFC_NXP_CHIP_TYPE == PN548C2) + if (gRecFWDwnld == TRUE) + wStatus = phDnldNfc_LoadRecoveryFW (PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen); + else +#endif + wStatus = phDnldNfc_LoadFW (PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen); if((pImageInfo == NULL) || (ImageInfoLen == 0)) { NXPLOG_FWDNLD_E("Image extraction Failed - invalid imginfo or imginfolen!!"); @@ -997,8 +1008,12 @@ NFCSTATUS phDnldNfc_LoadPKInfo(void) phDnldNfc_SetHwDevHandle(); /* load the PKU image library */ - wStatus = phDnldNfc_LoadFW(PKU_LIB_PATH, &pImageInfo, &ImageInfoLen); - +#if(NFC_NXP_CHIP_TYPE == PN548C2) + if (gRecFWDwnld == TRUE) + wStatus = phDnldNfc_LoadRecoveryFW (PKU_LIB_PATH, &pImageInfo, &ImageInfoLen); + else +#endif + wStatus = phDnldNfc_LoadFW (PKU_LIB_PATH, &pImageInfo, &ImageInfoLen); if((pImageInfo == NULL) || (ImageInfoLen == 0)) { NXPLOG_FWDNLD_E("Image extraction Failed - invalid imginfo or imginfolen!!"); @@ -1133,6 +1148,74 @@ NFCSTATUS phDnldNfc_LoadFW(const char* pathName, uint8_t **pImgInfo, uint16_t* p return NFCSTATUS_SUCCESS; } +#if(NFC_NXP_CHIP_TYPE == PN548C2) +/******************************************************************************* +** +** Function phDnldNfc_LoadRecoveryFW +** +** Description Load the dummy firmware version form firmware lib for recovery +** This will change the FW version of the NFCC firmware +** and enable flashing of firmware of same version. +** +** Parameters pathName - Firmware image path +** pImgInfo - Firmware image handle +** pImgInfoLen - Firmware image length +** +** Returns NFCSTATUS +** +*******************************************************************************/ +NFCSTATUS phDnldNfc_LoadRecoveryFW (const char* pathName, uint8_t **pImgInfo, uint16_t* pImgInfoLen) +{ + void* pImageInfo = NULL; + void* pImageInfoLen = NULL; + + /* check for path name */ + if (pathName == NULL) + { + pathName = "/system/vendor/firmware/libpn548ad_fw.so"; + } + + /* check if the handle is not NULL then free the library */ + if (pFwLibHandle != NULL) + { + phDnldNfc_UnloadFW (); + pFwLibHandle = NULL; + } + /* load the DLL file */ + pFwLibHandle = dlopen (pathName, RTLD_LAZY); + NXPLOG_FWDNLD_D ("phDnldNfc_LoadRecoveryFW %s ", pathName); + + /* if library load failed then handle will be NULL */ + if (pFwLibHandle == NULL) + { + NXPLOG_FWDNLD_E("NULL handler : unable to load the library file, specify correct path"); + return NFCSTATUS_FAILED; + } + + dlerror (); /* Clear any existing error */ + + /* load the address of download image pointer and image size */ + pImageInfo = (void*)dlsym (pFwLibHandle, "gphDnldNfc_DummyDlSeq"); + + if (dlerror() || (NULL == pImageInfo)) + { + NXPLOG_FWDNLD_E ("Problem loading symbol : gphDnldNfc_DummyDlSeq"); + return NFCSTATUS_FAILED; + } + + (*pImgInfo) = (*(uint8_t**)pImageInfo); + pImageInfoLen = (void*)dlsym (pFwLibHandle, "gphDnldNfc_DlSeqDummyFwSz"); + if (dlerror() ||(NULL == pImageInfoLen)) + { + NXPLOG_FWDNLD_E ("Problem loading symbol : gphDnldNfc_DlSeqDummyFwSz"); + return NFCSTATUS_FAILED; + } + + (*pImgInfoLen) = (uint16_t)(*((uint16_t*)pImageInfoLen)); + + return NFCSTATUS_SUCCESS; +} +#endif /******************************************************************************* ** diff --git a/halimpl/pn54x/dnld/phDnldNfc.h b/halimpl/pn54x/dnld/phDnldNfc.h index df95c93..331d39b 100644 --- a/halimpl/pn54x/dnld/phDnldNfc.h +++ b/halimpl/pn54x/dnld/phDnldNfc.h @@ -104,5 +104,8 @@ extern NFCSTATUS phDnldNfc_LoadRecInfo(void); extern NFCSTATUS phDnldNfc_LoadPKInfo(void); extern void phDnldNfc_CloseFwLibHandle(void); extern NFCSTATUS phDnldNfc_LoadFW(const char* pathName, uint8_t **pImgInfo, uint16_t* pImgInfoLen); +#if(NFC_NXP_CHIP_TYPE == PN548C2) +extern NFCSTATUS phDnldNfc_LoadRecoveryFW (const char* pathName, uint8_t **pImgInfo, uint16_t* pImgInfoLen); +#endif extern NFCSTATUS phDnldNfc_UnloadFW(void); #endif /* PHDNLDNFC_H */ diff --git a/halimpl/pn54x/dnld/phDnldNfc_Internal.c b/halimpl/pn54x/dnld/phDnldNfc_Internal.c index 628e582..e97dd2f 100644 --- a/halimpl/pn54x/dnld/phDnldNfc_Internal.c +++ b/halimpl/pn54x/dnld/phDnldNfc_Internal.c @@ -275,6 +275,8 @@ static void phDnldNfc_ProcessSeqState(void *pContext, phTmlNfc_TransactInfo_t *p (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessSeqState, (void *)pDlCtxt); + /* set read status to pDlCtxt->wCmdSendStatus to enable callback */ + pDlCtxt->wCmdSendStatus = wStatus; break; } else @@ -454,6 +456,8 @@ static void phDnldNfc_ProcessRWSeqState(void *pContext, phTmlNfc_TransactInfo_t (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessRWSeqState, (void *)pDlCtxt); + /* set read status to pDlCtxt->wCmdSendStatus to enable callback */ + pDlCtxt->wCmdSendStatus = wStatus; break; } else @@ -1232,12 +1236,12 @@ static NFCSTATUS phDnldNfc_UpdateRsp(pphDnldNfc_DlContext_t pDlContext, phTmlN } else if(PH_DL_STATUS_FIRMWARE_VERSION_ERROR == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])) { - NXPLOG_FWDNLD_E("Firmware Already Up To Date!!"); + NXPLOG_FWDNLD_E("FW version Error !!!could be either due to FW major version mismatch or Firmware Already Up To Date !!"); (pDlContext->tRWInfo.bFirstWrReq) = FALSE; /* resetting wRemBytes to 0 to avoid any further write frames send */ (pDlContext->tRWInfo.wRemBytes) = 0; (pDlContext->tRWInfo.wOffset) = 0; - wStatus = NFCSTATUS_SUCCESS; + wStatus = NFCSTATUS_FW_VERSION_ERROR; } else if(PH_DL_STATUS_PLL_ERROR == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])) { diff --git a/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c index c8acb13..40e7f36 100644 --- a/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c +++ b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c @@ -35,7 +35,9 @@ /* External global variable to get FW version */ extern uint16_t wFwVer; extern uint16_t wMwVer; - +#if(NFC_NXP_CHIP_TYPE == PN548C2) +extern uint8_t gRecFWDwnld; +#endif /* RF Configuration structure */ typedef struct phLibNfc_IoctlSetRfConfig { @@ -179,6 +181,20 @@ static NFCSTATUS (*phNxpNciHal_dwnld_seqhandler[])( NULL }; +#if(NFC_NXP_CHIP_TYPE == PN548C2) +/* Array of pointers to start dummy fw download seq */ +static NFCSTATUS (*phNxpNciHal_dummy_rec_dwnld_seqhandler[])( + void* pContext, NFCSTATUS status, void* pInfo) = { + phNxpNciHal_fw_dnld_normal, + phNxpNciHal_fw_dnld_normal, + phNxpNciHal_fw_dnld_get_sessn_state, + phNxpNciHal_fw_dnld_get_version, + phNxpNciHal_fw_dnld_log_read, + phNxpNciHal_fw_dnld_write, + NULL +}; +#endif + /* Download Recovery Sequence */ static NFCSTATUS (*phNxpNciHal_dwnld_rec_seqhandler[])( void* pContext, NFCSTATUS status, void* pInfo) = { @@ -1671,6 +1687,12 @@ static NFCSTATUS phNxpNciHal_fw_dnld_complete(void* pContext,NFCSTATUS status, (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE; /* Perform the Logging sequence */ wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_log_seqhandler); + if (NFCSTATUS_SUCCESS != gphNxpNciHal_fw_IoctlCtx.bLastStatus) + { + /* update the previous Download Write status to upper layer and not the status of Log command */ + wStatus = gphNxpNciHal_fw_IoctlCtx.bLastStatus; + NXPLOG_FWDNLD_E ("phNxpNciHal_fw_dnld_complete: Last Download Write Status before Log command bLastStatus = 0x%x", gphNxpNciHal_fw_IoctlCtx.bLastStatus); + } status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo); if (NFCSTATUS_SUCCESS == status) { @@ -1680,7 +1702,6 @@ static NFCSTATUS phNxpNciHal_fw_dnld_complete(void* pContext,NFCSTATUS status, { NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED"); } - } else if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery)) { @@ -1727,6 +1748,7 @@ static NFCSTATUS phNxpNciHal_fw_dnld_complete(void* pContext,NFCSTATUS status, } else { + NXPLOG_FWDNLD_D ("phNxpNciHal_fw_dnld_complete: Download Status = 0x%x", status); if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) { if(NFCSTATUS_SUCCESS == status) @@ -1854,7 +1876,16 @@ NFCSTATUS phNxpNciHal_fw_download_seq(uint8_t bClkSrcVal, uint8_t bClkFreqVal) if (NFCSTATUS_SUCCESS == phDnldNfc_InitImgInfo()) { NXPLOG_FWDNLD_D("phDnldNfc_InitImgInfo:SUCCESS"); - status = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler); +#if(NFC_NXP_CHIP_TYPE == PN548C2) + if (gRecFWDwnld == TRUE) + { + status = phNxpNciHal_fw_seq_handler (phNxpNciHal_dummy_rec_dwnld_seqhandler); + } + else +#endif + { + status = phNxpNciHal_fw_seq_handler (phNxpNciHal_dwnld_seqhandler); + } } else { diff --git a/halimpl/pn54x/hal/phNxpNciHal.c b/halimpl/pn54x/hal/phNxpNciHal.c index 7732b89..9cee96a 100644 --- a/halimpl/pn54x/hal/phNxpNciHal.c +++ b/halimpl/pn54x/hal/phNxpNciHal.c @@ -55,6 +55,10 @@ extern uint16_t wFwVer; extern int send_to_upper_kovio; extern int kovio_detected; extern int disable_kovio; +#if(NFC_NXP_CHIP_TYPE == PN548C2) +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]; uint8_t discovery_cmd[50] = { 0 }; uint8_t discovery_cmd_len = 0; @@ -90,6 +94,10 @@ static NFCSTATUS phNxpNciHal_get_mw_eeprom (void); static NFCSTATUS phNxpNciHal_set_mw_eeprom (void); NFCSTATUS phNxpNciHal_check_clock_config(void); NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void); +#if(NFC_NXP_CHIP_TYPE == PN548C2) +static NFCSTATUS phNxpNciHalRFConfigCmdRecSequence (); +static NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus (); +#endif int check_config_parameter(); /****************************************************************************** @@ -332,6 +340,12 @@ static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void) NXPLOG_NCIHAL_D("Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE not defiend)"); } } +#if(NFC_NXP_CHIP_TYPE == PN548C2) + 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"); @@ -966,6 +980,9 @@ int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params) int temp_fix = 1; #if(NFC_NXP_CHIP_TYPE == PN548C2) unsigned long num = 0; + //initialize dummy FW recovery variables + gRecFwRetryCount = 0; + gRecFWDwnld = 0; #endif // recovery --start /*NCI_INIT_CMD*/ @@ -980,7 +997,10 @@ int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params) retry_core_init: config_access = FALSE; if(buffer != NULL) + { free(buffer); + buffer = NULL; + } if(retry_core_init_cnt > 3) { return NFCSTATUS_FAILED; @@ -1171,11 +1191,28 @@ retry_core_init: } #endif retlen = 0; +#if(NFC_NXP_CHIP_TYPE == PN548C2) + 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 == PN548C2) + 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++; @@ -1189,6 +1226,20 @@ retry_core_init: bufflen, &retlen); if (retlen > 0) { status = phNxpNciHal_send_ext_cmd(retlen, buffer); +#if(NFC_NXP_CHIP_TYPE == PN548C2) + 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++; @@ -1202,6 +1253,20 @@ retry_core_init: bufflen, &retlen); if (retlen > 0) { status = phNxpNciHal_send_ext_cmd(retlen, buffer); +#if(NFC_NXP_CHIP_TYPE == PN548C2) + 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++; @@ -1215,6 +1280,20 @@ retry_core_init: bufflen, &retlen); if (retlen > 0) { status = phNxpNciHal_send_ext_cmd(retlen, buffer); +#if(NFC_NXP_CHIP_TYPE == PN548C2) + 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++; @@ -1228,6 +1307,20 @@ retry_core_init: bufflen, &retlen); if (retlen > 0) { status = phNxpNciHal_send_ext_cmd(retlen, buffer); +#if(NFC_NXP_CHIP_TYPE == PN548C2) + 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++; @@ -1241,6 +1334,20 @@ retry_core_init: bufflen, &retlen); if (retlen > 0) { status = phNxpNciHal_send_ext_cmd(retlen, buffer); +#if(NFC_NXP_CHIP_TYPE == PN548C2) + 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++; @@ -1248,7 +1355,9 @@ retry_core_init: } } retlen = 0; - +#if(NFC_NXP_CHIP_TYPE == PN548C2) + 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); @@ -1277,18 +1386,37 @@ retry_core_init: } retlen = 0; - +#if(NFC_NXP_CHIP_TYPE == PN548C2) + 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 == PN548C2) + 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 == PN548C2) + config_access = TRUE; +#endif #if(NFC_NXP_CHIP_TYPE != PN547C2) retlen = 0; @@ -1563,8 +1691,13 @@ retry_core_init: if(buffer) { free(buffer); + buffer = NULL; } - +#if(NFC_NXP_CHIP_TYPE == PN548C2) + //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 @@ -1588,7 +1721,96 @@ invoke_callback: #endif return NFCSTATUS_SUCCESS; } - +#if(NFC_NXP_CHIP_TYPE == PN548C2) +/****************************************************************************** + * Function phNxpNciHal_CheckRFCmdRespStatus + * + * Description This function is called to check the resp status of + * RF update commands. + * + * Returns NFCSTATUS_SUCCESS if successful, + * NFCSTATUS_INVALID_PARAMETER if parameter is inavlid + * NFCSTATUS_FAILED if failed response + * + ******************************************************************************/ +NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus () +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + static uint16_t INVALID_PARAM = 0x09; + if ((nxpncihal_ctrl.rx_data_len > 0) && (nxpncihal_ctrl.p_rx_data[2] > 0)) + { + if (nxpncihal_ctrl.p_rx_data[3] == 0x09) + { + status = INVALID_PARAM; + } + else if (nxpncihal_ctrl.p_rx_data[3] != NFCSTATUS_SUCCESS) + { + status = NFCSTATUS_FAILED; + } + } + return status; +} +/****************************************************************************** + * Function phNxpNciHalRFConfigCmdRecSequence + * + * Description This function is called to handle dummy FW recovery sequence + * Whenever RF settings are failed to apply with invalid param + * response, recovery mechanism includes dummy firmware download + * followed by firmware download and then config settings. The dummy + * firmware changes the major number of the firmware inside NFCC. + * Then actual firmware dowenload will be successful. This can be + * retried maximum three times. + * + * Returns Always returns NFCSTATUS_SUCCESS + * + ******************************************************************************/ +NFCSTATUS phNxpNciHalRFConfigCmdRecSequence () +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint16_t recFWState = 1; + gRecFWDwnld = TRUE; + gRecFwRetryCount++; + if (gRecFwRetryCount > 0x03) + { + NXPLOG_NCIHAL_D ("Max retry count for RF config FW recovery exceeded "); + gRecFWDwnld = FALSE; + return NFCSTATUS_FAILED; + } + do { + status = phTmlNfc_IoCtl (phTmlNfc_e_ResetDevice); + phDnldNfc_InitImgInfo (); + if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion ()) + { + fw_download_success = 0; + status = phNxpNciHal_fw_download (); + if (status == NFCSTATUS_SUCCESS) + { + fw_download_success = 1; + status = phTmlNfc_Read( + nxpncihal_ctrl.p_cmd_data, + NCI_MAX_DATA_LEN, + (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete, + NULL); + if (status != NFCSTATUS_PENDING) + { + NXPLOG_NCIHAL_E ("TML Read status error status = %x", status); + phTmlNfc_Shutdown (); + status = NFCSTATUS_FAILED; + break; + } + } + else + { + status = NFCSTATUS_FAILED; + break; + } + } + gRecFWDwnld = FALSE; + }while (recFWState--); + gRecFWDwnld = FALSE; + return status; +} +#endif /****************************************************************************** * Function phNxpNciHal_core_initialized_complete * -- cgit v1.2.3