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