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