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