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