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