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 == PN548C2)
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 == PN548C2)
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 *******************************************************************************/
phNxpNciHal_fw_dnld_reset_cb(void * pContext,NFCSTATUS status,void * pInfo)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 *******************************************************************************/
phNxpNciHal_fw_dnld_reset(void * pContext,NFCSTATUS status,void * pInfo)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 *******************************************************************************/
phNxpNciHal_fw_dnld_normal_cb(void * pContext,NFCSTATUS status,void * pInfo)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 *******************************************************************************/
phNxpNciHal_fw_dnld_force_cb(void * pContext,NFCSTATUS status,void * pInfo)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 *******************************************************************************/
phNxpNciHal_fw_dnld_normal(void * pContext,NFCSTATUS status,void * pInfo)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 *******************************************************************************/
phNxpNciHal_fw_dnld_force(void * pContext,NFCSTATUS status,void * pInfo)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 *******************************************************************************/
phNxpNciHal_fw_dnld_get_version_cb(void * pContext,NFCSTATUS status,void * pInfo)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                     (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 *******************************************************************************/
phNxpNciHal_fw_dnld_get_version(void * pContext,NFCSTATUS status,void * pInfo)676 static 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 
727 clean_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 *******************************************************************************/
phNxpNciHal_fw_dnld_get_sessn_state_cb(void * pContext,NFCSTATUS status,void * pInfo)742 static 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 *******************************************************************************/
phNxpNciHal_fw_dnld_get_sessn_state(void * pContext,NFCSTATUS status,void * pInfo)820 static 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 
870 clean_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 *******************************************************************************/
phNxpNciHal_fw_dnld_log_read_cb(void * pContext,NFCSTATUS status,void * pInfo)885 static 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 *******************************************************************************/
phNxpNciHal_fw_dnld_log_read(void * pContext,NFCSTATUS status,void * pInfo)915 static 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 
968 clean_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 *******************************************************************************/
phNxpNciHal_fw_dnld_write_cb(void * pContext,NFCSTATUS status,void * pInfo)983 static 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 *******************************************************************************/
phNxpNciHal_fw_dnld_write(void * pContext,NFCSTATUS status,void * pInfo)1048 static 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 
1111 clean_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 *******************************************************************************/
phNxpNciHal_fw_dnld_chk_integrity_cb(void * pContext,NFCSTATUS status,void * pInfo)1126 static 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 *******************************************************************************/
phNxpNciHal_fw_dnld_chk_integrity(void * pContext,NFCSTATUS status,void * pInfo)1174 static 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 
1236 clean_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 *******************************************************************************/
phNxpNciHal_fw_dnld_recover(void * pContext,NFCSTATUS status,void * pInfo)1251 static 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 
1296 clean_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 *******************************************************************************/
phNxpNciHal_fw_dnld_recover_cb(void * pContext,NFCSTATUS status,void * pInfo)1312 static 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 *******************************************************************************/
phNxpNciHal_fw_dnld_send_ncicmd_cb(void * pContext,NFCSTATUS status,void * pInfo)1360 static  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 *******************************************************************************/
phNxpNciHal_fw_dnld_send_ncicmd(void * pContext,NFCSTATUS status,void * pInfo)1425 static 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 
1487 clean_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 *******************************************************************************/
phNxpNciHal_fw_dnld_log_cb(void * pContext,NFCSTATUS status,void * pInfo)1504 static 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 *******************************************************************************/
phNxpNciHal_fw_dnld_log(void * pContext,NFCSTATUS status,void * pInfo)1537 static 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 
1589 clean_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 *******************************************************************************/
phNxpNciHal_fw_seq_handler(NFCSTATUS (* seq_handler[])(void * pContext,NFCSTATUS status,void * pInfo))1606 static 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 *******************************************************************************/
phNxpNciHal_fw_dnld_complete(void * pContext,NFCSTATUS status,void * pInfo)1643 static  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 *******************************************************************************/
phNxpNciHal_fw_download_seq(uint8_t bClkSrcVal,uint8_t bClkFreqVal)1854 NFCSTATUS 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 
1909 static
1910 NFCSTATUS
phLibNfc_VerifyCrcStatus(uint8_t bCrcStatus)1911 phLibNfc_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