aboutsummaryrefslogtreecommitdiff
path: root/pn54x/dnld/phNxpNciHal_Dnld.c
diff options
context:
space:
mode:
Diffstat (limited to 'pn54x/dnld/phNxpNciHal_Dnld.c')
-rw-r--r--pn54x/dnld/phNxpNciHal_Dnld.c1808
1 files changed, 1808 insertions, 0 deletions
diff --git a/pn54x/dnld/phNxpNciHal_Dnld.c b/pn54x/dnld/phNxpNciHal_Dnld.c
new file mode 100644
index 0000000..42cadba
--- /dev/null
+++ b/pn54x/dnld/phNxpNciHal_Dnld.c
@@ -0,0 +1,1808 @@
+/*
+ * Copyright (C) 2012-2014 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 <phDnldNfc.h>
+#include <phNxpConfig.h>
+#include <phNxpLog.h>
+#include <phNxpNciHal_Dnld.h>
+#include <phNxpNciHal_utils.h>
+#include <phTmlNfc.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;
+#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 (((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) ||
+ ((gphNxpNciHal_fw_IoctlCtx.bSkipReset) == true)) {
+ if ((gphNxpNciHal_fw_IoctlCtx.bSkipReset) == true) {
+ (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 ((gphNxpNciHal_fw_IoctlCtx.bSkipForce) == true) {
+ 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 ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) {
+ (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 ((gphNxpNciHal_fw_IoctlCtx.bSkipForce) == true) {
+ 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 ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) {
+ (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)
+#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");
+ NXPLOG_FWDNLD_E("NewVer %d != CurrVer %d\n", bNewVer[1], bCurrVer[1]);
+ 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 (((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) ||
+ ((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == true)) {
+ 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 ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) {
+ 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 (gphNxpNciHal_fw_IoctlCtx.bSkipSeq == true) {
+ 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 (((((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) ||
+ ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == true)) &&
+ ((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == false)) ||
+ ((((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == true)) &&
+ ((gphNxpNciHal_fw_IoctlCtx.bRetryDnld) == true)))
+
+ {
+ 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 ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) {
+ (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 ((gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) == false) {
+ 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 ((gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) == true) {
+ (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = false;
+ }
+ } else {
+ if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) {
+ (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 ((gphNxpNciHal_fw_IoctlCtx.bRetryDnld) == true) {
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
+ }
+
+ if (((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) &&
+ ((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == false)) {
+ 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 ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == false) {
+ 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 ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == false) {
+ 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 (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen == true) {
+ NXPLOG_FWDNLD_D(
+ "Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!");
+ return NFCSTATUS_SUCCESS;
+ }
+
+ if ((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) {
+ return NFCSTATUS_SUCCESS;
+ } else if (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen == true) {
+ 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 ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) {
+ 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 ((gphNxpNciHal_fw_IoctlCtx.bSkipForce) == false) {
+ 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 ((gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) == false) {
+ 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 ((((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) ||
+ ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == true)) &&
+ ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == false)) {
+ 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 ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) {
+ (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 ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) {
+ 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 ((gphNxpNciHal_fw_IoctlCtx.bRetryDnld) == true) {
+ (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 ((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == false) {
+ 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 (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd == false) {
+ /* 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 (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed == false) {
+ } 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;
+}