Home | History | Annotate | Download | only in dnld
      1 /*
      2  * Copyright (C) 2012-2014 NXP Semiconductors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <phDnldNfc.h>
     18 #include <phNxpConfig.h>
     19 #include <phNxpLog.h>
     20 #include <phNxpNciHal_Dnld.h>
     21 #include <phNxpNciHal_utils.h>
     22 #include <phTmlNfc.h>
     23 
     24 /* Macro */
     25 #define PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS 3
     26 #define PHLIBNFC_IOCTL_DNLD_GETVERLEN (0x0BU)
     27 #define PHLIBNFC_IOCTL_DNLD_GETVERLEN_MRA2_1 (0x09U)
     28 #define PHLIBNFC_DNLD_MEM_READ (0xECU)
     29 #define PHLIBNFC_DNLD_MEM_WRITE (0xEDU)
     30 #define PHLIBNFC_DNLD_READ_LOG (0xEEU)
     31 #define NFC_MEM_READ (0xD0U)
     32 #define NFC_MEM_WRITE (0xD1U)
     33 #define NFC_FW_DOWNLOAD (0x09F7U)
     34 
     35 /* External global variable to get FW version */
     36 extern uint16_t wFwVer;
     37 extern uint16_t wMwVer;
     38 extern uint8_t gRecFWDwnld;
     39 /* RF Configuration structure */
     40 typedef struct phLibNfc_IoctlSetRfConfig {
     41   uint8_t bNumOfParams;   /* Number of Rf configurable parameters to be set */
     42   uint8_t* pInputBuffer;  /* Buffer containing Rf configurable parameters */
     43   uint8_t bSetSysPmuFlag; /* Flag to decide wether to set SystemPmu or no from
     44                              the first byte */
     45 } phLibNfc_IoctlSetRfConfig;
     46 
     47 /* Structure to hold information from EEPROM */
     48 typedef struct phLibNfc_EELogParams {
     49   uint16_t wCurrMwVer;      /* Holds current MW version on the chip */
     50   uint16_t wCurrFwVer;      /* Holds current FW version on the chip */
     51   uint16_t wNumDnldTrig;    /* Total number of times dnld has been attempted */
     52   uint16_t wNumDnldSuccess; /* Total number of times dnld has been successful */
     53   uint16_t wNumDnldFail;    /* Total number of times dnld has Failed */
     54   uint16_t wDnldFailCnt;    /* holds the number of times dnld has failed,will be
     55                                reset on success */
     56   bool_t bConfig; /* Flag to be set in dnld mode after successful dnld,to be
     57                     reset in NCI Mode
     58                     after setting the NCI configuration */
     59 } phLibNfc_EELogParams_t;
     60 
     61 /* FW download module context structure */
     62 typedef struct {
     63   bool_t bDnldEepromWrite; /* Flag to indicate eeprom write request*/
     64   bool_t
     65       bSkipSeq; /* Flag to indicate FW download sequence to be skipped or not */
     66   bool_t bSkipReset; /* Flag to indicate Reset cmd to be skipped or not in FW
     67                         download sequence */
     68   bool_t bSkipForce; /* Flag to indicate Force cmd to be skipped or not in FW
     69                         recovery sequence */
     70   bool_t bPrevSessnOpen; /* Flag to indicate previous download session is open
     71                             or not */
     72   bool_t bLibNfcCtxtMem; /* flag to indicate if mem was allocated for
     73                             gpphLibNfc_Context */
     74   bool_t bDnldInitiated; /* Flag to indicate if fw upgrade was initiated */
     75   bool_t
     76       bSendNciCmd; /* Flag to indicate if NCI cmd to be sent or not,after PKU */
     77   uint8_t bChipVer;     /* holds the hw chip version */
     78   bool_t bDnldRecovery; /* Flag to indicate if dnld recovery sequence needs to
     79                            be triggered */
     80   bool_t bForceDnld; /* Flag to indicate if forced download option is enabled */
     81   bool_t bRetryDnld; /* Flag to indicate retry download after successful
     82                         recovery complete */
     83   uint8_t
     84       bDnldAttempts;  /* Holds the count of no. of dnld attempts made.max 3 */
     85   uint16_t IoctlCode; /* Ioctl code*/
     86   bool_t bDnldAttemptFailed; /* Flag to indicate last download attempt failed */
     87   NFCSTATUS bLastStatus; /* Holds the actual download write attempt status */
     88   phLibNfc_EELogParams_t
     89       tLogParams;     /* holds the params that could be logged to reserved EE
     90                          address */
     91   uint8_t bClkSrcVal; /* Holds the System clock source read from config file */
     92   uint8_t
     93       bClkFreqVal; /* Holds the System clock frequency read from config file */
     94 } phNxpNciHal_fw_Ioctl_Cntx_t;
     95 
     96 /* Global variables used in this file only*/
     97 static phNxpNciHal_fw_Ioctl_Cntx_t gphNxpNciHal_fw_IoctlCtx;
     98 
     99 /* Local function prototype */
    100 static NFCSTATUS phNxpNciHal_fw_dnld_reset(void* pContext, NFCSTATUS status,
    101                                            void* pInfo);
    102 
    103 static void phNxpNciHal_fw_dnld_reset_cb(void* pContext, NFCSTATUS status,
    104                                          void* pInfo);
    105 
    106 static NFCSTATUS phNxpNciHal_fw_dnld_force(void* pContext, NFCSTATUS status,
    107                                            void* pInfo);
    108 
    109 static void phNxpNciHal_fw_dnld_force_cb(void* pContext, NFCSTATUS status,
    110                                          void* pInfo);
    111 
    112 static void phNxpNciHal_fw_dnld_normal_cb(void* pContext, NFCSTATUS status,
    113                                           void* pInfo);
    114 
    115 static NFCSTATUS phNxpNciHal_fw_dnld_normal(void* pContext, NFCSTATUS status,
    116                                             void* pInfo);
    117 
    118 static void phNxpNciHal_fw_dnld_get_version_cb(void* pContext, NFCSTATUS status,
    119                                                void* pInfo);
    120 
    121 static NFCSTATUS phNxpNciHal_fw_dnld_get_version(void* pContext,
    122                                                  NFCSTATUS status, void* pInfo);
    123 
    124 static void phNxpNciHal_fw_dnld_get_sessn_state_cb(void* pContext,
    125                                                    NFCSTATUS status,
    126                                                    void* pInfo);
    127 
    128 static NFCSTATUS phNxpNciHal_fw_dnld_get_sessn_state(void* pContext,
    129                                                      NFCSTATUS status,
    130                                                      void* pInfo);
    131 
    132 static void phNxpNciHal_fw_dnld_log_read_cb(void* pContext, NFCSTATUS status,
    133                                             void* pInfo);
    134 
    135 static NFCSTATUS phNxpNciHal_fw_dnld_log_read(void* pContext, NFCSTATUS status,
    136                                               void* pInfo);
    137 
    138 static void phNxpNciHal_fw_dnld_write_cb(void* pContext, NFCSTATUS status,
    139                                          void* pInfo);
    140 
    141 static NFCSTATUS phNxpNciHal_fw_dnld_write(void* pContext, NFCSTATUS status,
    142                                            void* pInfo);
    143 
    144 static void phNxpNciHal_fw_dnld_chk_integrity_cb(void* pContext,
    145                                                  NFCSTATUS status, void* pInfo);
    146 
    147 static NFCSTATUS phNxpNciHal_fw_dnld_chk_integrity(void* pContext,
    148                                                    NFCSTATUS status,
    149                                                    void* pInfo);
    150 
    151 static void phNxpNciHal_fw_dnld_log_cb(void* pContext, NFCSTATUS status,
    152                                        void* pInfo);
    153 
    154 static NFCSTATUS phNxpNciHal_fw_dnld_log(void* pContext, NFCSTATUS status,
    155                                          void* pInfo);
    156 
    157 static NFCSTATUS phNxpNciHal_fw_dnld_send_ncicmd(void* pContext,
    158                                                  NFCSTATUS status, void* pInfo);
    159 
    160 static NFCSTATUS phNxpNciHal_fw_dnld_recover(void* pContext, NFCSTATUS status,
    161                                              void* pInfo);
    162 
    163 static NFCSTATUS phNxpNciHal_fw_dnld_complete(void* pContext, NFCSTATUS status,
    164                                               void* pInfo);
    165 
    166 /* Internal function to verify Crc Status byte received during CheckIntegrity */
    167 static NFCSTATUS phLibNfc_VerifyCrcStatus(uint8_t bCrcStatus);
    168 
    169 static void phNxpNciHal_fw_dnld_recover_cb(void* pContext, NFCSTATUS status,
    170                                            void* pInfo);
    171 
    172 static NFCSTATUS phNxpNciHal_fw_seq_handler(
    173     NFCSTATUS (*seq_handler[])(void* pContext, NFCSTATUS status, void* pInfo));
    174 
    175 /* Array of pointers to start fw download seq */
    176 static NFCSTATUS (*phNxpNciHal_dwnld_seqhandler[])(void* pContext,
    177                                                    NFCSTATUS status,
    178                                                    void* pInfo) = {
    179     phNxpNciHal_fw_dnld_get_sessn_state, phNxpNciHal_fw_dnld_get_version,
    180     phNxpNciHal_fw_dnld_log_read, phNxpNciHal_fw_dnld_write,
    181     phNxpNciHal_fw_dnld_get_sessn_state, phNxpNciHal_fw_dnld_get_version,
    182     phNxpNciHal_fw_dnld_log, phNxpNciHal_fw_dnld_chk_integrity, NULL};
    183 
    184 /* Array of pointers to start dummy fw download seq */
    185 static NFCSTATUS (*phNxpNciHal_dummy_rec_dwnld_seqhandler[])(void* pContext,
    186                                                              NFCSTATUS status,
    187                                                              void* pInfo) = {
    188     phNxpNciHal_fw_dnld_normal,          phNxpNciHal_fw_dnld_normal,
    189     phNxpNciHal_fw_dnld_get_sessn_state, phNxpNciHal_fw_dnld_get_version,
    190     phNxpNciHal_fw_dnld_log_read,        phNxpNciHal_fw_dnld_write,
    191     NULL};
    192 
    193 /* Download Recovery Sequence */
    194 static NFCSTATUS (*phNxpNciHal_dwnld_rec_seqhandler[])(void* pContext,
    195                                                        NFCSTATUS status,
    196                                                        void* pInfo) = {
    197     phNxpNciHal_fw_dnld_reset, phNxpNciHal_fw_dnld_force,
    198     phNxpNciHal_fw_dnld_recover, phNxpNciHal_fw_dnld_send_ncicmd, NULL};
    199 
    200 /* Download Log Sequence */
    201 static NFCSTATUS (*phNxpNciHal_dwnld_log_seqhandler[])(void* pContext,
    202                                                        NFCSTATUS status,
    203                                                        void* pInfo) = {
    204     phNxpNciHal_fw_dnld_log, NULL};
    205 
    206 /*******************************************************************************
    207 **
    208 ** Function         phNxpNciHal_fw_dnld_reset_cb
    209 **
    210 ** Description      Download Reset callback
    211 **
    212 ** Returns          None
    213 **
    214 *******************************************************************************/
    215 static void phNxpNciHal_fw_dnld_reset_cb(void* pContext, NFCSTATUS status,
    216                                          void* pInfo) {
    217   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
    218   UNUSED(pInfo);
    219   if (NFCSTATUS_SUCCESS == status) {
    220     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_reset_cb - Request Successful");
    221   } else {
    222     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset_cb - Request Failed!!");
    223   }
    224   p_cb_data->status = status;
    225 
    226   SEM_POST(p_cb_data);
    227 
    228   return;
    229 }
    230 
    231 /*******************************************************************************
    232 **
    233 ** Function         phNxpNciHal_fw_dnld_reset
    234 **
    235 ** Description      Download Reset
    236 **
    237 ** Returns          NFCSTATUS_SUCCESS if success
    238 **
    239 *******************************************************************************/
    240 static NFCSTATUS phNxpNciHal_fw_dnld_reset(void* pContext, NFCSTATUS status,
    241                                            void* pInfo) {
    242   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    243   phNxpNciHal_Sem_t cb_data;
    244   UNUSED(pContext);
    245   UNUSED(status);
    246   UNUSED(pInfo);
    247   if (((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) ||
    248       ((gphNxpNciHal_fw_IoctlCtx.bSkipReset) == true)) {
    249     if ((gphNxpNciHal_fw_IoctlCtx.bSkipReset) == true) {
    250       (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = false;
    251     }
    252     return NFCSTATUS_SUCCESS;
    253   }
    254 
    255   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
    256     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data  failed");
    257     return NFCSTATUS_FAILED;
    258   }
    259   wStatus = phDnldNfc_Reset((pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_reset_cb,
    260                             (void*)&cb_data);
    261 
    262   if (wStatus != NFCSTATUS_PENDING) {
    263     NXPLOG_FWDNLD_E("phDnldNfc_Reset failed");
    264     wStatus = NFCSTATUS_FAILED;
    265     goto clean_and_return;
    266   }
    267 
    268   /* Wait for callback response */
    269   if (SEM_WAIT(cb_data)) {
    270     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset semaphore error");
    271     wStatus = NFCSTATUS_FAILED;
    272     goto clean_and_return;
    273   }
    274 
    275   if (cb_data.status != NFCSTATUS_SUCCESS) {
    276     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset cb failed");
    277     wStatus = NFCSTATUS_FAILED;
    278     goto clean_and_return;
    279   }
    280 
    281   wStatus = NFCSTATUS_SUCCESS;
    282 
    283 clean_and_return:
    284   phNxpNciHal_cleanup_cb_data(&cb_data);
    285 
    286   return wStatus;
    287 }
    288 
    289 /*******************************************************************************
    290 **
    291 ** Function         phNxpNciHal_fw_dnld_normal_cb
    292 **
    293 ** Description      Download Normal callback
    294 **
    295 ** Returns          None
    296 **
    297 *******************************************************************************/
    298 static void phNxpNciHal_fw_dnld_normal_cb(void* pContext, NFCSTATUS status,
    299                                           void* pInfo) {
    300   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
    301   UNUSED(pInfo);
    302   if (NFCSTATUS_SUCCESS == status) {
    303     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_normal_cb - Request Successful");
    304   } else {
    305     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal_cb - Request Failed!!");
    306     /* In this fail scenario trick the sequence handler to call next recover
    307      * sequence */
    308     status = NFCSTATUS_SUCCESS;
    309   }
    310   p_cb_data->status = status;
    311 
    312   SEM_POST(p_cb_data);
    313   usleep(1000 * 10);
    314 
    315   return;
    316 }
    317 
    318 /*******************************************************************************
    319 **
    320 ** Function         phNxpNciHal_fw_dnld_force_cb
    321 **
    322 ** Description      Download Force callback
    323 **
    324 ** Returns          None
    325 **
    326 *******************************************************************************/
    327 static void phNxpNciHal_fw_dnld_force_cb(void* pContext, NFCSTATUS status,
    328                                          void* pInfo) {
    329   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
    330   UNUSED(pInfo);
    331   if (NFCSTATUS_SUCCESS == status) {
    332     NXPLOG_FWDNLD_D("phLibNfc_DnldForceCb - Request Successful");
    333     (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
    334     (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = true;
    335     (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = true;
    336   } else {
    337     /* In this fail scenario trick the sequence handler to call next recover
    338      * sequence */
    339     status = NFCSTATUS_SUCCESS;
    340     NXPLOG_FWDNLD_E("phLibNfc_DnldForceCb - Request Failed!!");
    341   }
    342   p_cb_data->status = status;
    343 
    344   SEM_POST(p_cb_data);
    345   usleep(1000 * 10);
    346 
    347   return;
    348 }
    349 
    350 /*******************************************************************************
    351 **
    352 ** Function         phNxpNciHal_fw_dnld_normal
    353 **
    354 ** Description      Download Normal
    355 **
    356 ** Returns          NFCSTATUS_SUCCESS if success
    357 **
    358 *******************************************************************************/
    359 static NFCSTATUS phNxpNciHal_fw_dnld_normal(void* pContext, NFCSTATUS status,
    360                                             void* pInfo) {
    361   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    362   uint8_t bClkVal[2];
    363   phDnldNfc_Buff_t tData;
    364   phNxpNciHal_Sem_t cb_data;
    365   UNUSED(pContext);
    366   UNUSED(status);
    367   UNUSED(pInfo);
    368   if ((gphNxpNciHal_fw_IoctlCtx.bSkipForce) == true) {
    369     return NFCSTATUS_SUCCESS;
    370   } else {
    371     /*
    372     bClkVal[0] = NXP_SYS_CLK_SRC_SEL;
    373     bClkVal[1] = NXP_SYS_CLK_FREQ_SEL;
    374     */
    375     bClkVal[0] = gphNxpNciHal_fw_IoctlCtx.bClkSrcVal;
    376     bClkVal[1] = gphNxpNciHal_fw_IoctlCtx.bClkFreqVal;
    377 
    378     (tData.pBuff) = bClkVal;
    379     (tData.wLen) = sizeof(bClkVal);
    380 
    381     if ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) {
    382       (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
    383     }
    384 
    385     if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
    386       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data  failed");
    387       return NFCSTATUS_FAILED;
    388     }
    389     wStatus = phDnldNfc_Force(
    390         &tData, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_normal_cb,
    391         (void*)&cb_data);
    392 
    393     if (NFCSTATUS_PENDING != wStatus) {
    394       NXPLOG_FWDNLD_E("phDnldNfc_Normal failed");
    395       (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false;
    396       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
    397       goto clean_and_return;
    398     }
    399   }
    400 
    401   /* Wait for callback response */
    402   if (SEM_WAIT(cb_data)) {
    403     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal semaphore error");
    404     wStatus = NFCSTATUS_FAILED;
    405     goto clean_and_return;
    406   }
    407 
    408   if (cb_data.status != NFCSTATUS_SUCCESS) {
    409     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal cb failed");
    410     wStatus = NFCSTATUS_FAILED;
    411     goto clean_and_return;
    412   }
    413 
    414   wStatus = NFCSTATUS_SUCCESS;
    415 
    416 clean_and_return:
    417   phNxpNciHal_cleanup_cb_data(&cb_data);
    418 
    419   return wStatus;
    420 }
    421 
    422 /*******************************************************************************
    423 **
    424 ** Function         phNxpNciHal_fw_dnld_force
    425 **
    426 ** Description      Download Force
    427 **
    428 ** Returns          NFCSTATUS_SUCCESS if success
    429 **
    430 *******************************************************************************/
    431 static NFCSTATUS phNxpNciHal_fw_dnld_force(void* pContext, NFCSTATUS status,
    432                                            void* pInfo) {
    433   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    434   uint8_t bClkVal[2];
    435   phDnldNfc_Buff_t tData;
    436   phNxpNciHal_Sem_t cb_data;
    437   UNUSED(pContext);
    438   UNUSED(status);
    439   UNUSED(pInfo);
    440   if ((gphNxpNciHal_fw_IoctlCtx.bSkipForce) == true) {
    441     return NFCSTATUS_SUCCESS;
    442   } else {
    443     /*
    444     bClkVal[0] = NXP_SYS_CLK_SRC_SEL;
    445     bClkVal[1] = NXP_SYS_CLK_FREQ_SEL;
    446     */
    447     bClkVal[0] = gphNxpNciHal_fw_IoctlCtx.bClkSrcVal;
    448     bClkVal[1] = gphNxpNciHal_fw_IoctlCtx.bClkFreqVal;
    449 
    450     (tData.pBuff) = bClkVal;
    451     (tData.wLen) = sizeof(bClkVal);
    452 
    453     if ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) {
    454       (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
    455     }
    456 
    457     if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
    458       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data  failed");
    459       return NFCSTATUS_FAILED;
    460     }
    461     wStatus = phDnldNfc_Force(&tData,
    462                               (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_force_cb,
    463                               (void*)&cb_data);
    464 
    465     if (NFCSTATUS_PENDING != wStatus) {
    466       NXPLOG_FWDNLD_E("phDnldNfc_Force failed");
    467       (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false;
    468       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
    469       goto clean_and_return;
    470     }
    471   }
    472 
    473   /* Wait for callback response */
    474   if (SEM_WAIT(cb_data)) {
    475     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_force semaphore error");
    476     wStatus = NFCSTATUS_FAILED;
    477     goto clean_and_return;
    478   }
    479 
    480   if (cb_data.status != NFCSTATUS_SUCCESS) {
    481     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_force cb failed");
    482     wStatus = NFCSTATUS_FAILED;
    483     goto clean_and_return;
    484   }
    485 
    486   wStatus = NFCSTATUS_SUCCESS;
    487 
    488 clean_and_return:
    489   phNxpNciHal_cleanup_cb_data(&cb_data);
    490 
    491   return wStatus;
    492 }
    493 
    494 /*******************************************************************************
    495 **
    496 ** Function         phNxpNciHal_fw_dnld_get_version_cb
    497 **
    498 ** Description      Download Get version callback
    499 **
    500 ** Returns          None
    501 **
    502 *******************************************************************************/
    503 static void phNxpNciHal_fw_dnld_get_version_cb(void* pContext, NFCSTATUS status,
    504                                                void* pInfo) {
    505   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
    506   NFCSTATUS wStatus = status;
    507   pphDnldNfc_Buff_t pRespBuff;
    508   uint16_t wFwVern = 0;
    509   uint16_t wMwVern = 0;
    510   uint8_t bHwVer = 0;
    511   uint8_t bExpectedLen = 0;
    512   uint8_t bNewVer[2];
    513   uint8_t bCurrVer[2];
    514 
    515   if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo)) {
    516     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_get_version_cb - Request Successful");
    517 
    518     pRespBuff = (pphDnldNfc_Buff_t)pInfo;
    519 
    520     if ((0 != pRespBuff->wLen) && (NULL != pRespBuff->pBuff)) {
    521       bHwVer = (pRespBuff->pBuff[0]);
    522       bHwVer &= 0x0F; /* 0x0F is the mask to extract chip version */
    523 
    524       if ((PHDNLDNFC_HWVER_MRA2_1 == bHwVer) ||
    525           (PHDNLDNFC_HWVER_MRA2_2 == bHwVer) ||
    526           ((nfcFL.chipType == pn551) &&
    527            (PHDNLDNFC_HWVER_PN551_MRA1_0 == bHwVer)) ||
    528           (((nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) &&
    529            (PHDNLDNFC_HWVER_PN553_MRA1_0 == bHwVer ||
    530             PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0]))) {
    531         bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN_MRA2_1;
    532         (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer;
    533         if ((nfcFL.chipType == pn553) &&
    534             (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0])) {
    535           (gphNxpNciHal_fw_IoctlCtx.bChipVer) = pRespBuff->pBuff[0];
    536         }
    537       } else if ((bHwVer >= PHDNLDNFC_HWVER_MRA1_0) &&
    538                  (bHwVer <= PHDNLDNFC_HWVER_MRA2_0)) {
    539         bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN;
    540         (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer;
    541       } else {
    542         wStatus = NFCSTATUS_FAILED;
    543         NXPLOG_FWDNLD_E(
    544             "phNxpNciHal_fw_dnld_get_version_cb - Invalid ChipVersion!!");
    545       }
    546     } else {
    547       wStatus = NFCSTATUS_FAILED;
    548       NXPLOG_FWDNLD_E(
    549           "phNxpNciHal_fw_dnld_get_version_cb - Version Resp Buff "
    550           "Invalid...\n");
    551     }
    552 
    553     if ((NFCSTATUS_SUCCESS == wStatus) && (bExpectedLen == pRespBuff->wLen) &&
    554         (NULL != pRespBuff->pBuff)) {
    555       NXPLOG_FWDNLD_D(
    556           "phNxpNciHal_fw_dnld_get_version_cb - Valid Version Resp "
    557           "Buff!!...\n");
    558 
    559       /* Validate version details to confirm if continue with the next sequence
    560        * of Operations. */
    561       memcpy(bCurrVer, &(pRespBuff->pBuff[bExpectedLen - 2]), sizeof(bCurrVer));
    562       wFwVern = wFwVer;
    563       wMwVern = wMwVer;
    564 
    565       memcpy(bNewVer, &wFwVern, sizeof(bNewVer));
    566 
    567       /* check if the ROM code version and FW Major version is valid for the
    568        * chip*/
    569       /* ES2.2 Rom Version - 0x7 and Valid FW Major Version - 0x1 */
    570       if ((pRespBuff->pBuff[1] == 0x07) && (bNewVer[1] != 0x01)) {
    571         NXPLOG_FWDNLD_E(
    572             "C1 FW on C2 chip is not allowed - FW Major Version!= 1 on ES2.2");
    573         wStatus = NFCSTATUS_NOT_ALLOWED;
    574       }
    575       /* Major Version number check */
    576       else if ((FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) &&
    577                (bNewVer[1] < bCurrVer[1])) {
    578         NXPLOG_FWDNLD_E("Version Check Failed - MajorVerNum Mismatch\n");
    579         NXPLOG_FWDNLD_E("NewVer %d != CurrVer %d\n", bNewVer[1], bCurrVer[1]);
    580         wStatus = NFCSTATUS_NOT_ALLOWED;
    581       }
    582       /* Minor Version number check - before download.*/
    583       else if ((FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) &&
    584                ((bNewVer[0] == bCurrVer[0]) && (bNewVer[1] == bCurrVer[1]))) {
    585         wStatus = NFCSTATUS_SUCCESS;
    586 #if (PH_LIBNFC_ENABLE_FORCE_DOWNLOAD == 0)
    587         NXPLOG_FWDNLD_D("Version Already UpToDate!!\n");
    588         (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = TRUE;
    589 #else
    590         (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = TRUE;
    591 #endif
    592 
    593       }
    594       /* Minor Version number check - after download
    595        * after download, we should get the same version information.*/
    596       else if ((TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) &&
    597                ((bNewVer[0] != bCurrVer[0]) || (bNewVer[1] != bCurrVer[1]))) {
    598         NXPLOG_FWDNLD_E("Version Not Updated After Download!!\n");
    599         wStatus = NFCSTATUS_FAILED;
    600       } else {
    601         NXPLOG_FWDNLD_D("Version Check Successful\n");
    602         /* Store the Mw & Fw Version for updating in EEPROM Log Area after
    603          * successful download */
    604         if (TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) {
    605           NXPLOG_FWDNLD_W("Updating Fw & Mw Versions..");
    606           (gphNxpNciHal_fw_IoctlCtx.tLogParams.wCurrMwVer) = wMwVern;
    607           (gphNxpNciHal_fw_IoctlCtx.tLogParams.wCurrFwVer) = wFwVern;
    608         }
    609       }
    610     } else {
    611       NXPLOG_FWDNLD_E(
    612           "phNxpNciHal_fw_dnld_get_version_cb - Version Resp Buff "
    613           "Invalid...\n");
    614     }
    615   } else {
    616     wStatus = NFCSTATUS_FAILED;
    617     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Request Failed!!");
    618   }
    619 
    620   p_cb_data->status = wStatus;
    621   SEM_POST(p_cb_data);
    622   return;
    623 }
    624 
    625 /*******************************************************************************
    626 **
    627 ** Function         phNxpNciHal_fw_dnld_get_version
    628 **
    629 ** Description      Download Get version
    630 **
    631 ** Returns          NFCSTATUS_SUCCESS if success
    632 **
    633 *******************************************************************************/
    634 static NFCSTATUS phNxpNciHal_fw_dnld_get_version(void* pContext,
    635                                                  NFCSTATUS status,
    636                                                  void* pInfo) {
    637   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    638   phNxpNciHal_Sem_t cb_data;
    639   static uint8_t bGetVerRes[11];
    640   phDnldNfc_Buff_t tDnldBuff;
    641   UNUSED(pContext);
    642   UNUSED(status);
    643   UNUSED(pInfo);
    644   if (((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) ||
    645       ((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == true)) {
    646     return NFCSTATUS_SUCCESS;
    647   }
    648 
    649   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
    650     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb_data creation failed");
    651     return NFCSTATUS_FAILED;
    652   }
    653 
    654   tDnldBuff.pBuff = bGetVerRes;
    655   tDnldBuff.wLen = sizeof(bGetVerRes);
    656 
    657   wStatus = phDnldNfc_GetVersion(
    658       &tDnldBuff, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_get_version_cb,
    659       (void*)&cb_data);
    660   if (wStatus != NFCSTATUS_PENDING) {
    661     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version failed");
    662     wStatus = NFCSTATUS_FAILED;
    663     goto clean_and_return;
    664   }
    665   /* Wait for callback response */
    666   if (SEM_WAIT(cb_data)) {
    667     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version semaphore error");
    668     wStatus = NFCSTATUS_FAILED;
    669     goto clean_and_return;
    670   }
    671 
    672   if (cb_data.status != NFCSTATUS_SUCCESS) {
    673     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb failed");
    674     wStatus = NFCSTATUS_FAILED;
    675     goto clean_and_return;
    676   }
    677 
    678   wStatus = NFCSTATUS_SUCCESS;
    679 
    680 clean_and_return:
    681   phNxpNciHal_cleanup_cb_data(&cb_data);
    682 
    683   return wStatus;
    684 }
    685 
    686 /*******************************************************************************
    687 **
    688 ** Function         phNxpNciHal_fw_dnld_get_sessn_state_cb
    689 **
    690 ** Description      Download Get session state callback
    691 **
    692 ** Returns          None
    693 **
    694 *******************************************************************************/
    695 static void phNxpNciHal_fw_dnld_get_sessn_state_cb(void* pContext,
    696                                                    NFCSTATUS status,
    697                                                    void* pInfo) {
    698   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
    699   NFCSTATUS wStatus = status;
    700   pphDnldNfc_Buff_t pRespBuff;
    701   if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo)) {
    702     NXPLOG_FWDNLD_D(
    703         "phNxpNciHal_fw_dnld_get_sessn_state_cb - Request Successful");
    704 
    705     pRespBuff = (pphDnldNfc_Buff_t)pInfo;
    706 
    707     if ((3 == (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff))) {
    708       NXPLOG_FWDNLD_D(
    709           "phNxpNciHal_fw_dnld_get_sessn_state_cb - Valid Session State Resp "
    710           "Buff!!...");
    711 
    712       if (phDnldNfc_LCOper == pRespBuff->pBuff[2]) {
    713         if (PHLIBNFC_FWDNLD_SESSNOPEN == pRespBuff->pBuff[0]) {
    714           NXPLOG_FWDNLD_E("Prev Fw Upgrade Session still Open..");
    715           (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = true;
    716           if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) {
    717             NXPLOG_FWDNLD_D(
    718                 "Session still Open after Prev Fw Upgrade attempt!!");
    719 
    720             if ((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) <
    721                 PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS) {
    722               NXPLOG_FWDNLD_W("Setting Dnld Retry ..");
    723               (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = true;
    724             } else {
    725               NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!");
    726               (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
    727             }
    728             wStatus = NFCSTATUS_FAILED;
    729           }
    730         } else {
    731           gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen = false;
    732         }
    733       } else {
    734         wStatus = NFCSTATUS_FAILED;
    735         NXPLOG_FWDNLD_E(
    736             "NFCC not in Operational State..Fw Upgrade not allowed!!");
    737       }
    738     } else {
    739       wStatus = NFCSTATUS_FAILED;
    740       NXPLOG_FWDNLD_E(
    741           "phNxpNciHal_fw_dnld_get_sessn_state_cb - Session State Resp Buff "
    742           "Invalid...");
    743     }
    744   } else {
    745     wStatus = NFCSTATUS_FAILED;
    746     NXPLOG_FWDNLD_E(
    747         "phNxpNciHal_fw_dnld_get_sessn_state_cb - Request Failed!!");
    748   }
    749 
    750   p_cb_data->status = wStatus;
    751 
    752   SEM_POST(p_cb_data);
    753 
    754   return;
    755 }
    756 
    757 /*******************************************************************************
    758 **
    759 ** Function         phNxpNciHal_fw_dnld_get_sessn_state
    760 **
    761 ** Description      Download Get session state
    762 **
    763 ** Returns          NFCSTATUS_SUCCESS if success
    764 **
    765 *******************************************************************************/
    766 static NFCSTATUS phNxpNciHal_fw_dnld_get_sessn_state(void* pContext,
    767                                                      NFCSTATUS status,
    768                                                      void* pInfo) {
    769   phDnldNfc_Buff_t tDnldBuff;
    770   static uint8_t bGSnStateRes[3];
    771   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    772   phNxpNciHal_Sem_t cb_data;
    773   UNUSED(pContext);
    774   UNUSED(status);
    775   UNUSED(pInfo);
    776   if (gphNxpNciHal_fw_IoctlCtx.bSkipSeq == true) {
    777     return NFCSTATUS_SUCCESS;
    778   }
    779 
    780   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
    781     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb_data creation failed");
    782     return NFCSTATUS_FAILED;
    783   }
    784 
    785   tDnldBuff.pBuff = bGSnStateRes;
    786   tDnldBuff.wLen = sizeof(bGSnStateRes);
    787 
    788   wStatus = phDnldNfc_GetSessionState(
    789       &tDnldBuff, &phNxpNciHal_fw_dnld_get_sessn_state_cb, (void*)&cb_data);
    790   if (wStatus != NFCSTATUS_PENDING) {
    791     NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState failed");
    792     wStatus = NFCSTATUS_FAILED;
    793     goto clean_and_return;
    794   }
    795 
    796   /* Wait for callback response */
    797   if (SEM_WAIT(cb_data)) {
    798     NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState semaphore error");
    799     wStatus = NFCSTATUS_FAILED;
    800     goto clean_and_return;
    801   }
    802 
    803   if (cb_data.status != NFCSTATUS_SUCCESS) {
    804     NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState cb failed");
    805     wStatus = NFCSTATUS_FAILED;
    806     goto clean_and_return;
    807   }
    808 
    809   wStatus = NFCSTATUS_SUCCESS;
    810 
    811 clean_and_return:
    812   phNxpNciHal_cleanup_cb_data(&cb_data);
    813 
    814   return wStatus;
    815 }
    816 
    817 /*******************************************************************************
    818 **
    819 ** Function         phNxpNciHal_fw_dnld_log_read_cb
    820 **
    821 ** Description      Download Logread callback
    822 **
    823 ** Returns          None
    824 **
    825 *******************************************************************************/
    826 static void phNxpNciHal_fw_dnld_log_read_cb(void* pContext, NFCSTATUS status,
    827                                             void* pInfo) {
    828   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
    829 
    830   if ((NFCSTATUS_SUCCESS == status) && (NULL != pInfo)) {
    831     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_log_read_cb - Request Successful");
    832   } else {
    833     status = NFCSTATUS_FAILED;
    834     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read_cb - Request Failed!!");
    835   }
    836 
    837   p_cb_data->status = status;
    838   SEM_POST(p_cb_data);
    839 
    840   return;
    841 }
    842 
    843 /*******************************************************************************
    844 **
    845 ** Function         phNxpNciHal_fw_dnld_log_read
    846 **
    847 ** Description      Download Log Read
    848 **
    849 ** Returns          NFCSTATUS_SUCCESS if success
    850 **
    851 *******************************************************************************/
    852 static NFCSTATUS phNxpNciHal_fw_dnld_log_read(void* pContext, NFCSTATUS status,
    853                                               void* pInfo) {
    854   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    855   phNxpNciHal_Sem_t cb_data;
    856   phDnldNfc_Buff_t Data;
    857   UNUSED(pContext);
    858   UNUSED(status);
    859   UNUSED(pInfo);
    860   if (((((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) ||
    861         ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == true)) &&
    862        ((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == false)) ||
    863       ((((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == true)) &&
    864        ((gphNxpNciHal_fw_IoctlCtx.bRetryDnld) == true)))
    865 
    866   {
    867     return NFCSTATUS_SUCCESS;
    868   }
    869 
    870   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
    871     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read cb_data creation failed");
    872     return NFCSTATUS_FAILED;
    873   }
    874 
    875   (Data.pBuff) = (uint8_t*)&(gphNxpNciHal_fw_IoctlCtx.tLogParams);
    876   (Data.wLen) = sizeof(phLibNfc_EELogParams_t);
    877 
    878   wStatus = phDnldNfc_ReadLog(
    879       &Data, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_log_read_cb,
    880       (void*)&cb_data);
    881   if (wStatus != NFCSTATUS_PENDING) {
    882     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read failed");
    883     wStatus = NFCSTATUS_FAILED;
    884     goto clean_and_return;
    885   }
    886 
    887   /* Wait for callback response */
    888   if (SEM_WAIT(cb_data)) {
    889     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read semaphore error");
    890     wStatus = NFCSTATUS_FAILED;
    891     goto clean_and_return;
    892   }
    893 
    894   if (cb_data.status != NFCSTATUS_SUCCESS) {
    895     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read cb failed");
    896     wStatus = NFCSTATUS_FAILED;
    897     goto clean_and_return;
    898   }
    899 
    900   wStatus = NFCSTATUS_SUCCESS;
    901 
    902 clean_and_return:
    903   phNxpNciHal_cleanup_cb_data(&cb_data);
    904 
    905   return wStatus;
    906 }
    907 
    908 /*******************************************************************************
    909 **
    910 ** Function         phNxpNciHal_fw_dnld_write_cb
    911 **
    912 ** Description      Download Write callback
    913 **
    914 ** Returns          None
    915 **
    916 *******************************************************************************/
    917 static void phNxpNciHal_fw_dnld_write_cb(void* pContext, NFCSTATUS status,
    918                                          void* pInfo) {
    919   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
    920   UNUSED(pInfo);
    921   if (NFCSTATUS_SUCCESS == status) {
    922     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Request Successful");
    923     (gphNxpNciHal_fw_IoctlCtx.bDnldEepromWrite) = false;
    924     if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) {
    925       (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldSuccess) += 1;
    926 
    927       if ((gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) > 0) {
    928         NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Resetting DnldFailCnt");
    929         (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) = 0;
    930       }
    931 
    932       if ((gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) == false) {
    933         NXPLOG_FWDNLD_D(
    934             "phNxpNciHal_fw_dnld_write_cb - Setting bConfig for use by NCI "
    935             "mode");
    936         (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = true;
    937       }
    938     }
    939 
    940     /* Reset the previously set DnldAttemptFailed flag */
    941     if ((gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) == true) {
    942       (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = false;
    943     }
    944   } else {
    945     if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) {
    946       (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldFail) += 1;
    947       (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) += 1;
    948       (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = false;
    949     }
    950     if (NFCSTATUS_WRITE_FAILED == status) {
    951       (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = true;
    952       (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = true;
    953     }
    954     // status = NFCSTATUS_FAILED;
    955 
    956     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write_cb - Request Failed!!");
    957   }
    958 
    959   p_cb_data->status = status;
    960   SEM_POST(p_cb_data);
    961 
    962   return;
    963 }
    964 
    965 /*******************************************************************************
    966 **
    967 ** Function         phNxpNciHal_fw_dnld_write
    968 **
    969 ** Description      Download Write
    970 **
    971 ** Returns          NFCSTATUS_SUCCESS if success
    972 **
    973 *******************************************************************************/
    974 static NFCSTATUS phNxpNciHal_fw_dnld_write(void* pContext, NFCSTATUS status,
    975                                            void* pInfo) {
    976   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    977   phNxpNciHal_Sem_t cb_data;
    978   UNUSED(pContext);
    979   UNUSED(status);
    980   UNUSED(pInfo);
    981   if ((gphNxpNciHal_fw_IoctlCtx.bRetryDnld) == true) {
    982     (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
    983   }
    984 
    985   if (((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) &&
    986       ((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == false)) {
    987     return NFCSTATUS_SUCCESS;
    988   }
    989 
    990   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
    991     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write cb_data creation failed");
    992     return NFCSTATUS_FAILED;
    993   }
    994   if ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == false) {
    995     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write - Incrementing NumDnldTrig..");
    996     (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = true;
    997     (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
    998     (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldTrig) += 1;
    999   }
   1000   wStatus = phDnldNfc_Write(false, NULL,
   1001                             (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_write_cb,
   1002                             (void*)&cb_data);
   1003   if ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == false) {
   1004     if (wStatus != NFCSTATUS_PENDING) {
   1005       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write failed");
   1006       wStatus = NFCSTATUS_FAILED;
   1007       (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldFail) += 1;
   1008       (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) += 1;
   1009       (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = false;
   1010       goto clean_and_return;
   1011     }
   1012   }
   1013   /* Wait for callback response */
   1014   if (SEM_WAIT(cb_data)) {
   1015     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write semaphore error");
   1016     wStatus = NFCSTATUS_FAILED;
   1017     goto clean_and_return;
   1018   }
   1019 
   1020   if (cb_data.status != NFCSTATUS_SUCCESS) {
   1021     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write cb failed");
   1022     wStatus = cb_data.status;
   1023     goto clean_and_return;
   1024   }
   1025 
   1026   wStatus = NFCSTATUS_SUCCESS;
   1027 
   1028 clean_and_return:
   1029   phNxpNciHal_cleanup_cb_data(&cb_data);
   1030 
   1031   return wStatus;
   1032 }
   1033 
   1034 /*******************************************************************************
   1035 **
   1036 ** Function         phNxpNciHal_fw_dnld_chk_integrity_cb
   1037 **
   1038 ** Description      Download Check Integrity callback
   1039 **
   1040 ** Returns          None
   1041 **
   1042 *******************************************************************************/
   1043 static void phNxpNciHal_fw_dnld_chk_integrity_cb(void* pContext,
   1044                                                  NFCSTATUS status,
   1045                                                  void* pInfo) {
   1046   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
   1047   NFCSTATUS wStatus = status;
   1048   pphDnldNfc_Buff_t pRespBuff;
   1049   // uint8_t bUserDataCrc[4];
   1050 
   1051   if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo)) {
   1052     NXPLOG_FWDNLD_D(
   1053         "phNxpNciHal_fw_dnld_chk_integrity_cb - Request Successful");
   1054     pRespBuff = (pphDnldNfc_Buff_t)pInfo;
   1055 
   1056     if ((31 == (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff))) {
   1057       NXPLOG_FWDNLD_D(
   1058           "phNxpNciHal_fw_dnld_chk_integrity_cb - Valid Resp Buff!!...\n");
   1059       wStatus = phLibNfc_VerifyCrcStatus(pRespBuff->pBuff[0]);
   1060       /*
   1061       memcpy(bUserDataCrc, &(pRespBuff->pBuff[27]),
   1062               sizeof(bUserDataCrc));*/
   1063     } else {
   1064       NXPLOG_FWDNLD_E(
   1065           "phNxpNciHal_fw_dnld_chk_integrity_cb - Resp Buff Invalid...\n");
   1066     }
   1067   } else {
   1068     wStatus = NFCSTATUS_FAILED;
   1069     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity_cb - Request Failed!!");
   1070   }
   1071 
   1072   p_cb_data->status = wStatus;
   1073 
   1074   SEM_POST(p_cb_data);
   1075 
   1076   return;
   1077 }
   1078 
   1079 /*******************************************************************************
   1080 **
   1081 ** Function         phNxpNciHal_fw_dnld_chk_integrity
   1082 **
   1083 ** Description      Download Check Integrity
   1084 **
   1085 ** Returns          NFCSTATUS_SUCCESS if success
   1086 **
   1087 *******************************************************************************/
   1088 static NFCSTATUS phNxpNciHal_fw_dnld_chk_integrity(void* pContext,
   1089                                                    NFCSTATUS status,
   1090                                                    void* pInfo) {
   1091   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1092   phNxpNciHal_Sem_t cb_data;
   1093   phDnldNfc_Buff_t tDnldBuff;
   1094   static uint8_t bChkIntgRes[31];
   1095   UNUSED(pInfo);
   1096   UNUSED(pContext);
   1097   UNUSED(status);
   1098   if (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen == true) {
   1099     NXPLOG_FWDNLD_D(
   1100         "Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!");
   1101     return NFCSTATUS_SUCCESS;
   1102   }
   1103 
   1104   if ((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) {
   1105     return NFCSTATUS_SUCCESS;
   1106   } else if (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen == true) {
   1107     NXPLOG_FWDNLD_E(
   1108         "Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!");
   1109     return NFCSTATUS_SUCCESS;
   1110   }
   1111 
   1112   tDnldBuff.pBuff = bChkIntgRes;
   1113   tDnldBuff.wLen = sizeof(bChkIntgRes);
   1114 
   1115   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
   1116     NXPLOG_FWDNLD_E(
   1117         "phNxpNciHal_fw_dnld_chk_integrity cb_data creation failed");
   1118     return NFCSTATUS_FAILED;
   1119   }
   1120 
   1121   wStatus = phDnldNfc_CheckIntegrity(
   1122       (gphNxpNciHal_fw_IoctlCtx.bChipVer), &tDnldBuff,
   1123       &phNxpNciHal_fw_dnld_chk_integrity_cb, (void*)&cb_data);
   1124   if (wStatus != NFCSTATUS_PENDING) {
   1125     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity failed");
   1126     wStatus = NFCSTATUS_FAILED;
   1127     goto clean_and_return;
   1128   }
   1129 
   1130   /* Wait for callback response */
   1131   if (SEM_WAIT(cb_data)) {
   1132     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity semaphore error");
   1133     wStatus = NFCSTATUS_FAILED;
   1134     goto clean_and_return;
   1135   }
   1136 
   1137   if (cb_data.status != NFCSTATUS_SUCCESS) {
   1138     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity cb failed");
   1139     wStatus = NFCSTATUS_FAILED;
   1140     goto clean_and_return;
   1141   }
   1142 
   1143   wStatus = NFCSTATUS_SUCCESS;
   1144 
   1145 clean_and_return:
   1146   phNxpNciHal_cleanup_cb_data(&cb_data);
   1147 
   1148   return wStatus;
   1149 }
   1150 
   1151 /*******************************************************************************
   1152 **
   1153 ** Function         phNxpNciHal_fw_dnld_recover
   1154 **
   1155 ** Description      Download Recover
   1156 **
   1157 ** Returns          NFCSTATUS_SUCCESS if success
   1158 **
   1159 *******************************************************************************/
   1160 static NFCSTATUS phNxpNciHal_fw_dnld_recover(void* pContext, NFCSTATUS status,
   1161                                              void* pInfo) {
   1162   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1163   phNxpNciHal_Sem_t cb_data;
   1164 
   1165   UNUSED(pInfo);
   1166   UNUSED(status);
   1167   UNUSED(pContext);
   1168   if ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) {
   1169     if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
   1170       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover cb_data creation failed");
   1171       return NFCSTATUS_FAILED;
   1172     }
   1173     (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
   1174 
   1175     /* resetting this flag to avoid cyclic issuance of recovery sequence in case
   1176      * of failure */
   1177     (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1178 
   1179     wStatus = phDnldNfc_Write(
   1180         true, NULL, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_recover_cb,
   1181         (void*)&cb_data);
   1182 
   1183     if (NFCSTATUS_PENDING != wStatus) {
   1184       (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false;
   1185       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1186       goto clean_and_return;
   1187     }
   1188     /* Wait for callback response */
   1189     if (SEM_WAIT(cb_data)) {
   1190       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover semaphore error");
   1191       wStatus = NFCSTATUS_FAILED;
   1192       goto clean_and_return;
   1193     }
   1194 
   1195     if (cb_data.status != NFCSTATUS_SUCCESS) {
   1196       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover cb failed");
   1197       wStatus = NFCSTATUS_FAILED;
   1198       goto clean_and_return;
   1199     }
   1200     wStatus = NFCSTATUS_SUCCESS;
   1201 
   1202   clean_and_return:
   1203     phNxpNciHal_cleanup_cb_data(&cb_data);
   1204   }
   1205 
   1206   return wStatus;
   1207 }
   1208 
   1209 /*******************************************************************************
   1210 **
   1211 ** Function         phNxpNciHal_fw_dnld_recover_cb
   1212 **
   1213 ** Description      Download Recover callback
   1214 **
   1215 ** Returns          None
   1216 **
   1217 *******************************************************************************/
   1218 static void phNxpNciHal_fw_dnld_recover_cb(void* pContext, NFCSTATUS status,
   1219                                            void* pInfo) {
   1220   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
   1221   NFCSTATUS wStatus = status;
   1222   UNUSED(pContext);
   1223   UNUSED(pInfo);
   1224 
   1225   if (NFCSTATUS_SUCCESS == wStatus) {
   1226     if ((gphNxpNciHal_fw_IoctlCtx.bSkipForce) == false) {
   1227       NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Request Successful");
   1228       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = true;
   1229     } else {
   1230       NXPLOG_FWDNLD_D(
   1231           "phNxpNciHal_fw_dnld_recoverCb - Production key update Request "
   1232           "Successful");
   1233       (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = true;
   1234     }
   1235   } else {
   1236     wStatus = NFCSTATUS_FAILED;
   1237     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Request Failed!!");
   1238   }
   1239 
   1240   /* resetting this flag to avoid cyclic issuance of recovery sequence in case
   1241    * of failure */
   1242   (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1243 
   1244   /* reset previously set SkipForce */
   1245   (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false;
   1246   p_cb_data->status = wStatus;
   1247 
   1248   SEM_POST(p_cb_data);
   1249 
   1250   return;
   1251 }
   1252 
   1253 /*******************************************************************************
   1254 **
   1255 ** Function         phNxpNciHal_fw_dnld_send_ncicmd_cb
   1256 **
   1257 ** Description      Download Send NCI Command callback
   1258 **
   1259 ** Returns          None
   1260 **
   1261 *******************************************************************************/
   1262 static void phNxpNciHal_fw_dnld_send_ncicmd_cb(void* pContext, NFCSTATUS status,
   1263                                                void* pInfo) {
   1264   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
   1265   NFCSTATUS wStatus = status;
   1266   pphDnldNfc_Buff_t pRespBuff;
   1267   UNUSED(pContext);
   1268 
   1269   if (NFCSTATUS_SUCCESS == wStatus) {
   1270     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_send_ncicmdCb - Request Successful");
   1271     pRespBuff = (pphDnldNfc_Buff_t)pInfo;
   1272 
   1273     if ((0 != (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff))) {
   1274       if (0 == (pRespBuff->pBuff[3])) {
   1275         NXPLOG_FWDNLD_D("Successful Response received for Nci Reset Cmd");
   1276       } else {
   1277         NXPLOG_FWDNLD_E("Nci Reset Request Failed!!");
   1278       }
   1279     } else {
   1280       NXPLOG_FWDNLD_E("Invalid Response received for Nci Reset Request!!");
   1281     }
   1282     /* Call Tml Ioctl to enable download mode */
   1283     wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
   1284 
   1285     if (NFCSTATUS_SUCCESS == wStatus) {
   1286       NXPLOG_FWDNLD_D("Switched Successfully to dnld mode..");
   1287       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = true;
   1288     } else {
   1289       NXPLOG_FWDNLD_E("Switching back to dnld mode Failed!!");
   1290       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1291       wStatus = NFCSTATUS_FAILED;
   1292     }
   1293   } else {
   1294     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmdCb - Request Failed!!");
   1295   }
   1296 
   1297   (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false;
   1298   p_cb_data->status = wStatus;
   1299 
   1300   SEM_POST(p_cb_data);
   1301 
   1302   return;
   1303 }
   1304 
   1305 /*******************************************************************************
   1306 **
   1307 ** Function         phNxpNciHal_fw_dnld_send_ncicmd
   1308 **
   1309 ** Description      Download Send NCI Command
   1310 **
   1311 ** Returns          NFCSTATUS_SUCCESS if success
   1312 **
   1313 *******************************************************************************/
   1314 static NFCSTATUS phNxpNciHal_fw_dnld_send_ncicmd(void* pContext,
   1315                                                  NFCSTATUS status,
   1316                                                  void* pInfo) {
   1317   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1318   static uint8_t bNciCmd[4] = {0x20, 0x00, 0x01,
   1319                                0x00}; /* Nci Reset Cmd with KeepConfig option */
   1320   static uint8_t bNciResp[6];
   1321   phDnldNfc_Buff_t tsData;
   1322   phDnldNfc_Buff_t trData;
   1323   phNxpNciHal_Sem_t cb_data;
   1324 
   1325   UNUSED(pInfo);
   1326   UNUSED(status);
   1327   UNUSED(pContext);
   1328   if ((gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) == false) {
   1329     return NFCSTATUS_SUCCESS;
   1330   } else {
   1331     /* Call Tml Ioctl to enable/restore normal mode */
   1332     wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
   1333 
   1334     if (NFCSTATUS_SUCCESS != wStatus) {
   1335       NXPLOG_FWDNLD_E("Switching to NormalMode Failed!!");
   1336       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1337       (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false;
   1338     } else {
   1339       if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
   1340         NXPLOG_FWDNLD_E(
   1341             "phNxpNciHal_fw_dnld_send_ncicmd cb_data creation failed");
   1342         return NFCSTATUS_FAILED;
   1343       }
   1344       (tsData.pBuff) = bNciCmd;
   1345       (tsData.wLen) = sizeof(bNciCmd);
   1346       (trData.pBuff) = bNciResp;
   1347       (trData.wLen) = sizeof(bNciResp);
   1348 
   1349       wStatus = phDnldNfc_RawReq(
   1350           &tsData, &trData,
   1351           (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_send_ncicmd_cb,
   1352           (void*)&cb_data);
   1353       if (NFCSTATUS_PENDING != wStatus) {
   1354         goto clean_and_return;
   1355       }
   1356       /* Wait for callback response */
   1357       if (SEM_WAIT(cb_data)) {
   1358         NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd semaphore error");
   1359         wStatus = NFCSTATUS_FAILED;
   1360         goto clean_and_return;
   1361       }
   1362 
   1363       if (cb_data.status != NFCSTATUS_SUCCESS) {
   1364         NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd cb failed");
   1365         wStatus = NFCSTATUS_FAILED;
   1366         goto clean_and_return;
   1367       }
   1368       wStatus = NFCSTATUS_SUCCESS;
   1369 
   1370     clean_and_return:
   1371       phNxpNciHal_cleanup_cb_data(&cb_data);
   1372     }
   1373   }
   1374 
   1375   return wStatus;
   1376 }
   1377 
   1378 /*******************************************************************************
   1379 **
   1380 ** Function         phNxpNciHal_fw_dnld_log_cb
   1381 **
   1382 ** Description      Download Log callback
   1383 **
   1384 ** Returns          None
   1385 **
   1386 *******************************************************************************/
   1387 static void phNxpNciHal_fw_dnld_log_cb(void* pContext, NFCSTATUS status,
   1388                                        void* pInfo) {
   1389   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
   1390   NFCSTATUS wStatus = status;
   1391   UNUSED(pContext);
   1392   UNUSED(pInfo);
   1393 
   1394   if (NFCSTATUS_SUCCESS == wStatus) {
   1395     NXPLOG_FWDNLD_D("phLibNfc_DnldLogCb - Request Successful");
   1396     (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false;
   1397   } else {
   1398     wStatus = NFCSTATUS_FAILED;
   1399     NXPLOG_FWDNLD_E("phLibNfc_DnldLogCb - Request Failed!!");
   1400   }
   1401   p_cb_data->status = wStatus;
   1402 
   1403   SEM_POST(p_cb_data);
   1404   return;
   1405 }
   1406 
   1407 /*******************************************************************************
   1408 **
   1409 ** Function         phNxpNciHal_fw_dnld_log
   1410 **
   1411 ** Description      Download Log
   1412 **
   1413 ** Returns          NFCSTATUS_SUCCESS if success
   1414 **
   1415 *******************************************************************************/
   1416 static NFCSTATUS phNxpNciHal_fw_dnld_log(void* pContext, NFCSTATUS status,
   1417                                          void* pInfo) {
   1418   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1419   phNxpNciHal_Sem_t cb_data;
   1420   phDnldNfc_Buff_t tData;
   1421 
   1422   UNUSED(pInfo);
   1423   UNUSED(status);
   1424   UNUSED(pContext);
   1425   if ((((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) ||
   1426        ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == true)) &&
   1427       ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == false)) {
   1428     return NFCSTATUS_SUCCESS;
   1429   } else {
   1430     if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
   1431       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log cb_data creation failed");
   1432       return NFCSTATUS_FAILED;
   1433     }
   1434     (tData.pBuff) = (uint8_t*)&(gphNxpNciHal_fw_IoctlCtx.tLogParams);
   1435     (tData.wLen) = sizeof(gphNxpNciHal_fw_IoctlCtx.tLogParams);
   1436 
   1437     wStatus =
   1438         phDnldNfc_Log(&tData, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_log_cb,
   1439                       (void*)&cb_data);
   1440 
   1441     if (wStatus != NFCSTATUS_PENDING) {
   1442       NXPLOG_FWDNLD_E("phDnldNfc_Log failed");
   1443       (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false;
   1444       wStatus = NFCSTATUS_FAILED;
   1445       goto clean_and_return;
   1446     }
   1447     /* Wait for callback response */
   1448     if (SEM_WAIT(cb_data)) {
   1449       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log semaphore error");
   1450       wStatus = NFCSTATUS_FAILED;
   1451       goto clean_and_return;
   1452     }
   1453 
   1454     if (cb_data.status != NFCSTATUS_SUCCESS) {
   1455       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_cb failed");
   1456       wStatus = NFCSTATUS_FAILED;
   1457       goto clean_and_return;
   1458     }
   1459 
   1460     wStatus = NFCSTATUS_SUCCESS;
   1461 
   1462   clean_and_return:
   1463     phNxpNciHal_cleanup_cb_data(&cb_data);
   1464 
   1465     return wStatus;
   1466   }
   1467 }
   1468 
   1469 /*******************************************************************************
   1470 **
   1471 ** Function         phNxpNciHal_fw_seq_handler
   1472 **
   1473 ** Description      Sequence Handler
   1474 **
   1475 ** Returns          NFCSTATUS_SUCCESS if sequence completed uninterrupted
   1476 **
   1477 *******************************************************************************/
   1478 static NFCSTATUS phNxpNciHal_fw_seq_handler(
   1479     NFCSTATUS (*seq_handler[])(void* pContext, NFCSTATUS status, void* pInfo)) {
   1480   const char* pContext = "FW-Download";
   1481   int16_t seq_counter = 0;
   1482   phDnldNfc_Buff_t pInfo;
   1483   NFCSTATUS status = NFCSTATUS_FAILED;
   1484 
   1485   status = phTmlNfc_ReadAbort();
   1486   if (NFCSTATUS_SUCCESS != status) {
   1487     NXPLOG_FWDNLD_E("Tml Read Abort failed!!");
   1488     return status;
   1489   }
   1490 
   1491   while (seq_handler[seq_counter] != NULL) {
   1492     status = NFCSTATUS_FAILED;
   1493     status = (seq_handler[seq_counter])((void*)pContext, status, &pInfo);
   1494     if (NFCSTATUS_SUCCESS != status) {
   1495       NXPLOG_FWDNLD_E(" phNxpNciHal_fw_seq_handler : FAILED");
   1496       break;
   1497     }
   1498     seq_counter++;
   1499   }
   1500   return status;
   1501 }
   1502 
   1503 /*******************************************************************************
   1504 **
   1505 ** Function         phNxpNciHal_fw_dnld_complete
   1506 **
   1507 ** Description      Download Sequence Complete
   1508 **
   1509 ** Returns          NFCSTATUS_SUCCESS if success
   1510 **
   1511 *******************************************************************************/
   1512 static NFCSTATUS phNxpNciHal_fw_dnld_complete(void* pContext, NFCSTATUS status,
   1513                                               void* pInfo) {
   1514   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1515   NFCSTATUS fStatus = status;
   1516   UNUSED(pInfo);
   1517   UNUSED(pContext);
   1518 
   1519   if (NFCSTATUS_WRITE_FAILED == status) {
   1520     if ((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) <
   1521         PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS) {
   1522       (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = true;
   1523     } else {
   1524       NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!");
   1525       (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1526       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1527     }
   1528   } else if (NFCSTATUS_REJECTED == status) {
   1529     if ((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) <
   1530         PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS) {
   1531       (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = true;
   1532 
   1533       /* in case of signature error we need to try recover sequence directly
   1534        * bypassing the force cmd */
   1535       (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = true;
   1536     } else {
   1537       NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!");
   1538       (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1539       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1540     }
   1541   }
   1542 
   1543   if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) {
   1544     (gphNxpNciHal_fw_IoctlCtx.bLastStatus) = status;
   1545     (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = true;
   1546 
   1547     NXPLOG_FWDNLD_E("Invoking Pending Download Log Sequence..");
   1548     (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false;
   1549     /* Perform the Logging sequence */
   1550     wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_log_seqhandler);
   1551     if (NFCSTATUS_SUCCESS != gphNxpNciHal_fw_IoctlCtx.bLastStatus) {
   1552       /* update the previous Download Write status to upper layer and not the
   1553        * status of Log command */
   1554       wStatus = gphNxpNciHal_fw_IoctlCtx.bLastStatus;
   1555       NXPLOG_FWDNLD_E(
   1556           "phNxpNciHal_fw_dnld_complete: Last Download Write Status before Log "
   1557           "command bLastStatus = 0x%x",
   1558           gphNxpNciHal_fw_IoctlCtx.bLastStatus);
   1559     }
   1560     status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo);
   1561     if (NFCSTATUS_SUCCESS == status) {
   1562       NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
   1563     } else {
   1564       NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
   1565     }
   1566   } else if ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) {
   1567     NXPLOG_FWDNLD_E("Invoking Download Recovery Sequence..");
   1568 
   1569     if (NFCSTATUS_SUCCESS == wStatus) {
   1570       /* Perform the download Recovery sequence */
   1571       wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_rec_seqhandler);
   1572 
   1573       status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo);
   1574       if (NFCSTATUS_SUCCESS == status) {
   1575         NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
   1576       } else {
   1577         NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
   1578       }
   1579     }
   1580   } else if ((gphNxpNciHal_fw_IoctlCtx.bRetryDnld) == true) {
   1581     (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = false;
   1582     (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false;
   1583     (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = false;
   1584     (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = false;
   1585     (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false;
   1586     (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1587     (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false;
   1588 
   1589     /* Perform the download sequence ... after successful recover attempt */
   1590     wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler);
   1591 
   1592     status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo);
   1593     if (NFCSTATUS_SUCCESS == status) {
   1594       NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
   1595     } else {
   1596       NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
   1597     }
   1598   } else {
   1599     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_complete: Download Status = 0x%x",
   1600                     status);
   1601     if ((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == false) {
   1602       if (NFCSTATUS_SUCCESS == status) {
   1603         if (NFC_FW_DOWNLOAD == gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1604           NXPLOG_FWDNLD_E("Fw Download success.. ");
   1605         } else if (PHLIBNFC_DNLD_MEM_READ ==
   1606                    gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1607           NXPLOG_FWDNLD_E("Read Request success.. ");
   1608         } else if (PHLIBNFC_DNLD_MEM_WRITE ==
   1609                    gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1610           NXPLOG_FWDNLD_E("Write Request success.. ");
   1611         } else if (PHLIBNFC_DNLD_READ_LOG ==
   1612                    gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1613           NXPLOG_FWDNLD_E("ReadLog Request success.. ");
   1614         } else {
   1615           NXPLOG_FWDNLD_E("Invalid Request!!");
   1616         }
   1617       } else {
   1618         if (NFC_FW_DOWNLOAD == gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1619           NXPLOG_FWDNLD_E("Fw Download Failed!!");
   1620         } else if (NFC_MEM_READ == gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1621           NXPLOG_FWDNLD_E("Read Request Failed!!");
   1622         } else if (NFC_MEM_WRITE == gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1623           NXPLOG_FWDNLD_E("Write Request Failed!!");
   1624         } else if (PHLIBNFC_DNLD_READ_LOG ==
   1625                    gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1626           NXPLOG_FWDNLD_E("ReadLog Request Failed!!");
   1627         } else {
   1628           NXPLOG_FWDNLD_E("Invalid Request!!");
   1629         }
   1630       }
   1631     }
   1632 
   1633     if (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd == false) {
   1634       /* Call Tml Ioctl to enable/restore normal mode */
   1635       wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
   1636 
   1637       if (NFCSTATUS_SUCCESS != wStatus) {
   1638         NXPLOG_FWDNLD_E("Switching to NormalMode Failed!!");
   1639       } else {
   1640         wStatus = fStatus;
   1641       }
   1642     }
   1643 
   1644     (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = false;
   1645     (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false;
   1646     (gphNxpNciHal_fw_IoctlCtx.bChipVer) = 0;
   1647     (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = false;
   1648     (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = false;
   1649     (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1650     (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1651     (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = false;
   1652     (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false;
   1653     (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false;
   1654     (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) = 0;
   1655 
   1656     if (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed == false) {
   1657     } else {
   1658       NXPLOG_FWDNLD_E("Returning Download Failed Status to Caller!!");
   1659 
   1660       (gphNxpNciHal_fw_IoctlCtx.bLastStatus) = NFCSTATUS_SUCCESS;
   1661       (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = false;
   1662     }
   1663     phDnldNfc_CloseFwLibHandle();
   1664   }
   1665 
   1666   return wStatus;
   1667 }
   1668 
   1669 /*******************************************************************************
   1670 **
   1671 ** Function         phNxpNciHal_fw_download_seq
   1672 **
   1673 ** Description      Download Sequence
   1674 **
   1675 ** Returns          NFCSTATUS_SUCCESS if success
   1676 **
   1677 *******************************************************************************/
   1678 NFCSTATUS phNxpNciHal_fw_download_seq(uint8_t bClkSrcVal, uint8_t bClkFreqVal) {
   1679   NFCSTATUS status = NFCSTATUS_FAILED;
   1680   phDnldNfc_Buff_t pInfo;
   1681   const char* pContext = "FW-Download";
   1682 
   1683   /* reset the global flags */
   1684   gphNxpNciHal_fw_IoctlCtx.IoctlCode = NFC_FW_DOWNLOAD;
   1685   (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = false;
   1686   (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false;
   1687   (gphNxpNciHal_fw_IoctlCtx.bChipVer) = 0;
   1688   (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = false;
   1689   (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = false;
   1690   (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1691   (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1692   (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = false;
   1693   (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false;
   1694   (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false;
   1695   (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) = 0;
   1696   (gphNxpNciHal_fw_IoctlCtx.bClkSrcVal) = bClkSrcVal;
   1697   (gphNxpNciHal_fw_IoctlCtx.bClkFreqVal) = bClkFreqVal;
   1698   /* Get firmware version */
   1699   if (NFCSTATUS_SUCCESS == phDnldNfc_InitImgInfo()) {
   1700     NXPLOG_FWDNLD_D("phDnldNfc_InitImgInfo:SUCCESS");
   1701     if (gRecFWDwnld == true) {
   1702       status =
   1703           phNxpNciHal_fw_seq_handler(phNxpNciHal_dummy_rec_dwnld_seqhandler);
   1704     } else {
   1705       status = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler);
   1706     }
   1707   } else {
   1708     NXPLOG_FWDNLD_E("phDnldNfc_InitImgInfo: FAILED");
   1709   }
   1710 
   1711   /* Chage to normal mode */
   1712   status = phNxpNciHal_fw_dnld_complete((void*)pContext, status, &pInfo);
   1713   /*if (NFCSTATUS_SUCCESS == status)
   1714   {
   1715       NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
   1716   }
   1717   else
   1718   {
   1719       NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
   1720   }*/
   1721 
   1722   return status;
   1723 }
   1724 
   1725 static NFCSTATUS phLibNfc_VerifyCrcStatus(uint8_t bCrcStatus) {
   1726   uint8_t bBitPos = 1;
   1727   uint8_t bShiftVal = 2;
   1728   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1729   while (bBitPos < 7) {
   1730     if (!(bCrcStatus & bShiftVal)) {
   1731       switch (bBitPos) {
   1732         case 0: {
   1733           NXPLOG_FWDNLD_E("User Data Crc is NOT OK!!");
   1734           wStatus = NFCSTATUS_FAILED;
   1735           break;
   1736         }
   1737         case 1: {
   1738           NXPLOG_FWDNLD_E("Trim Data Crc is NOT OK!!");
   1739           wStatus = NFCSTATUS_FAILED;
   1740           break;
   1741         }
   1742         case 2: {
   1743           NXPLOG_FWDNLD_E("Protected Data Crc is NOT OK!!");
   1744           wStatus = NFCSTATUS_FAILED;
   1745           break;
   1746         }
   1747         case 3: {
   1748           NXPLOG_FWDNLD_E("Patch Code Crc is NOT OK!!");
   1749           wStatus = NFCSTATUS_FAILED;
   1750           break;
   1751         }
   1752         case 4: {
   1753           NXPLOG_FWDNLD_E("Function Code Crc is NOT OK!!");
   1754           wStatus = NFCSTATUS_FAILED;
   1755           break;
   1756         }
   1757         case 5: {
   1758           NXPLOG_FWDNLD_E("Patch Table Crc is NOT OK!!");
   1759           wStatus = NFCSTATUS_FAILED;
   1760           break;
   1761         }
   1762         case 6: {
   1763           NXPLOG_FWDNLD_E("Function Table Crc is NOT OK!!");
   1764           wStatus = NFCSTATUS_FAILED;
   1765           break;
   1766         }
   1767         default: { break; }
   1768       }
   1769     }
   1770 
   1771     bShiftVal <<= 1;
   1772     ++bBitPos;
   1773   }
   1774 
   1775   return wStatus;
   1776 }
   1777