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