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