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