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