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