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