1 /*
2  *  Copyright 2010-2021 NXP
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  * Download Component
19  * Download Interface routines implementation
20  */
21 
22 #include <dlfcn.h>
23 #include <phDnldNfc_Internal.h>
24 #include <phNxpConfig.h>
25 #include <phNxpLog.h>
26 #include <phTmlNfc.h>
27 #include <string>
28 static void* pFwHandle; /* Global firmware handle*/
29 uint16_t wMwVer = 0;    /* Middleware version no */
30 uint16_t wFwVer = 0;    /* Firmware version no */
31 uint8_t gRecFWDwnld;    /* flag set to true to indicate recovery FW download */
32 phTmlNfc_i2cfragmentation_t fragmentation_enabled = I2C_FRAGMENATATION_DISABLED;
33 static pphDnldNfc_DlContext_t gpphDnldContext = NULL; /* Download contex */
34 #undef EEPROM_Read_Mem_IMP
35 
36 /*******************************************************************************
37 **
38 ** Function         phDnldNfc_Reset
39 **
40 ** Description      Performs a soft reset of the download module
41 **
42 ** Parameters       pNotify  - notify caller after getting response
43 **                  pContext - caller context
44 **
45 ** Returns          NFC status:
46 **                  NFCSTATUS_SUCCESS - reset request to NFCC is successful
47 **                  NFCSTATUS_FAILED - reset request failed due to internal
48 **                                     error
49 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
50 **                  Other command specific errors
51 **
52 *******************************************************************************/
phDnldNfc_Reset(pphDnldNfc_RspCb_t pNotify,void * pContext)53 NFCSTATUS phDnldNfc_Reset(pphDnldNfc_RspCb_t pNotify, void* pContext) {
54   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
55 
56   if ((NULL == pNotify) || (NULL == pContext)) {
57     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
58     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
59   } else {
60     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
61       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
62       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
63     } else {
64       (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
65       (gpphDnldContext->tCmdId) = PH_DL_CMD_RESET;
66       (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
67       (gpphDnldContext->tRspBuffInfo.wLen) = 0;
68       (gpphDnldContext->tUserData.pBuff) = NULL;
69       (gpphDnldContext->tUserData.wLen) = 0;
70       (gpphDnldContext->UserCb) = pNotify;
71       (gpphDnldContext->UserCtxt) = pContext;
72 
73       wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventReset);
74 
75       if (NFCSTATUS_PENDING == wStatus) {
76         NXPLOG_FWDNLD_D("Reset Request submitted successfully");
77       } else {
78         NXPLOG_FWDNLD_E("Reset Request Failed!!");
79       }
80     }
81   }
82 
83   return wStatus;
84 }
85 
86 /*******************************************************************************
87 **
88 ** Function         phDnldNfc_GetVersion
89 **
90 ** Description      Retrieves Hardware version, ROM Code version, Protected Data
91 **                  version, Trim data version, User data version, and Firmware
92 **                  version information
93 **
94 ** Parameters       pVersionInfo - response buffer which gets updated with
95 **                                 complete version info from NFCC
96 **                  pNotify - notify caller after getting response
97 **                  pContext - caller context
98 **
99 ** Returns          NFC status:
100 **                  NFCSTATUS_SUCCESS - GetVersion request to NFCC is successful
101 **                  NFCSTATUS_FAILED - GetVersion request failed due to internal
102 **                                     error
103 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
104 **                  Other command specific errors
105 **
106 *******************************************************************************/
phDnldNfc_GetVersion(pphDnldNfc_Buff_t pVersionInfo,pphDnldNfc_RspCb_t pNotify,void * pContext)107 NFCSTATUS phDnldNfc_GetVersion(pphDnldNfc_Buff_t pVersionInfo,
108                                pphDnldNfc_RspCb_t pNotify, void* pContext) {
109   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
110 
111   if ((NULL == pVersionInfo) || (NULL == pNotify) || (NULL == pContext)) {
112     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
113     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
114   } else {
115     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
116       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
117       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
118     } else {
119       if ((NULL != pVersionInfo->pBuff) && (0 != pVersionInfo->wLen)) {
120         (gpphDnldContext->tRspBuffInfo.pBuff) = pVersionInfo->pBuff;
121         (gpphDnldContext->tRspBuffInfo.wLen) = pVersionInfo->wLen;
122         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
123         (gpphDnldContext->tCmdId) = PH_DL_CMD_GETVERSION;
124         (gpphDnldContext->tUserData.pBuff) = NULL;
125         (gpphDnldContext->tUserData.wLen) = 0;
126         (gpphDnldContext->UserCb) = pNotify;
127         (gpphDnldContext->UserCtxt) = pContext;
128 
129         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventGetVer);
130 
131         if (NFCSTATUS_PENDING == wStatus) {
132           NXPLOG_FWDNLD_D("GetVersion Request submitted successfully");
133         } else {
134           NXPLOG_FWDNLD_E("GetVersion Request Failed!!");
135         }
136       } else {
137         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
138         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
139       }
140     }
141   }
142 
143   return wStatus;
144 }
145 
146 /*******************************************************************************
147 **
148 ** Function         phDnldNfc_GetSessionState
149 **
150 ** Description      Retrieves the current session state of NFCC
151 **
152 ** Parameters       pSession - response buffer which gets updated with complete
153 **                             version info from NFCC
154 **                  pNotify - notify caller after getting response
155 **                  pContext - caller context
156 **
157 ** Returns          NFC status:
158 **                  NFCSTATUS_SUCCESS - GetSessionState request to NFCC is
159 **                                      successful
160 **                  NFCSTATUS_FAILED - GetSessionState request failed due to
161 **                                     internal error
162 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
163 **                  Other command specific errors
164 **
165 *******************************************************************************/
phDnldNfc_GetSessionState(pphDnldNfc_Buff_t pSession,pphDnldNfc_RspCb_t pNotify,void * pContext)166 NFCSTATUS phDnldNfc_GetSessionState(pphDnldNfc_Buff_t pSession,
167                                     pphDnldNfc_RspCb_t pNotify,
168                                     void* pContext) {
169   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
170 
171   if ((NULL == pSession) || (NULL == pNotify) || (NULL == pContext)) {
172     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
173     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
174   } else {
175     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
176       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
177       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
178     } else {
179       if ((NULL != pSession->pBuff) && (0 != pSession->wLen)) {
180         (gpphDnldContext->tRspBuffInfo.pBuff) = pSession->pBuff;
181         (gpphDnldContext->tRspBuffInfo.wLen) = pSession->wLen;
182         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
183         (gpphDnldContext->tCmdId) = PH_DL_CMD_GETSESSIONSTATE;
184         (gpphDnldContext->tUserData.pBuff) = NULL;
185         (gpphDnldContext->tUserData.wLen) = 0;
186         (gpphDnldContext->UserCb) = pNotify;
187         (gpphDnldContext->UserCtxt) = pContext;
188 
189         wStatus =
190             phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventGetSesnSt);
191 
192         if (NFCSTATUS_PENDING == wStatus) {
193           NXPLOG_FWDNLD_D("GetSessionState Request submitted successfully");
194         } else {
195           NXPLOG_FWDNLD_E("GetSessionState Request Failed!!");
196         }
197       } else {
198         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
199         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
200       }
201     }
202   }
203 
204   return wStatus;
205 }
206 
207 /*******************************************************************************
208 **
209 ** Function         phDnldNfc_CheckIntegrity
210 **
211 ** Description      Inspects the integrity of EEPROM and FLASH contents of the
212 **                  NFCC, provides CRC for each section
213 **                  NOTE: The user data section CRC is valid only after fresh
214 **                        download
215 **
216 ** Parameters       bChipVer - current ChipVersion for including additional
217 **                             parameters in request payload
218 **                  pCRCData - response buffer which gets updated with
219 **                             respective section CRC status and CRC bytes from
220 **                             NFCC
221 **                  pNotify - notify caller after getting response
222 **                  pContext - caller context
223 **
224 ** Returns          NFC status:
225 **                  NFCSTATUS_SUCCESS - CheckIntegrity request is successful
226 **                  NFCSTATUS_FAILED - CheckIntegrity request failed due to
227 **                                     internal error
228 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
229 **                  Other command specific errors
230 **
231 *******************************************************************************/
phDnldNfc_CheckIntegrity(uint8_t bChipVer,pphDnldNfc_Buff_t pCRCData,pphDnldNfc_RspCb_t pNotify,void * pContext)232 NFCSTATUS phDnldNfc_CheckIntegrity(uint8_t bChipVer, pphDnldNfc_Buff_t pCRCData,
233                                    pphDnldNfc_RspCb_t pNotify, void* pContext) {
234   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
235 
236   if ((NULL == pNotify) || (NULL == pContext)) {
237     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
238     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
239   } else {
240     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
241       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
242       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
243     } else {
244       if ((PHDNLDNFC_HWVER_MRA2_1 == bChipVer) ||
245           (PHDNLDNFC_HWVER_MRA2_2 == bChipVer) ||
246           ((nfcFL.chipType == pn551) &&
247            ((PHDNLDNFC_HWVER_PN551_MRA1_0 == bChipVer))) ||
248           (((nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) &&
249            ((PHDNLDNFC_HWVER_PN553_MRA1_0 == bChipVer) ||
250             (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & bChipVer) ||
251             ((PHDNLDNFC_HWVER_PN557_MRA1_0 == bChipVer)))) ||
252           ((nfcFL.chipType == sn100u) &&
253            (PHDNLDNFC_HWVER_VENUS_MRA1_0 & bChipVer)) ||
254           ((nfcFL.chipType == sn220u) &&
255            (PHDNLDNFC_HWVER_VULCAN_MRA1_0 & bChipVer))) {
256         (gpphDnldContext->FrameInp.Type) = phDnldNfc_ChkIntg;
257       } else {
258         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
259       }
260 
261       if ((NULL != pCRCData->pBuff) && (0 != pCRCData->wLen)) {
262         (gpphDnldContext->tRspBuffInfo.pBuff) = pCRCData->pBuff;
263         (gpphDnldContext->tRspBuffInfo.wLen) = pCRCData->wLen;
264         (gpphDnldContext->tCmdId) = PH_DL_CMD_CHECKINTEGRITY;
265         (gpphDnldContext->tUserData.pBuff) = NULL;
266         (gpphDnldContext->tUserData.wLen) = 0;
267         (gpphDnldContext->UserCb) = pNotify;
268         (gpphDnldContext->UserCtxt) = pContext;
269 
270         wStatus =
271             phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventIntegChk);
272 
273         if (NFCSTATUS_PENDING == wStatus) {
274           NXPLOG_FWDNLD_D("CheckIntegrity Request submitted successfully");
275         } else {
276           NXPLOG_FWDNLD_E("CheckIntegrity Request Failed!!");
277         }
278       } else {
279         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
280         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
281       }
282     }
283   }
284 
285   return wStatus;
286 }
287 /*******************************************************************************
288 **
289 ** Function         phDnldNfc_ReadLog
290 **
291 ** Description      Retrieves log data from EEPROM
292 **
293 ** Parameters       pData - response buffer which gets updated with data from
294 **                          EEPROM
295 **                  pNotify - notify caller after getting response
296 **                  pContext - caller context
297 **
298 ** Returns          NFC status:
299 **                  NFCSTATUS_SUCCESS - Read request to NFCC is successful
300 **                  NFCSTATUS_FAILED - Read request failed due to internal error
301 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
302 **                  Other command specific errors
303 **
304 *******************************************************************************/
phDnldNfc_ReadLog(pphDnldNfc_Buff_t pData,pphDnldNfc_RspCb_t pNotify,void * pContext)305 NFCSTATUS phDnldNfc_ReadLog(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify,
306                             void* pContext) {
307   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
308 
309   if ((NULL == pNotify) || (NULL == pData) || (NULL == pContext)) {
310     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
311     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
312   } else {
313     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
314       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
315       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
316     } else {
317       if ((NULL != pData->pBuff) && (0 != pData->wLen)) {
318         (gpphDnldContext->tCmdId) = PH_DL_CMD_READ;
319         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRead;
320         (gpphDnldContext->FrameInp.dwAddr) = PHDNLDNFC_EEPROM_LOG_START_ADDR;
321         (gpphDnldContext->tRspBuffInfo.pBuff) = pData->pBuff;
322         (gpphDnldContext->tRspBuffInfo.wLen) = pData->wLen;
323         (gpphDnldContext->tUserData.pBuff) = NULL;
324         (gpphDnldContext->tUserData.wLen) = 0;
325         (gpphDnldContext->UserCb) = pNotify;
326         (gpphDnldContext->UserCtxt) = pContext;
327 
328         memset(&(gpphDnldContext->tRWInfo), 0,
329                sizeof(gpphDnldContext->tRWInfo));
330 
331         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRead);
332 
333         if (NFCSTATUS_PENDING == wStatus) {
334           NXPLOG_FWDNLD_D("Read Request submitted successfully");
335         } else {
336           NXPLOG_FWDNLD_E("Read Request Failed!!");
337         }
338       } else {
339         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
340         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
341       }
342     }
343   }
344 
345   return wStatus;
346 }
347 
348 /*******************************************************************************
349 **
350 ** Function         phDnldNfc_Write
351 **
352 ** Description      Writes requested  data of length len to desired EEPROM/FLASH
353 **                  address
354 **
355 ** Parameters       bRecoverSeq - flag to indicate whether recover sequence data
356 **                                needs to be written or not
357 **                  pData - data buffer to write into EEPROM/FLASH by user
358 **                  pNotify - notify caller after getting response
359 **                  pContext - caller context
360 **
361 ** Returns          NFC status:
362 **                  NFCSTATUS_SUCCESS - Write request to NFCC is successful
363 **                  NFCSTATUS_FAILED - Write request failed due to internal
364 **                                     error
365 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
366 **                  Other command specific errors
367 **
368 *******************************************************************************/
phDnldNfc_Write(bool_t bRecoverSeq,pphDnldNfc_Buff_t pData,pphDnldNfc_RspCb_t pNotify,void * pContext)369 NFCSTATUS phDnldNfc_Write(bool_t bRecoverSeq, pphDnldNfc_Buff_t pData,
370                           pphDnldNfc_RspCb_t pNotify, void* pContext) {
371   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
372   uint8_t* pImgPtr = NULL;
373   uint32_t wLen = 0;
374   phDnldNfc_Buff_t tImgBuff;
375 
376   if ((NULL == pNotify) || (NULL == pContext)) {
377     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
378     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
379   } else {
380     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
381       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
382       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
383     } else {
384       if (NULL != pData) {
385         pImgPtr = pData->pBuff;
386         wLen = pData->wLen;
387       } else {
388         if (bRecoverSeq == false) {
389           pImgPtr = (uint8_t*)gpphDnldContext->nxp_nfc_fw;
390           wLen = gpphDnldContext->nxp_nfc_fw_len;
391 
392         } else {
393           if (PH_DL_STATUS_PLL_ERROR == (gpphDnldContext->tLastStatus)) {
394             wStatus = phDnldNfc_LoadRecInfo();
395           } else if (PH_DL_STATUS_SIGNATURE_ERROR ==
396                      (gpphDnldContext->tLastStatus)) {
397             wStatus = phDnldNfc_LoadPKInfo();
398           } else {
399           }
400 
401           if (NFCSTATUS_SUCCESS == wStatus) {
402             pImgPtr = (uint8_t*)gpphDnldContext->nxp_nfc_fwp;
403             wLen = gpphDnldContext->nxp_nfc_fwp_len;
404           } else {
405             NXPLOG_FWDNLD_E("Platform Recovery Image extraction Failed!!");
406             pImgPtr = NULL;
407             wLen = 0;
408           }
409         }
410       }
411 
412       if ((NULL != pImgPtr) && (0 != wLen)) {
413         tImgBuff.pBuff = pImgPtr;
414         tImgBuff.wLen = wLen;
415 
416         (gpphDnldContext->tCmdId) = PH_DL_CMD_WRITE;
417         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTWrite;
418         (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
419         (gpphDnldContext->tRspBuffInfo.wLen) = 0;
420         (gpphDnldContext->tUserData.pBuff) = pImgPtr;
421         (gpphDnldContext->tUserData.wLen) = wLen;
422         (gpphDnldContext->bResendLastFrame) = false;
423 
424         memset(&(gpphDnldContext->tRWInfo), 0,
425                sizeof(gpphDnldContext->tRWInfo));
426         (gpphDnldContext->tRWInfo.bFirstWrReq) = true;
427         (gpphDnldContext->UserCb) = pNotify;
428         (gpphDnldContext->UserCtxt) = pContext;
429 
430         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventWrite);
431 
432         if (NFCSTATUS_PENDING == wStatus) {
433           NXPLOG_FWDNLD_D("Write Request submitted successfully");
434         } else {
435           NXPLOG_FWDNLD_E("Write Request Failed!!");
436         }
437       } else {
438         NXPLOG_FWDNLD_E("Download Image Primitives extraction failed!!");
439         wStatus = NFCSTATUS_FAILED;
440       }
441     }
442   }
443 
444   return wStatus;
445 }
446 
447 /*******************************************************************************
448 **
449 ** Function         phDnldNfc_Log
450 **
451 ** Description      Provides a full page free write to EEPROM
452 **
453 ** Parameters       pData - data buffer to write into EEPROM/FLASH by user
454 **                  pNotify - notify caller after getting response
455 **                  pContext - caller context
456 **
457 ** Returns          NFC status:
458 **                  NFCSTATUS_SUCCESS - Write request to NFCC is successful
459 **                  NFCSTATUS_FAILED - Write request failed due to internal
460 **                                     error
461 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
462 **                  Other command specific error
463 **
464 *******************************************************************************/
phDnldNfc_Log(pphDnldNfc_Buff_t pData,pphDnldNfc_RspCb_t pNotify,void * pContext)465 NFCSTATUS phDnldNfc_Log(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify,
466                         void* pContext) {
467   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
468 
469   if ((NULL == pNotify) || (NULL == pData) || (NULL == pContext)) {
470     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
471     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
472   } else {
473     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
474       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
475       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
476     } else {
477       if ((NULL != (pData->pBuff)) &&
478           ((0 != (pData->wLen) && (PHDNLDNFC_MAX_LOG_SIZE >= (pData->wLen))))) {
479         (gpphDnldContext->tCmdId) = PH_DL_CMD_LOG;
480         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTLog;
481         (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
482         (gpphDnldContext->tRspBuffInfo.wLen) = 0;
483         (gpphDnldContext->tUserData.pBuff) = (pData->pBuff);
484         (gpphDnldContext->tUserData.wLen) = (pData->wLen);
485 
486         memset(&(gpphDnldContext->tRWInfo), 0,
487                sizeof(gpphDnldContext->tRWInfo));
488         (gpphDnldContext->UserCb) = pNotify;
489         (gpphDnldContext->UserCtxt) = pContext;
490 
491         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventLog);
492 
493         if (NFCSTATUS_PENDING == wStatus) {
494           NXPLOG_FWDNLD_D("Log Request submitted successfully");
495         } else {
496           NXPLOG_FWDNLD_E("Log Request Failed!!");
497         }
498       } else {
499         NXPLOG_FWDNLD_E("Invalid Input Parameters for Log!!");
500         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
501       }
502     }
503   }
504 
505   return wStatus;
506 }
507 
508 /*******************************************************************************
509 **
510 ** Function         phDnldNfc_Force
511 **
512 ** Description      Used as an emergency recovery procedure for NFCC due to
513 **                  corrupt settings of system platform specific parameters by
514 **                  the host
515 **
516 ** Parameters       pInputs - input buffer which contains  clk src & clk freq
517 **                            settings for desired platform
518 **                  pNotify - notify caller after getting response
519 **                  pContext - caller context
520 **
521 ** Returns          NFC status:
522 **                  NFCSTATUS_SUCCESS - Emergency Recovery request is successful
523 **                  NFCSTATUS_FAILED - Emergency Recovery failed due to internal
524 **                                     error
525 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
526 **                  Other command specific errors
527 **
528 *******************************************************************************/
phDnldNfc_Force(pphDnldNfc_Buff_t pInputs,pphDnldNfc_RspCb_t pNotify,void * pContext)529 NFCSTATUS phDnldNfc_Force(pphDnldNfc_Buff_t pInputs, pphDnldNfc_RspCb_t pNotify,
530                           void* pContext) {
531   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
532   uint8_t bClkSrc = 0x00, bClkFreq = 0x00;
533   uint8_t bPldVal[3] = {
534       0x11, 0x00, 0x00}; /* default values to be used if input not provided */
535 
536   if ((NULL == pNotify) || (NULL == pContext)) {
537     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
538     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
539   } else {
540     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
541       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
542       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
543     } else {
544       (gpphDnldContext->tCmdId) = PH_DL_CMD_FORCE;
545       (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTForce;
546       (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
547       (gpphDnldContext->tRspBuffInfo.wLen) = 0;
548 
549       if ((0 != (pInputs->wLen)) || (NULL != (pInputs->pBuff))) {
550         if (CLK_SRC_XTAL == (pInputs->pBuff[0])) {
551           bClkSrc = phDnldNfc_ClkSrcXtal;
552         } else if (CLK_SRC_PLL == (pInputs->pBuff[0])) {
553           bClkSrc = phDnldNfc_ClkSrcPLL;
554           if (CLK_FREQ_13MHZ == (pInputs->pBuff[1])) {
555             bClkFreq = phDnldNfc_ClkFreq_13Mhz;
556           } else if (CLK_FREQ_19_2MHZ == (pInputs->pBuff[1])) {
557             bClkFreq = phDnldNfc_ClkFreq_19_2Mhz;
558           } else if (CLK_FREQ_24MHZ == (pInputs->pBuff[1])) {
559             bClkFreq = phDnldNfc_ClkFreq_24Mhz;
560           } else if (CLK_FREQ_26MHZ == (pInputs->pBuff[1])) {
561             bClkFreq = phDnldNfc_ClkFreq_26Mhz;
562           } else if (CLK_FREQ_38_4MHZ == (pInputs->pBuff[1])) {
563             bClkFreq = phDnldNfc_ClkFreq_38_4Mhz;
564           } else if (CLK_FREQ_52MHZ == (pInputs->pBuff[1])) {
565             bClkFreq = phDnldNfc_ClkFreq_52Mhz;
566           } else {
567             NXPLOG_FWDNLD_E(
568                 "Invalid Clk Frequency !! Using default value of 19.2Mhz..");
569             bClkFreq = phDnldNfc_ClkFreq_19_2Mhz;
570           }
571 
572         } else if (CLK_SRC_PADDIRECT == (pInputs->pBuff[0])) {
573           bClkSrc = phDnldNfc_ClkSrcPad;
574         } else {
575           NXPLOG_FWDNLD_E("Invalid Clk src !! Using default value of PLL..");
576           bClkSrc = phDnldNfc_ClkSrcPLL;
577         }
578 
579         bPldVal[0] = 0U;
580         bPldVal[0] = ((bClkSrc << 3U) | bClkFreq);
581       } else {
582         NXPLOG_FWDNLD_E("Clk src inputs not provided!! Using default values..");
583       }
584 
585       (gpphDnldContext->tUserData.pBuff) = bPldVal;
586       (gpphDnldContext->tUserData.wLen) = sizeof(bPldVal);
587 
588       memset(&(gpphDnldContext->tRWInfo), 0, sizeof(gpphDnldContext->tRWInfo));
589       (gpphDnldContext->UserCb) = pNotify;
590       (gpphDnldContext->UserCtxt) = pContext;
591 
592       wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventForce);
593 
594       if (NFCSTATUS_PENDING == wStatus) {
595         NXPLOG_FWDNLD_D("Force Command Request submitted successfully");
596       } else {
597         NXPLOG_FWDNLD_E("Force Command Request Failed!!");
598       }
599     }
600   }
601 
602   return wStatus;
603 }
604 
605 /*******************************************************************************
606 **
607 ** Function         phDnldNfc_SetHwDevHandle
608 **
609 ** Description      Stores the HwDev handle to download context. The handle is
610 **                  required for subsequent operations
611 **
612 ** Parameters       None
613 **
614 ** Returns          None                -
615 **
616 *******************************************************************************/
phDnldNfc_SetHwDevHandle(void)617 void phDnldNfc_SetHwDevHandle(void) {
618   pphDnldNfc_DlContext_t psDnldContext = NULL;
619 
620   if (NULL == gpphDnldContext) {
621     NXPLOG_FWDNLD_D("Allocating Mem for Dnld Context..");
622     /* Create the memory for Download Mgmt Context */
623     psDnldContext =
624         (pphDnldNfc_DlContext_t)malloc(sizeof(phDnldNfc_DlContext_t));
625 
626     if (psDnldContext != NULL) {
627       (void)memset((void*)psDnldContext, 0, sizeof(phDnldNfc_DlContext_t));
628       gpphDnldContext = psDnldContext;
629     } else {
630       NXPLOG_FWDNLD_E("Error Allocating Mem for Dnld Context..");
631     }
632   } else {
633     (void)memset((void*)gpphDnldContext, 0, sizeof(phDnldNfc_DlContext_t));
634   }
635   return;
636 }
637 
638 /*******************************************************************************
639 **
640 ** Function         phDnldNfc_ReSetHwDevHandle
641 **
642 ** Description      Frees the HwDev handle to download context.
643 **
644 ** Parameters       None
645 **
646 ** Returns          None                -
647 **
648 *******************************************************************************/
phDnldNfc_ReSetHwDevHandle(void)649 void phDnldNfc_ReSetHwDevHandle(void) {
650   if (gpphDnldContext != NULL) {
651     NXPLOG_FWDNLD_D("Freeing Mem for Dnld Context..");
652     free(gpphDnldContext);
653     gpphDnldContext = NULL;
654   }
655 }
656 
657 /*******************************************************************************
658 **
659 ** Function         phDnldNfc_RawReq
660 **
661 ** Description      Sends raw frame request to NFCC.
662 **                  It is currently used for sending an NCI RESET cmd after
663 **                  doing a production key update
664 **
665 ** Parameters       pFrameData - input buffer, contains raw frame packet to be
666 **                               sent to NFCC
667 **                  pRspData - response buffer received from NFCC
668 **                  pNotify - notify caller after getting response
669 **                  pContext - caller context
670 **
671 ** Returns          NFC status:
672 **                  NFCSTATUS_SUCCESS - GetSessionState request to NFCC is
673 **                                      successful
674 **                  NFCSTATUS_FAILED - GetSessionState request failed due to
675 **                                     internal error
676 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
677 **                  Other command specific errors
678 **
679 *******************************************************************************/
phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData,pphDnldNfc_Buff_t pRspData,pphDnldNfc_RspCb_t pNotify,void * pContext)680 NFCSTATUS phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData,
681                            pphDnldNfc_Buff_t pRspData,
682                            pphDnldNfc_RspCb_t pNotify, void* pContext) {
683   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
684 
685   if ((NULL == pFrameData) || (NULL == pNotify) || (NULL == pRspData) ||
686       (NULL == pContext)) {
687     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
688     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
689   } else {
690     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
691       NXPLOG_FWDNLD_E("Raw Cmd Request in Progress..Cannot Continue!!");
692       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
693     } else {
694       if (((NULL != pFrameData->pBuff) && (0 != pFrameData->wLen)) &&
695           ((NULL != pRspData->pBuff) && (0 != pRspData->wLen))) {
696         (gpphDnldContext->tRspBuffInfo.pBuff) = pRspData->pBuff;
697         (gpphDnldContext->tRspBuffInfo.wLen) = pRspData->wLen;
698         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRaw;
699         (gpphDnldContext->tCmdId) = PH_DL_CMD_NONE;
700         (gpphDnldContext->tUserData.pBuff) = pFrameData->pBuff;
701         (gpphDnldContext->tUserData.wLen) = pFrameData->wLen;
702         (gpphDnldContext->UserCb) = pNotify;
703         (gpphDnldContext->UserCtxt) = pContext;
704 
705         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRaw);
706 
707         if (NFCSTATUS_PENDING == wStatus) {
708           NXPLOG_FWDNLD_D("RawFrame Request submitted successfully");
709         } else {
710           NXPLOG_FWDNLD_E("RawFrame Request Failed!!");
711         }
712       } else {
713         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
714         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
715       }
716     }
717   }
718 
719   return wStatus;
720 }
721 
722 /*******************************************************************************
723 **
724 ** Function         phDnldNfc_InitImgInfo
725 **
726 ** Description      Extracts image information and stores it in respective
727 **                  variables, to be used internally for write operation
728 **
729 ** Parameters       None
730 **
731 ** Returns          NFC status
732 **
733 *******************************************************************************/
phDnldNfc_InitImgInfo(void)734 NFCSTATUS phDnldNfc_InitImgInfo(void) {
735   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
736   uint8_t* pImageInfo = NULL;
737   uint32_t ImageInfoLen = 0;
738   unsigned long fwType = FW_FORMAT_SO;
739 
740   /* if memory is not allocated then allocate memory for download context
741    * structure */
742   phDnldNfc_SetHwDevHandle();
743 
744   gpphDnldContext->FwFormat = FW_FORMAT_UNKNOWN;
745   phDnldNfc_SetDlRspTimeout((uint16_t)PHDNLDNFC_RSP_TIMEOUT);
746   /*Read Firmware file name from config file*/
747   if (GetNxpNumValue(NAME_NXP_FW_TYPE, &fwType, sizeof(fwType)) == true) {
748     NXPLOG_FWDNLD_D("firmware type from conf file: %lu", fwType);
749   } else {
750     NXPLOG_FWDNLD_W("firmware type not found. Taking default value: %lu",
751                     fwType);
752   }
753 
754   if (fwType == FW_FORMAT_BIN) {
755     gpphDnldContext->FwFormat = FW_FORMAT_BIN;
756     wStatus = phDnldNfc_LoadBinFW(&pImageInfo, &ImageInfoLen);
757   } else if (fwType == FW_FORMAT_SO) {
758     gpphDnldContext->FwFormat = FW_FORMAT_SO;
759 #ifdef NXP_DUMMY_FW_DNLD
760     if (gRecFWDwnld == true) {
761       wStatus =
762           phDnldNfc_LoadRecoveryFW(Fw_Lib_Path, &pImageInfo, &ImageInfoLen);
763     } else {
764       wStatus = phDnldNfc_LoadFW(Fw_Lib_Path, &pImageInfo, &ImageInfoLen);
765     }
766 #else
767     wStatus = phDnldNfc_LoadFW(Fw_Lib_Path, &pImageInfo, &ImageInfoLen);
768 #endif
769   } else {
770     NXPLOG_FWDNLD_E("firmware file format mismatch!!!\n");
771     return NFCSTATUS_FAILED;
772   }
773 
774   NXPLOG_FWDNLD_D("FW Image Length - ImageInfoLen %d", ImageInfoLen);
775   NXPLOG_FWDNLD_D("FW Image Info Pointer - pImageInfo %p", pImageInfo);
776 
777   if ((pImageInfo == NULL) || (ImageInfoLen == 0)) {
778     NXPLOG_FWDNLD_E(
779         "Image extraction Failed - invalid imginfo or imginfolen!!");
780     wStatus = NFCSTATUS_FAILED;
781   }
782 
783   if (wStatus != NFCSTATUS_SUCCESS) {
784     NXPLOG_FWDNLD_E("Error loading libpn54x_fw !!\n");
785   }
786 
787   /* get the MW version */
788   if (NFCSTATUS_SUCCESS == wStatus) {
789     // NXPLOG_FWDNLD_D("MW Major Version Num - %x",NXP_MW_VERSION_MAJ);
790     // NXPLOG_FWDNLD_D("MW Minor Version Num - %x",NXP_MW_VERSION_MIN);
791     wMwVer = (((uint16_t)(NXP_MW_VERSION_MAJ) << 8U) | (NXP_MW_VERSION_MIN));
792   }
793 
794   if (NFCSTATUS_SUCCESS == wStatus) {
795     gpphDnldContext->nxp_nfc_fw = (uint8_t*)pImageInfo;
796     gpphDnldContext->nxp_nfc_fw_len = ImageInfoLen;
797     if ((NULL != gpphDnldContext->nxp_nfc_fw) &&
798         (0 != gpphDnldContext->nxp_nfc_fw_len)) {
799       uint16_t offsetFwMajorNum, offsetFwMinorNum;
800       if (nfcFL.chipType == sn220u) {
801         offsetFwMajorNum = ((uint16_t)(gpphDnldContext->nxp_nfc_fw[795]) << 8U);
802         offsetFwMinorNum = ((uint16_t)(gpphDnldContext->nxp_nfc_fw[794]));
803       } else {
804         offsetFwMajorNum = ((uint16_t)(gpphDnldContext->nxp_nfc_fw[5]) << 8U);
805         offsetFwMinorNum = ((uint16_t)(gpphDnldContext->nxp_nfc_fw[4]));
806       }
807       NXPLOG_FWDNLD_D("FW Major Version Num - %x", offsetFwMajorNum);
808       NXPLOG_FWDNLD_D("FW Minor Version Num - %x", offsetFwMinorNum);
809       /* get the FW version */
810       wFwVer = (offsetFwMajorNum | offsetFwMinorNum);
811 
812       NXPLOG_FWDNLD_D("FW Image Length - %d", ImageInfoLen);
813       NXPLOG_FWDNLD_D("FW Image Info Pointer - %p", pImageInfo);
814       wStatus = NFCSTATUS_SUCCESS;
815     } else {
816       NXPLOG_FWDNLD_E("Image details extraction Failed!!");
817       wStatus = NFCSTATUS_FAILED;
818     }
819   }
820 
821   return wStatus;
822 }
823 
824 /*******************************************************************************
825 **
826 ** Function         phDnldNfc_LoadRecInfo
827 **
828 ** Description      Extracts recovery sequence image information and stores it
829 **                  in respective variables, to be used internally for write
830 **                  operation
831 **
832 ** Parameters       None
833 **
834 ** Returns          NFC status
835 **
836 *******************************************************************************/
phDnldNfc_LoadRecInfo(void)837 NFCSTATUS phDnldNfc_LoadRecInfo(void) {
838   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
839   uint8_t* pImageInfo = NULL;
840   uint32_t ImageInfoLen = 0;
841 
842   /* if memory is not allocated then allocate memory for donwload context
843    * structure */
844   phDnldNfc_SetHwDevHandle();
845 #ifdef NXP_DUMMY_FW_DNLD
846   if (gRecFWDwnld == true)
847     wStatus =
848         phDnldNfc_LoadRecoveryFW(PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen);
849   else
850 #endif
851     wStatus = phDnldNfc_LoadFW(PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen);
852   if ((pImageInfo == NULL) || (ImageInfoLen == 0)) {
853     NXPLOG_FWDNLD_E(
854         "Image extraction Failed - invalid imginfo or imginfolen!!");
855     wStatus = NFCSTATUS_FAILED;
856   }
857 
858   /* load the PLL recovery image library */
859   if (wStatus != NFCSTATUS_SUCCESS) {
860     NXPLOG_FWDNLD_E("Error loading libpn54x_fw_platform !!\n");
861   }
862 
863   if (NFCSTATUS_SUCCESS == wStatus) {
864     /* fetch the PLL recovery image pointer and the image length */
865     gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo;
866     gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen;
867     if ((NULL != gpphDnldContext->nxp_nfc_fwp) &&
868         (0 != gpphDnldContext->nxp_nfc_fwp_len)) {
869       NXPLOG_FWDNLD_D("Recovery Image Length - %d", ImageInfoLen);
870       NXPLOG_FWDNLD_D("Recovery Image Info Pointer - %p", pImageInfo);
871       wStatus = NFCSTATUS_SUCCESS;
872     } else {
873       NXPLOG_FWDNLD_E("Recovery Image details extraction Failed!!");
874       wStatus = NFCSTATUS_FAILED;
875     }
876   }
877 
878   return wStatus;
879 }
880 
881 /*******************************************************************************
882 **
883 ** Function         phDnldNfc_LoadPKInfo
884 **
885 ** Description      Extracts production sequence image information and stores it
886 **                  in respective variables, to be used internally for write
887 **                  operation
888 **
889 ** Parameters       None
890 **
891 ** Returns          NFC status
892 **
893 *******************************************************************************/
phDnldNfc_LoadPKInfo(void)894 NFCSTATUS phDnldNfc_LoadPKInfo(void) {
895   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
896   uint8_t* pImageInfo = NULL;
897   uint32_t ImageInfoLen = 0;
898 
899   /* if memory is not allocated then allocate memory for donwload context
900    * structure */
901   phDnldNfc_SetHwDevHandle();
902 
903 /* load the PKU image library */
904 #ifdef NXP_DUMMY_FW_DNLD
905   if (gRecFWDwnld == true)
906     wStatus =
907         phDnldNfc_LoadRecoveryFW(PKU_LIB_PATH, &pImageInfo, &ImageInfoLen);
908   else
909 #endif
910     wStatus = phDnldNfc_LoadFW(PKU_LIB_PATH, &pImageInfo, &ImageInfoLen);
911   if ((pImageInfo == NULL) || (ImageInfoLen == 0)) {
912     NXPLOG_FWDNLD_E(
913         "Image extraction Failed - invalid imginfo or imginfolen!!");
914     wStatus = NFCSTATUS_FAILED;
915   }
916 
917   if (wStatus != NFCSTATUS_SUCCESS) {
918     NXPLOG_FWDNLD_E("Error loading libpn54x_fw_pku !!\n");
919   }
920 
921   if (NFCSTATUS_SUCCESS == wStatus) {
922     /* fetch the PKU image pointer and the image length */
923     gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo;
924     gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen;
925 
926     if ((NULL != gpphDnldContext->nxp_nfc_fwp) &&
927         (0 != gpphDnldContext->nxp_nfc_fwp_len)) {
928       NXPLOG_FWDNLD_D("PKU Image Length - %d", ImageInfoLen);
929       NXPLOG_FWDNLD_D("PKU Image Info Pointer - %p", pImageInfo);
930       wStatus = NFCSTATUS_SUCCESS;
931     } else {
932       NXPLOG_FWDNLD_E("PKU Image details extraction Failed!!");
933       wStatus = NFCSTATUS_FAILED;
934     }
935   }
936 
937   return wStatus;
938 }
939 
940 /*******************************************************************************
941 **
942 ** Function         phDnldNfc_CloseFwLibHandle
943 **
944 ** Description      Closes previously opened fw library handle as part of
945 **                  dynamic loader processing
946 **
947 ** Parameters       None
948 **
949 ** Returns          None
950 **
951 *******************************************************************************/
phDnldNfc_CloseFwLibHandle(void)952 void phDnldNfc_CloseFwLibHandle(void) {
953   NFCSTATUS wStatus = NFCSTATUS_FAILED;
954   if (gpphDnldContext->FwFormat == FW_FORMAT_SO) {
955     wStatus = phDnldNfc_UnloadFW();
956     if (wStatus != NFCSTATUS_SUCCESS) {
957       NXPLOG_FWDNLD_E("free library FAILED !!\n");
958     } else {
959       NXPLOG_FWDNLD_E("free library SUCCESS !!\n");
960     }
961   } else if (gpphDnldContext->FwFormat == FW_FORMAT_BIN) {
962     if (pFwHandle != NULL) {
963       free(pFwHandle);
964       pFwHandle = NULL;
965     }
966   }
967   return;
968 }
969 
970 /*******************************************************************************
971 **
972 ** Function         phDnldNfc_LoadFW
973 **
974 ** Description      Load the firmware version form firmware lib
975 **
976 ** Parameters       pathName    - Firmware image path
977 **                  pImgInfo    - Firmware image handle
978 **                  pImgInfoLen - Firmware image length
979 **
980 ** Returns          NFC status
981 **
982 *******************************************************************************/
phDnldNfc_LoadFW(const char * pathName,uint8_t ** pImgInfo,uint32_t * pImgInfoLen)983 NFCSTATUS phDnldNfc_LoadFW(const char* pathName, uint8_t** pImgInfo,
984                            uint32_t* pImgInfoLen) {
985   void* pImageInfo = NULL;
986   void* pImageInfoLen = NULL;
987 
988   /* check for path name */
989   if (pathName == NULL) pathName = nfcFL._FW_LIB_PATH.c_str();
990 
991   /* check if the handle is not NULL then free the library */
992   if (pFwHandle != NULL) {
993     phDnldNfc_CloseFwLibHandle();
994     pFwHandle = NULL;
995   }
996 
997   /* load the DLL file */
998   pFwHandle = dlopen(pathName, RTLD_LAZY);
999   NXPLOG_FWDNLD_D("@@@%s", pathName);
1000 
1001   /* if library load failed then handle will be NULL */
1002   if (pFwHandle == NULL) {
1003     NXPLOG_FWDNLD_E(
1004         "NULL handler : unable to load the library file, specify correct path");
1005     return NFCSTATUS_FAILED;
1006   }
1007 
1008   dlerror(); /* Clear any existing error */
1009 
1010   /* load the address of download image pointer and image size */
1011   pImageInfo = (void*)dlsym(pFwHandle, "gphDnldNfc_DlSeq");
1012 
1013   if (dlerror() || (NULL == pImageInfo)) {
1014     NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeq");
1015     return NFCSTATUS_FAILED;
1016   }
1017   (*pImgInfo) = (*(uint8_t**)pImageInfo);
1018 
1019   pImageInfoLen = (void*)dlsym(pFwHandle, "gphDnldNfc_DlSeqSz");
1020   if (dlerror() || (NULL == pImageInfoLen)) {
1021     NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeqSz");
1022     return NFCSTATUS_FAILED;
1023   }
1024 
1025   (*pImgInfoLen) = (uint32_t)(*((uint32_t*)pImageInfoLen));
1026   return NFCSTATUS_SUCCESS;
1027 }
1028 
1029 /*******************************************************************************
1030 **
1031 ** Function         phDnldNfc_LoadBinFW
1032 **
1033 ** Description      Load the firmware version form firmware lib
1034 **
1035 ** Parameters       pImgInfo    - Firmware image handle
1036 **                  pImgInfoLen - Firmware image length
1037 **
1038 ** Returns          NFC status
1039 **
1040 *******************************************************************************/
phDnldNfc_LoadBinFW(uint8_t ** pImgInfo,uint32_t * pImgInfoLen)1041 NFCSTATUS phDnldNfc_LoadBinFW(uint8_t** pImgInfo, uint32_t* pImgInfoLen) {
1042   FILE* pFile = NULL;
1043   long fileSize = 0;
1044   long bytesRead = 0;
1045   long ftellFileSize = 0;
1046 
1047   /* check for path name */
1048   if (nfcFL._FW_BIN_PATH.c_str() == NULL) {
1049     NXPLOG_FWDNLD_E("Invalid FW file path!!!\n");
1050     return NFCSTATUS_FAILED;
1051   }
1052 
1053   /* check if the handle is not NULL then free the memory*/
1054   if (pFwHandle != NULL) {
1055     phDnldNfc_CloseFwLibHandle();
1056     pFwHandle = NULL;
1057   }
1058 
1059   /* Open the FW binary image file to be read */
1060   pFile = fopen(nfcFL._FW_BIN_PATH.c_str(), "r");
1061   if (NULL == pFile) {
1062     NXPLOG_FWDNLD_E("Failed to load FW binary image file!!!\n");
1063     return NFCSTATUS_FAILED;
1064   }
1065 
1066   /* Seek to the end of the file */
1067   fseek(pFile, 0, SEEK_END);
1068 
1069   /* get the actual length of the file */
1070   ftellFileSize = ftell(pFile);
1071 
1072   if (ftellFileSize > 0) {
1073     fileSize = ftellFileSize;
1074   } else {
1075     fileSize = 0;
1076   }
1077 
1078   /* Seek to the start of the file, to move file handle back to start of file*/
1079   fseek(pFile, 0, SEEK_SET);
1080 
1081   /* allocate the memory to read the FW binary image */
1082   pFwHandle = (void*)malloc(sizeof(uint8_t) * fileSize);
1083 
1084   /* check for valid memory allocation */
1085   if (NULL == pFwHandle) {
1086     NXPLOG_FWDNLD_E("Failed to allocate memory to load FW image !!!\n");
1087     fclose(pFile);
1088     return NFCSTATUS_FAILED;
1089   }
1090 
1091   /* Read the actual contents of the FW binary image */
1092   bytesRead =
1093       (uint32_t)fread(pFwHandle, sizeof(uint8_t), (size_t)fileSize, pFile);
1094   if (bytesRead != fileSize) {
1095     NXPLOG_FWDNLD_E("Unable to read the specified size from file !!!\n");
1096     fclose(pFile);
1097     free(pFwHandle);
1098     pFwHandle = NULL;
1099     return NFCSTATUS_FAILED;
1100   }
1101 
1102   /* Update the image info pointer to the caller */
1103   *pImgInfo = (uint8_t*)pFwHandle;
1104   *pImgInfoLen = (uint32_t)(bytesRead & 0xFFFFFFFF);
1105 
1106   /* close the FW binary image file */
1107   fclose(pFile);
1108   return NFCSTATUS_SUCCESS;
1109 }
1110 
1111 /*******************************************************************************
1112 **
1113 ** Function         phDnldNfc_LoadRecoveryFW
1114 **
1115 ** Description      Load the recovery firmware version form firmware lib for
1116 **                  recovery. This will change the FW version of the NFCC
1117 **                  firmware and enable flashing of firmware of same version.
1118 **
1119 ** Parameters       pathName    - Firmware image path
1120 **                  pImgInfo    - Firmware image handle
1121 **                  pImgInfoLen - Firmware image length
1122 **
1123 ** Returns          NFCSTATUS
1124 **
1125 *******************************************************************************/
phDnldNfc_LoadRecoveryFW(const char * pathName,uint8_t ** pImgInfo,uint32_t * pImgInfoLen)1126 NFCSTATUS phDnldNfc_LoadRecoveryFW(const char* pathName, uint8_t** pImgInfo,
1127                                    uint32_t* pImgInfoLen) {
1128   void* pImageInfo = NULL;
1129   void* pImageInfoLen = NULL;
1130 
1131   /* check for path name */
1132   if (pathName == NULL) pathName = nfcFL._FW_LIB_PATH.c_str();
1133 
1134   /* check if the handle is not NULL then free the library */
1135   if (pFwHandle != NULL) {
1136     phDnldNfc_CloseFwLibHandle();
1137     pFwHandle = NULL;
1138   }
1139   /* load the DLL file */
1140   pFwHandle = dlopen(pathName, RTLD_LAZY);
1141   NXPLOG_FWDNLD_D("phDnldNfc_LoadRecoveryFW %s ", pathName);
1142 
1143   /* if library load failed then handle will be NULL */
1144   if (pFwHandle == NULL) {
1145     NXPLOG_FWDNLD_E(
1146         "NULL handler : unable to load the library file, specify correct path");
1147     return NFCSTATUS_FAILED;
1148   }
1149 
1150   dlerror(); /* Clear any existing error */
1151 
1152   /* load the address of download image pointer and image size */
1153   pImageInfo = (void*)dlsym(pFwHandle, "gphDnldNfc_DummyDlSeq");
1154 
1155   if (dlerror() || (NULL == pImageInfo)) {
1156     NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DummyDlSeq");
1157     return NFCSTATUS_FAILED;
1158   }
1159 
1160   (*pImgInfo) = (*(uint8_t**)pImageInfo);
1161   pImageInfoLen = (void*)dlsym(pFwHandle, "gphDnldNfc_DlSeqDummyFwSz");
1162   if (dlerror() || (NULL == pImageInfoLen)) {
1163     NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeqDummyFwSz");
1164     return NFCSTATUS_FAILED;
1165   }
1166 
1167   (*pImgInfoLen) = (uint32_t)(*((uint32_t*)pImageInfoLen));
1168 
1169   return NFCSTATUS_SUCCESS;
1170 }
1171 
1172 /*******************************************************************************
1173 **
1174 ** Function         phDnldNfc_UnloadFW
1175 **
1176 ** Description      Deinit the firmware handle
1177 **
1178 ** Parameters       None
1179 **
1180 ** Returns          NFC status
1181 **
1182 *******************************************************************************/
phDnldNfc_UnloadFW(void)1183 NFCSTATUS phDnldNfc_UnloadFW(void) {
1184   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1185   int32_t status;
1186 
1187   /* check if the handle is not NULL then free the library */
1188   if (pFwHandle != NULL) {
1189     status = dlclose(pFwHandle);
1190     pFwHandle = NULL;
1191 
1192     dlerror(); /* Clear any existing error */
1193     if (status != 0) {
1194       wStatus = NFCSTATUS_FAILED;
1195       NXPLOG_FWDNLD_E("Free library file failed");
1196     }
1197   }
1198 
1199   return wStatus;
1200 }
1201 
1202 /*******************************************************************************
1203 **
1204 ** Function         phDnldNfc_SetDlRspTimeout
1205 **
1206 ** Description      This function sets the timeout value dnld cmd response
1207 **
1208 ** Parameters       timeout : timeout value for dnld response
1209 **
1210 ** Returns          None
1211 **
1212 *******************************************************************************/
phDnldNfc_SetDlRspTimeout(uint16_t timeout)1213 void phDnldNfc_SetDlRspTimeout(uint16_t timeout) {
1214   gpphDnldContext->TimerInfo.rspTimeout = timeout;
1215   NXPLOG_FWDNLD_E("phDnldNfc_SetDlRspTimeout timeout value =%x", timeout);
1216 }
1217 
1218 #ifdef EEPROM_Read_Mem_IMP
1219 static pphDnldNfc_RspCb_t UserCb; /* Upper layer call back function */
1220 static void* UserCtxt;            /* Pointer to upper layer context */
1221 /* Function prototype declaration */
1222 static void phDnldNfc_ReadComplete(void* pContext, NFCSTATUS status,
1223                                    void* pInfo);
1224 
1225 /*******************************************************************************
1226 **
1227 ** Function         phDnldNfc_ReadMem
1228 **
1229 ** Description      Dumps the contents of EEPROM. The handle is required for
1230 **                  subsequent operations
1231 **
1232 ** Parameters       pHwRef - pointer to the hardware device
1233 **                  pNotify - notify caller after getting response
1234 **                  pContext - caller context
1235 **
1236 ** Returns          NFC status:
1237 **                  NFCSTATUS_SUCCESS - request to NFCC is successful
1238 **                  NFCSTATUS_FAILED - request failed due to internal error
1239 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
1240 **                  Other command specific errors
1241 **
1242 *******************************************************************************/
phDnldNfc_ReadMem(void * pHwRef,pphDnldNfc_RspCb_t pNotify,void * pContext)1243 NFCSTATUS phDnldNfc_ReadMem(void* pHwRef, pphDnldNfc_RspCb_t pNotify,
1244                             void* pContext) {
1245   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1246   uint32_t wAddr = 0x2011C0; /* eeprom platform specific area start address */
1247   uint32_t wRdAddr = 0;
1248   uint8_t* pAddr;
1249   static uint8_t bRdData[3519]; /* buffer to hold the read data */
1250   static phDnldNfc_Buff_t Data;
1251 
1252   if ((NULL == pNotify) || (NULL == pContext)) {
1253     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
1254     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
1255   } else {
1256     /* Call Tml Ioctl to enable download mode */
1257     wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
1258 
1259     if (NFCSTATUS_SUCCESS == wStatus) {
1260       /* Set the obtained device handle to download module */
1261       phDnldNfc_SetHwDevHandle();
1262     } else {
1263       wStatus = NFCSTATUS_FAILED;
1264     }
1265 
1266     if (NFCSTATUS_SUCCESS == wStatus) {
1267       pAddr = (uint8_t*)&wAddr;
1268 
1269       wRdAddr = (pAddr[3]);
1270       wRdAddr <<= 8;
1271       wRdAddr |= (pAddr[2]);
1272       wRdAddr <<= 8;
1273       wRdAddr |= (pAddr[1]);
1274       wRdAddr <<= 8;
1275       wRdAddr |= (pAddr[0]);
1276 
1277       Data.pBuff = bRdData;
1278       Data.wLen = sizeof(bRdData);
1279       UserCb = pNotify;
1280       UserCtxt = pContext;
1281 
1282       wStatus = phDnldNfc_Read(&Data, wRdAddr,
1283                                (pphDnldNfc_RspCb_t)phDnldNfc_ReadComplete,
1284                                gpphDnldContext);
1285     } else {
1286       Data.pBuff = NULL;
1287       Data.wLen = 0;
1288       wStatus = NFCSTATUS_FAILED;
1289     }
1290 
1291     if (NFCSTATUS_PENDING == wStatus) {
1292       NXPLOG_FWDNLD_D("Read Request submitted successfully..");
1293     } else {
1294       NXPLOG_FWDNLD_E("Read Request submission failed!!");
1295     }
1296   }
1297 
1298   return wStatus;
1299 }
1300 
1301 /*******************************************************************************
1302 **
1303 ** Function         phDnldNfc_ReadComplete
1304 **
1305 ** Description      Read complete
1306 **
1307 ** Parameters       pContext - caller layer context
1308 **                  status   - status of the transaction
1309 **                  pInfo    - transaction info
1310 **
1311 ** Returns          None
1312 **
1313 *******************************************************************************/
phDnldNfc_ReadComplete(void * pContext,NFCSTATUS status,void * pInfo)1314 static void phDnldNfc_ReadComplete(void* pContext, NFCSTATUS status,
1315                                    void* pInfo) {
1316   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1317   UNUSED_PROP(pContext);
1318 
1319   /* Call Tml Ioctl to enable/restore normal mode */
1320   wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
1321 
1322   if (NFCSTATUS_SUCCESS == wStatus) {
1323     NXPLOG_FWDNLD_D("Read Done!!");
1324   }
1325 
1326   UserCb(&UserCtxt, status, pInfo);
1327 
1328   return;
1329 }
1330 
1331 /*******************************************************************************
1332 **
1333 ** Function         phDnldNfc_Read
1334 **
1335 ** Description      Retrieves requested data of specified length from desired
1336 **                  EEPROM address
1337 **
1338 ** Parameters       pData - response buffer which gets updated with data from
1339 **                          EEPROM
1340 **                  dwRdAddr - EEPROM address for data read
1341 **                  pNotify - notify caller after getting response
1342 **                  pContext - caller context
1343 **
1344 ** Returns          NFC status:
1345 **                  NFCSTATUS_SUCCESS - Read request to NFCC is successful
1346 **                  NFCSTATUS_FAILED - Read request failed due to internal error
1347 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
1348 **                  Other command specific errors
1349 **
1350 *******************************************************************************/
phDnldNfc_Read(pphDnldNfc_Buff_t pData,uint32_t dwRdAddr,pphDnldNfc_RspCb_t pNotify,void * pContext)1351 NFCSTATUS phDnldNfc_Read(pphDnldNfc_Buff_t pData, uint32_t dwRdAddr,
1352                          pphDnldNfc_RspCb_t pNotify, void* pContext) {
1353   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1354 
1355   if ((NULL == pNotify) || (NULL == pData) || (NULL == pContext)) {
1356     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
1357     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
1358   } else {
1359     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
1360       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
1361       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
1362     } else {
1363       if ((NULL != pData->pBuff) && (0 != pData->wLen)) {
1364         (gpphDnldContext->tCmdId) = PH_DL_CMD_READ;
1365         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRead;
1366         (gpphDnldContext->FrameInp.dwAddr) = dwRdAddr;
1367         (gpphDnldContext->tRspBuffInfo.pBuff) = pData->pBuff;
1368         (gpphDnldContext->tRspBuffInfo.wLen) = pData->wLen;
1369         (gpphDnldContext->tUserData.pBuff) = NULL;
1370         (gpphDnldContext->tUserData.wLen) = 0;
1371         (gpphDnldContext->UserCb) = pNotify;
1372         (gpphDnldContext->UserCtxt) = pContext;
1373 
1374         memset(&(gpphDnldContext->tRWInfo), 0,
1375                sizeof(gpphDnldContext->tRWInfo));
1376 
1377         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRead);
1378 
1379         if (NFCSTATUS_PENDING == wStatus) {
1380           NXPLOG_FWDNLD_D("Read Request submitted successfully");
1381         } else {
1382           NXPLOG_FWDNLD_E("Read Request Failed!!");
1383         }
1384       } else {
1385         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
1386         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
1387       }
1388     }
1389   }
1390 
1391   return wStatus;
1392 }
1393 #endif
1394