| /* |
| * Copyright (C) 2015 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 <phTmlNfc.h> |
| #include <phDnldNfc.h> |
| #include <phNxpNciHal_Dnld.h> |
| #include <phNxpNciHal_utils.h> |
| #include <phNxpLog.h> |
| #include <phNxpConfig.h> |
| |
| /* Macro */ |
| #define PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS 3 |
| #define PHLIBNFC_IOCTL_DNLD_GETVERLEN (0x0BU) |
| #define PHLIBNFC_IOCTL_DNLD_GETVERLEN_MRA2_1 (0x09U) |
| #define PHLIBNFC_DNLD_MEM_READ (0xECU) |
| #define PHLIBNFC_DNLD_MEM_WRITE (0xEDU) |
| #define PHLIBNFC_DNLD_READ_LOG (0xEEU) |
| #define NFC_MEM_READ (0xD0U) |
| #define NFC_MEM_WRITE (0xD1U) |
| #define NFC_FW_DOWNLOAD (0x09F7U) |
| |
| /* External global variable to get FW version */ |
| extern uint16_t wFwVer; |
| extern uint16_t wMwVer; |
| #if(NFC_NXP_CHIP_TYPE != PN547C2) |
| extern uint8_t gRecFWDwnld; /* flag set to true to indicate dummy FW download */ |
| #endif |
| /* RF Configuration structure */ |
| typedef struct phLibNfc_IoctlSetRfConfig |
| { |
| uint8_t bNumOfParams; /* Number of Rf configurable parameters to be set */ |
| uint8_t *pInputBuffer; /* Buffer containing Rf configurable parameters */ |
| uint8_t bSetSysPmuFlag; /* Flag to decide wether to set SystemPmu or no from the first byte */ |
| }phLibNfc_IoctlSetRfConfig; |
| |
| /* Structure to hold information from EEPROM */ |
| typedef struct phLibNfc_EELogParams |
| { |
| uint16_t wCurrMwVer; /* Holds current MW version on the chip */ |
| uint16_t wCurrFwVer; /* Holds current FW version on the chip */ |
| uint16_t wNumDnldTrig; /* Total number of times dnld has been attempted */ |
| uint16_t wNumDnldSuccess; /* Total number of times dnld has been successful */ |
| uint16_t wNumDnldFail; /* Total number of times dnld has Failed */ |
| uint16_t wDnldFailCnt; /* holds the number of times dnld has failed,will be reset on success */ |
| bool_t bConfig; /* Flag to be set in dnld mode after successful dnld,to be reset in NCI Mode |
| after setting the NCI configuration */ |
| } phLibNfc_EELogParams_t; |
| |
| /* FW download module context structure */ |
| typedef struct |
| { |
| bool_t bDnldEepromWrite; /* Flag to indicate eeprom write request*/ |
| bool_t bSkipSeq; /* Flag to indicate FW download sequence to be skipped or not */ |
| bool_t bSkipReset; /* Flag to indicate Reset cmd to be skipped or not in FW download sequence */ |
| bool_t bSkipForce; /* Flag to indicate Force cmd to be skipped or not in FW recovery sequence */ |
| bool_t bPrevSessnOpen; /* Flag to indicate previous download session is open or not */ |
| bool_t bLibNfcCtxtMem; /* flag to indicate if mem was allocated for gpphLibNfc_Context */ |
| bool_t bDnldInitiated; /* Flag to indicate if fw upgrade was initiated */ |
| bool_t bSendNciCmd; /* Flag to indicate if NCI cmd to be sent or not,after PKU */ |
| uint8_t bChipVer; /* holds the hw chip version */ |
| bool_t bDnldRecovery; /* Flag to indicate if dnld recovery sequence needs to be triggered */ |
| bool_t bForceDnld; /* Flag to indicate if forced download option is enabled */ |
| bool_t bRetryDnld; /* Flag to indicate retry download after successful recovery complete */ |
| uint8_t bDnldAttempts; /* Holds the count of no. of dnld attempts made.max 3 */ |
| uint16_t IoctlCode; /* Ioctl code*/ |
| bool_t bDnldAttemptFailed; /* Flag to indicate last download attempt failed */ |
| NFCSTATUS bLastStatus; /* Holds the actual download write attempt status */ |
| phLibNfc_EELogParams_t tLogParams; /* holds the params that could be logged to reserved EE address */ |
| uint8_t bClkSrcVal; /* Holds the System clock source read from config file */ |
| uint8_t bClkFreqVal; /* Holds the System clock frequency read from config file */ |
| } phNxpNciHal_fw_Ioctl_Cntx_t; |
| |
| |
| /* Global variables used in this file only*/ |
| static phNxpNciHal_fw_Ioctl_Cntx_t gphNxpNciHal_fw_IoctlCtx; |
| |
| /* Local function prototype */ |
| static NFCSTATUS |
| phNxpNciHal_fw_dnld_reset(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static void |
| phNxpNciHal_fw_dnld_reset_cb(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static NFCSTATUS |
| phNxpNciHal_fw_dnld_force(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static void |
| phNxpNciHal_fw_dnld_force_cb(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static void |
| phNxpNciHal_fw_dnld_normal_cb(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static NFCSTATUS |
| phNxpNciHal_fw_dnld_normal(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static void |
| phNxpNciHal_fw_dnld_get_version_cb(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static NFCSTATUS |
| phNxpNciHal_fw_dnld_get_version(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static void |
| phNxpNciHal_fw_dnld_get_sessn_state_cb(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static NFCSTATUS |
| phNxpNciHal_fw_dnld_get_sessn_state(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static void |
| phNxpNciHal_fw_dnld_log_read_cb(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static NFCSTATUS |
| phNxpNciHal_fw_dnld_log_read(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static void |
| phNxpNciHal_fw_dnld_write_cb(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static NFCSTATUS |
| phNxpNciHal_fw_dnld_write(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static void |
| phNxpNciHal_fw_dnld_chk_integrity_cb(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static NFCSTATUS |
| phNxpNciHal_fw_dnld_chk_integrity(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static void |
| phNxpNciHal_fw_dnld_log_cb(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static NFCSTATUS |
| phNxpNciHal_fw_dnld_log(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static void |
| phNxpNciHal_fw_dnld_send_ncicmd_Cb(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static NFCSTATUS |
| phNxpNciHal_fw_dnld_send_ncicmd(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static NFCSTATUS |
| phNxpNciHal_fw_dnld_recover(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| static NFCSTATUS |
| phNxpNciHal_fw_dnld_complete(void* pContext, NFCSTATUS status, void* pInfo); |
| |
| /** Internal function to verify Crc Status byte received during CheckIntegrity */ |
| static NFCSTATUS |
| phLibNfc_VerifyCrcStatus(uint8_t bCrcStatus); |
| |
| static void phNxpNciHal_fw_dnld_recover_cb(void* pContext, NFCSTATUS status, |
| void* pInfo); |
| |
| static NFCSTATUS phNxpNciHal_fw_seq_handler(NFCSTATUS (*seq_handler[])(void* pContext, NFCSTATUS status, void* pInfo)); |
| |
| /* Array of pointers to start fw download seq */ |
| static NFCSTATUS (*phNxpNciHal_dwnld_seqhandler[])( |
| void* pContext, NFCSTATUS status, void* pInfo) = { |
| #if(NFC_NXP_CHIP_TYPE == PN547C2) |
| phNxpNciHal_fw_dnld_normal, |
| phNxpNciHal_fw_dnld_normal, |
| #endif |
| phNxpNciHal_fw_dnld_get_sessn_state, |
| phNxpNciHal_fw_dnld_get_version, |
| phNxpNciHal_fw_dnld_log_read, |
| phNxpNciHal_fw_dnld_write, |
| phNxpNciHal_fw_dnld_get_sessn_state, |
| phNxpNciHal_fw_dnld_get_version, |
| phNxpNciHal_fw_dnld_log, |
| phNxpNciHal_fw_dnld_chk_integrity, |
| NULL |
| }; |
| |
| #if(NFC_NXP_CHIP_TYPE != PN547C2) |
| /* 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) = { |
| phNxpNciHal_fw_dnld_reset, |
| phNxpNciHal_fw_dnld_force, |
| phNxpNciHal_fw_dnld_recover, |
| phNxpNciHal_fw_dnld_send_ncicmd, |
| NULL |
| }; |
| |
| /* Download Log Sequence */ |
| static NFCSTATUS (*phNxpNciHal_dwnld_log_seqhandler[])( |
| void* pContext, NFCSTATUS status, void* pInfo) = { |
| phNxpNciHal_fw_dnld_log, |
| NULL |
| }; |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_reset_cb |
| ** |
| ** Description Download Reset callback |
| ** |
| ** Returns None |
| ** |
| *******************************************************************************/ |
| static void phNxpNciHal_fw_dnld_reset_cb(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; |
| UNUSED(pInfo); |
| if (NFCSTATUS_SUCCESS == status) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_reset_cb - Request Successful"); |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset_cb - Request Failed!!"); |
| } |
| p_cb_data->status = status; |
| |
| SEM_POST(p_cb_data); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_reset |
| ** |
| ** Description Download Reset |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_dnld_reset(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| phNxpNciHal_Sem_t cb_data; |
| UNUSED(pContext); |
| UNUSED(status); |
| UNUSED(pInfo); |
| if((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) || (TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipReset))) |
| { |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipReset)) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = FALSE; |
| } |
| return NFCSTATUS_SUCCESS; |
| } |
| |
| if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data failed"); |
| return NFCSTATUS_FAILED; |
| } |
| wStatus = phDnldNfc_Reset((pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_reset_cb, (void*) &cb_data); |
| |
| if (wStatus != NFCSTATUS_PENDING) |
| { |
| NXPLOG_FWDNLD_E("phDnldNfc_Reset failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| /* Wait for callback response */ |
| if (SEM_WAIT(cb_data)) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset semaphore error"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| if (cb_data.status != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset cb failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| wStatus = NFCSTATUS_SUCCESS; |
| |
| clean_and_return: |
| phNxpNciHal_cleanup_cb_data(&cb_data); |
| |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_normal_cb |
| ** |
| ** Description Download Normal callback |
| ** |
| ** Returns None |
| ** |
| *******************************************************************************/ |
| static void phNxpNciHal_fw_dnld_normal_cb(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; |
| UNUSED(pInfo); |
| if (NFCSTATUS_SUCCESS == status) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_normal_cb - Request Successful"); |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal_cb - Request Failed!!"); |
| /* In this fail scenario trick the sequence handler to call next recover sequence */ |
| status = NFCSTATUS_SUCCESS; |
| } |
| p_cb_data->status = status; |
| |
| SEM_POST(p_cb_data); |
| usleep(1000 * 10); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_force_cb |
| ** |
| ** Description Download Force callback |
| ** |
| ** Returns None |
| ** |
| *******************************************************************************/ |
| static void phNxpNciHal_fw_dnld_force_cb(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; |
| UNUSED(pInfo); |
| if (NFCSTATUS_SUCCESS == status) |
| { |
| NXPLOG_FWDNLD_D("phLibNfc_DnldForceCb - Request Successful"); |
| (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = TRUE; |
| (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = TRUE; |
| } |
| else |
| { |
| /* In this fail scenario trick the sequence handler to call next recover sequence */ |
| status = NFCSTATUS_SUCCESS; |
| NXPLOG_FWDNLD_E("phLibNfc_DnldForceCb - Request Failed!!"); |
| |
| } |
| p_cb_data->status = status; |
| |
| SEM_POST(p_cb_data); |
| usleep(1000 * 10); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_normal |
| ** |
| ** Description Download Normal |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_dnld_normal(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| uint8_t bClkVal[2]; |
| phDnldNfc_Buff_t tData; |
| phNxpNciHal_Sem_t cb_data; |
| UNUSED(pContext); |
| UNUSED(status); |
| UNUSED(pInfo); |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipForce)) |
| { |
| return NFCSTATUS_SUCCESS; |
| } |
| else |
| { |
| /* |
| bClkVal[0] = NXP_SYS_CLK_SRC_SEL; |
| bClkVal[1] = NXP_SYS_CLK_FREQ_SEL; |
| */ |
| bClkVal[0] = gphNxpNciHal_fw_IoctlCtx.bClkSrcVal; |
| bClkVal[1] = gphNxpNciHal_fw_IoctlCtx.bClkFreqVal; |
| |
| (tData.pBuff) = bClkVal; |
| (tData.wLen) = sizeof(bClkVal); |
| |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery)) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++; |
| } |
| |
| if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data failed"); |
| return NFCSTATUS_FAILED; |
| } |
| wStatus = phDnldNfc_Force(&tData,(pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_normal_cb, (void*) &cb_data); |
| |
| if(NFCSTATUS_PENDING != wStatus) |
| { |
| NXPLOG_FWDNLD_E("phDnldNfc_Normal failed"); |
| (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE; |
| goto clean_and_return; |
| } |
| } |
| |
| /* Wait for callback response */ |
| if (SEM_WAIT(cb_data)) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal semaphore error"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| if (cb_data.status != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal cb failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| wStatus = NFCSTATUS_SUCCESS; |
| |
| clean_and_return: |
| phNxpNciHal_cleanup_cb_data(&cb_data); |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_force |
| ** |
| ** Description Download Force |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_dnld_force(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| uint8_t bClkVal[2]; |
| phDnldNfc_Buff_t tData; |
| phNxpNciHal_Sem_t cb_data; |
| UNUSED(pContext); |
| UNUSED(status); |
| UNUSED(pInfo); |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipForce)) |
| { |
| return NFCSTATUS_SUCCESS; |
| } |
| else |
| { |
| /* |
| bClkVal[0] = NXP_SYS_CLK_SRC_SEL; |
| bClkVal[1] = NXP_SYS_CLK_FREQ_SEL; |
| */ |
| bClkVal[0] = gphNxpNciHal_fw_IoctlCtx.bClkSrcVal; |
| bClkVal[1] = gphNxpNciHal_fw_IoctlCtx.bClkFreqVal; |
| |
| (tData.pBuff) = bClkVal; |
| (tData.wLen) = sizeof(bClkVal); |
| |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery)) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++; |
| } |
| |
| if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data failed"); |
| return NFCSTATUS_FAILED; |
| } |
| wStatus = phDnldNfc_Force(&tData,(pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_force_cb, (void*) &cb_data); |
| |
| if(NFCSTATUS_PENDING != wStatus) |
| { |
| NXPLOG_FWDNLD_E("phDnldNfc_Force failed"); |
| (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE; |
| goto clean_and_return; |
| } |
| } |
| |
| /* Wait for callback response */ |
| if (SEM_WAIT(cb_data)) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_force semaphore error"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| if (cb_data.status != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_force cb failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| wStatus = NFCSTATUS_SUCCESS; |
| |
| clean_and_return: |
| phNxpNciHal_cleanup_cb_data(&cb_data); |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_get_version_cb |
| ** |
| ** Description Download Get version callback |
| ** |
| ** Returns None |
| ** |
| *******************************************************************************/ |
| static void phNxpNciHal_fw_dnld_get_version_cb(void* pContext, |
| NFCSTATUS status, void* pInfo) |
| { |
| phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; |
| NFCSTATUS wStatus = status; |
| pphDnldNfc_Buff_t pRespBuff; |
| uint16_t wFwVern = 0; |
| uint16_t wMwVern = 0; |
| uint8_t bHwVer = 0; |
| uint8_t bExpectedLen = 0; |
| uint8_t bNewVer[2]; |
| uint8_t bCurrVer[2]; |
| |
| if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo)) |
| { |
| NXPLOG_FWDNLD_D ("phNxpNciHal_fw_dnld_get_version_cb - Request Successful"); |
| |
| pRespBuff = (pphDnldNfc_Buff_t) pInfo; |
| |
| if ((0 != pRespBuff->wLen) && (NULL != pRespBuff->pBuff)) |
| { |
| bHwVer = (pRespBuff->pBuff[0]); |
| bHwVer &= 0x0F; /* 0x0F is the mask to extract chip version */ |
| |
| if ((PHDNLDNFC_HWVER_MRA2_1 == bHwVer) || (PHDNLDNFC_HWVER_MRA2_2 == bHwVer) |
| #if(NFC_NXP_CHIP_TYPE == PN551) |
| || (PHDNLDNFC_HWVER_PN551_MRA1_0 == bHwVer)|| (PHDNLDNFC_HWVER_PN553_MRA1_0 == bHwVer) |
| #elif(NFC_NXP_CHIP_TYPE == PN548C2) |
| || (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bHwVer) |
| #elif(NFC_NXP_CHIP_TYPE == PN553) |
| || (PHDNLDNFC_HWVER_PN553_MRA1_0 == bHwVer || PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0]) |
| #endif |
| ) |
| { |
| bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN_MRA2_1; |
| (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer; |
| #if(NFC_NXP_CHIP_TYPE == PN553) |
| if(PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0]) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.bChipVer) = pRespBuff->pBuff[0]; |
| } |
| #endif |
| |
| } |
| else if ((bHwVer >= PHDNLDNFC_HWVER_MRA1_0) && (bHwVer |
| <= PHDNLDNFC_HWVER_MRA2_0)) |
| { |
| bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN; |
| (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer; |
| } |
| else |
| { |
| wStatus = NFCSTATUS_FAILED; |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Invalid ChipVersion!!"); |
| } |
| } |
| else |
| { |
| wStatus = NFCSTATUS_FAILED; |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Version Resp Buff Invalid...\n"); |
| } |
| |
| if ((NFCSTATUS_SUCCESS == wStatus) && (bExpectedLen == pRespBuff->wLen) |
| && (NULL != pRespBuff->pBuff)) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_get_version_cb - Valid Version Resp Buff!!...\n"); |
| |
| /* Validate version details to confirm if continue with the next sequence of Operations. */ |
| memcpy(bCurrVer, &(pRespBuff->pBuff[bExpectedLen - 2]), |
| sizeof(bCurrVer)); |
| wFwVern = wFwVer; |
| wMwVern = wMwVer; |
| |
| memcpy(bNewVer,&wFwVern,sizeof(bNewVer)); |
| |
| /* check if the ROM code version and FW Major version is valid for the chip*/ |
| /* ES2.2 Rom Version - 0x7 and Valid FW Major Version - 0x1 */ |
| if ((pRespBuff->pBuff[1] == 0x07) &&(bNewVer[1] !=0x01)) |
| { |
| NXPLOG_FWDNLD_E("C1 FW on C2 chip is not allowed - FW Major Version!= 1 on ES2.2"); |
| wStatus = NFCSTATUS_NOT_ALLOWED; |
| } |
| /* Major Version number check */ |
| else if((FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) && (bNewVer[1] < bCurrVer[1])) |
| { |
| NXPLOG_FWDNLD_E("Version Check Failed - MajorVerNum Mismatch\n"); |
| wStatus = NFCSTATUS_NOT_ALLOWED; |
| } |
| /* Minor Version number check - before download.*/ |
| else if((FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) && ((bNewVer[0] == bCurrVer[0]) && |
| (bNewVer[1] == bCurrVer[1]))) |
| { |
| wStatus = NFCSTATUS_SUCCESS; |
| #if (PH_LIBNFC_ENABLE_FORCE_DOWNLOAD == 0) |
| NXPLOG_FWDNLD_D("Version Already UpToDate!!\n"); |
| (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = TRUE; |
| #else |
| (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = TRUE; |
| #endif |
| |
| } |
| /* Minor Version number check - after download |
| * after download, we should get the same version information.*/ |
| else if ((TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) && ((bNewVer[0] != bCurrVer[0]) || |
| (bNewVer[1] != bCurrVer[1]))) |
| { |
| NXPLOG_FWDNLD_E("Version Not Updated After Download!!\n"); |
| wStatus = NFCSTATUS_FAILED; |
| } |
| else |
| { |
| NXPLOG_FWDNLD_D("Version Check Successful\n"); |
| /* Store the Mw & Fw Version for updating in EEPROM Log Area after successful download */ |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) |
| { |
| NXPLOG_FWDNLD_W("Updating Fw & Mw Versions.."); |
| (gphNxpNciHal_fw_IoctlCtx.tLogParams.wCurrMwVer) = wMwVern; |
| (gphNxpNciHal_fw_IoctlCtx.tLogParams.wCurrFwVer) = wFwVern; |
| } |
| |
| } |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Version Resp Buff Invalid...\n"); |
| } |
| } |
| else |
| { |
| wStatus = NFCSTATUS_FAILED; |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Request Failed!!"); |
| } |
| |
| p_cb_data->status = wStatus; |
| SEM_POST(p_cb_data); |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_get_version |
| ** |
| ** Description Download Get version |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_dnld_get_version(void* pContext, |
| NFCSTATUS status, void* pInfo) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| phNxpNciHal_Sem_t cb_data; |
| static uint8_t bGetVerRes[11]; |
| phDnldNfc_Buff_t tDnldBuff; |
| UNUSED(pContext); |
| UNUSED(status); |
| UNUSED(pInfo); |
| if((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) || |
| (TRUE == (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen))) |
| { |
| return NFCSTATUS_SUCCESS; |
| } |
| |
| if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb_data creation failed"); |
| return NFCSTATUS_FAILED; |
| } |
| |
| tDnldBuff.pBuff = bGetVerRes; |
| tDnldBuff.wLen = sizeof(bGetVerRes); |
| |
| wStatus = phDnldNfc_GetVersion(&tDnldBuff, |
| (pphDnldNfc_RspCb_t) &phNxpNciHal_fw_dnld_get_version_cb, |
| (void*) &cb_data); |
| if (wStatus != NFCSTATUS_PENDING) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| /* Wait for callback response */ |
| if (SEM_WAIT(cb_data)) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version semaphore error"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| if (cb_data.status != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| wStatus = NFCSTATUS_SUCCESS; |
| |
| clean_and_return: |
| phNxpNciHal_cleanup_cb_data(&cb_data); |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_get_sessn_state_cb |
| ** |
| ** Description Download Get session state callback |
| ** |
| ** Returns None |
| ** |
| *******************************************************************************/ |
| static void phNxpNciHal_fw_dnld_get_sessn_state_cb(void* pContext, |
| NFCSTATUS status, void* pInfo) |
| { |
| phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; |
| NFCSTATUS wStatus = status; |
| pphDnldNfc_Buff_t pRespBuff; |
| if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo)) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_get_sessn_state_cb - Request Successful"); |
| |
| pRespBuff = (pphDnldNfc_Buff_t) pInfo; |
| |
| if ((3 == (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff))) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_get_sessn_state_cb - Valid Session State Resp Buff!!..."); |
| |
| if (phDnldNfc_LCOper == pRespBuff->pBuff[2]) |
| { |
| if (PHLIBNFC_FWDNLD_SESSNOPEN == pRespBuff->pBuff[0]) |
| { |
| NXPLOG_FWDNLD_E("Prev Fw Upgrade Session still Open.."); |
| (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = TRUE; |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) |
| { |
| NXPLOG_FWDNLD_D("Session still Open after Prev Fw Upgrade attempt!!"); |
| |
| if((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) < PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS) |
| { |
| NXPLOG_FWDNLD_W("Setting Dnld Retry .."); |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = TRUE; |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!"); |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE; |
| } |
| wStatus = NFCSTATUS_FAILED; |
| } |
| } |
| else |
| { |
| gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen = FALSE; |
| } |
| } |
| else |
| { |
| wStatus = NFCSTATUS_FAILED; |
| NXPLOG_FWDNLD_E("NFCC not in Operational State..Fw Upgrade not allowed!!"); |
| } |
| } |
| else |
| { |
| wStatus = NFCSTATUS_FAILED; |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_sessn_state_cb - Session State Resp Buff Invalid..."); |
| } |
| } |
| else |
| { |
| wStatus = NFCSTATUS_FAILED; |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_sessn_state_cb - Request Failed!!"); |
| } |
| |
| p_cb_data->status = wStatus; |
| |
| SEM_POST(p_cb_data); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_get_sessn_state |
| ** |
| ** Description Download Get session state |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_dnld_get_sessn_state(void* pContext, |
| NFCSTATUS status, void* pInfo) |
| { |
| phDnldNfc_Buff_t tDnldBuff; |
| static uint8_t bGSnStateRes[3]; |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| phNxpNciHal_Sem_t cb_data; |
| UNUSED(pContext); |
| UNUSED(status); |
| UNUSED(pInfo); |
| if (TRUE == gphNxpNciHal_fw_IoctlCtx.bSkipSeq) |
| { |
| return NFCSTATUS_SUCCESS; |
| } |
| |
| if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb_data creation failed"); |
| return NFCSTATUS_FAILED; |
| } |
| |
| tDnldBuff.pBuff = bGSnStateRes; |
| tDnldBuff.wLen = sizeof(bGSnStateRes); |
| |
| wStatus = phDnldNfc_GetSessionState(&tDnldBuff, |
| &phNxpNciHal_fw_dnld_get_sessn_state_cb, (void *) &cb_data); |
| if (wStatus != NFCSTATUS_PENDING) |
| { |
| NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| /* Wait for callback response */ |
| if (SEM_WAIT(cb_data)) |
| { |
| NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState semaphore error"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| if (cb_data.status != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState cb failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| wStatus = NFCSTATUS_SUCCESS; |
| |
| clean_and_return: |
| phNxpNciHal_cleanup_cb_data(&cb_data); |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_log_read_cb |
| ** |
| ** Description Download Logread callback |
| ** |
| ** Returns None |
| ** |
| *******************************************************************************/ |
| static void phNxpNciHal_fw_dnld_log_read_cb(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; |
| |
| if((NFCSTATUS_SUCCESS == status) && (NULL != pInfo)) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_log_read_cb - Request Successful"); |
| } |
| else |
| { |
| status = NFCSTATUS_FAILED; |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read_cb - Request Failed!!"); |
| } |
| |
| p_cb_data->status = status; |
| SEM_POST(p_cb_data); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_log_read |
| ** |
| ** Description Download Log Read |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_dnld_log_read(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| phNxpNciHal_Sem_t cb_data; |
| phDnldNfc_Buff_t Data; |
| UNUSED(pContext); |
| UNUSED(status); |
| UNUSED(pInfo); |
| if((((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) || (TRUE == (gphNxpNciHal_fw_IoctlCtx.bForceDnld))) && |
| (FALSE == (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen))) || (((TRUE == (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen))) && |
| (TRUE == (gphNxpNciHal_fw_IoctlCtx.bRetryDnld)))) |
| |
| { |
| return NFCSTATUS_SUCCESS; |
| } |
| |
| if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read cb_data creation failed"); |
| return NFCSTATUS_FAILED; |
| } |
| |
| (Data.pBuff) = (void *)&(gphNxpNciHal_fw_IoctlCtx.tLogParams); |
| (Data.wLen) = sizeof(phLibNfc_EELogParams_t); |
| |
| wStatus = phDnldNfc_ReadLog(&Data, |
| (pphDnldNfc_RspCb_t) &phNxpNciHal_fw_dnld_log_read_cb, |
| (void *) &cb_data); |
| if (wStatus != NFCSTATUS_PENDING) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| /* Wait for callback response */ |
| if (SEM_WAIT(cb_data)) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read semaphore error"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| if (cb_data.status != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read cb failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| wStatus = NFCSTATUS_SUCCESS; |
| |
| clean_and_return: |
| phNxpNciHal_cleanup_cb_data(&cb_data); |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_write_cb |
| ** |
| ** Description Download Write callback |
| ** |
| ** Returns None |
| ** |
| *******************************************************************************/ |
| static void phNxpNciHal_fw_dnld_write_cb(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; |
| UNUSED(pInfo); |
| if (NFCSTATUS_SUCCESS == status) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Request Successful"); |
| (gphNxpNciHal_fw_IoctlCtx.bDnldEepromWrite) = FALSE; |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldSuccess) += 1; |
| |
| if((gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) > 0) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Resetting DnldFailCnt"); |
| (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) = 0; |
| } |
| |
| if(FALSE == (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig)) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Setting bConfig for use by NCI mode"); |
| (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = TRUE; |
| } |
| } |
| |
| /* Reset the previously set DnldAttemptFailed flag */ |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed)) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = FALSE; |
| } |
| } |
| else |
| { |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldFail) += 1; |
| (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) += 1; |
| (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = FALSE; |
| } |
| if(NFCSTATUS_WRITE_FAILED == status) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = TRUE; |
| (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = TRUE; |
| } |
| //status = NFCSTATUS_FAILED; |
| |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write_cb - Request Failed!!"); |
| } |
| |
| p_cb_data->status = status; |
| SEM_POST(p_cb_data); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_write |
| ** |
| ** Description Download Write |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_dnld_write(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| phNxpNciHal_Sem_t cb_data; |
| UNUSED(pContext); |
| UNUSED(status); |
| UNUSED(pInfo); |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bRetryDnld)) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE; |
| } |
| |
| if((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) |
| && (FALSE == (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen))) |
| { |
| return NFCSTATUS_SUCCESS; |
| } |
| |
| if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write cb_data creation failed"); |
| return NFCSTATUS_FAILED; |
| } |
| if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bForceDnld)) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write - Incrementing NumDnldTrig.."); |
| (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = TRUE; |
| (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++; |
| (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldTrig) += 1; |
| } |
| wStatus = phDnldNfc_Write(FALSE, NULL, |
| (pphDnldNfc_RspCb_t) &phNxpNciHal_fw_dnld_write_cb, |
| (void *) &cb_data); |
| if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bForceDnld)) |
| { |
| if (wStatus != NFCSTATUS_PENDING) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write failed"); |
| wStatus = NFCSTATUS_FAILED; |
| (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldFail) += 1; |
| (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) += 1; |
| (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = FALSE; |
| goto clean_and_return; |
| } |
| } |
| /* Wait for callback response */ |
| if (SEM_WAIT(cb_data)) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write semaphore error"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| if (cb_data.status != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write cb failed"); |
| wStatus = cb_data.status; |
| goto clean_and_return; |
| } |
| |
| wStatus = NFCSTATUS_SUCCESS; |
| |
| clean_and_return: |
| phNxpNciHal_cleanup_cb_data(&cb_data); |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_chk_integrity_cb |
| ** |
| ** Description Download Check Integrity callback |
| ** |
| ** Returns None |
| ** |
| *******************************************************************************/ |
| static void phNxpNciHal_fw_dnld_chk_integrity_cb(void* pContext, |
| NFCSTATUS status, void* pInfo) |
| { |
| phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; |
| NFCSTATUS wStatus = status; |
| pphDnldNfc_Buff_t pRespBuff; |
| //uint8_t bUserDataCrc[4]; |
| |
| if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo)) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_chk_integrity_cb - Request Successful"); |
| pRespBuff = (pphDnldNfc_Buff_t) pInfo; |
| |
| if ((31 == (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff))) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_chk_integrity_cb - Valid Resp Buff!!...\n"); |
| wStatus = phLibNfc_VerifyCrcStatus(pRespBuff->pBuff[0]); |
| /* |
| memcpy(bUserDataCrc, &(pRespBuff->pBuff[27]), |
| sizeof(bUserDataCrc));*/ |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity_cb - Resp Buff Invalid...\n"); |
| } |
| } |
| else |
| { |
| wStatus = NFCSTATUS_FAILED; |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity_cb - Request Failed!!"); |
| } |
| |
| p_cb_data->status = wStatus; |
| |
| SEM_POST(p_cb_data); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_chk_integrity |
| ** |
| ** Description Download Check Integrity |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_dnld_chk_integrity(void* pContext, |
| NFCSTATUS status, void* pInfo) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| phNxpNciHal_Sem_t cb_data; |
| phDnldNfc_Buff_t tDnldBuff; |
| static uint8_t bChkIntgRes[31]; |
| UNUSED(pInfo); |
| UNUSED(pContext); |
| UNUSED(status); |
| if(TRUE == gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) |
| { |
| NXPLOG_FWDNLD_D("Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!"); |
| return NFCSTATUS_SUCCESS; |
| } |
| |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) |
| { |
| return NFCSTATUS_SUCCESS; |
| } |
| else if(TRUE == gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) |
| { |
| NXPLOG_FWDNLD_E("Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!"); |
| return NFCSTATUS_SUCCESS; |
| } |
| |
| tDnldBuff.pBuff = bChkIntgRes; |
| tDnldBuff.wLen = sizeof(bChkIntgRes); |
| |
| if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity cb_data creation failed"); |
| return NFCSTATUS_FAILED; |
| } |
| |
| wStatus = phDnldNfc_CheckIntegrity((gphNxpNciHal_fw_IoctlCtx.bChipVer), |
| &tDnldBuff, &phNxpNciHal_fw_dnld_chk_integrity_cb, |
| (void *) &cb_data); |
| if (wStatus != NFCSTATUS_PENDING) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| /* Wait for callback response */ |
| if (SEM_WAIT(cb_data)) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity semaphore error"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| if (cb_data.status != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity cb failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| wStatus = NFCSTATUS_SUCCESS; |
| |
| clean_and_return: |
| phNxpNciHal_cleanup_cb_data(&cb_data); |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_recover |
| ** |
| ** Description Download Recover |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_dnld_recover(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| phNxpNciHal_Sem_t cb_data; |
| |
| UNUSED(pInfo); |
| UNUSED(status); |
| UNUSED(pContext); |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery)) |
| { |
| if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover cb_data creation failed"); |
| return NFCSTATUS_FAILED; |
| } |
| (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++; |
| |
| /* resetting this flag to avoid cyclic issuance of recovery sequence in case of failure */ |
| (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE; |
| |
| wStatus = phDnldNfc_Write(TRUE,NULL,(pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_recover_cb, (void*) &cb_data); |
| |
| if(NFCSTATUS_PENDING != wStatus) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE; |
| goto clean_and_return; |
| } |
| /* Wait for callback response */ |
| if (SEM_WAIT(cb_data)) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover semaphore error"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| if (cb_data.status != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover cb failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| wStatus = NFCSTATUS_SUCCESS; |
| |
| clean_and_return: |
| phNxpNciHal_cleanup_cb_data(&cb_data); |
| } |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_recover_cb |
| ** |
| ** Description Download Recover callback |
| ** |
| ** Returns None |
| ** |
| *******************************************************************************/ |
| static void phNxpNciHal_fw_dnld_recover_cb(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; |
| NFCSTATUS wStatus = status; |
| UNUSED(pContext); |
| UNUSED(pInfo); |
| |
| if(NFCSTATUS_SUCCESS == wStatus) |
| { |
| if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bSkipForce)) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Request Successful"); |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = TRUE; |
| } |
| else |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Production key update Request Successful"); |
| (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = TRUE; |
| } |
| } |
| else |
| { |
| wStatus = NFCSTATUS_FAILED; |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Request Failed!!"); |
| } |
| |
| /* resetting this flag to avoid cyclic issuance of recovery sequence in case of failure */ |
| (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE; |
| |
| /* reset previously set SkipForce */ |
| (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE; |
| p_cb_data->status = wStatus; |
| |
| SEM_POST(p_cb_data); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_send_ncicmd_cb |
| ** |
| ** Description Download Send NCI Command callback |
| ** |
| ** Returns None |
| ** |
| *******************************************************************************/ |
| static void phNxpNciHal_fw_dnld_send_ncicmd_cb(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; |
| NFCSTATUS wStatus = status; |
| pphDnldNfc_Buff_t pRespBuff; |
| UNUSED(pContext); |
| |
| if(NFCSTATUS_SUCCESS == wStatus) |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_send_ncicmdCb - Request Successful"); |
| pRespBuff = (pphDnldNfc_Buff_t)pInfo; |
| |
| if((0 != (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff))) |
| { |
| if(0 == (pRespBuff->pBuff[3])) |
| { |
| NXPLOG_FWDNLD_D("Successful Response received for Nci Reset Cmd"); |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("Nci Reset Request Failed!!"); |
| } |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("Invalid Response received for Nci Reset Request!!"); |
| } |
| /* Call Tml Ioctl to enable download mode */ |
| wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode); |
| |
| if(NFCSTATUS_SUCCESS == wStatus) |
| { |
| NXPLOG_FWDNLD_D("Switched Successfully to dnld mode.."); |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = TRUE; |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("Switching back to dnld mode Failed!!"); |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE; |
| wStatus = NFCSTATUS_FAILED; |
| } |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmdCb - Request Failed!!"); |
| } |
| |
| (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE; |
| p_cb_data->status = wStatus; |
| |
| SEM_POST(p_cb_data); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_send_ncicmd |
| ** |
| ** Description Download Send NCI Command |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_dnld_send_ncicmd(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| static uint8_t bNciCmd[4] = {0x20,0x00,0x01,0x00}; /* Nci Reset Cmd with KeepConfig option */ |
| static uint8_t bNciResp[6]; |
| phDnldNfc_Buff_t tsData; |
| phDnldNfc_Buff_t trData; |
| phNxpNciHal_Sem_t cb_data; |
| |
| UNUSED(pInfo); |
| UNUSED(status); |
| UNUSED(pContext); |
| if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd)) |
| { |
| return NFCSTATUS_SUCCESS; |
| } |
| else |
| { |
| /* Call Tml Ioctl to enable/restore normal mode */ |
| wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode); |
| |
| if(NFCSTATUS_SUCCESS != wStatus) |
| { |
| NXPLOG_FWDNLD_E("Switching to NormalMode Failed!!"); |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE; |
| } |
| else |
| { |
| if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd cb_data creation failed"); |
| return NFCSTATUS_FAILED; |
| } |
| (tsData.pBuff) = bNciCmd; |
| (tsData.wLen) = sizeof(bNciCmd); |
| (trData.pBuff) = bNciResp; |
| (trData.wLen) = sizeof(bNciResp); |
| |
| wStatus = phDnldNfc_RawReq(&tsData,&trData, |
| (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_send_ncicmd_cb, (void*) &cb_data); |
| if(NFCSTATUS_PENDING != wStatus) |
| { |
| goto clean_and_return; |
| } |
| /* Wait for callback response */ |
| if (SEM_WAIT(cb_data)) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd semaphore error"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| if (cb_data.status != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd cb failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| wStatus = NFCSTATUS_SUCCESS; |
| |
| clean_and_return: |
| phNxpNciHal_cleanup_cb_data(&cb_data); |
| } |
| } |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_log_cb |
| ** |
| ** Description Download Log callback |
| ** |
| ** Returns None |
| ** |
| *******************************************************************************/ |
| static void phNxpNciHal_fw_dnld_log_cb(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext; |
| NFCSTATUS wStatus = status; |
| UNUSED(pContext); |
| UNUSED(pInfo); |
| |
| if(NFCSTATUS_SUCCESS == wStatus) |
| { |
| NXPLOG_FWDNLD_D("phLibNfc_DnldLogCb - Request Successful"); |
| (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE; |
| } |
| else |
| { |
| wStatus = NFCSTATUS_FAILED; |
| NXPLOG_FWDNLD_E("phLibNfc_DnldLogCb - Request Failed!!"); |
| } |
| p_cb_data->status = wStatus; |
| |
| SEM_POST(p_cb_data); |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_log |
| ** |
| ** Description Download Log |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_dnld_log(void* pContext, NFCSTATUS status, |
| void* pInfo) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| phNxpNciHal_Sem_t cb_data; |
| phDnldNfc_Buff_t tData; |
| |
| UNUSED(pInfo); |
| UNUSED(status); |
| UNUSED(pContext); |
| if(((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) || |
| (TRUE == (gphNxpNciHal_fw_IoctlCtx.bForceDnld))) && |
| (FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated))) |
| { |
| return NFCSTATUS_SUCCESS; |
| } |
| else |
| { |
| if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log cb_data creation failed"); |
| return NFCSTATUS_FAILED; |
| } |
| (tData.pBuff) = (void *)&(gphNxpNciHal_fw_IoctlCtx.tLogParams); |
| (tData.wLen) = sizeof(gphNxpNciHal_fw_IoctlCtx.tLogParams); |
| |
| wStatus = phDnldNfc_Log(&tData,(pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_log_cb, (void*) &cb_data); |
| |
| if (wStatus != NFCSTATUS_PENDING) |
| { |
| NXPLOG_FWDNLD_E("phDnldNfc_Log failed"); |
| (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE; |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| /* Wait for callback response */ |
| if (SEM_WAIT(cb_data)) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log semaphore error"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| if (cb_data.status != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_cb failed"); |
| wStatus = NFCSTATUS_FAILED; |
| goto clean_and_return; |
| } |
| |
| wStatus = NFCSTATUS_SUCCESS; |
| |
| clean_and_return: |
| phNxpNciHal_cleanup_cb_data(&cb_data); |
| |
| return wStatus; |
| } |
| |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_seq_handler |
| ** |
| ** Description Sequence Handler |
| ** |
| ** Returns NFCSTATUS_SUCCESS if sequence completed uninterrupted |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_seq_handler(NFCSTATUS (*seq_handler[])(void* pContext, NFCSTATUS status, void* pInfo)) |
| { |
| char *pContext = "FW-Download"; |
| int16_t seq_counter = 0; |
| phDnldNfc_Buff_t pInfo; |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| |
| status = phTmlNfc_ReadAbort(); |
| if(NFCSTATUS_SUCCESS != status) |
| { |
| NXPLOG_FWDNLD_E("Tml Read Abort failed!!"); |
| return status; |
| } |
| |
| while(seq_handler[seq_counter] != NULL ) |
| { |
| status = NFCSTATUS_FAILED; |
| status = (seq_handler[seq_counter])(pContext, status, &pInfo ); |
| if(NFCSTATUS_SUCCESS != status) |
| { |
| NXPLOG_FWDNLD_E(" phNxpNciHal_fw_seq_handler : FAILED"); |
| break; |
| } |
| seq_counter++; |
| } |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_dnld_complete |
| ** |
| ** Description Download Sequence Complete |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| static NFCSTATUS phNxpNciHal_fw_dnld_complete(void* pContext,NFCSTATUS status, |
| void* pInfo) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| NFCSTATUS fStatus = status; |
| UNUSED(pInfo); |
| UNUSED(pContext); |
| |
| if(NFCSTATUS_WRITE_FAILED == status) |
| { |
| if((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) < PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = TRUE; |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!"); |
| (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE; |
| } |
| } |
| else if(NFCSTATUS_REJECTED == status) |
| { |
| if((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) < PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = TRUE; |
| |
| /* in case of signature error we need to try recover sequence directly bypassing the force cmd */ |
| (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = TRUE; |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!"); |
| (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE; |
| } |
| } |
| |
| if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.bLastStatus) = status; |
| (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = TRUE; |
| |
| NXPLOG_FWDNLD_E("Invoking Pending Download Log Sequence.."); |
| (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) |
| { |
| NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS"); |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED"); |
| } |
| } |
| else if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery)) |
| { |
| NXPLOG_FWDNLD_E("Invoking Download Recovery Sequence.."); |
| |
| if(NFCSTATUS_SUCCESS == wStatus) |
| { |
| /* Perform the download Recovery sequence */ |
| wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_rec_seqhandler); |
| |
| status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo); |
| if (NFCSTATUS_SUCCESS == status) |
| { |
| NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS"); |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED"); |
| } |
| } |
| } |
| else if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bRetryDnld)) |
| { |
| (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE; |
| |
| /* Perform the download sequence ... after successful recover attempt */ |
| wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler); |
| |
| status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo); |
| if (NFCSTATUS_SUCCESS == status) |
| { |
| NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS"); |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED"); |
| } |
| } |
| else |
| { |
| NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_complete: Download Status = 0x%x", status); |
| if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) |
| { |
| if(NFCSTATUS_SUCCESS == status) |
| { |
| if(NFC_FW_DOWNLOAD == gphNxpNciHal_fw_IoctlCtx.IoctlCode) |
| { |
| NXPLOG_FWDNLD_E("Fw Download success.. "); |
| } |
| else if(PHLIBNFC_DNLD_MEM_READ == gphNxpNciHal_fw_IoctlCtx.IoctlCode) |
| { |
| NXPLOG_FWDNLD_E("Read Request success.. "); |
| } |
| else if(PHLIBNFC_DNLD_MEM_WRITE == gphNxpNciHal_fw_IoctlCtx.IoctlCode) |
| { |
| NXPLOG_FWDNLD_E("Write Request success.. "); |
| } |
| else if(PHLIBNFC_DNLD_READ_LOG == gphNxpNciHal_fw_IoctlCtx.IoctlCode) |
| { |
| NXPLOG_FWDNLD_E("ReadLog Request success.. "); |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("Invalid Request!!"); |
| } |
| } |
| else |
| { |
| if(NFC_FW_DOWNLOAD == gphNxpNciHal_fw_IoctlCtx.IoctlCode) |
| { |
| NXPLOG_FWDNLD_E("Fw Download Failed!!"); |
| } |
| else if(NFC_MEM_READ == gphNxpNciHal_fw_IoctlCtx.IoctlCode) |
| { |
| NXPLOG_FWDNLD_E("Read Request Failed!!"); |
| } |
| else if(NFC_MEM_WRITE == gphNxpNciHal_fw_IoctlCtx.IoctlCode) |
| { |
| NXPLOG_FWDNLD_E("Write Request Failed!!"); |
| } |
| else if(PHLIBNFC_DNLD_READ_LOG == gphNxpNciHal_fw_IoctlCtx.IoctlCode) |
| { |
| NXPLOG_FWDNLD_E("ReadLog Request Failed!!"); |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("Invalid Request!!"); |
| } |
| } |
| } |
| |
| if(FALSE == gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) |
| { |
| /* Call Tml Ioctl to enable/restore normal mode */ |
| wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode); |
| |
| if(NFCSTATUS_SUCCESS != wStatus) |
| { |
| NXPLOG_FWDNLD_E("Switching to NormalMode Failed!!"); |
| } |
| else |
| { |
| wStatus = fStatus; |
| } |
| } |
| |
| (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bChipVer) = 0; |
| (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) = 0; |
| |
| if(FALSE == gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) |
| { |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("Returning Download Failed Status to Caller!!"); |
| |
| (gphNxpNciHal_fw_IoctlCtx.bLastStatus) = NFCSTATUS_SUCCESS; |
| (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = FALSE; |
| } |
| phDnldNfc_CloseFwLibHandle(); |
| } |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpNciHal_fw_download_seq |
| ** |
| ** Description Download Sequence |
| ** |
| ** Returns NFCSTATUS_SUCCESS if success |
| ** |
| *******************************************************************************/ |
| NFCSTATUS phNxpNciHal_fw_download_seq(uint8_t bClkSrcVal, uint8_t bClkFreqVal) |
| { |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| phDnldNfc_Buff_t pInfo; |
| char *pContext = "FW-Download"; |
| |
| /* reset the global flags */ |
| gphNxpNciHal_fw_IoctlCtx.IoctlCode = NFC_FW_DOWNLOAD; |
| (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bChipVer) = 0; |
| (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE; |
| (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) = 0; |
| (gphNxpNciHal_fw_IoctlCtx.bClkSrcVal) = bClkSrcVal; |
| (gphNxpNciHal_fw_IoctlCtx.bClkFreqVal) = bClkFreqVal; |
| /* Get firmware version */ |
| if (NFCSTATUS_SUCCESS == phDnldNfc_InitImgInfo()) |
| { |
| NXPLOG_FWDNLD_D("phDnldNfc_InitImgInfo:SUCCESS"); |
| #if(NFC_NXP_CHIP_TYPE != PN547C2) |
| if(gRecFWDwnld == TRUE) |
| { |
| status = phNxpNciHal_fw_seq_handler(phNxpNciHal_dummy_rec_dwnld_seqhandler); |
| } |
| else |
| #endif |
| { |
| status = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler); |
| } |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E("phDnldNfc_InitImgInfo: FAILED"); |
| } |
| |
| /* Chage to normal mode */ |
| status = phNxpNciHal_fw_dnld_complete(pContext, status, &pInfo); |
| /*if (NFCSTATUS_SUCCESS == status) |
| { |
| NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS"); |
| } |
| else |
| { |
| NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED"); |
| }*/ |
| |
| return status; |
| } |
| |
| static |
| NFCSTATUS |
| phLibNfc_VerifyCrcStatus(uint8_t bCrcStatus) |
| { |
| #if((NFC_NXP_CHIP_TYPE == PN551)||(NFC_NXP_CHIP_TYPE == PN553)) |
| uint8_t bBitPos = 1; |
| uint8_t bShiftVal = 2; |
| #else |
| uint8_t bBitPos = 0; |
| uint8_t bShiftVal = 1; |
| #endif |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| while(bBitPos < 7) |
| { |
| if(!(bCrcStatus & bShiftVal)) |
| { |
| switch(bBitPos) |
| { |
| case 0: |
| { |
| NXPLOG_FWDNLD_E("User Data Crc is NOT OK!!"); |
| wStatus = NFCSTATUS_FAILED; |
| break; |
| } |
| case 1: |
| { |
| NXPLOG_FWDNLD_E("Trim Data Crc is NOT OK!!"); |
| wStatus = NFCSTATUS_FAILED; |
| break; |
| } |
| case 2: |
| { |
| NXPLOG_FWDNLD_E("Protected Data Crc is NOT OK!!"); |
| wStatus = NFCSTATUS_FAILED; |
| break; |
| } |
| case 3: |
| { |
| NXPLOG_FWDNLD_E("Patch Code Crc is NOT OK!!"); |
| wStatus = NFCSTATUS_FAILED; |
| break; |
| } |
| case 4: |
| { |
| NXPLOG_FWDNLD_E("Function Code Crc is NOT OK!!"); |
| wStatus = NFCSTATUS_FAILED; |
| break; |
| } |
| case 5: |
| { |
| NXPLOG_FWDNLD_E("Patch Table Crc is NOT OK!!"); |
| wStatus = NFCSTATUS_FAILED; |
| break; |
| } |
| case 6: |
| { |
| NXPLOG_FWDNLD_E("Function Table Crc is NOT OK!!"); |
| wStatus = NFCSTATUS_FAILED; |
| break; |
| } |
| default: |
| { |
| break; |
| } |
| } |
| } |
| |
| bShiftVal <<= 1; |
| ++bBitPos; |
| } |
| |
| return wStatus; |
| } |