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 #if (NFC_NXP_CHIP_TYPE == PN553)
    557         if (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0]) {
    558           (gphNxpNciHal_fw_IoctlCtx.bChipVer) = pRespBuff->pBuff[0];
    559         }
    560 #endif
    561       } else if ((bHwVer >= PHDNLDNFC_HWVER_MRA1_0) &&
    562                  (bHwVer <= PHDNLDNFC_HWVER_MRA2_0)) {
    563         bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN;
    564         (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer;
    565       } else {
    566         wStatus = NFCSTATUS_FAILED;
    567         NXPLOG_FWDNLD_E(
    568             "phNxpNciHal_fw_dnld_get_version_cb - Invalid ChipVersion!!");
    569       }
    570     } else {
    571       wStatus = NFCSTATUS_FAILED;
    572       NXPLOG_FWDNLD_E(
    573           "phNxpNciHal_fw_dnld_get_version_cb - Version Resp Buff "
    574           "Invalid...\n");
    575     }
    576 
    577     if ((NFCSTATUS_SUCCESS == wStatus) && (bExpectedLen == pRespBuff->wLen) &&
    578         (NULL != pRespBuff->pBuff)) {
    579       NXPLOG_FWDNLD_D(
    580           "phNxpNciHal_fw_dnld_get_version_cb - Valid Version Resp "
    581           "Buff!!...\n");
    582 
    583       /* Validate version details to confirm if continue with the next sequence
    584        * of Operations. */
    585       memcpy(bCurrVer, &(pRespBuff->pBuff[bExpectedLen - 2]), sizeof(bCurrVer));
    586       wFwVern = wFwVer;
    587       wMwVern = wMwVer;
    588 
    589       memcpy(bNewVer, &wFwVern, sizeof(bNewVer));
    590 
    591       /* check if the ROM code version and FW Major version is valid for the
    592        * chip*/
    593       /* ES2.2 Rom Version - 0x7 and Valid FW Major Version - 0x1 */
    594       if ((pRespBuff->pBuff[1] == 0x07) && (bNewVer[1] != 0x01)) {
    595         NXPLOG_FWDNLD_E(
    596             "C1 FW on C2 chip is not allowed - FW Major Version!= 1 on ES2.2");
    597         wStatus = NFCSTATUS_NOT_ALLOWED;
    598       }
    599       /* Major Version number check */
    600       else if ((FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) &&
    601                (bNewVer[1] < bCurrVer[1])) {
    602         NXPLOG_FWDNLD_E("Version Check Failed - MajorVerNum Mismatch\n");
    603         NXPLOG_FWDNLD_E("NewVer %d != CurrVer %d\n", bNewVer[1], bCurrVer[1]);
    604         wStatus = NFCSTATUS_NOT_ALLOWED;
    605       }
    606       /* Minor Version number check - before download.*/
    607       else if ((FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) &&
    608                ((bNewVer[0] == bCurrVer[0]) && (bNewVer[1] == bCurrVer[1]))) {
    609         wStatus = NFCSTATUS_SUCCESS;
    610 #if (PH_LIBNFC_ENABLE_FORCE_DOWNLOAD == 0)
    611         NXPLOG_FWDNLD_D("Version Already UpToDate!!\n");
    612         (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = TRUE;
    613 #else
    614         (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = TRUE;
    615 #endif
    616 
    617       }
    618       /* Minor Version number check - after download
    619        * after download, we should get the same version information.*/
    620       else if ((TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) &&
    621                ((bNewVer[0] != bCurrVer[0]) || (bNewVer[1] != bCurrVer[1]))) {
    622         NXPLOG_FWDNLD_E("Version Not Updated After Download!!\n");
    623         wStatus = NFCSTATUS_FAILED;
    624       } else {
    625         NXPLOG_FWDNLD_D("Version Check Successful\n");
    626         /* Store the Mw & Fw Version for updating in EEPROM Log Area after
    627          * successful download */
    628         if (TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) {
    629           NXPLOG_FWDNLD_W("Updating Fw & Mw Versions..");
    630           (gphNxpNciHal_fw_IoctlCtx.tLogParams.wCurrMwVer) = wMwVern;
    631           (gphNxpNciHal_fw_IoctlCtx.tLogParams.wCurrFwVer) = wFwVern;
    632         }
    633       }
    634     } else {
    635       NXPLOG_FWDNLD_E(
    636           "phNxpNciHal_fw_dnld_get_version_cb - Version Resp Buff "
    637           "Invalid...\n");
    638     }
    639   } else {
    640     wStatus = NFCSTATUS_FAILED;
    641     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Request Failed!!");
    642   }
    643 
    644   p_cb_data->status = wStatus;
    645   SEM_POST(p_cb_data);
    646   return;
    647 }
    648 
    649 /*******************************************************************************
    650 **
    651 ** Function         phNxpNciHal_fw_dnld_get_version
    652 **
    653 ** Description      Download Get version
    654 **
    655 ** Returns          NFCSTATUS_SUCCESS if success
    656 **
    657 *******************************************************************************/
    658 static NFCSTATUS phNxpNciHal_fw_dnld_get_version(void* pContext,
    659                                                  NFCSTATUS status,
    660                                                  void* pInfo) {
    661   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    662   phNxpNciHal_Sem_t cb_data;
    663   static uint8_t bGetVerRes[11];
    664   phDnldNfc_Buff_t tDnldBuff;
    665   UNUSED(pContext);
    666   UNUSED(status);
    667   UNUSED(pInfo);
    668   if (((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) ||
    669       ((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == true)) {
    670     return NFCSTATUS_SUCCESS;
    671   }
    672 
    673   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
    674     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb_data creation failed");
    675     return NFCSTATUS_FAILED;
    676   }
    677 
    678   tDnldBuff.pBuff = bGetVerRes;
    679   tDnldBuff.wLen = sizeof(bGetVerRes);
    680 
    681   wStatus = phDnldNfc_GetVersion(
    682       &tDnldBuff, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_get_version_cb,
    683       (void*)&cb_data);
    684   if (wStatus != NFCSTATUS_PENDING) {
    685     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version failed");
    686     wStatus = NFCSTATUS_FAILED;
    687     goto clean_and_return;
    688   }
    689   /* Wait for callback response */
    690   if (SEM_WAIT(cb_data)) {
    691     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version semaphore error");
    692     wStatus = NFCSTATUS_FAILED;
    693     goto clean_and_return;
    694   }
    695 
    696   if (cb_data.status != NFCSTATUS_SUCCESS) {
    697     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb failed");
    698     wStatus = NFCSTATUS_FAILED;
    699     goto clean_and_return;
    700   }
    701 
    702   wStatus = NFCSTATUS_SUCCESS;
    703 
    704 clean_and_return:
    705   phNxpNciHal_cleanup_cb_data(&cb_data);
    706 
    707   return wStatus;
    708 }
    709 
    710 /*******************************************************************************
    711 **
    712 ** Function         phNxpNciHal_fw_dnld_get_sessn_state_cb
    713 **
    714 ** Description      Download Get session state callback
    715 **
    716 ** Returns          None
    717 **
    718 *******************************************************************************/
    719 static void phNxpNciHal_fw_dnld_get_sessn_state_cb(void* pContext,
    720                                                    NFCSTATUS status,
    721                                                    void* pInfo) {
    722   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
    723   NFCSTATUS wStatus = status;
    724   pphDnldNfc_Buff_t pRespBuff;
    725   if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo)) {
    726     NXPLOG_FWDNLD_D(
    727         "phNxpNciHal_fw_dnld_get_sessn_state_cb - Request Successful");
    728 
    729     pRespBuff = (pphDnldNfc_Buff_t)pInfo;
    730 
    731     if ((3 == (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff))) {
    732       NXPLOG_FWDNLD_D(
    733           "phNxpNciHal_fw_dnld_get_sessn_state_cb - Valid Session State Resp "
    734           "Buff!!...");
    735 
    736       if (phDnldNfc_LCOper == pRespBuff->pBuff[2]) {
    737         if (PHLIBNFC_FWDNLD_SESSNOPEN == pRespBuff->pBuff[0]) {
    738           NXPLOG_FWDNLD_E("Prev Fw Upgrade Session still Open..");
    739           (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = true;
    740           if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) {
    741             NXPLOG_FWDNLD_D(
    742                 "Session still Open after Prev Fw Upgrade attempt!!");
    743 
    744             if ((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) <
    745                 PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS) {
    746               NXPLOG_FWDNLD_W("Setting Dnld Retry ..");
    747               (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = true;
    748             } else {
    749               NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!");
    750               (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
    751             }
    752             wStatus = NFCSTATUS_FAILED;
    753           }
    754         } else {
    755           gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen = false;
    756         }
    757       } else {
    758         wStatus = NFCSTATUS_FAILED;
    759         NXPLOG_FWDNLD_E(
    760             "NFCC not in Operational State..Fw Upgrade not allowed!!");
    761       }
    762     } else {
    763       wStatus = NFCSTATUS_FAILED;
    764       NXPLOG_FWDNLD_E(
    765           "phNxpNciHal_fw_dnld_get_sessn_state_cb - Session State Resp Buff "
    766           "Invalid...");
    767     }
    768   } else {
    769     wStatus = NFCSTATUS_FAILED;
    770     NXPLOG_FWDNLD_E(
    771         "phNxpNciHal_fw_dnld_get_sessn_state_cb - Request Failed!!");
    772   }
    773 
    774   p_cb_data->status = wStatus;
    775 
    776   SEM_POST(p_cb_data);
    777 
    778   return;
    779 }
    780 
    781 /*******************************************************************************
    782 **
    783 ** Function         phNxpNciHal_fw_dnld_get_sessn_state
    784 **
    785 ** Description      Download Get session state
    786 **
    787 ** Returns          NFCSTATUS_SUCCESS if success
    788 **
    789 *******************************************************************************/
    790 static NFCSTATUS phNxpNciHal_fw_dnld_get_sessn_state(void* pContext,
    791                                                      NFCSTATUS status,
    792                                                      void* pInfo) {
    793   phDnldNfc_Buff_t tDnldBuff;
    794   static uint8_t bGSnStateRes[3];
    795   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    796   phNxpNciHal_Sem_t cb_data;
    797   UNUSED(pContext);
    798   UNUSED(status);
    799   UNUSED(pInfo);
    800   if (gphNxpNciHal_fw_IoctlCtx.bSkipSeq == true) {
    801     return NFCSTATUS_SUCCESS;
    802   }
    803 
    804   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
    805     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb_data creation failed");
    806     return NFCSTATUS_FAILED;
    807   }
    808 
    809   tDnldBuff.pBuff = bGSnStateRes;
    810   tDnldBuff.wLen = sizeof(bGSnStateRes);
    811 
    812   wStatus = phDnldNfc_GetSessionState(
    813       &tDnldBuff, &phNxpNciHal_fw_dnld_get_sessn_state_cb, (void*)&cb_data);
    814   if (wStatus != NFCSTATUS_PENDING) {
    815     NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState failed");
    816     wStatus = NFCSTATUS_FAILED;
    817     goto clean_and_return;
    818   }
    819 
    820   /* Wait for callback response */
    821   if (SEM_WAIT(cb_data)) {
    822     NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState semaphore error");
    823     wStatus = NFCSTATUS_FAILED;
    824     goto clean_and_return;
    825   }
    826 
    827   if (cb_data.status != NFCSTATUS_SUCCESS) {
    828     NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState cb failed");
    829     wStatus = NFCSTATUS_FAILED;
    830     goto clean_and_return;
    831   }
    832 
    833   wStatus = NFCSTATUS_SUCCESS;
    834 
    835 clean_and_return:
    836   phNxpNciHal_cleanup_cb_data(&cb_data);
    837 
    838   return wStatus;
    839 }
    840 
    841 /*******************************************************************************
    842 **
    843 ** Function         phNxpNciHal_fw_dnld_log_read_cb
    844 **
    845 ** Description      Download Logread callback
    846 **
    847 ** Returns          None
    848 **
    849 *******************************************************************************/
    850 static void phNxpNciHal_fw_dnld_log_read_cb(void* pContext, NFCSTATUS status,
    851                                             void* pInfo) {
    852   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
    853 
    854   if ((NFCSTATUS_SUCCESS == status) && (NULL != pInfo)) {
    855     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_log_read_cb - Request Successful");
    856   } else {
    857     status = NFCSTATUS_FAILED;
    858     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read_cb - Request Failed!!");
    859   }
    860 
    861   p_cb_data->status = status;
    862   SEM_POST(p_cb_data);
    863 
    864   return;
    865 }
    866 
    867 /*******************************************************************************
    868 **
    869 ** Function         phNxpNciHal_fw_dnld_log_read
    870 **
    871 ** Description      Download Log Read
    872 **
    873 ** Returns          NFCSTATUS_SUCCESS if success
    874 **
    875 *******************************************************************************/
    876 static NFCSTATUS phNxpNciHal_fw_dnld_log_read(void* pContext, NFCSTATUS status,
    877                                               void* pInfo) {
    878   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
    879   phNxpNciHal_Sem_t cb_data;
    880   phDnldNfc_Buff_t Data;
    881   UNUSED(pContext);
    882   UNUSED(status);
    883   UNUSED(pInfo);
    884   if (((((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) ||
    885         ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == true)) &&
    886        ((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == false)) ||
    887       ((((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == true)) &&
    888        ((gphNxpNciHal_fw_IoctlCtx.bRetryDnld) == true)))
    889 
    890   {
    891     return NFCSTATUS_SUCCESS;
    892   }
    893 
    894   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
    895     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read cb_data creation failed");
    896     return NFCSTATUS_FAILED;
    897   }
    898 
    899   (Data.pBuff) = (void*)&(gphNxpNciHal_fw_IoctlCtx.tLogParams);
    900   (Data.wLen) = sizeof(phLibNfc_EELogParams_t);
    901 
    902   wStatus = phDnldNfc_ReadLog(
    903       &Data, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_log_read_cb,
    904       (void*)&cb_data);
    905   if (wStatus != NFCSTATUS_PENDING) {
    906     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read failed");
    907     wStatus = NFCSTATUS_FAILED;
    908     goto clean_and_return;
    909   }
    910 
    911   /* Wait for callback response */
    912   if (SEM_WAIT(cb_data)) {
    913     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read semaphore error");
    914     wStatus = NFCSTATUS_FAILED;
    915     goto clean_and_return;
    916   }
    917 
    918   if (cb_data.status != NFCSTATUS_SUCCESS) {
    919     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read cb failed");
    920     wStatus = NFCSTATUS_FAILED;
    921     goto clean_and_return;
    922   }
    923 
    924   wStatus = NFCSTATUS_SUCCESS;
    925 
    926 clean_and_return:
    927   phNxpNciHal_cleanup_cb_data(&cb_data);
    928 
    929   return wStatus;
    930 }
    931 
    932 /*******************************************************************************
    933 **
    934 ** Function         phNxpNciHal_fw_dnld_write_cb
    935 **
    936 ** Description      Download Write callback
    937 **
    938 ** Returns          None
    939 **
    940 *******************************************************************************/
    941 static void phNxpNciHal_fw_dnld_write_cb(void* pContext, NFCSTATUS status,
    942                                          void* pInfo) {
    943   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
    944   UNUSED(pInfo);
    945   if (NFCSTATUS_SUCCESS == status) {
    946     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Request Successful");
    947     (gphNxpNciHal_fw_IoctlCtx.bDnldEepromWrite) = false;
    948     if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) {
    949       (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldSuccess) += 1;
    950 
    951       if ((gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) > 0) {
    952         NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Resetting DnldFailCnt");
    953         (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) = 0;
    954       }
    955 
    956       if ((gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) == false) {
    957         NXPLOG_FWDNLD_D(
    958             "phNxpNciHal_fw_dnld_write_cb - Setting bConfig for use by NCI "
    959             "mode");
    960         (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = true;
    961       }
    962     }
    963 
    964     /* Reset the previously set DnldAttemptFailed flag */
    965     if ((gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) == true) {
    966       (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = false;
    967     }
    968   } else {
    969     if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) {
    970       (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldFail) += 1;
    971       (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) += 1;
    972       (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = false;
    973     }
    974     if (NFCSTATUS_WRITE_FAILED == status) {
    975       (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = true;
    976       (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = true;
    977     }
    978     // status = NFCSTATUS_FAILED;
    979 
    980     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write_cb - Request Failed!!");
    981   }
    982 
    983   p_cb_data->status = status;
    984   SEM_POST(p_cb_data);
    985 
    986   return;
    987 }
    988 
    989 /*******************************************************************************
    990 **
    991 ** Function         phNxpNciHal_fw_dnld_write
    992 **
    993 ** Description      Download Write
    994 **
    995 ** Returns          NFCSTATUS_SUCCESS if success
    996 **
    997 *******************************************************************************/
    998 static NFCSTATUS phNxpNciHal_fw_dnld_write(void* pContext, NFCSTATUS status,
    999                                            void* pInfo) {
   1000   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1001   phNxpNciHal_Sem_t cb_data;
   1002   UNUSED(pContext);
   1003   UNUSED(status);
   1004   UNUSED(pInfo);
   1005   if ((gphNxpNciHal_fw_IoctlCtx.bRetryDnld) == true) {
   1006     (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1007   }
   1008 
   1009   if (((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) &&
   1010       ((gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) == false)) {
   1011     return NFCSTATUS_SUCCESS;
   1012   }
   1013 
   1014   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
   1015     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write cb_data creation failed");
   1016     return NFCSTATUS_FAILED;
   1017   }
   1018   if ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == false) {
   1019     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write - Incrementing NumDnldTrig..");
   1020     (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = true;
   1021     (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
   1022     (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldTrig) += 1;
   1023   }
   1024   wStatus = phDnldNfc_Write(false, NULL,
   1025                             (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_write_cb,
   1026                             (void*)&cb_data);
   1027   if ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == false) {
   1028     if (wStatus != NFCSTATUS_PENDING) {
   1029       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write failed");
   1030       wStatus = NFCSTATUS_FAILED;
   1031       (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldFail) += 1;
   1032       (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) += 1;
   1033       (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = false;
   1034       goto clean_and_return;
   1035     }
   1036   }
   1037   /* Wait for callback response */
   1038   if (SEM_WAIT(cb_data)) {
   1039     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write semaphore error");
   1040     wStatus = NFCSTATUS_FAILED;
   1041     goto clean_and_return;
   1042   }
   1043 
   1044   if (cb_data.status != NFCSTATUS_SUCCESS) {
   1045     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write cb failed");
   1046     wStatus = cb_data.status;
   1047     goto clean_and_return;
   1048   }
   1049 
   1050   wStatus = NFCSTATUS_SUCCESS;
   1051 
   1052 clean_and_return:
   1053   phNxpNciHal_cleanup_cb_data(&cb_data);
   1054 
   1055   return wStatus;
   1056 }
   1057 
   1058 /*******************************************************************************
   1059 **
   1060 ** Function         phNxpNciHal_fw_dnld_chk_integrity_cb
   1061 **
   1062 ** Description      Download Check Integrity callback
   1063 **
   1064 ** Returns          None
   1065 **
   1066 *******************************************************************************/
   1067 static void phNxpNciHal_fw_dnld_chk_integrity_cb(void* pContext,
   1068                                                  NFCSTATUS status,
   1069                                                  void* pInfo) {
   1070   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
   1071   NFCSTATUS wStatus = status;
   1072   pphDnldNfc_Buff_t pRespBuff;
   1073   // uint8_t bUserDataCrc[4];
   1074 
   1075   if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo)) {
   1076     NXPLOG_FWDNLD_D(
   1077         "phNxpNciHal_fw_dnld_chk_integrity_cb - Request Successful");
   1078     pRespBuff = (pphDnldNfc_Buff_t)pInfo;
   1079 
   1080     if ((31 == (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff))) {
   1081       NXPLOG_FWDNLD_D(
   1082           "phNxpNciHal_fw_dnld_chk_integrity_cb - Valid Resp Buff!!...\n");
   1083       wStatus = phLibNfc_VerifyCrcStatus(pRespBuff->pBuff[0]);
   1084       /*
   1085       memcpy(bUserDataCrc, &(pRespBuff->pBuff[27]),
   1086               sizeof(bUserDataCrc));*/
   1087     } else {
   1088       NXPLOG_FWDNLD_E(
   1089           "phNxpNciHal_fw_dnld_chk_integrity_cb - Resp Buff Invalid...\n");
   1090     }
   1091   } else {
   1092     wStatus = NFCSTATUS_FAILED;
   1093     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity_cb - Request Failed!!");
   1094   }
   1095 
   1096   p_cb_data->status = wStatus;
   1097 
   1098   SEM_POST(p_cb_data);
   1099 
   1100   return;
   1101 }
   1102 
   1103 /*******************************************************************************
   1104 **
   1105 ** Function         phNxpNciHal_fw_dnld_chk_integrity
   1106 **
   1107 ** Description      Download Check Integrity
   1108 **
   1109 ** Returns          NFCSTATUS_SUCCESS if success
   1110 **
   1111 *******************************************************************************/
   1112 static NFCSTATUS phNxpNciHal_fw_dnld_chk_integrity(void* pContext,
   1113                                                    NFCSTATUS status,
   1114                                                    void* pInfo) {
   1115   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1116   phNxpNciHal_Sem_t cb_data;
   1117   phDnldNfc_Buff_t tDnldBuff;
   1118   static uint8_t bChkIntgRes[31];
   1119   UNUSED(pInfo);
   1120   UNUSED(pContext);
   1121   UNUSED(status);
   1122   if (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen == true) {
   1123     NXPLOG_FWDNLD_D(
   1124         "Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!");
   1125     return NFCSTATUS_SUCCESS;
   1126   }
   1127 
   1128   if ((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) {
   1129     return NFCSTATUS_SUCCESS;
   1130   } else if (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen == true) {
   1131     NXPLOG_FWDNLD_E(
   1132         "Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!");
   1133     return NFCSTATUS_SUCCESS;
   1134   }
   1135 
   1136   tDnldBuff.pBuff = bChkIntgRes;
   1137   tDnldBuff.wLen = sizeof(bChkIntgRes);
   1138 
   1139   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
   1140     NXPLOG_FWDNLD_E(
   1141         "phNxpNciHal_fw_dnld_chk_integrity cb_data creation failed");
   1142     return NFCSTATUS_FAILED;
   1143   }
   1144 
   1145   wStatus = phDnldNfc_CheckIntegrity(
   1146       (gphNxpNciHal_fw_IoctlCtx.bChipVer), &tDnldBuff,
   1147       &phNxpNciHal_fw_dnld_chk_integrity_cb, (void*)&cb_data);
   1148   if (wStatus != NFCSTATUS_PENDING) {
   1149     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity failed");
   1150     wStatus = NFCSTATUS_FAILED;
   1151     goto clean_and_return;
   1152   }
   1153 
   1154   /* Wait for callback response */
   1155   if (SEM_WAIT(cb_data)) {
   1156     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity semaphore error");
   1157     wStatus = NFCSTATUS_FAILED;
   1158     goto clean_and_return;
   1159   }
   1160 
   1161   if (cb_data.status != NFCSTATUS_SUCCESS) {
   1162     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity cb failed");
   1163     wStatus = NFCSTATUS_FAILED;
   1164     goto clean_and_return;
   1165   }
   1166 
   1167   wStatus = NFCSTATUS_SUCCESS;
   1168 
   1169 clean_and_return:
   1170   phNxpNciHal_cleanup_cb_data(&cb_data);
   1171 
   1172   return wStatus;
   1173 }
   1174 
   1175 /*******************************************************************************
   1176 **
   1177 ** Function         phNxpNciHal_fw_dnld_recover
   1178 **
   1179 ** Description      Download Recover
   1180 **
   1181 ** Returns          NFCSTATUS_SUCCESS if success
   1182 **
   1183 *******************************************************************************/
   1184 static NFCSTATUS phNxpNciHal_fw_dnld_recover(void* pContext, NFCSTATUS status,
   1185                                              void* pInfo) {
   1186   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1187   phNxpNciHal_Sem_t cb_data;
   1188 
   1189   UNUSED(pInfo);
   1190   UNUSED(status);
   1191   UNUSED(pContext);
   1192   if ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) {
   1193     if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
   1194       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover cb_data creation failed");
   1195       return NFCSTATUS_FAILED;
   1196     }
   1197     (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
   1198 
   1199     /* resetting this flag to avoid cyclic issuance of recovery sequence in case
   1200      * of failure */
   1201     (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1202 
   1203     wStatus = phDnldNfc_Write(
   1204         true, NULL, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_recover_cb,
   1205         (void*)&cb_data);
   1206 
   1207     if (NFCSTATUS_PENDING != wStatus) {
   1208       (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false;
   1209       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1210       goto clean_and_return;
   1211     }
   1212     /* Wait for callback response */
   1213     if (SEM_WAIT(cb_data)) {
   1214       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover semaphore error");
   1215       wStatus = NFCSTATUS_FAILED;
   1216       goto clean_and_return;
   1217     }
   1218 
   1219     if (cb_data.status != NFCSTATUS_SUCCESS) {
   1220       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover cb failed");
   1221       wStatus = NFCSTATUS_FAILED;
   1222       goto clean_and_return;
   1223     }
   1224     wStatus = NFCSTATUS_SUCCESS;
   1225 
   1226   clean_and_return:
   1227     phNxpNciHal_cleanup_cb_data(&cb_data);
   1228   }
   1229 
   1230   return wStatus;
   1231 }
   1232 
   1233 /*******************************************************************************
   1234 **
   1235 ** Function         phNxpNciHal_fw_dnld_recover_cb
   1236 **
   1237 ** Description      Download Recover callback
   1238 **
   1239 ** Returns          None
   1240 **
   1241 *******************************************************************************/
   1242 static void phNxpNciHal_fw_dnld_recover_cb(void* pContext, NFCSTATUS status,
   1243                                            void* pInfo) {
   1244   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
   1245   NFCSTATUS wStatus = status;
   1246   UNUSED(pContext);
   1247   UNUSED(pInfo);
   1248 
   1249   if (NFCSTATUS_SUCCESS == wStatus) {
   1250     if ((gphNxpNciHal_fw_IoctlCtx.bSkipForce) == false) {
   1251       NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Request Successful");
   1252       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = true;
   1253     } else {
   1254       NXPLOG_FWDNLD_D(
   1255           "phNxpNciHal_fw_dnld_recoverCb - Production key update Request "
   1256           "Successful");
   1257       (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = true;
   1258     }
   1259   } else {
   1260     wStatus = NFCSTATUS_FAILED;
   1261     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Request Failed!!");
   1262   }
   1263 
   1264   /* resetting this flag to avoid cyclic issuance of recovery sequence in case
   1265    * of failure */
   1266   (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1267 
   1268   /* reset previously set SkipForce */
   1269   (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false;
   1270   p_cb_data->status = wStatus;
   1271 
   1272   SEM_POST(p_cb_data);
   1273 
   1274   return;
   1275 }
   1276 
   1277 /*******************************************************************************
   1278 **
   1279 ** Function         phNxpNciHal_fw_dnld_send_ncicmd_cb
   1280 **
   1281 ** Description      Download Send NCI Command callback
   1282 **
   1283 ** Returns          None
   1284 **
   1285 *******************************************************************************/
   1286 static void phNxpNciHal_fw_dnld_send_ncicmd_cb(void* pContext, NFCSTATUS status,
   1287                                                void* pInfo) {
   1288   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
   1289   NFCSTATUS wStatus = status;
   1290   pphDnldNfc_Buff_t pRespBuff;
   1291   UNUSED(pContext);
   1292 
   1293   if (NFCSTATUS_SUCCESS == wStatus) {
   1294     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_send_ncicmdCb - Request Successful");
   1295     pRespBuff = (pphDnldNfc_Buff_t)pInfo;
   1296 
   1297     if ((0 != (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff))) {
   1298       if (0 == (pRespBuff->pBuff[3])) {
   1299         NXPLOG_FWDNLD_D("Successful Response received for Nci Reset Cmd");
   1300       } else {
   1301         NXPLOG_FWDNLD_E("Nci Reset Request Failed!!");
   1302       }
   1303     } else {
   1304       NXPLOG_FWDNLD_E("Invalid Response received for Nci Reset Request!!");
   1305     }
   1306     /* Call Tml Ioctl to enable download mode */
   1307     wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
   1308 
   1309     if (NFCSTATUS_SUCCESS == wStatus) {
   1310       NXPLOG_FWDNLD_D("Switched Successfully to dnld mode..");
   1311       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = true;
   1312     } else {
   1313       NXPLOG_FWDNLD_E("Switching back to dnld mode Failed!!");
   1314       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1315       wStatus = NFCSTATUS_FAILED;
   1316     }
   1317   } else {
   1318     NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmdCb - Request Failed!!");
   1319   }
   1320 
   1321   (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false;
   1322   p_cb_data->status = wStatus;
   1323 
   1324   SEM_POST(p_cb_data);
   1325 
   1326   return;
   1327 }
   1328 
   1329 /*******************************************************************************
   1330 **
   1331 ** Function         phNxpNciHal_fw_dnld_send_ncicmd
   1332 **
   1333 ** Description      Download Send NCI Command
   1334 **
   1335 ** Returns          NFCSTATUS_SUCCESS if success
   1336 **
   1337 *******************************************************************************/
   1338 static NFCSTATUS phNxpNciHal_fw_dnld_send_ncicmd(void* pContext,
   1339                                                  NFCSTATUS status,
   1340                                                  void* pInfo) {
   1341   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1342   static uint8_t bNciCmd[4] = {0x20, 0x00, 0x01,
   1343                                0x00}; /* Nci Reset Cmd with KeepConfig option */
   1344   static uint8_t bNciResp[6];
   1345   phDnldNfc_Buff_t tsData;
   1346   phDnldNfc_Buff_t trData;
   1347   phNxpNciHal_Sem_t cb_data;
   1348 
   1349   UNUSED(pInfo);
   1350   UNUSED(status);
   1351   UNUSED(pContext);
   1352   if ((gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) == false) {
   1353     return NFCSTATUS_SUCCESS;
   1354   } else {
   1355     /* Call Tml Ioctl to enable/restore normal mode */
   1356     wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
   1357 
   1358     if (NFCSTATUS_SUCCESS != wStatus) {
   1359       NXPLOG_FWDNLD_E("Switching to NormalMode Failed!!");
   1360       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1361       (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false;
   1362     } else {
   1363       if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
   1364         NXPLOG_FWDNLD_E(
   1365             "phNxpNciHal_fw_dnld_send_ncicmd cb_data creation failed");
   1366         return NFCSTATUS_FAILED;
   1367       }
   1368       (tsData.pBuff) = bNciCmd;
   1369       (tsData.wLen) = sizeof(bNciCmd);
   1370       (trData.pBuff) = bNciResp;
   1371       (trData.wLen) = sizeof(bNciResp);
   1372 
   1373       wStatus = phDnldNfc_RawReq(
   1374           &tsData, &trData,
   1375           (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_send_ncicmd_cb,
   1376           (void*)&cb_data);
   1377       if (NFCSTATUS_PENDING != wStatus) {
   1378         goto clean_and_return;
   1379       }
   1380       /* Wait for callback response */
   1381       if (SEM_WAIT(cb_data)) {
   1382         NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd semaphore error");
   1383         wStatus = NFCSTATUS_FAILED;
   1384         goto clean_and_return;
   1385       }
   1386 
   1387       if (cb_data.status != NFCSTATUS_SUCCESS) {
   1388         NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd cb failed");
   1389         wStatus = NFCSTATUS_FAILED;
   1390         goto clean_and_return;
   1391       }
   1392       wStatus = NFCSTATUS_SUCCESS;
   1393 
   1394     clean_and_return:
   1395       phNxpNciHal_cleanup_cb_data(&cb_data);
   1396     }
   1397   }
   1398 
   1399   return wStatus;
   1400 }
   1401 
   1402 /*******************************************************************************
   1403 **
   1404 ** Function         phNxpNciHal_fw_dnld_log_cb
   1405 **
   1406 ** Description      Download Log callback
   1407 **
   1408 ** Returns          None
   1409 **
   1410 *******************************************************************************/
   1411 static void phNxpNciHal_fw_dnld_log_cb(void* pContext, NFCSTATUS status,
   1412                                        void* pInfo) {
   1413   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
   1414   NFCSTATUS wStatus = status;
   1415   UNUSED(pContext);
   1416   UNUSED(pInfo);
   1417 
   1418   if (NFCSTATUS_SUCCESS == wStatus) {
   1419     NXPLOG_FWDNLD_D("phLibNfc_DnldLogCb - Request Successful");
   1420     (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false;
   1421   } else {
   1422     wStatus = NFCSTATUS_FAILED;
   1423     NXPLOG_FWDNLD_E("phLibNfc_DnldLogCb - Request Failed!!");
   1424   }
   1425   p_cb_data->status = wStatus;
   1426 
   1427   SEM_POST(p_cb_data);
   1428   return;
   1429 }
   1430 
   1431 /*******************************************************************************
   1432 **
   1433 ** Function         phNxpNciHal_fw_dnld_log
   1434 **
   1435 ** Description      Download Log
   1436 **
   1437 ** Returns          NFCSTATUS_SUCCESS if success
   1438 **
   1439 *******************************************************************************/
   1440 static NFCSTATUS phNxpNciHal_fw_dnld_log(void* pContext, NFCSTATUS status,
   1441                                          void* pInfo) {
   1442   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1443   phNxpNciHal_Sem_t cb_data;
   1444   phDnldNfc_Buff_t tData;
   1445 
   1446   UNUSED(pInfo);
   1447   UNUSED(status);
   1448   UNUSED(pContext);
   1449   if ((((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == true) ||
   1450        ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == true)) &&
   1451       ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == false)) {
   1452     return NFCSTATUS_SUCCESS;
   1453   } else {
   1454     if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
   1455       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log cb_data creation failed");
   1456       return NFCSTATUS_FAILED;
   1457     }
   1458     (tData.pBuff) = (void*)&(gphNxpNciHal_fw_IoctlCtx.tLogParams);
   1459     (tData.wLen) = sizeof(gphNxpNciHal_fw_IoctlCtx.tLogParams);
   1460 
   1461     wStatus =
   1462         phDnldNfc_Log(&tData, (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_log_cb,
   1463                       (void*)&cb_data);
   1464 
   1465     if (wStatus != NFCSTATUS_PENDING) {
   1466       NXPLOG_FWDNLD_E("phDnldNfc_Log failed");
   1467       (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false;
   1468       wStatus = NFCSTATUS_FAILED;
   1469       goto clean_and_return;
   1470     }
   1471     /* Wait for callback response */
   1472     if (SEM_WAIT(cb_data)) {
   1473       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log semaphore error");
   1474       wStatus = NFCSTATUS_FAILED;
   1475       goto clean_and_return;
   1476     }
   1477 
   1478     if (cb_data.status != NFCSTATUS_SUCCESS) {
   1479       NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_cb failed");
   1480       wStatus = NFCSTATUS_FAILED;
   1481       goto clean_and_return;
   1482     }
   1483 
   1484     wStatus = NFCSTATUS_SUCCESS;
   1485 
   1486   clean_and_return:
   1487     phNxpNciHal_cleanup_cb_data(&cb_data);
   1488 
   1489     return wStatus;
   1490   }
   1491 }
   1492 
   1493 /*******************************************************************************
   1494 **
   1495 ** Function         phNxpNciHal_fw_seq_handler
   1496 **
   1497 ** Description      Sequence Handler
   1498 **
   1499 ** Returns          NFCSTATUS_SUCCESS if sequence completed uninterrupted
   1500 **
   1501 *******************************************************************************/
   1502 static NFCSTATUS phNxpNciHal_fw_seq_handler(
   1503     NFCSTATUS (*seq_handler[])(void* pContext, NFCSTATUS status, void* pInfo)) {
   1504   char* pContext = "FW-Download";
   1505   int16_t seq_counter = 0;
   1506   phDnldNfc_Buff_t pInfo;
   1507   NFCSTATUS status = NFCSTATUS_FAILED;
   1508 
   1509   status = phTmlNfc_ReadAbort();
   1510   if (NFCSTATUS_SUCCESS != status) {
   1511     NXPLOG_FWDNLD_E("Tml Read Abort failed!!");
   1512     return status;
   1513   }
   1514 
   1515   while (seq_handler[seq_counter] != NULL) {
   1516     status = NFCSTATUS_FAILED;
   1517     status = (seq_handler[seq_counter])(pContext, status, &pInfo);
   1518     if (NFCSTATUS_SUCCESS != status) {
   1519       NXPLOG_FWDNLD_E(" phNxpNciHal_fw_seq_handler : FAILED");
   1520       break;
   1521     }
   1522     seq_counter++;
   1523   }
   1524   return status;
   1525 }
   1526 
   1527 /*******************************************************************************
   1528 **
   1529 ** Function         phNxpNciHal_fw_dnld_complete
   1530 **
   1531 ** Description      Download Sequence Complete
   1532 **
   1533 ** Returns          NFCSTATUS_SUCCESS if success
   1534 **
   1535 *******************************************************************************/
   1536 static NFCSTATUS phNxpNciHal_fw_dnld_complete(void* pContext, NFCSTATUS status,
   1537                                               void* pInfo) {
   1538   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1539   NFCSTATUS fStatus = status;
   1540   UNUSED(pInfo);
   1541   UNUSED(pContext);
   1542 
   1543   if (NFCSTATUS_WRITE_FAILED == status) {
   1544     if ((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) <
   1545         PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS) {
   1546       (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = true;
   1547     } else {
   1548       NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!");
   1549       (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1550       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1551     }
   1552   } else if (NFCSTATUS_REJECTED == status) {
   1553     if ((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) <
   1554         PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS) {
   1555       (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = true;
   1556 
   1557       /* in case of signature error we need to try recover sequence directly
   1558        * bypassing the force cmd */
   1559       (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = true;
   1560     } else {
   1561       NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!");
   1562       (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1563       (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1564     }
   1565   }
   1566 
   1567   if ((gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) == true) {
   1568     (gphNxpNciHal_fw_IoctlCtx.bLastStatus) = status;
   1569     (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = true;
   1570 
   1571     NXPLOG_FWDNLD_E("Invoking Pending Download Log Sequence..");
   1572     (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false;
   1573     /* Perform the Logging sequence */
   1574     wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_log_seqhandler);
   1575     if (NFCSTATUS_SUCCESS != gphNxpNciHal_fw_IoctlCtx.bLastStatus) {
   1576       /* update the previous Download Write status to upper layer and not the
   1577        * status of Log command */
   1578       wStatus = gphNxpNciHal_fw_IoctlCtx.bLastStatus;
   1579       NXPLOG_FWDNLD_E(
   1580           "phNxpNciHal_fw_dnld_complete: Last Download Write Status before Log "
   1581           "command bLastStatus = 0x%x",
   1582           gphNxpNciHal_fw_IoctlCtx.bLastStatus);
   1583     }
   1584     status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo);
   1585     if (NFCSTATUS_SUCCESS == status) {
   1586       NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
   1587     } else {
   1588       NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
   1589     }
   1590   } else if ((gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) == true) {
   1591     NXPLOG_FWDNLD_E("Invoking Download Recovery Sequence..");
   1592 
   1593     if (NFCSTATUS_SUCCESS == wStatus) {
   1594       /* Perform the download Recovery sequence */
   1595       wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_rec_seqhandler);
   1596 
   1597       status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo);
   1598       if (NFCSTATUS_SUCCESS == status) {
   1599         NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
   1600       } else {
   1601         NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
   1602       }
   1603     }
   1604   } else if ((gphNxpNciHal_fw_IoctlCtx.bRetryDnld) == true) {
   1605     (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = false;
   1606     (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false;
   1607     (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = false;
   1608     (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = false;
   1609     (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false;
   1610     (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1611     (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false;
   1612 
   1613     /* Perform the download sequence ... after successful recover attempt */
   1614     wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler);
   1615 
   1616     status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo);
   1617     if (NFCSTATUS_SUCCESS == status) {
   1618       NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
   1619     } else {
   1620       NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
   1621     }
   1622   } else {
   1623     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_complete: Download Status = 0x%x",
   1624                     status);
   1625     if ((gphNxpNciHal_fw_IoctlCtx.bSkipSeq) == false) {
   1626       if (NFCSTATUS_SUCCESS == status) {
   1627         if (NFC_FW_DOWNLOAD == gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1628           NXPLOG_FWDNLD_E("Fw Download success.. ");
   1629         } else if (PHLIBNFC_DNLD_MEM_READ ==
   1630                    gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1631           NXPLOG_FWDNLD_E("Read Request success.. ");
   1632         } else if (PHLIBNFC_DNLD_MEM_WRITE ==
   1633                    gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1634           NXPLOG_FWDNLD_E("Write Request success.. ");
   1635         } else if (PHLIBNFC_DNLD_READ_LOG ==
   1636                    gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1637           NXPLOG_FWDNLD_E("ReadLog Request success.. ");
   1638         } else {
   1639           NXPLOG_FWDNLD_E("Invalid Request!!");
   1640         }
   1641       } else {
   1642         if (NFC_FW_DOWNLOAD == gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1643           NXPLOG_FWDNLD_E("Fw Download Failed!!");
   1644         } else if (NFC_MEM_READ == gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1645           NXPLOG_FWDNLD_E("Read Request Failed!!");
   1646         } else if (NFC_MEM_WRITE == gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1647           NXPLOG_FWDNLD_E("Write Request Failed!!");
   1648         } else if (PHLIBNFC_DNLD_READ_LOG ==
   1649                    gphNxpNciHal_fw_IoctlCtx.IoctlCode) {
   1650           NXPLOG_FWDNLD_E("ReadLog Request Failed!!");
   1651         } else {
   1652           NXPLOG_FWDNLD_E("Invalid Request!!");
   1653         }
   1654       }
   1655     }
   1656 
   1657     if (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd == false) {
   1658       /* Call Tml Ioctl to enable/restore normal mode */
   1659       wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
   1660 
   1661       if (NFCSTATUS_SUCCESS != wStatus) {
   1662         NXPLOG_FWDNLD_E("Switching to NormalMode Failed!!");
   1663       } else {
   1664         wStatus = fStatus;
   1665       }
   1666     }
   1667 
   1668     (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = false;
   1669     (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false;
   1670     (gphNxpNciHal_fw_IoctlCtx.bChipVer) = 0;
   1671     (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = false;
   1672     (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = false;
   1673     (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1674     (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1675     (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = false;
   1676     (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false;
   1677     (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false;
   1678     (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) = 0;
   1679 
   1680     if (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed == false) {
   1681     } else {
   1682       NXPLOG_FWDNLD_E("Returning Download Failed Status to Caller!!");
   1683 
   1684       (gphNxpNciHal_fw_IoctlCtx.bLastStatus) = NFCSTATUS_SUCCESS;
   1685       (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = false;
   1686     }
   1687     phDnldNfc_CloseFwLibHandle();
   1688   }
   1689 
   1690   return wStatus;
   1691 }
   1692 
   1693 /*******************************************************************************
   1694 **
   1695 ** Function         phNxpNciHal_fw_download_seq
   1696 **
   1697 ** Description      Download Sequence
   1698 **
   1699 ** Returns          NFCSTATUS_SUCCESS if success
   1700 **
   1701 *******************************************************************************/
   1702 NFCSTATUS phNxpNciHal_fw_download_seq(uint8_t bClkSrcVal, uint8_t bClkFreqVal) {
   1703   NFCSTATUS status = NFCSTATUS_FAILED;
   1704   phDnldNfc_Buff_t pInfo;
   1705   char* pContext = "FW-Download";
   1706 
   1707   /* reset the global flags */
   1708   gphNxpNciHal_fw_IoctlCtx.IoctlCode = NFC_FW_DOWNLOAD;
   1709   (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = false;
   1710   (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = false;
   1711   (gphNxpNciHal_fw_IoctlCtx.bChipVer) = 0;
   1712   (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = false;
   1713   (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = false;
   1714   (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = false;
   1715   (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = false;
   1716   (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = false;
   1717   (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = false;
   1718   (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = false;
   1719   (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) = 0;
   1720   (gphNxpNciHal_fw_IoctlCtx.bClkSrcVal) = bClkSrcVal;
   1721   (gphNxpNciHal_fw_IoctlCtx.bClkFreqVal) = bClkFreqVal;
   1722   /* Get firmware version */
   1723   if (NFCSTATUS_SUCCESS == phDnldNfc_InitImgInfo()) {
   1724     NXPLOG_FWDNLD_D("phDnldNfc_InitImgInfo:SUCCESS");
   1725 #if (NFC_NXP_CHIP_TYPE != PN547C2)
   1726     if (gRecFWDwnld == true) {
   1727       status =
   1728           phNxpNciHal_fw_seq_handler(phNxpNciHal_dummy_rec_dwnld_seqhandler);
   1729     } else
   1730 #endif
   1731     {
   1732       status = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler);
   1733     }
   1734   } else {
   1735     NXPLOG_FWDNLD_E("phDnldNfc_InitImgInfo: FAILED");
   1736   }
   1737 
   1738   /* Chage to normal mode */
   1739   status = phNxpNciHal_fw_dnld_complete(pContext, status, &pInfo);
   1740   /*if (NFCSTATUS_SUCCESS == status)
   1741   {
   1742       NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
   1743   }
   1744   else
   1745   {
   1746       NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
   1747   }*/
   1748 
   1749   return status;
   1750 }
   1751 
   1752 static NFCSTATUS phLibNfc_VerifyCrcStatus(uint8_t bCrcStatus) {
   1753 #if ((NFC_NXP_CHIP_TYPE == PN551) || (NFC_NXP_CHIP_TYPE == PN553))
   1754   uint8_t bBitPos = 1;
   1755   uint8_t bShiftVal = 2;
   1756 #else
   1757   uint8_t bBitPos = 0;
   1758   uint8_t bShiftVal = 1;
   1759 #endif
   1760   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
   1761   while (bBitPos < 7) {
   1762     if (!(bCrcStatus & bShiftVal)) {
   1763       switch (bBitPos) {
   1764         case 0: {
   1765           NXPLOG_FWDNLD_E("User Data Crc is NOT OK!!");
   1766           wStatus = NFCSTATUS_FAILED;
   1767           break;
   1768         }
   1769         case 1: {
   1770           NXPLOG_FWDNLD_E("Trim Data Crc is NOT OK!!");
   1771           wStatus = NFCSTATUS_FAILED;
   1772           break;
   1773         }
   1774         case 2: {
   1775           NXPLOG_FWDNLD_E("Protected Data Crc is NOT OK!!");
   1776           wStatus = NFCSTATUS_FAILED;
   1777           break;
   1778         }
   1779         case 3: {
   1780           NXPLOG_FWDNLD_E("Patch Code Crc is NOT OK!!");
   1781           wStatus = NFCSTATUS_FAILED;
   1782           break;
   1783         }
   1784         case 4: {
   1785           NXPLOG_FWDNLD_E("Function Code Crc is NOT OK!!");
   1786           wStatus = NFCSTATUS_FAILED;
   1787           break;
   1788         }
   1789         case 5: {
   1790           NXPLOG_FWDNLD_E("Patch Table Crc is NOT OK!!");
   1791           wStatus = NFCSTATUS_FAILED;
   1792           break;
   1793         }
   1794         case 6: {
   1795           NXPLOG_FWDNLD_E("Function Table Crc is NOT OK!!");
   1796           wStatus = NFCSTATUS_FAILED;
   1797           break;
   1798         }
   1799         default: { break; }
   1800       }
   1801     }
   1802 
   1803     bShiftVal <<= 1;
   1804     ++bBitPos;
   1805   }
   1806 
   1807   return wStatus;
   1808 }
   1809