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