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