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