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