1 /*
2  *  Copyright 2010-2023 NXP
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
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 {
582             NXPLOG_FWDNLD_E(
583                 "Invalid Clk Frequency !! Using default value of 19.2Mhz..");
584             bClkFreq = phDnldNfc_ClkFreq_19_2Mhz;
585           }
586 
587         } else if (CLK_SRC_PADDIRECT == (pInputs->pBuff[0])) {
588           bClkSrc = phDnldNfc_ClkSrcPad;
589         } else {
590           NXPLOG_FWDNLD_E("Invalid Clk src !! Using default value of PLL..");
591           bClkSrc = phDnldNfc_ClkSrcPLL;
592         }
593 
594         bPldVal[0] = 0U;
595         bPldVal[0] = ((bClkSrc << 3U) | bClkFreq);
596       } else {
597         NXPLOG_FWDNLD_E("Clk src inputs not provided!! Using default values..");
598       }
599 
600       (gpphDnldContext->tUserData.pBuff) = bPldVal;
601       (gpphDnldContext->tUserData.wLen) = sizeof(bPldVal);
602 
603       memset(&(gpphDnldContext->tRWInfo), 0, sizeof(gpphDnldContext->tRWInfo));
604       (gpphDnldContext->UserCb) = pNotify;
605       (gpphDnldContext->UserCtxt) = pContext;
606 
607       wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventForce);
608 
609       if (NFCSTATUS_PENDING == wStatus) {
610         NXPLOG_FWDNLD_D("Force Command Request submitted successfully");
611       } else {
612         NXPLOG_FWDNLD_E("Force Command Request Failed!!");
613       }
614     }
615   }
616 
617   return wStatus;
618 }
619 
620 /*******************************************************************************
621 **
622 ** Function         phDnldNfc_SetHwDevHandle
623 **
624 ** Description      Stores the HwDev handle to download context. The handle is
625 **                  required for subsequent operations. Also, sets the I2C
626 **                  fragmentation length as per the chip type.
627 **
628 ** Parameters       None
629 **
630 ** Returns          None                -
631 **
632 *******************************************************************************/
phDnldNfc_SetHwDevHandle(void)633 void phDnldNfc_SetHwDevHandle(void) {
634   if (NULL == gpphDnldContext) {
635     NXPLOG_FWDNLD_D("Allocating Mem for Dnld Context..");
636     /* Create the memory for Download Mgmt Context */
637     gpphDnldContext =
638         (pphDnldNfc_DlContext_t)calloc(1, sizeof(phDnldNfc_DlContext_t));
639     if (gpphDnldContext == NULL) {
640       NXPLOG_FWDNLD_E("Error Allocating Mem for Dnld Context..");
641       return;
642     }
643   } else {
644     if (gpphDnldContext->tCmdRspFrameInfo.aFrameBuff != NULL) {
645       free(gpphDnldContext->tCmdRspFrameInfo.aFrameBuff);
646     }
647     (void)memset((void*)gpphDnldContext, 0, sizeof(phDnldNfc_DlContext_t));
648   }
649   // Set the gpphDnldContext->nxp_i2c_fragment_len as per chiptype
650   phDnldNfc_SetI2CFragmentLength();
651   gpphDnldContext->tCmdRspFrameInfo.aFrameBuff =
652       (uint8_t*)calloc(gpphDnldContext->nxp_i2c_fragment_len, sizeof(uint8_t));
653   if (gpphDnldContext->tCmdRspFrameInfo.aFrameBuff == NULL) {
654     NXPLOG_FWDNLD_E("Error Allocating Mem for Dnld Context aFrameBuff..");
655   }
656   // Update the write Fragmentation Length at TML layer
657   phTmlNfc_IoCtl(phTmlNfc_e_setFragmentSize);
658   return;
659 }
660 
661 /*******************************************************************************
662 **
663 ** Function         phDnldNfc_ReSetHwDevHandle
664 **
665 ** Description      Frees the HwDev handle to download context.
666 **
667 ** Parameters       None
668 **
669 ** Returns          None                -
670 **
671 *******************************************************************************/
phDnldNfc_ReSetHwDevHandle(void)672 void phDnldNfc_ReSetHwDevHandle(void) {
673   if (gpphDnldContext != NULL) {
674     NXPLOG_FWDNLD_D("Freeing Mem for Dnld Context..");
675     free(gpphDnldContext);
676     gpphDnldContext = NULL;
677   }
678   phTmlNfc_IoCtl(phTmlNfc_e_setFragmentSize);
679 }
680 
681 /*******************************************************************************
682 **
683 ** Function         phDnldNfc_RawReq
684 **
685 ** Description      Sends raw frame request to NFCC.
686 **                  It is currently used for sending an NCI RESET cmd after
687 **                  doing a production key update
688 **
689 ** Parameters       pFrameData - input buffer, contains raw frame packet to be
690 **                               sent to NFCC
691 **                  pRspData - response buffer received from NFCC
692 **                  pNotify - notify caller after getting response
693 **                  pContext - caller context
694 **
695 ** Returns          NFC status:
696 **                  NFCSTATUS_SUCCESS - GetSessionState request to NFCC is
697 **                                      successful
698 **                  NFCSTATUS_FAILED - GetSessionState request failed due to
699 **                                     internal error
700 **                  NFCSTATUS_NOT_ALLOWED - command not allowed
701 **                  Other command specific errors
702 **
703 *******************************************************************************/
phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData,pphDnldNfc_Buff_t pRspData,pphDnldNfc_RspCb_t pNotify,void * pContext)704 NFCSTATUS phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData,
705                            pphDnldNfc_Buff_t pRspData,
706                            pphDnldNfc_RspCb_t pNotify, void* pContext) {
707   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
708 
709   if ((NULL == pFrameData) || (NULL == pNotify) || (NULL == pRspData) ||
710       (NULL == pContext)) {
711     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
712     wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
713   } else {
714     if (phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress) {
715       NXPLOG_FWDNLD_E("Raw Cmd Request in Progress..Cannot Continue!!");
716       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
717     } else {
718       if (((NULL != pFrameData->pBuff) && (0 != pFrameData->wLen)) &&
719           ((NULL != pRspData->pBuff) && (0 != pRspData->wLen))) {
720         (gpphDnldContext->tRspBuffInfo.pBuff) = pRspData->pBuff;
721         (gpphDnldContext->tRspBuffInfo.wLen) = pRspData->wLen;
722         (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRaw;
723         (gpphDnldContext->tCmdId) = PH_DL_CMD_NONE;
724         (gpphDnldContext->tUserData.pBuff) = pFrameData->pBuff;
725         (gpphDnldContext->tUserData.wLen) = pFrameData->wLen;
726         (gpphDnldContext->UserCb) = pNotify;
727         (gpphDnldContext->UserCtxt) = pContext;
728 
729         wStatus = phDnldNfc_CmdHandler(gpphDnldContext, phDnldNfc_EventRaw);
730 
731         if (NFCSTATUS_PENDING == wStatus) {
732           NXPLOG_FWDNLD_D("RawFrame Request submitted successfully");
733         } else {
734           NXPLOG_FWDNLD_E("RawFrame Request Failed!!");
735         }
736       } else {
737         NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
738         wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
739       }
740     }
741   }
742 
743   return wStatus;
744 }
745 
746 /*******************************************************************************
747 **
748 ** Function         phDnldNfc_InitImgInfo
749 **
750 ** Description      Extracts image information and stores it in respective
751 **                  variables, to be used internally for write operation
752 **
753 ** Parameters       bMinimalFw - flag indicates for minimal FW Image
754 **                  degradedFwDnld - Indicates if degraded FW download is
755 **                  requested
756 **
757 ** Returns          NFC status
758 **
759 *******************************************************************************/
phDnldNfc_InitImgInfo(bool bMinimalFw,bool degradedFwDnld)760 NFCSTATUS phDnldNfc_InitImgInfo(bool bMinimalFw, bool degradedFwDnld) {
761   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
762   uint8_t* pImageInfo = NULL;
763   uint32_t ImageInfoLen = 0;
764   unsigned long fwType = FW_FORMAT_SO;
765 
766   /* if memory is not allocated then allocate memory for download context
767    * structure */
768   phDnldNfc_SetHwDevHandle();
769 
770   gpphDnldContext->FwFormat = FW_FORMAT_UNKNOWN;
771   phDnldNfc_SetDlRspTimeout((uint16_t)PHDNLDNFC_RSP_TIMEOUT);
772   if (bMinimalFw) {
773     fwType = FW_FORMAT_ARRAY;
774   } else if (GetNxpNumValue(NAME_NXP_FW_TYPE, &fwType, sizeof(fwType)) ==
775              true) {
776     /*Read Firmware file name from config file*/
777     NXPLOG_FWDNLD_D("firmware type from conf file: %lu", fwType);
778   } else {
779     NXPLOG_FWDNLD_W("firmware type not found. Taking default value: %lu",
780                     fwType);
781   }
782 
783   if (fwType == FW_FORMAT_ARRAY) {
784     gpphDnldContext->FwFormat = FW_FORMAT_ARRAY;
785 #if (NXP_NFC_RECOVERY == TRUE)
786     pImageInfo = (uint8_t*)gphDnldNfc_DlSequence;
787     ImageInfoLen = gphDnldNfc_DlSeqSz;
788 #endif
789     wStatus = NFCSTATUS_SUCCESS;
790   } else if (fwType == FW_FORMAT_BIN) {
791     gpphDnldContext->FwFormat = FW_FORMAT_BIN;
792     wStatus = phDnldNfc_LoadBinFW(&pImageInfo, &ImageInfoLen);
793   } else if (fwType == FW_FORMAT_SO) {
794     gpphDnldContext->FwFormat = FW_FORMAT_SO;
795     wStatus = phDnldNfc_LoadFW(Fw_Lib_Path, &pImageInfo, &ImageInfoLen,
796                                degradedFwDnld);
797   } else {
798     NXPLOG_FWDNLD_E("firmware file format mismatch!!!\n");
799     return NFCSTATUS_FAILED;
800   }
801 
802   NXPLOG_FWDNLD_D("FW Image Length - ImageInfoLen %d", ImageInfoLen);
803   NXPLOG_FWDNLD_D("FW Image Info Pointer - pImageInfo %p", pImageInfo);
804 
805   if ((pImageInfo == NULL) || (ImageInfoLen == 0)) {
806     NXPLOG_FWDNLD_E(
807         "Image extraction Failed - invalid imginfo or imginfolen!!");
808     wStatus = NFCSTATUS_FAILED;
809   }
810 
811   if (wStatus != NFCSTATUS_SUCCESS) {
812     NXPLOG_FWDNLD_E("Error loading FW file !!\n");
813   }
814 
815   /* get the MW version */
816   if (NFCSTATUS_SUCCESS == wStatus) {
817     // NXPLOG_FWDNLD_D("MW Major Version Num - %x",NXP_MW_VERSION_MAJ);
818     // NXPLOG_FWDNLD_D("MW Minor Version Num - %x",NXP_MW_VERSION_MIN);
819     wMwVer = (((uint16_t)(NXP_MW_VERSION_MAJ) << 8U) | (NXP_MW_VERSION_MIN));
820   }
821 
822   if (NFCSTATUS_SUCCESS == wStatus) {
823     gpphDnldContext->nxp_nfc_fw = (uint8_t*)pImageInfo;
824     gpphDnldContext->nxp_nfc_fw_len = ImageInfoLen;
825     if ((NULL != gpphDnldContext->nxp_nfc_fw) &&
826         (0 != gpphDnldContext->nxp_nfc_fw_len)) {
827       uint16_t offsetFwMajorNum, offsetFwMinorNum;
828       if (IS_CHIP_TYPE_GE(sn220u) || IS_CHIP_TYPE_EQ(pn560)) {
829         offsetFwMajorNum = ((uint16_t)(gpphDnldContext->nxp_nfc_fw[795]) << 8U);
830         offsetFwMinorNum = ((uint16_t)(gpphDnldContext->nxp_nfc_fw[794]));
831       } else {
832         offsetFwMajorNum = ((uint16_t)(gpphDnldContext->nxp_nfc_fw[5]) << 8U);
833         offsetFwMinorNum = ((uint16_t)(gpphDnldContext->nxp_nfc_fw[4]));
834       }
835       NXPLOG_FWDNLD_D("FW Major Version Num - %x", offsetFwMajorNum);
836       NXPLOG_FWDNLD_D("FW Minor Version Num - %x", offsetFwMinorNum);
837       /* get the FW version */
838       wFwVer = (offsetFwMajorNum | offsetFwMinorNum);
839 
840       NXPLOG_FWDNLD_D("FW Image Length - %d", ImageInfoLen);
841       NXPLOG_FWDNLD_D("FW Image Info Pointer - %p", pImageInfo);
842       wStatus = NFCSTATUS_SUCCESS;
843     } else {
844       NXPLOG_FWDNLD_E("Image details extraction Failed!!");
845       wStatus = NFCSTATUS_FAILED;
846     }
847   }
848 
849   return wStatus;
850 }
851 
852 /*******************************************************************************
853 **
854 ** Function         phDnldNfc_LoadRecInfo
855 **
856 ** Description      Extracts recovery sequence image information and stores it
857 **                  in respective variables, to be used internally for write
858 **                  operation
859 **
860 ** Parameters       None
861 **
862 ** Returns          NFC status
863 **
864 *******************************************************************************/
phDnldNfc_LoadRecInfo(void)865 NFCSTATUS phDnldNfc_LoadRecInfo(void) {
866   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
867   uint8_t* pImageInfo = NULL;
868   uint32_t ImageInfoLen = 0;
869 
870   /* if memory is not allocated then allocate memory for donwload context
871    * structure */
872   phDnldNfc_SetHwDevHandle();
873   wStatus = phDnldNfc_LoadFW(PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen);
874   if ((pImageInfo == NULL) || (ImageInfoLen == 0)) {
875     NXPLOG_FWDNLD_E(
876         "Image extraction Failed - invalid imginfo or imginfolen!!");
877     wStatus = NFCSTATUS_FAILED;
878   }
879 
880   /* load the PLL recovery image library */
881   if (wStatus != NFCSTATUS_SUCCESS) {
882     NXPLOG_FWDNLD_E("Error loading FW file... !!\n");
883   }
884 
885   if (NFCSTATUS_SUCCESS == wStatus) {
886     /* fetch the PLL recovery image pointer and the image length */
887     gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo;
888     gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen;
889 
890     if ((NULL != gpphDnldContext->nxp_nfc_fwp) &&
891         (0 != gpphDnldContext->nxp_nfc_fwp_len)) {
892       NXPLOG_FWDNLD_D("Recovery Image Length - %d", ImageInfoLen);
893       NXPLOG_FWDNLD_D("Recovery Image Info Pointer - %p", pImageInfo);
894       wStatus = NFCSTATUS_SUCCESS;
895     } else {
896       NXPLOG_FWDNLD_E("Recovery Image details extraction Failed!!");
897       wStatus = NFCSTATUS_FAILED;
898     }
899   }
900 
901   return wStatus;
902 }
903 
904 /*******************************************************************************
905 **
906 ** Function         phDnldNfc_LoadPKInfo
907 **
908 ** Description      Extracts production sequence image information and stores it
909 **                  in respective variables, to be used internally for write
910 **                  operation
911 **
912 ** Parameters       None
913 **
914 ** Returns          NFC status
915 **
916 *******************************************************************************/
phDnldNfc_LoadPKInfo(void)917 NFCSTATUS phDnldNfc_LoadPKInfo(void) {
918   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
919   uint8_t* pImageInfo = NULL;
920   uint32_t ImageInfoLen = 0;
921 
922   /* if memory is not allocated then allocate memory for donwload context
923    * structure */
924   phDnldNfc_SetHwDevHandle();
925 
926   /* load the PKU image library */
927   wStatus = phDnldNfc_LoadFW(PKU_LIB_PATH, &pImageInfo, &ImageInfoLen);
928   if ((pImageInfo == NULL) || (ImageInfoLen == 0)) {
929     NXPLOG_FWDNLD_E(
930         "Image extraction Failed - invalid imginfo or imginfolen!!");
931     wStatus = NFCSTATUS_FAILED;
932   }
933 
934   if (wStatus != NFCSTATUS_SUCCESS) {
935     NXPLOG_FWDNLD_E("Error loading FW File pku !!\n");
936   }
937 
938   if (NFCSTATUS_SUCCESS == wStatus) {
939     /* fetch the PKU image pointer and the image length */
940     gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo;
941     gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen;
942 
943     if ((NULL != gpphDnldContext->nxp_nfc_fwp) &&
944         (0 != gpphDnldContext->nxp_nfc_fwp_len)) {
945       NXPLOG_FWDNLD_D("PKU Image Length - %d", ImageInfoLen);
946       NXPLOG_FWDNLD_D("PKU Image Info Pointer - %p", pImageInfo);
947       wStatus = NFCSTATUS_SUCCESS;
948     } else {
949       NXPLOG_FWDNLD_E("PKU Image details extraction Failed!!");
950       wStatus = NFCSTATUS_FAILED;
951     }
952   }
953 
954   return wStatus;
955 }
956 
957 /*******************************************************************************
958 **
959 ** Function         phDnldNfc_CloseFwLibHandle
960 **
961 ** Description      Closes previously opened fw library handle as part of
962 **                  dynamic loader processing
963 **
964 ** Parameters       None
965 **
966 ** Returns          None
967 **
968 *******************************************************************************/
phDnldNfc_CloseFwLibHandle(void)969 void phDnldNfc_CloseFwLibHandle(void) {
970   NFCSTATUS wStatus = NFCSTATUS_FAILED;
971   if (gpphDnldContext->FwFormat == FW_FORMAT_SO) {
972     wStatus = phDnldNfc_UnloadFW();
973     if (wStatus != NFCSTATUS_SUCCESS) {
974       NXPLOG_FWDNLD_E("free library FAILED !!\n");
975     } else {
976       NXPLOG_FWDNLD_E("free library SUCCESS !!\n");
977     }
978   } else if (gpphDnldContext->FwFormat == FW_FORMAT_BIN) {
979     if (pFwHandle != NULL) {
980       free(pFwHandle);
981       pFwHandle = NULL;
982     }
983   }
984   return;
985 }
986 
987 /*******************************************************************************
988 **
989 ** Function         phDnldNfc_LoadFW
990 **
991 ** Description      Load the firmware version form firmware lib
992 **
993 ** Parameters       pathName    - Firmware image path
994 **                  pImgInfo    - Firmware image handle
995 **                  pImgInfoLen - Firmware image length
996 **                  degradedFwDnld - Indicates if degraded FW download is
997 **                  requested
998 **
999 ** Returns          NFC status
1000 **
1001 *******************************************************************************/
phDnldNfc_LoadFW(const char * pathName,uint8_t ** pImgInfo,uint32_t * pImgInfoLen,bool degradedFwDnld)1002 NFCSTATUS phDnldNfc_LoadFW(const char* pathName, uint8_t** pImgInfo,
1003                            uint32_t* pImgInfoLen, bool degradedFwDnld) {
1004   void* pImageInfo = NULL;
1005   void* pImageInfoLen = NULL;
1006   const char* pFwSymbol = "gphDnldNfc_DlSeq";
1007   const char* pFwSymbolSz = "gphDnldNfc_DlSeqSz";
1008   /* check for path name */
1009   if (pathName == NULL) pathName = nfcFL._FW_LIB_PATH.c_str();
1010 
1011   /* check if the handle is not NULL then free the library */
1012   if (pFwHandle != NULL) {
1013     phDnldNfc_CloseFwLibHandle();
1014     pFwHandle = NULL;
1015   }
1016 
1017   /* load the DLL file */
1018   pFwHandle = dlopen(pathName, RTLD_LAZY);
1019   NXPLOG_FWDNLD_D("@@@%s", pathName);
1020 
1021   /* if library load failed then handle will be NULL */
1022   if (pFwHandle == NULL) {
1023     NXPLOG_FWDNLD_E(
1024         "NULL handler : unable to load the library file, specify correct path");
1025     return NFCSTATUS_FAILED;
1026   }
1027 
1028   dlerror(); /* Clear any existing error */
1029 
1030   if (degradedFwDnld) {
1031     NXPLOG_FWDNLD_D("%s: Loading Degraded FW info", __func__);
1032     pFwSymbol = "gphDnldNfc_DlSeq_DegradedFw";
1033     pFwSymbolSz = "gphDnldNfc_DlSeqSz_DegradedFw";
1034   }
1035 
1036   /* load the address of download image pointer and image size */
1037   pImageInfo = (void*)dlsym(pFwHandle, pFwSymbol);
1038 
1039   if (dlerror() || (NULL == pImageInfo)) {
1040     NXPLOG_FWDNLD_E("Problem loading symbol : %s", pFwSymbol);
1041     return NFCSTATUS_FAILED;
1042   }
1043   (*pImgInfo) = (*(uint8_t**)pImageInfo);
1044 
1045   pImageInfoLen = (void*)dlsym(pFwHandle, pFwSymbolSz);
1046   if (dlerror() || (NULL == pImageInfoLen)) {
1047     NXPLOG_FWDNLD_E("Problem loading symbol : %s", pFwSymbolSz);
1048     return NFCSTATUS_FAILED;
1049   }
1050 
1051   if (IS_CHIP_TYPE_GE(sn100u)) {
1052     (*pImgInfoLen) = (uint32_t)(*((uint32_t*)pImageInfoLen));
1053   } else {
1054     (*pImgInfoLen) = (uint16_t)(*((uint16_t*)pImageInfoLen));
1055   }
1056   NXPLOG_FWDNLD_D("FW image loaded for chipType %s",
1057                   pConfigFL->product[nfcFL.chipType]);
1058   return NFCSTATUS_SUCCESS;
1059 }
1060 
1061 /*******************************************************************************
1062 **
1063 ** Function         phDnldNfc_LoadBinFW
1064 **
1065 ** Description      Load the firmware version form firmware lib
1066 **
1067 ** Parameters       pImgInfo    - Firmware image handle
1068 **                  pImgInfoLen - Firmware image length
1069 **
1070 ** Returns          NFC status
1071 **
1072 *******************************************************************************/
phDnldNfc_LoadBinFW(uint8_t ** pImgInfo,uint32_t * pImgInfoLen)1073 NFCSTATUS phDnldNfc_LoadBinFW(uint8_t** pImgInfo, uint32_t* pImgInfoLen) {
1074   FILE* pFile = NULL;
1075   long fileSize = 0;
1076   long bytesRead = 0;
1077   long ftellFileSize = 0;
1078 
1079   /* check for path name */
1080   if (nfcFL._FW_BIN_PATH.c_str() == NULL) {
1081     NXPLOG_FWDNLD_E("Invalid FW file path!!!\n");
1082     return NFCSTATUS_FAILED;
1083   }
1084 
1085   /* check if the handle is not NULL then free the memory*/
1086   if (pFwHandle != NULL) {
1087     phDnldNfc_CloseFwLibHandle();
1088     pFwHandle = NULL;
1089   }
1090 
1091   /* Open the FW binary image file to be read */
1092   pFile = fopen(nfcFL._FW_BIN_PATH.c_str(), "r");
1093   if (NULL == pFile) {
1094     NXPLOG_FWDNLD_E("Failed to load FW binary image file!!!\n");
1095     return NFCSTATUS_FAILED;
1096   }
1097 
1098   /* Seek to the end of the file */
1099   fseek(pFile, 0, SEEK_END);
1100 
1101   /* get the actual length of the file */
1102   ftellFileSize = ftell(pFile);
1103 
1104   if (ftellFileSize > 0) {
1105     fileSize = ftellFileSize;
1106   } else {
1107     fileSize = 0;
1108   }
1109 
1110   /* Seek to the start of the file, to move file handle back to start of file*/
1111   fseek(pFile, 0, SEEK_SET);
1112 
1113   /* allocate the memory to read the FW binary image */
1114   pFwHandle = (void*)malloc(sizeof(uint8_t) * fileSize);
1115 
1116   /* check for valid memory allocation */
1117   if (NULL == pFwHandle) {
1118     NXPLOG_FWDNLD_E("Failed to allocate memory to load FW image !!!\n");
1119     fclose(pFile);
1120     return NFCSTATUS_FAILED;
1121   }
1122 
1123   /* Read the actual contents of the FW binary image */
1124   bytesRead =
1125       (uint32_t)fread(pFwHandle, sizeof(uint8_t), (size_t)fileSize, pFile);
1126   if (bytesRead != fileSize) {
1127     NXPLOG_FWDNLD_E("Unable to read the specified size from file !!!\n");
1128     fclose(pFile);
1129     free(pFwHandle);
1130     pFwHandle = NULL;
1131     return NFCSTATUS_FAILED;
1132   }
1133 
1134   /* Update the image info pointer to the caller */
1135   *pImgInfo = (uint8_t*)pFwHandle;
1136   *pImgInfoLen = (uint32_t)(bytesRead & 0xFFFFFFFF);
1137 
1138   /* close the FW binary image file */
1139   fclose(pFile);
1140   return NFCSTATUS_SUCCESS;
1141 }
1142 
1143 /*******************************************************************************
1144 **
1145 ** Function         phDnldNfc_UnloadFW
1146 **
1147 ** Description      Deinit the firmware handle
1148 **
1149 ** Parameters       None
1150 **
1151 ** Returns          NFC status
1152 **
1153 *******************************************************************************/
phDnldNfc_UnloadFW(void)1154 NFCSTATUS phDnldNfc_UnloadFW(void) {
1155   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
1156   int32_t status;
1157 
1158   /* check if the handle is not NULL then free the library */
1159   if (pFwHandle != NULL) {
1160     status = dlclose(pFwHandle);
1161     pFwHandle = NULL;
1162 
1163     dlerror(); /* Clear any existing error */
1164     if (status != 0) {
1165       wStatus = NFCSTATUS_FAILED;
1166       NXPLOG_FWDNLD_E("Free library file failed");
1167     }
1168   }
1169 
1170   return wStatus;
1171 }
1172 
1173 /*******************************************************************************
1174 **
1175 ** Function         phDnldNfc_SetDlRspTimeout
1176 **
1177 ** Description      This function sets the timeout value dnld cmd response
1178 **
1179 ** Parameters       timeout : timeout value for dnld response
1180 **
1181 ** Returns          None
1182 **
1183 *******************************************************************************/
phDnldNfc_SetDlRspTimeout(uint16_t timeout)1184 void phDnldNfc_SetDlRspTimeout(uint16_t timeout) {
1185   gpphDnldContext->TimerInfo.rspTimeout = timeout;
1186   NXPLOG_FWDNLD_E("phDnldNfc_SetDlRspTimeout timeout value =%x", timeout);
1187 }
1188 
1189 /*******************************************************************************
1190 **
1191 ** Function         phDnldNfc_SetI2CFragmentLength
1192 **
1193 ** Description      sets the fragment length as per chip being used
1194 **
1195 ** Parameters       None
1196 **
1197 ** Returns          None                -
1198 **
1199 *******************************************************************************/
phDnldNfc_SetI2CFragmentLength()1200 void phDnldNfc_SetI2CFragmentLength() {
1201   if (NULL != gpphDnldContext) {
1202     if (IS_CHIP_TYPE_EQ(sn300u)) {
1203       gpphDnldContext->nxp_i2c_fragment_len = PH_TMLNFC_FRGMENT_SIZE_SN300;
1204     } else if (IS_CHIP_TYPE_GE(sn100u)) {
1205       gpphDnldContext->nxp_i2c_fragment_len = PH_TMLNFC_FRGMENT_SIZE_SNXXX;
1206     } else {
1207       gpphDnldContext->nxp_i2c_fragment_len = PH_TMLNFC_FRGMENT_SIZE_PN557;
1208     }
1209     NXPLOG_FWDNLD_D("fragment len set %u",
1210                     gpphDnldContext->nxp_i2c_fragment_len);
1211   } else {
1212     NXPLOG_FWDNLD_E("Error setting the fragment length");
1213   }
1214   return;
1215 }
1216