1 /* 2 * Copyright (C) 2010 NXP Semiconductors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /*! 18 * =========================================================================== * 19 * * 20 * * 21 * \file phDnldNfc.c * 22 * \brief Download Mgmt Interface Source for the Firmware Download. * 23 * * 24 * * 25 * Project: NFC-FRI-1.1 * 26 * * 27 * $Date: Tue Jun 28 14:25:44 2011 $ * 28 * $Author: ing04880 $ * 29 * $Revision: 1.33 $ * 30 * $Aliases: $ 31 * * 32 * =========================================================================== * 33 */ 34 35 36 /* 37 ################################################################################ 38 ***************************** Header File Inclusion **************************** 39 ################################################################################ 40 */ 41 #include <stdlib.h> 42 #include <unistd.h> 43 #include <phNfcConfig.h> 44 #include <phNfcCompId.h> 45 #include <phNfcIoctlCode.h> 46 #include <phDnldNfc.h> 47 #include <phOsalNfc.h> 48 #include <phOsalNfc_Timer.h> 49 #include <phDal4Nfc.h> 50 #include <utils/Log.h> 51 /* 52 ################################################################################ 53 ****************************** Macro Definitions ******************************* 54 ################################################################################ 55 */ 56 57 #ifndef STATIC 58 #define STATIC static 59 #endif 60 61 #if defined (DNLD_SUMMARY) && !defined (DNLD_TRACE) 62 #define DNLD_TRACE 63 #endif 64 65 /* #if defined(PHDBG_INFO) && defined (PHDBG_CRITICAL_ERROR) */ 66 #if defined(DNLD_TRACE) 67 extern char phOsalNfc_DbgTraceBuffer[]; 68 69 #define MAX_TRACE_BUFFER 0x0410 70 #define Trace_buffer phOsalNfc_DbgTraceBuffer 71 /* #define DNLD_PRINT( str ) phOsalNfc_DbgTrace(str) */ 72 #define DNLD_PRINT( str ) phOsalNfc_DbgString(str) 73 #define DNLD_DEBUG(str, arg) \ 74 { \ 75 snprintf(Trace_buffer,MAX_TRACE_BUFFER,str,arg); \ 76 phOsalNfc_DbgString(Trace_buffer); \ 77 } 78 #define DNLD_PRINT_BUFFER(msg,buf,len) \ 79 { \ 80 snprintf(Trace_buffer,MAX_TRACE_BUFFER,"\n\t %s:",msg); \ 81 phOsalNfc_DbgString(Trace_buffer); \ 82 phOsalNfc_DbgTrace(buf,len); \ 83 phOsalNfc_DbgString("\r"); \ 84 } 85 #else 86 #define DNLD_PRINT( str ) 87 #define DNLD_DEBUG(str, arg) 88 #define DNLD_PRINT_BUFFER(msg,buf,len) 89 #endif 90 91 #define DO_DELAY(period) usleep(period) 92 93 /* delay after SW reset cmd in ms, required on uart for XTAL stability */ 94 #define PHDNLD_DNLD_DELAY 5000 95 //#define PHDNLD_MAX_PACKET 0x0200U /* Max Total Packet Size is 512 */ 96 #define PHDNLD_MAX_PACKET 32U /* Max Total Packet Size is 512 */ 97 #define PHDNLD_DATA_SIZE ((PHDNLD_MAX_PACKET)- 8U) /* 0x01F8U */ 98 /* Max Data Size is 504 */ 99 #define PHDNLD_MIN_PACKET 0x03U /* Minimum Packet Size is 3*/ 100 101 #define DNLD_DEFAULT_RESPONSE_TIMEOUT 0x4000U 102 103 #define NXP_FW_MIN_TX_RX_LEN 0x0AU 104 105 106 #if defined( NXP_FW_MAX_TX_RX_LEN ) && \ 107 ( NXP_FW_MAX_TX_RX_LEN > NXP_FW_MIN_TX_RX_LEN ) 108 109 #define PHDNLD_FW_TX_RX_LEN NXP_FW_MAX_TX_RX_LEN 110 111 #elif !defined( NXP_FW_MAX_TX_RX_LEN ) 112 113 /* To specify the Maximum TX/RX Len */ 114 #define NXP_FW_MAX_TX_RX_LEN 0x200 115 #define PHDNLD_FW_TX_RX_LEN NXP_FW_MAX_TX_RX_LEN 116 117 #else 118 119 #define PHDNLD_FW_TX_RX_LEN NXP_FW_MIN_TX_RX_LEN 120 121 #endif 122 123 #define PHDNLD_FRAME_LEN_SIZE 0x02U 124 #define PHDNLD_ADDR_SIZE 0x03U 125 #define PHDNLD_DATA_LEN_SIZE 0x02U 126 #define PHDNLD_FRAME_DATA_OFFSET 0x03U 127 128 #define DNLD_SM_UNLOCK_MASK 0x01U 129 #define DNLD_TRIM_MASK 0x02U 130 #define DNLD_RESET_MASK 0x04U 131 #define DNLD_VERIFY_MASK 0x08U 132 #define DNLD_CRITICAL_MASK 0x10U 133 134 135 #define NXP_NFC_IMAG_FW_MAX 0x05U 136 137 #define PHDNLD_FW_PATCH_SEC 0x5FU 138 139 #define PHDNLD_PAGE_SIZE 0x80U /* Page Size Configured for 64 Bytes */ 140 141 #define FW_MAX_SECTION 0x15U /* Max Number of Sections */ 142 143 #define DNLD_CRC16_SIZE 0x02U 144 145 #define DNLD_CRC32_SIZE 0x04U 146 147 #define DNLD_CFG_PG_ADDR 0x00008000U 148 #define DNLD_FW_CODE_ADDR 0x00800000U 149 #define DNLD_PATCH_CODE_ADDR 0x00018800U 150 #define DNLD_PATCH_TABLE_ADDR 0x00008200U 151 152 153 /* Raw Command to pass the Data in Download Mode */ 154 #define PHDNLD_CMD_RAW 0x00U 155 /* Command to Reset the Device in Download Mode */ 156 #define PHDNLD_CMD_RESET 0x01U 157 /* Command to Read from the Address specified in Download Mode */ 158 #define PHDNLD_CMD_READ 0x07U 159 #define PHDNLD_CMD_READ_LEN 0x0005U 160 /* Command to write to the Address specified in Download Mode */ 161 #define PHDNLD_CMD_WRITE 0x08U 162 #define PHDNLD_CMD_SEC_WRITE 0x0CU 163 #define PHDNLD_CMD_WRITE_MIN_LEN 0x0005U 164 #define PHDNLD_CMD_WRITE_MAX_LEN PHDNLD_DATA_SIZE 165 /* Command to verify the data written */ 166 #define PHDNLD_CMD_CHECK 0x06U 167 #define PHDNLD_CMD_CHECK_LEN 0x0007U 168 169 /* Command to Lock the */ 170 #define PHDNLD_CMD_LOCK 0x40U 171 #define PHDNLD_CMD_LOCK_LEN 0x0002U 172 173 174 /* Command to set the Host Interface properties */ 175 #define PHDNLD_CMD_SET_HIF 0x09U 176 177 /* Command to Activate the Patches Updated */ 178 #define PHDNLD_CMD_ACTIVATE_PATCH 0x0AU 179 180 /* Command to verify the Integrity of the data written */ 181 #define PHDNLD_CMD_CHECK_INTEGRITY 0x0BU 182 183 /* Command to verify the Integrity of the data written */ 184 #define PHDNLD_CMD_ENCAPSULATE 0x0DU 185 186 #define CHECK_INTEGRITY_RESP_CRC16_LEN 0x03U 187 #define CHECK_INTEGRITY_RESP_CRC32_LEN 0x05U 188 #define CHECK_INTEGRITY_RESP_COMP_LEN 0x10U 189 190 191 /* Success Response to a Command Sent in the Download Mode */ 192 #define PHDNLD_RESP_SUCCESS 0x00U 193 /* Timeout Response to a Command Sent in the Download Mode */ 194 #define PHDNLD_RESP_TIMEOUT 0x01U 195 /* CRC Error Response to a Command Sent in the Download Mode */ 196 #define PHDNLD_RESP_CRC_ERROR 0x02U 197 /* Access Denied Response to a Command Sent in the Download Mode */ 198 #define PHDNLD_RESP_ACCESS_DENIED 0x08U 199 /* PROTOCOL Error Response to a Command Sent in the Download Mode */ 200 #define PHDNLD_RESP_PROTOCOL_ERROR 0x0BU 201 /* Invalid parameter Response to a Command Sent in the Download Mode */ 202 #define PHDNLD_RESP_INVALID_PARAMETER 0x11U 203 /* Command Not Supported Response to a Command Sent in the Download Mode */ 204 #define PHDNLD_RESP_CMD_NOT_SUPPORTED 0x13U 205 /* Length parameter error Response to a Command Sent in the Download Mode */ 206 #define PHDNLD_RESP_INVALID_LENGTH 0x18U 207 /* Checksum Error Response to a Command Sent in the Download Mode */ 208 #define PHDNLD_RESP_CHKSUM_ERROR 0x19U 209 /* Version already uptodate Response to a Command Sent in the Download Mode */ 210 #define PHDNLD_RESP_VERSION_UPTODATE 0x1DU 211 /* Memory operation error during the processing of 212 the Command Frame in the Download Mode */ 213 #define PHDNLD_RESP_MEMORY_UPDATE_ERROR 0x20U 214 /* The Chaining of the Command Frame was Successful in the Download Mode */ 215 #define PHDNLD_RESP_CHAINING_SUCCESS 0x21U 216 /* The Command is not allowed anymore in the Download Mode */ 217 #define PHDNLD_RESP_CMD_NOT_ALLOWED 0xE0U 218 /* The Error during the Chaining the Command Frame in the Download Mode */ 219 #define PHDNLD_RESP_CHAINING_ERROR 0xE6U 220 /* Write Error Response to a Command Sent in the Download Mode */ 221 #define PHDNLD_RESP_WRITE_ERROR 0x74U 222 223 #define PNDNLD_WORD_LEN 0x04U 224 225 #define NXP_MAX_DNLD_RETRY 0x02U 226 227 #define NXP_MAX_SECTION_WRITE 0x05U 228 229 #define NXP_PATCH_VER_INDEX 0x05U 230 231 232 /* 233 ################################################################################ 234 ******************** Enumeration and Structure Definition ********************** 235 ################################################################################ 236 */ 237 238 typedef enum phDnldNfc_eSeqType{ 239 DNLD_SEQ_RESET = 0x00U, 240 DNLD_SEQ_INIT, 241 DNLD_SEQ_RAW, 242 DNLD_SEQ_LOCK, 243 DNLD_SEQ_UNLOCK, 244 DNLD_SEQ_UPDATE, 245 DNLD_SEQ_ROLLBACK, 246 DNLD_SEQ_COMPLETE 247 } phDnldNfc_eSeqType_t; 248 249 typedef enum phDnldNfc_eState 250 { 251 phDnld_Reset_State = 0x00, 252 phDnld_Unlock_State, 253 phDnld_Upgrade_State, 254 phDnld_Verify_State, 255 phDnld_Complete_State, 256 phDnld_Invalid_State 257 }phDnldNfc_eState_t; 258 259 260 typedef enum phDnldNfc_eSeq 261 { 262 phDnld_Reset_Seq = 0x00, 263 phDnld_Activate_Patch, 264 phDnld_Deactivate_Patch, 265 phDnld_Update_Patch, 266 phDnld_Update_Patchtable, 267 phDnld_Lock_System, 268 phDnld_Unlock_System, 269 phDnld_Upgrade_Section, 270 phDnld_Verify_Integrity, 271 phDnld_Verify_Section, 272 phDnld_Complete_Seq, 273 phDnld_Raw_Upgrade, 274 phDnld_Invalid_Seq 275 }phDnldNfc_eSeq_t; 276 277 typedef enum phDnldNfc_eChkCrc{ 278 CHK_INTEGRITY_CONFIG_PAGE_CRC = 0x00U, 279 CHK_INTEGRITY_PATCH_TABLE_CRC = 0x01U, 280 CHK_INTEGRITY_FLASH_CODE_CRC = 0x02U, 281 CHK_INTEGRITY_PATCH_CODE_CRC = 0x03U, 282 CHK_INTEGRITY_COMPLETE_CRC = 0xFFU 283 } phDnldNfc_eChkCrc_t; 284 285 286 287 typedef struct hw_comp_tbl 288 { 289 uint8_t hw_version[3]; 290 uint8_t compatibility; 291 }hw_comp_tbl_t; 292 293 294 typedef struct img_data_hdr 295 { 296 /* Image Identification */ 297 uint32_t img_id; 298 /* Offset of the Data from the header */ 299 uint8_t img_data_offset; 300 /* Number of fimware images available in the img_data */ 301 uint8_t no_of_fw_img; 302 /* Fimware image Padding in the img_data */ 303 uint8_t fw_img_pad[2]; 304 /* HW Compatiblity table for the set of the Hardwares */ 305 hw_comp_tbl_t comp_tbl; 306 /* This data consists of the firmware images required to download */ 307 }img_data_hdr_t; 308 309 310 typedef struct fw_data_hdr 311 { 312 /* The data offset from the firmware header. 313 * Just in case if in future we require to 314 * add some more information. 315 */ 316 uint8_t fw_hdr_len; 317 /* Total size of all the sections which needs to be updated */ 318 uint8_t no_of_sections; 319 uint8_t hw_comp_no; 320 uint8_t fw_patch; 321 uint32_t fw_version; 322 }fw_data_hdr_t; 323 324 325 326 /* This data consists all the sections that needs to be downloaded */ 327 typedef struct section_hdr 328 { 329 uint8_t section_hdr_len; 330 uint8_t section_mem_type; 331 uint8_t section_checksum; 332 uint8_t section_conf; 333 uint32_t section_address; 334 uint32_t section_length; 335 }section_hdr_t; 336 337 typedef struct section_info 338 { 339 section_hdr_t *p_sec_hdr; 340 uint8_t *p_trim_data; 341 /* The section data consist of the Firmware binary required 342 * to be loaded to the particular address. 343 */ 344 uint8_t *p_sec_data; 345 /* The Section checksum to verify the integrity of the section 346 * data. 347 */ 348 uint8_t *p_sec_chksum; 349 /** \internal Index used to refer and process the 350 * Firmware Section Data */ 351 volatile uint32_t section_offset; 352 353 /** \internal Section Read Sequence */ 354 volatile uint8_t section_read; 355 356 /** \internal Section Write Sequence */ 357 volatile uint8_t section_write; 358 359 /** \internal TRIM Write Sequence */ 360 volatile uint8_t trim_write; 361 362 volatile uint8_t sec_verify_retry; 363 364 }section_info_t; 365 366 367 typedef struct phDnldNfc_sParam 368 { 369 uint8_t data_addr[PHDNLD_ADDR_SIZE]; 370 uint8_t data_len[PHDNLD_DATA_LEN_SIZE]; 371 uint8_t data_packet[PHDNLD_DATA_SIZE]; 372 }phDnldNfc_sParam_t; 373 374 typedef struct phDnldNfc_sDataHdr 375 { 376 uint8_t frame_type; 377 uint8_t frame_length[PHDNLD_FRAME_LEN_SIZE]; 378 }phDnldNfc_sData_Hdr_t; 379 380 typedef struct phDnldNfc_sRawHdr 381 { 382 uint8_t frame_type; 383 uint8_t frame_length[PHDNLD_FRAME_LEN_SIZE]; 384 }phDnldNfc_sRawHdr_t; 385 386 typedef struct phDnldNfc_sRawDataHdr 387 { 388 uint8_t data_addr[PHDNLD_ADDR_SIZE]; 389 uint8_t data_len[PHDNLD_DATA_LEN_SIZE]; 390 }phDnldNfc_sRawDataHdr_t; 391 392 typedef struct phDnldNfc_sChkCrc16_Resp 393 { 394 uint8_t Chk_status; 395 uint8_t Chk_Crc16[2]; 396 397 }phDnldNfc_sChkCrc16_Resp_t; 398 399 typedef struct phDnldNfc_sChkCrc32_Resp 400 { 401 uint8_t Chk_status; 402 uint8_t Chk_Crc32[4]; 403 404 }phDnldNfc_sChkCrc32_Resp_t; 405 406 407 typedef struct phDnldNfc_sChkCrcComplete 408 { 409 phDnldNfc_sChkCrc16_Resp_t config_page; 410 phDnldNfc_sChkCrc16_Resp_t patch_table; 411 phDnldNfc_sChkCrc32_Resp_t flash_code; 412 phDnldNfc_sChkCrc32_Resp_t patch_code; 413 }phDnldNfc_sChkCrcComplete_t; 414 415 typedef struct phDnldNfc_sData 416 { 417 uint8_t frame_type; 418 uint8_t frame_length[PHDNLD_FRAME_LEN_SIZE]; 419 union param 420 { 421 phDnldNfc_sParam_t data_param; 422 uint8_t response_data[PHDNLD_MAX_PACKET]; 423 uint8_t cmd_param; 424 }param_info; 425 }phDnldNfc_sData_t; 426 427 #ifdef NXP_NFC_MULTIPLE_FW 428 429 typedef struct phDnldNfc_sFwImageInfo 430 { 431 /** \internal Data Pointer to the Firmware header section of the Firmware */ 432 fw_data_hdr_t *p_fw_hdr; 433 /** \internal Buffer pointer to store the Firmware Section Data */ 434 section_info_t *p_fw_sec; 435 /** \internal Buffer pointer to store the Firmware Raw Data */ 436 uint8_t *p_fw_raw; 437 }phDnldNfc_sFwImageInfo_t; 438 439 #endif /* #ifdef NXP_NFC_MULTIPLE_FW */ 440 441 442 typedef struct phDnldNfc_TxInfo 443 { 444 uint8_t *transmit_frame; 445 446 uint16_t tx_offset; 447 448 /** \internal Remaining amount of data to be sent */ 449 uint16_t tx_len; 450 451 uint16_t tx_total; 452 453 /** \internal Chain information for the data to be sent */ 454 uint8_t tx_chain; 455 456 }phDnldNfc_TxInfo_t; 457 458 459 typedef struct phDnldNfc_RxInfo 460 { 461 /** \internal Total length of the received buffer */ 462 uint16_t rx_total; 463 /** \internal Chain information of the received buffer */ 464 uint16_t rx_chain; 465 /** \internal Remaining Data information to be read to complete the 466 * Data Information. 467 */ 468 uint16_t rx_remain; 469 470 /** \internal Buffer to Send the Raw Data Frame */ 471 uint8_t raw_buffer_data[PHDNLD_MAX_PACKET 472 + PHDNLD_PAGE_SIZE]; 473 }phDnldNfc_RxInfo_t; 474 475 476 typedef struct phDnldNfc_sContext 477 { 478 /** \internal Structure to store the lower interface operations */ 479 phNfc_sLowerIF_t lower_interface; 480 481 phNfc_sData_t *p_fw_version; 482 483 /** \internal Pointer to the Hardware Reference Sturcture */ 484 phHal_sHwReference_t *p_hw_ref; 485 486 /** \internal Pointer to the upper layer notification callback function */ 487 pphNfcIF_Notification_CB_t p_upper_notify; 488 /** \internal Pointer to the upper layer context */ 489 void *p_upper_context; 490 491 /** \internal Timer ID for the Download Abort */ 492 uint32_t timer_id; 493 /** \internal Internal Download for the Download Abort */ 494 uint32_t dnld_timeout; 495 /** \internal Data Pointer to the Image header section of the Firmware */ 496 img_data_hdr_t *p_img_hdr; 497 498 #ifdef NXP_NFC_MULTIPLE_FW 499 /** \internal Data Pointer to the Firmware Image Information */ 500 phDnldNfc_sFwImageInfo_t *p_img_info; 501 #endif /* #ifdef NXP_NFC_MULTIPLE_FW */ 502 503 /** \internal Data Pointer to the Firmware header section of the Firmware */ 504 fw_data_hdr_t *p_fw_hdr; 505 /** \internal Buffer pointer to store the Firmware Data */ 506 section_info_t *p_fw_sec; 507 /** \internal Buffer pointer to store the Firmware Raw Data */ 508 uint8_t *p_fw_raw; 509 510 /** \internal Previous Download Size */ 511 uint32_t prev_dnld_size; 512 513 /** \internal Single Data Block to download the Firmware */ 514 uint8_t dnld_data[PHDNLD_MAX_PACKET 515 + PHDNLD_PAGE_SIZE]; 516 /** \internal Index used to refer and process the Download Data */ 517 volatile uint32_t dnld_index; 518 519 /** \internal Response Data to process the response */ 520 phDnldNfc_sData_t dnld_resp; 521 522 /** \internal Previously downloaded data stored 523 * to compare the written data */ 524 phNfc_sData_t dnld_store; 525 526 /** \internal Previously downloaded trimmed data stored 527 * to compare the written data */ 528 phNfc_sData_t trim_store; 529 530 uint8_t *p_resp_buffer; 531 532 phDnldNfc_sChkCrcComplete_t chk_integrity_crc; 533 534 phDnldNfc_eChkCrc_t chk_integrity_param; 535 536 #define NXP_FW_SW_VMID_TRIM 537 #ifdef NXP_FW_SW_VMID_TRIM 538 539 #define NXP_FW_VMID_TRIM_CHK_ADDR 0x0000813DU 540 #define NXP_FW_VMID_CARD_MODE_ADDR 0x00009931U 541 #define NXP_FW_VMID_RD_MODE_ADDR 0x00009981U 542 543 uint8_t vmid_trim_update; 544 #endif /* #ifdef NXP_FW_SW_VMID_TRIM */ 545 546 uint8_t cur_frame_info; 547 548 uint8_t raw_mode_upgrade; 549 550 uint8_t *p_patch_table_crc; 551 552 uint8_t *p_flash_code_crc; 553 554 uint8_t *p_patch_code_crc; 555 556 uint16_t resp_length; 557 558 /** \internal Current FW Section in Process */ 559 volatile uint8_t section_index; 560 561 /** \internal Previous Command sent */ 562 volatile uint8_t prev_cmd; 563 564 uint8_t dnld_retry; 565 566 /** \internal Current Download State */ 567 volatile uint8_t cur_dnld_state; 568 /** \internal Next Download State */ 569 volatile uint8_t next_dnld_state; 570 571 /** \internal Current step in Download Sequence */ 572 volatile uint8_t cur_dnld_seq; 573 /** \internal Next step in Download Sequence */ 574 volatile uint8_t next_dnld_seq; 575 576 /* \internal Data Transmit information */ 577 phDnldNfc_TxInfo_t tx_info; 578 579 /* \internal Data Receive information */ 580 phDnldNfc_RxInfo_t rx_info; 581 582 583 }phDnldNfc_sContext_t; 584 585 586 /* 587 ################################################################################ 588 ******************** Global and Static Variables Definition ******************** 589 ################################################################################ 590 */ 591 592 #ifndef NFC_TIMER_CONTEXT 593 static phDnldNfc_sContext_t *gpphDnldContext = NULL; 594 #endif 595 596 #ifdef NXP_FW_DNLD_CHECK_PHASE 597 598 #define NXP_FW_DNLD_COMPLETE_PHASE 0x00U 599 #define NXP_FW_DNLD_SYSTEM_PHASE 0x01U 600 #define NXP_FW_DNLD_CFG_PHASE 0x02U 601 #define NXP_FW_DNLD_DATA_PHASE 0x03U 602 #define NXP_FW_DNLD_RAW_PHASE 0x04U 603 #define NXP_FW_DNLD_INVALID_PHASE 0xFFU 604 605 static uint8_t gphDnldPhase = NXP_FW_DNLD_COMPLETE_PHASE; 606 607 #endif /* #ifdef NXP_FW_DNLD_CHECK_PHASE */ 608 609 /**/ 610 611 /* 612 *************************** Static Function Declaration ************************** 613 */ 614 615 STATIC 616 NFCSTATUS 617 phDnldNfc_Send_Command( 618 phDnldNfc_sContext_t *psDnldContext, 619 void *pHwRef, 620 uint8_t cmd, 621 void *params, 622 uint16_t param_length 623 ); 624 625 static 626 NFCSTATUS 627 phDnldNfc_Process_FW( 628 phDnldNfc_sContext_t *psDnldContext, 629 phHal_sHwReference_t *pHwRef 630 #ifdef NXP_FW_PARAM 631 , 632 uint8_t *nxp_nfc_fw, 633 uint32_t fw_length 634 #endif 635 ); 636 637 STATIC 638 void 639 phDnldNfc_Send_Complete ( 640 void *psContext, 641 void *pHwRef, 642 phNfc_sTransactionInfo_t *pInfo 643 ); 644 645 STATIC 646 void 647 phDnldNfc_Receive_Complete ( 648 void *psContext, 649 void *pHwRef, 650 phNfc_sTransactionInfo_t *pInfo 651 ); 652 653 STATIC 654 NFCSTATUS 655 phDnldNfc_Process_Response( 656 phDnldNfc_sContext_t *psDnldContext, 657 void *pHwRef, 658 void *pdata, 659 uint16_t length 660 ); 661 662 663 static 664 NFCSTATUS 665 phDnldNfc_Resume( 666 phDnldNfc_sContext_t *psDnldContext, 667 void *pHwRef, 668 void *pdata, 669 uint16_t length 670 ); 671 672 static 673 NFCSTATUS 674 phDnldNfc_Resume_Write( 675 phDnldNfc_sContext_t *psDnldContext, 676 void *pHwRef 677 ); 678 679 static 680 NFCSTATUS 681 phDnldNfc_Process_Write( 682 phDnldNfc_sContext_t *psDnldContext, 683 void *pHwRef, 684 section_info_t *p_sec_info, 685 uint32_t *p_sec_offset 686 ); 687 688 static 689 NFCSTATUS 690 phDnldNfc_Sequence( 691 phDnldNfc_sContext_t *psDnldContext, 692 void *pHwRef, 693 void *pdata, 694 uint16_t length 695 ); 696 697 static 698 NFCSTATUS 699 phDnldNfc_Upgrade_Sequence( 700 phDnldNfc_sContext_t *psDnldContext, 701 void *pHwRef, 702 void *pdata, 703 uint16_t length 704 ); 705 706 STATIC 707 NFCSTATUS 708 phDnldNfc_Receive( 709 void *psContext, 710 void *pHwRef, 711 uint8_t *pdata, 712 uint16_t length 713 ); 714 715 716 STATIC 717 NFCSTATUS 718 phDnldNfc_Send ( 719 void *psContext, 720 void *pHwRef, 721 uint8_t *pdata, 722 uint16_t length 723 ); 724 725 STATIC 726 NFCSTATUS 727 phDnldNfc_Set_Seq( 728 phDnldNfc_sContext_t *psDnldContext, 729 phDnldNfc_eSeqType_t seq_type 730 ); 731 732 static 733 void 734 phDnldNfc_Notify( 735 pphNfcIF_Notification_CB_t p_upper_notify, 736 void *p_upper_context, 737 void *pHwRef, 738 uint8_t type, 739 void *pInfo 740 ); 741 742 STATIC 743 NFCSTATUS 744 phDnldNfc_Allocate_Resource ( 745 void **ppBuffer, 746 uint16_t size 747 ); 748 749 STATIC 750 void 751 phDnldNfc_Release_Resources ( 752 phDnldNfc_sContext_t **ppsDnldContext 753 ); 754 755 STATIC 756 void 757 phDnldNfc_Release_Lower( 758 phDnldNfc_sContext_t *psDnldContext, 759 void *pHwRef 760 ); 761 762 763 static 764 NFCSTATUS 765 phDnldNfc_Read( 766 phDnldNfc_sContext_t *psDnldContext, 767 void *pHwRef, 768 section_info_t *p_sec_info 769 ); 770 771 STATIC 772 void 773 phDnldNfc_Abort ( 774 uint32_t abort_id 775 #ifdef NFC_TIMER_CONTEXT 776 , void *dnld_cntxt 777 #endif 778 ); 779 780 781 #ifdef DNLD_CRC_CALC 782 783 static 784 void 785 phDnldNfc_UpdateCrc16( 786 uint8_t crcByte, 787 uint16_t *pCrc 788 ); 789 790 STATIC 791 uint16_t 792 phDnldNfc_ComputeCrc16( 793 uint8_t *pData, 794 uint16_t length 795 ); 796 797 798 /* 799 *************************** Function Definitions ************************** 800 */ 801 #define CRC32_POLYNOMIAL 0xEDB88320L 802 803 static uint32_t CRC32Table[0x100]; 804 805 void BuildCRCTable() 806 { 807 unsigned long crc; 808 uint8_t i = 0, j = 0; 809 810 for ( i = 0; i <= 0xFF ; i++ ) 811 { 812 crc = i; 813 for ( j = 8 ; j> 0; j-- ) 814 { 815 if ( crc & 1 ) 816 { 817 crc = ( crc>> 1 ) ^ CRC32_POLYNOMIAL; 818 } 819 else 820 { 821 crc>>= 1; 822 } 823 } 824 CRC32Table[ i ] = crc; 825 } 826 } 827 828 /* 829 * This routine calculates the CRC for a block of data using the 830 * table lookup method. It accepts an original value for the crc, 831 * and returns the updated value. 832 */ 833 834 uint32_t CalculateCRC32( void *buffer , uint32_t count, uint32_t crc ) 835 { 836 uint8_t *p; 837 uint32_t temp1; 838 uint32_t temp2; 839 840 p = (uint8_t *) buffer; 841 while ( count-- != 0 ) { 842 temp1 = ( crc>> 8 ) & 0x00FFFFFFL; 843 temp2 = CRC32Table[ ( (int) crc ^ *p++ ) & 0xff ]; 844 crc = temp1 ^ temp2; 845 } 846 return( crc ); 847 } 848 849 850 static 851 void 852 phDnldNfc_UpdateCrc16( 853 uint8_t crcByte, 854 uint16_t *pCrc 855 ) 856 { 857 crcByte = (crcByte ^ (uint8_t)((*pCrc) & 0x00FF)); 858 crcByte = (crcByte ^ (uint8_t)(crcByte << 4)); 859 *pCrc = (*pCrc >> 8) ^ ((uint16_t)crcByte << 8) ^ 860 ((uint16_t)crcByte << 3) ^ 861 ((uint16_t)crcByte >> 4); 862 } 863 864 865 STATIC 866 uint16_t 867 phDnldNfc_ComputeCrc16( 868 uint8_t *pData, 869 uint16_t length 870 ) 871 { 872 uint8_t crc_byte = 0; 873 uint16_t index = 0; 874 uint16_t crc = 0; 875 876 #ifdef CRC_A 877 crc = 0x6363; /* ITU-V.41 */ 878 #else 879 crc = 0xFFFF; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */ 880 #endif /* #ifdef CRC_A */ 881 882 do 883 { 884 crc_byte = pData[index]; 885 phDnldNfc_UpdateCrc16(crc_byte, &crc); 886 index++; 887 } while (index < length); 888 889 #ifndef INVERT_CRC 890 crc = ~crc; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */ 891 #endif /* #ifndef INVERT_CRC */ 892 893 /* *pCrc1 = (uint8_t) (crc & BYTE_MASK); 894 *pCrc2 = (uint8_t) ((crc >> 8) & BYTE_MASK); */ 895 return crc ; 896 } 897 898 #endif /* #ifdef DNLD_CRC_CALC */ 899 900 901 /*! 902 * \brief Allocation of the Download Interface resources. 903 * 904 * This function releases and frees all the resources used by Download Mode 905 * Feature. 906 */ 907 908 STATIC 909 NFCSTATUS 910 phDnldNfc_Allocate_Resource ( 911 void **ppBuffer, 912 uint16_t size 913 ) 914 { 915 NFCSTATUS status = NFCSTATUS_SUCCESS; 916 917 *ppBuffer = (void *) phOsalNfc_GetMemory(size); 918 if( *ppBuffer != NULL ) 919 { 920 (void )memset(((void *)*ppBuffer), 0, 921 size); 922 } 923 else 924 { 925 *ppBuffer = NULL; 926 status = PHNFCSTVAL(CID_NFC_DNLD, 927 NFCSTATUS_INSUFFICIENT_RESOURCES); 928 } 929 return status; 930 } 931 932 933 /*! 934 * \brief Release of the Download Interface resources. 935 * 936 * This function releases and frees all the resources used by Download layer. 937 */ 938 939 STATIC 940 void 941 phDnldNfc_Release_Resources ( 942 phDnldNfc_sContext_t **ppsDnldContext 943 ) 944 { 945 946 if(NULL != (*ppsDnldContext)->p_resp_buffer) 947 { 948 phOsalNfc_FreeMemory((*ppsDnldContext)->p_resp_buffer); 949 (*ppsDnldContext)->p_resp_buffer = NULL; 950 } 951 if(NULL != (*ppsDnldContext)->dnld_store.buffer) 952 { 953 phOsalNfc_FreeMemory((*ppsDnldContext)->dnld_store.buffer); 954 (*ppsDnldContext)->dnld_store.buffer = NULL; 955 (*ppsDnldContext)->dnld_store.length = 0; 956 } 957 if(NULL != (*ppsDnldContext)->trim_store.buffer) 958 { 959 phOsalNfc_FreeMemory((*ppsDnldContext)->trim_store.buffer); 960 (*ppsDnldContext)->trim_store.buffer = NULL; 961 (*ppsDnldContext)->trim_store.length = 0; 962 } 963 if(NULL != (*ppsDnldContext)->p_fw_sec) 964 { 965 phOsalNfc_FreeMemory((*ppsDnldContext)->p_fw_sec); 966 (*ppsDnldContext)->p_fw_sec = NULL; 967 } 968 if ( NXP_INVALID_TIMER_ID != (*ppsDnldContext)->timer_id ) 969 { 970 phOsalNfc_Timer_Stop((*ppsDnldContext)->timer_id ); 971 phOsalNfc_Timer_Delete((*ppsDnldContext)->timer_id ); 972 (*ppsDnldContext)->timer_id = NXP_INVALID_TIMER_ID; 973 } 974 975 phOsalNfc_FreeMemory((*ppsDnldContext)); 976 (*ppsDnldContext) = NULL; 977 978 return ; 979 } 980 981 982 STATIC 983 void 984 phDnldNfc_Release_Lower( 985 phDnldNfc_sContext_t *psDnldContext, 986 void *pHwRef 987 ) 988 { 989 phNfc_sLowerIF_t *plower_if = 990 &(psDnldContext->lower_interface); 991 NFCSTATUS status = NFCSTATUS_SUCCESS; 992 993 PHNFC_UNUSED_VARIABLE(status); 994 995 if(NULL != plower_if->release) 996 { 997 #ifdef DNLD_LOWER_RELEASE 998 status = plower_if->release((void *)plower_if->pcontext, 999 (void *)pHwRef); 1000 #else 1001 PHNFC_UNUSED_VARIABLE(pHwRef); 1002 1003 #endif 1004 (void)memset((void *)plower_if, 1005 0, sizeof(phNfc_sLowerIF_t)); 1006 DNLD_DEBUG(" FW_DNLD: Releasing the Lower Layer Resources: Status = %02X\n" 1007 ,status); 1008 } 1009 1010 return; 1011 } 1012 1013 1014 1015 static 1016 void 1017 phDnldNfc_Notify( 1018 pphNfcIF_Notification_CB_t p_upper_notify, 1019 void *p_upper_context, 1020 void *pHwRef, 1021 uint8_t type, 1022 void *pInfo 1023 ) 1024 { 1025 if( ( NULL != p_upper_notify) ) 1026 { 1027 /* Notify the to the Upper Layer */ 1028 (p_upper_notify)(p_upper_context, pHwRef, type, pInfo); 1029 } 1030 } 1031 1032 1033 STATIC 1034 NFCSTATUS 1035 phDnldNfc_Set_Seq( 1036 phDnldNfc_sContext_t *psDnldContext, 1037 phDnldNfc_eSeqType_t seq_type 1038 ) 1039 { 1040 NFCSTATUS status = NFCSTATUS_SUCCESS; 1041 static uint8_t prev_temp_state = 0; 1042 static uint8_t prev_temp_seq = 1043 (uint8_t) phDnld_Activate_Patch; 1044 1045 switch(seq_type) 1046 { 1047 case DNLD_SEQ_RESET: 1048 case DNLD_SEQ_INIT: 1049 { 1050 psDnldContext->cur_dnld_state = 1051 (uint8_t) phDnld_Reset_State; 1052 psDnldContext->next_dnld_state = 1053 (uint8_t)phDnld_Upgrade_State; 1054 psDnldContext->cur_dnld_seq = 1055 (uint8_t)phDnld_Upgrade_Section; 1056 psDnldContext->next_dnld_seq = 1057 psDnldContext->cur_dnld_seq; 1058 break; 1059 } 1060 case DNLD_SEQ_RAW: 1061 { 1062 psDnldContext->cur_dnld_state = 1063 (uint8_t) phDnld_Reset_State; 1064 psDnldContext->next_dnld_state = 1065 (uint8_t)phDnld_Upgrade_State; 1066 psDnldContext->cur_dnld_seq = 1067 (uint8_t)phDnld_Raw_Upgrade; 1068 psDnldContext->next_dnld_seq = 1069 psDnldContext->cur_dnld_seq; 1070 break; 1071 } 1072 case DNLD_SEQ_UNLOCK: 1073 { 1074 psDnldContext->cur_dnld_state = 1075 (uint8_t) phDnld_Reset_State; 1076 1077 #ifdef NXP_FW_DNLD_CHECK_PHASE 1078 if( NXP_FW_DNLD_SYSTEM_PHASE < gphDnldPhase ) 1079 { 1080 psDnldContext->next_dnld_state = 1081 (uint8_t)phDnld_Upgrade_State; 1082 psDnldContext->cur_dnld_seq = 1083 (uint8_t)phDnld_Upgrade_Section; 1084 } 1085 else 1086 #endif /* NXP_FW_DNLD_CHECK_PHASE */ 1087 { 1088 psDnldContext->next_dnld_state = 1089 (uint8_t) phDnld_Unlock_State; 1090 psDnldContext->cur_dnld_seq = 1091 (uint8_t) phDnld_Activate_Patch; 1092 } 1093 psDnldContext->next_dnld_seq = 1094 psDnldContext->cur_dnld_seq; 1095 break; 1096 } 1097 case DNLD_SEQ_LOCK: 1098 { 1099 psDnldContext->cur_dnld_state = 1100 (uint8_t) phDnld_Reset_State; 1101 psDnldContext->next_dnld_state = 1102 (uint8_t) phDnld_Reset_State; 1103 psDnldContext->cur_dnld_seq = 1104 (uint8_t) phDnld_Lock_System; 1105 psDnldContext->next_dnld_seq = 1106 psDnldContext->cur_dnld_seq; 1107 break; 1108 } 1109 case DNLD_SEQ_UPDATE: 1110 { 1111 prev_temp_state = (uint8_t) psDnldContext->cur_dnld_state; 1112 psDnldContext->cur_dnld_state = 1113 psDnldContext->next_dnld_state; 1114 /* psDnldContext->next_dnld_state = 1115 (uint8_t)phDnld_Invalid_State ; */ 1116 prev_temp_seq = (uint8_t) psDnldContext->cur_dnld_seq; 1117 psDnldContext->cur_dnld_seq = 1118 psDnldContext->next_dnld_seq; 1119 break; 1120 } 1121 case DNLD_SEQ_ROLLBACK: 1122 { 1123 psDnldContext->cur_dnld_seq = (uint8_t) prev_temp_seq; 1124 psDnldContext->next_dnld_seq = 1125 (uint8_t)phDnld_Invalid_Seq ; 1126 prev_temp_seq = 0; 1127 1128 psDnldContext->cur_dnld_state = (uint8_t) prev_temp_state; 1129 /* psDnldContext->next_dnld_state = 1130 (uint8_t)phDnld_Invalid_State ; */ 1131 prev_temp_state = 0; 1132 break; 1133 } 1134 case DNLD_SEQ_COMPLETE: 1135 { 1136 psDnldContext->cur_dnld_state = 1137 (uint8_t) phDnld_Reset_State; 1138 psDnldContext->next_dnld_state = 1139 (uint8_t) phDnld_Verify_State; 1140 psDnldContext->cur_dnld_seq = 1141 (uint8_t) phDnld_Verify_Integrity; 1142 psDnldContext->next_dnld_seq = 1143 psDnldContext->cur_dnld_seq ; 1144 break; 1145 } 1146 default: 1147 { 1148 break; 1149 } 1150 } 1151 1152 return status; 1153 } 1154 1155 1156 1157 /*! 1158 * \brief Sends the data the corresponding peripheral device. 1159 * 1160 * This function sends the Download data to the connected NFC Pheripheral device 1161 */ 1162 1163 1164 STATIC 1165 NFCSTATUS 1166 phDnldNfc_Send ( 1167 void *psContext, 1168 void *pHwRef, 1169 uint8_t *pdata, 1170 uint16_t length 1171 ) 1172 { 1173 phDnldNfc_sContext_t *psDnldContext= (phDnldNfc_sContext_t *)psContext; 1174 NFCSTATUS status = NFCSTATUS_SUCCESS; 1175 1176 phNfc_sLowerIF_t *plower_if = &(psDnldContext->lower_interface); 1177 1178 if( (NULL != plower_if) 1179 && (NULL != plower_if->send) 1180 ) 1181 { 1182 #ifndef DNLD_SUMMARY 1183 DNLD_PRINT_BUFFER("Send Buffer",pdata,length); 1184 #endif 1185 status = plower_if->send((void *)plower_if->pcontext, 1186 (void *)pHwRef, pdata, length); 1187 1188 #if defined(FW_DOWNLOAD_TIMER) && \ 1189 (FW_DOWNLOAD_TIMER == 2) 1190 if ( 1191 (NFCSTATUS_PENDING == status) 1192 && ( NXP_INVALID_TIMER_ID != psDnldContext->timer_id ) 1193 ) 1194 { 1195 psDnldContext->dnld_timeout = NXP_DNLD_COMPLETE_TIMEOUT; 1196 1197 if ( psDnldContext->dnld_timeout 1198 < DNLD_DEFAULT_RESPONSE_TIMEOUT) 1199 { 1200 psDnldContext->dnld_timeout 1201 = DNLD_DEFAULT_RESPONSE_TIMEOUT; 1202 } 1203 /* Start the Download Timer */ 1204 phOsalNfc_Timer_Start( psDnldContext->timer_id, 1205 psDnldContext->dnld_timeout, 1206 (ppCallBck_t) phDnldNfc_Abort 1207 #ifdef NFC_TIMER_CONTEXT 1208 , (void *) psDnldContext 1209 #endif 1210 ); 1211 1212 DNLD_DEBUG(" DNLD : Timer %X Started ", psDnldContext->timer_id); 1213 DNLD_DEBUG(" \t\t With %U Timeout \n", psDnldContext->dnld_timeout); 1214 } 1215 1216 #endif /* (NXP_NFC_DNLD_TIMER == 1) */ 1217 } 1218 1219 return status; 1220 } 1221 1222 1223 /*! 1224 * \brief Receives the Download Mode Response from the corresponding peripheral device. 1225 * 1226 * This function receives the Download Command Response to the connected NFC 1227 * Pheripheral device. 1228 */ 1229 1230 STATIC 1231 NFCSTATUS 1232 phDnldNfc_Receive( 1233 void *psContext, 1234 void *pHwRef, 1235 uint8_t *pdata, 1236 uint16_t length 1237 ) 1238 { 1239 phDnldNfc_sContext_t *psDnldContext= (phDnldNfc_sContext_t *)psContext; 1240 phNfc_sLowerIF_t *plower_if = NULL ; 1241 NFCSTATUS status = NFCSTATUS_SUCCESS; 1242 1243 if(NULL == psDnldContext ) 1244 { 1245 status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); 1246 } 1247 else 1248 { 1249 plower_if = &(psDnldContext->lower_interface); 1250 1251 if( (NULL != plower_if) 1252 && (NULL != plower_if->receive) 1253 ) 1254 { 1255 status = plower_if->receive((void *)plower_if->pcontext, 1256 (void *)pHwRef, pdata, length); 1257 } 1258 } 1259 return status; 1260 } 1261 1262 1263 static 1264 NFCSTATUS 1265 phDnldNfc_Read( 1266 phDnldNfc_sContext_t *psDnldContext, 1267 void *pHwRef, 1268 section_info_t *p_sec_info 1269 ) 1270 { 1271 NFCSTATUS status = NFCSTATUS_SUCCESS; 1272 phDnldNfc_sData_t *p_dnld_data = 1273 (phDnldNfc_sData_t *)psDnldContext->dnld_data; 1274 phDnldNfc_sParam_t *p_data_param = 1275 &p_dnld_data->param_info.data_param; 1276 uint32_t read_addr = (p_sec_info->p_sec_hdr->section_address 1277 + p_sec_info->section_offset); 1278 static unsigned sec_type = 0; 1279 uint8_t i = 0; 1280 uint16_t read_size = 0 ; 1281 1282 sec_type = (unsigned int)p_sec_info->p_sec_hdr->section_mem_type; 1283 1284 if( ( FALSE == p_sec_info->section_read ) 1285 && ((sec_type & DNLD_TRIM_MASK)) 1286 && (FALSE == p_sec_info->trim_write) ) 1287 { 1288 read_size = (uint16_t) p_sec_info->p_sec_hdr->section_length; 1289 DNLD_DEBUG(" FW_DNLD: Section Read = %X \n", read_size); 1290 } 1291 else 1292 { 1293 if (( FALSE == p_sec_info->section_read ) 1294 && ((sec_type & DNLD_VERIFY_MASK)) 1295 ) 1296 { 1297 read_size = (uint16_t)(psDnldContext->prev_dnld_size ); 1298 DNLD_DEBUG(" FW_DNLD: Section Read = %X \n", read_size); 1299 } 1300 else if( ( TRUE == p_sec_info->section_read ) 1301 && ( TRUE == p_sec_info->section_write ) 1302 ) 1303 { 1304 /*Already Read the Data Hence Ignore the Read */ 1305 DNLD_DEBUG(" FW_DNLD: Already Read, Read Ignored, read_size = %X \n", read_size); 1306 } 1307 else 1308 { 1309 /* Ignore the Read */ 1310 DNLD_DEBUG(" FW_DNLD: Section Read Status = %X \n", p_sec_info->section_read); 1311 DNLD_DEBUG(" FW_DNLD: Section Write Status = %X \n", p_sec_info->section_write); 1312 DNLD_DEBUG(" FW_DNLD: No Read Required, Read_size = %X \n", read_size); 1313 } 1314 } 1315 1316 if (read_size != 0) 1317 { 1318 1319 read_size = (uint16_t)((PHDNLD_DATA_SIZE >= read_size)? 1320 read_size: PHDNLD_DATA_SIZE); 1321 1322 p_dnld_data->frame_length[i] = (uint8_t)0; 1323 /* Update the LSB of the Data and the Address Parameter*/ 1324 p_data_param->data_addr[i] = (uint8_t)((read_addr >> 1325 (BYTE_SIZE + BYTE_SIZE)) & BYTE_MASK); 1326 p_data_param->data_len[i] = (uint8_t)((read_size >> 1327 BYTE_SIZE) & BYTE_MASK); 1328 i++; 1329 1330 p_dnld_data->frame_length[i] = (uint8_t) 1331 ( PHDNLD_CMD_READ_LEN & BYTE_MASK); 1332 /* Update the 2nd byte of the Data and the Address Parameter*/ 1333 p_data_param->data_addr[i] = (uint8_t)((read_addr >> 1334 BYTE_SIZE) & BYTE_MASK); 1335 p_data_param->data_len[i] = (uint8_t) (read_size & BYTE_MASK); 1336 i++; 1337 1338 /* Update the 3rd byte of the the Address Parameter*/ 1339 p_data_param->data_addr[i] = (uint8_t)(read_addr & BYTE_MASK); 1340 1341 status = phDnldNfc_Send_Command( psDnldContext, pHwRef, 1342 PHDNLD_CMD_READ, NULL , 0 ); 1343 1344 if ( NFCSTATUS_PENDING == status ) 1345 { 1346 p_sec_info->section_read = TRUE ; 1347 psDnldContext->next_dnld_state = phDnld_Upgrade_State; 1348 DNLD_DEBUG(" FW_DNLD: Memory Read at Address %X : ", read_addr); 1349 DNLD_DEBUG(" of Size %X \n", read_size); 1350 } 1351 1352 } 1353 return status; 1354 } 1355 1356 1357 1358 static 1359 NFCSTATUS 1360 phDnldNfc_Process_Write( 1361 phDnldNfc_sContext_t *psDnldContext, 1362 void *pHwRef, 1363 section_info_t *p_sec_info, 1364 uint32_t *p_sec_offset 1365 ) 1366 { 1367 NFCSTATUS status = NFCSTATUS_SUCCESS; 1368 phDnldNfc_sData_t *p_dnld_data = 1369 (phDnldNfc_sData_t *)psDnldContext->dnld_data; 1370 phDnldNfc_sParam_t *dnld_data = 1371 &p_dnld_data->param_info.data_param; 1372 uint8_t *p_sm_trim_data = (uint8_t *)psDnldContext-> 1373 dnld_resp.param_info.response_data; 1374 uint32_t dnld_addr = 0; 1375 #ifdef NXP_FW_SW_VMID_TRIM 1376 uint32_t trim_addr = 0; 1377 #endif /* #ifdef NXP_FW_SW_VMID_TRIM */ 1378 static unsigned sec_type = 0; 1379 uint8_t i = 0; 1380 uint16_t dnld_size = 0; 1381 int cmp_val = 0x00; 1382 1383 1384 sec_type = (unsigned int)p_sec_info->p_sec_hdr->section_mem_type; 1385 1386 status = phDnldNfc_Read(psDnldContext, pHwRef, p_sec_info); 1387 if( NFCSTATUS_PENDING != status ) 1388 { 1389 if( (TRUE == p_sec_info->trim_write) 1390 && (TRUE == p_sec_info->section_read) 1391 && ((sec_type & DNLD_VERIFY_MASK)) 1392 ) 1393 { 1394 if(NULL != psDnldContext->trim_store.buffer) 1395 { 1396 uint32_t trim_cmp_size = psDnldContext->prev_dnld_size; 1397 1398 if( p_sec_info->p_sec_hdr->section_address 1399 < (DNLD_CFG_PG_ADDR + PHDNLD_PAGE_SIZE) ) 1400 { 1401 trim_cmp_size = trim_cmp_size - 2; 1402 } 1403 1404 /* Below Comparison fails due to the checksum */ 1405 cmp_val = phOsalNfc_MemCompare( 1406 psDnldContext->trim_store.buffer, 1407 &psDnldContext->dnld_resp. 1408 param_info.response_data[0] 1409 ,trim_cmp_size); 1410 DNLD_DEBUG(" FW_DNLD: %X Bytes Trim Write Complete ", 1411 psDnldContext->prev_dnld_size); 1412 DNLD_DEBUG(" Comparison Status %X\n", cmp_val); 1413 } 1414 p_sec_info->trim_write = FALSE; 1415 DNLD_DEBUG(" FW_DNLD: TRIMMED %X Bytes Write Complete\n", psDnldContext->prev_dnld_size); 1416 } 1417 else 1418 { 1419 if((NULL != psDnldContext->dnld_store.buffer) 1420 && ((sec_type & DNLD_VERIFY_MASK)) 1421 && (TRUE == p_sec_info->section_write) 1422 && (TRUE == p_sec_info->section_read) 1423 ) 1424 { 1425 cmp_val = phOsalNfc_MemCompare( 1426 psDnldContext->dnld_store.buffer, 1427 &psDnldContext->dnld_resp. 1428 param_info.response_data[0] 1429 ,psDnldContext->dnld_store.length); 1430 p_sec_info->section_read = FALSE; 1431 p_sec_info->section_write = FALSE; 1432 DNLD_DEBUG(" FW_DNLD: %X Bytes Write Complete ", 1433 psDnldContext->dnld_store.length); 1434 DNLD_DEBUG(" Comparison Status %X\n", cmp_val); 1435 } 1436 else 1437 { 1438 if(( TRUE == p_sec_info->section_write) 1439 && ( FALSE == p_sec_info->section_read) 1440 ) 1441 { 1442 p_sec_info->section_write = FALSE; 1443 } 1444 } 1445 /* p_sec_info->section_read = FALSE; */ 1446 } 1447 1448 if (( 0 == psDnldContext->dnld_retry ) 1449 && (0 == cmp_val) 1450 ) 1451 { 1452 p_sec_info->sec_verify_retry = 0; 1453 p_sec_info->section_offset = p_sec_info->section_offset + 1454 psDnldContext->prev_dnld_size; 1455 psDnldContext->prev_dnld_size = 0; 1456 DNLD_DEBUG(" FW_DNLD: Memory Write Retry - %X \n", 1457 psDnldContext->dnld_retry); 1458 } 1459 else 1460 { 1461 p_sec_info->sec_verify_retry++; 1462 DNLD_DEBUG(" FW_DNLD: Memory Verification Failed, Retry = %X \n", 1463 p_sec_info->sec_verify_retry); 1464 } 1465 1466 if( p_sec_info->sec_verify_retry < NXP_MAX_SECTION_WRITE ) 1467 { 1468 1469 dnld_addr = (p_sec_info->p_sec_hdr->section_address + *p_sec_offset); 1470 dnld_size = (uint16_t)(p_sec_info->p_sec_hdr->section_length 1471 - *p_sec_offset); 1472 } 1473 else 1474 { 1475 status = NFCSTATUS_FAILED; 1476 DNLD_DEBUG(" FW_DNLD: Memory Verification - Maximum Limit, Retry = %X \n", 1477 p_sec_info->sec_verify_retry); 1478 } 1479 } 1480 1481 1482 if (dnld_size != 0) 1483 { 1484 1485 dnld_size = (uint16_t)((PHDNLD_DATA_SIZE >= dnld_size)? 1486 dnld_size: PHDNLD_DATA_SIZE); 1487 1488 /* Update the LSB of the Data and the Address Parameter*/ 1489 dnld_data->data_addr[i] = (uint8_t)((dnld_addr >> 1490 (BYTE_SIZE + BYTE_SIZE)) & BYTE_MASK); 1491 dnld_data->data_len[i] = (uint8_t)((dnld_size >> BYTE_SIZE) 1492 & BYTE_MASK); 1493 p_dnld_data->frame_length[i] = (uint8_t) 1494 (((dnld_size + PHDNLD_CMD_WRITE_MIN_LEN) >> BYTE_SIZE) 1495 & BYTE_MASK); 1496 i++; 1497 /* Update the 2nd byte of the Data and the Address Parameter*/ 1498 dnld_data->data_addr[i] = (uint8_t)((dnld_addr >> BYTE_SIZE) 1499 & BYTE_MASK); 1500 dnld_data->data_len[i] = (uint8_t) (dnld_size & BYTE_MASK); 1501 p_dnld_data->frame_length[i] = (uint8_t) ((dnld_size + 1502 PHDNLD_CMD_WRITE_MIN_LEN) & BYTE_MASK); 1503 i++; 1504 /* Update the 3rd byte of the the Address Parameter*/ 1505 dnld_data->data_addr[i] = (uint8_t)(dnld_addr & BYTE_MASK); 1506 1507 (void)memcpy( dnld_data->data_packet, 1508 (p_sec_info->p_sec_data + *p_sec_offset), dnld_size ); 1509 1510 if( ((sec_type & DNLD_TRIM_MASK)) 1511 && (p_sec_info->sec_verify_retry != 0) 1512 && (NULL != psDnldContext->trim_store.buffer) 1513 ) 1514 { 1515 (void)memcpy( dnld_data->data_packet, 1516 psDnldContext->trim_store.buffer, dnld_size ); 1517 } 1518 else if(((sec_type & DNLD_TRIM_MASK)) 1519 && ( TRUE == p_sec_info->section_read ) 1520 ) 1521 { 1522 for(i = 0; i < *(p_sec_info->p_trim_data);i++) 1523 { 1524 1525 #ifdef NXP_FW_SW_VMID_TRIM 1526 1527 /* 1528 if(bit 0 of 0x813D is equal to 1) then 1529 1530 Do not overwrite 0x9931 / 0x9981 during download 1531 1532 else 1533 1534 @0x9931 = 0x79 // card Mode 1535 @0x9981 = 0x79 // Reader Mode 1536 */ 1537 trim_addr = p_sec_info->p_sec_hdr->section_address 1538 + p_sec_info->p_trim_data[i+1]; 1539 if (NXP_FW_VMID_TRIM_CHK_ADDR == trim_addr) 1540 { 1541 psDnldContext->vmid_trim_update = 1542 p_sm_trim_data[p_sec_info->p_trim_data[i+1]] ; 1543 } 1544 1545 if((NXP_FW_VMID_CARD_MODE_ADDR == trim_addr) 1546 || (NXP_FW_VMID_RD_MODE_ADDR == trim_addr)) 1547 { 1548 if (TRUE == psDnldContext->vmid_trim_update) 1549 { 1550 dnld_data->data_packet[p_sec_info->p_trim_data[i+1]] = 1551 p_sm_trim_data[p_sec_info->p_trim_data[i+1]] ; 1552 } 1553 } 1554 else 1555 1556 #endif 1557 { 1558 dnld_data->data_packet[p_sec_info->p_trim_data[i+1]] = 1559 p_sm_trim_data[p_sec_info->p_trim_data[i+1]] ; 1560 } 1561 } 1562 if(NULL != psDnldContext->trim_store.buffer) 1563 { 1564 phOsalNfc_FreeMemory(psDnldContext->trim_store.buffer); 1565 psDnldContext->trim_store.buffer = NULL; 1566 psDnldContext->trim_store.length = 0; 1567 } 1568 #if 1 1569 (void) 1570 phDnldNfc_Allocate_Resource((void **) 1571 &(psDnldContext->trim_store.buffer),dnld_size); 1572 #else 1573 psDnldContext->trim_store.buffer = 1574 (uint8_t *) phOsalNfc_GetMemory(dnld_size); 1575 #endif 1576 1577 if(NULL != psDnldContext->trim_store.buffer) 1578 { 1579 (void )memset((void *)psDnldContext->trim_store.buffer,0, 1580 dnld_size); 1581 (void)memcpy( psDnldContext->trim_store.buffer, 1582 dnld_data->data_packet, dnld_size ); 1583 psDnldContext->trim_store.length = dnld_size; 1584 DNLD_DEBUG(" FW_DNLD: Write with Trimming at Address %X ", dnld_addr ); 1585 DNLD_DEBUG(" of Size %X and ", dnld_size ); 1586 DNLD_DEBUG(" with %X Trimming Values \n", *(p_sec_info->p_trim_data) ); 1587 1588 } 1589 } 1590 else 1591 { 1592 if(NULL != psDnldContext->dnld_store.buffer) 1593 { 1594 phOsalNfc_FreeMemory(psDnldContext->dnld_store.buffer); 1595 psDnldContext->dnld_store.buffer = NULL; 1596 psDnldContext->dnld_store.length = 0; 1597 } 1598 #if 1 1599 (void) 1600 phDnldNfc_Allocate_Resource((void **) 1601 &(psDnldContext->dnld_store.buffer),dnld_size); 1602 #else 1603 psDnldContext->dnld_store.buffer = 1604 (uint8_t *) phOsalNfc_GetMemory(dnld_size); 1605 #endif 1606 if(NULL != psDnldContext->dnld_store.buffer) 1607 { 1608 (void )memset((void *)psDnldContext->dnld_store.buffer,0, 1609 dnld_size); 1610 (void)memcpy( psDnldContext->dnld_store.buffer, 1611 dnld_data->data_packet, dnld_size ); 1612 psDnldContext->dnld_store.length = dnld_size; 1613 DNLD_DEBUG(" FW_DNLD: Memory Write at Address %X ", dnld_addr ); 1614 DNLD_DEBUG(" of Size %X ", dnld_size ); 1615 } 1616 } 1617 1618 if(PHDNLD_FW_PATCH_SEC != psDnldContext->p_fw_hdr->fw_patch) 1619 { 1620 status = phDnldNfc_Send_Command( psDnldContext, pHwRef, 1621 PHDNLD_CMD_WRITE, NULL , 0 ); 1622 } 1623 else 1624 { 1625 status = phDnldNfc_Send_Command( psDnldContext, pHwRef, 1626 PHDNLD_CMD_SEC_WRITE, NULL , 0 ); 1627 } 1628 1629 DNLD_DEBUG(" FW_DNLD: Memory Write Status = %X \n", status); 1630 if ( NFCSTATUS_PENDING == status ) 1631 { 1632 psDnldContext->prev_dnld_size = dnld_size; 1633 cmp_val = 0x00; 1634 if((sec_type & DNLD_TRIM_MASK)) 1635 { 1636 p_sec_info->trim_write = TRUE; 1637 DNLD_DEBUG(" FW_DNLD: Bytes Downloaded (Trimming Values) = %X Bytes \n", 1638 dnld_size); 1639 } 1640 else 1641 { 1642 p_sec_info->section_write = TRUE; 1643 DNLD_DEBUG(" FW_DNLD: Bytes Downloaded = %X : ", 1644 (*p_sec_offset + dnld_size)); 1645 DNLD_DEBUG(" Bytes Remaining = %X \n", 1646 (p_sec_info->p_sec_hdr->section_length - 1647 (*p_sec_offset + dnld_size))); 1648 } 1649 1650 p_sec_info->section_read = FALSE; 1651 } 1652 } 1653 return status; 1654 } 1655 1656 1657 1658 static 1659 NFCSTATUS 1660 phDnldNfc_Resume_Write( 1661 phDnldNfc_sContext_t *psDnldContext, 1662 void *pHwRef 1663 ) 1664 { 1665 NFCSTATUS status = NFCSTATUS_SUCCESS; 1666 uint8_t sec_index = psDnldContext->section_index; 1667 section_info_t *p_sec_info = (psDnldContext->p_fw_sec + sec_index); 1668 1669 while((sec_index < psDnldContext->p_fw_hdr->no_of_sections) 1670 && (NFCSTATUS_SUCCESS == status ) 1671 ) 1672 { 1673 1674 status = phDnldNfc_Process_Write(psDnldContext, pHwRef, 1675 p_sec_info, (uint32_t *)&(p_sec_info->section_offset)); 1676 if (NFCSTATUS_SUCCESS == status) 1677 { 1678 unsigned sec_type = 0; 1679 sec_type = (unsigned int)p_sec_info->p_sec_hdr->section_mem_type; 1680 1681 p_sec_info->section_offset = 0; 1682 p_sec_info->section_read = FALSE; 1683 p_sec_info->section_write = FALSE; 1684 p_sec_info->trim_write = FALSE; 1685 1686 DNLD_DEBUG(" FW_DNLD: Section %02X Download Complete\n", sec_index); 1687 if((sec_type & DNLD_RESET_MASK)) 1688 { 1689 DNLD_DEBUG(" FW_DNLD: Reset After Section %02X Download \n", sec_index); 1690 status = phDnldNfc_Send_Command( psDnldContext, pHwRef, 1691 PHDNLD_CMD_RESET , NULL, 0 ); 1692 } 1693 DNLD_PRINT("*******************************************\n\n"); 1694 1695 sec_index++; 1696 1697 #ifdef NXP_FW_DNLD_CHECK_PHASE 1698 if( p_sec_info->p_sec_hdr->section_address 1699 < (DNLD_CFG_PG_ADDR + PHDNLD_PAGE_SIZE) ) 1700 { 1701 gphDnldPhase = NXP_FW_DNLD_DATA_PHASE; 1702 1703 } 1704 1705 p_sec_info = (psDnldContext->p_fw_sec + sec_index); 1706 1707 if( (sec_index < psDnldContext->p_fw_hdr->no_of_sections) 1708 && ( p_sec_info->p_sec_hdr->section_address 1709 < (DNLD_CFG_PG_ADDR + PHDNLD_PAGE_SIZE) ) 1710 ) 1711 { 1712 if( NXP_FW_DNLD_CFG_PHASE >= gphDnldPhase ) 1713 { 1714 gphDnldPhase = NXP_FW_DNLD_CFG_PHASE; 1715 } 1716 else 1717 { 1718 sec_index++; 1719 p_sec_info = (psDnldContext->p_fw_sec + sec_index); 1720 } 1721 } 1722 #else 1723 p_sec_info = (psDnldContext->p_fw_sec + sec_index); 1724 #endif /* #ifdef NXP_FW_DNLD_CHECK_PHASE */ 1725 1726 psDnldContext->section_index = sec_index; 1727 /* psDnldContext->next_dnld_state = (uint8_t) phDnld_Upgrade_State; */ 1728 } 1729 } 1730 if (NFCSTATUS_PENDING == status) 1731 { 1732 psDnldContext->next_dnld_state = (uint8_t) phDnld_Upgrade_State; 1733 } 1734 else if (NFCSTATUS_SUCCESS == status) 1735 { 1736 /* Reset the PN544 Device */ 1737 psDnldContext->next_dnld_state = (uint8_t) phDnld_Complete_State; 1738 } 1739 else 1740 { 1741 1742 } 1743 return status; 1744 } 1745 1746 1747 #define NXP_DNLD_SM_UNLOCK_ADDR 0x008002U 1748 1749 #if !defined (ES_HW_VER) 1750 #define ES_HW_VER 32 1751 #endif 1752 1753 #if (ES_HW_VER <= 30) 1754 #define NXP_DNLD_PATCH_ADDR 0x01AFFFU 1755 #else 1756 #define NXP_DNLD_PATCH_ADDR 0x01A1E0U 1757 #endif 1758 1759 #if (ES_HW_VER <= 30) 1760 #define NXP_DNLD_PATCH_TABLE_ADDR 0x008107U 1761 #else 1762 #define NXP_DNLD_PATCH_TABLE_ADDR 0x00825AU 1763 #endif 1764 1765 1766 static 1767 NFCSTATUS 1768 phDnldNfc_Sequence( 1769 phDnldNfc_sContext_t *psDnldContext, 1770 void *pHwRef, 1771 void *pdata, 1772 uint16_t length 1773 ) 1774 { 1775 NFCSTATUS status = NFCSTATUS_SUCCESS; 1776 uint32_t dnld_addr = 0; 1777 phDnldNfc_sData_t *p_dnld_data = 1778 (phDnldNfc_sData_t *)psDnldContext->dnld_data; 1779 phDnldNfc_sParam_t *p_data_param = 1780 & p_dnld_data->param_info.data_param; 1781 uint8_t *p_data = NULL; 1782 static uint32_t patch_size = 0; 1783 1784 #if (ES_HW_VER == 32) 1785 1786 static uint8_t patch_table[] = {0xA0, 0xA1, 0xE0, 0x80, 0xA9, 0x6C }; 1787 static uint8_t patch_data[] = {0xA5, 0xD0, 0xFE, 0xA5, 0xD0, 0xFD, 0xA5, 1788 0xD0, 0xFC, 0xA5, 0x02, 0x80, 0xA9, 0x75}; 1789 1790 #elif (ES_HW_VER == 31) 1791 1792 static uint8_t patch_table[] = {0xA0, 0xAF, 0xE0, 0x80, 0x78, 0x84 }; 1793 static uint8_t patch_data[] = {0xA5, 0xD0, 0xFE, 0xA5, 0xD0, 0xFD, 0xA5, 1794 0xD0, 0xFC, 0xD0, 0xE0, 0xA5, 0x02, 0x80, 0x78, 0x8D}; 1795 1796 #elif (ES_HW_VER == 30) 1797 1798 static uint8_t patch_table[] = {0x80, 0x91, 0x51, 0xA0, 0xAF, 1799 0xFF, 0x80, 0x91, 0x5A}; 1800 static uint8_t patch_data[] = {0x22}; 1801 1802 #endif 1803 1804 static uint8_t unlock_data[] = {0x00, 0x00}; 1805 static uint8_t lock_data[] = {0x0C, 0x00}; 1806 1807 uint8_t i = 0; 1808 1809 PHNFC_UNUSED_VARIABLE(pdata); 1810 PHNFC_UNUSED_VARIABLE(length); 1811 switch(psDnldContext->cur_dnld_seq) 1812 { 1813 case phDnld_Reset_Seq: 1814 { 1815 status = phDnldNfc_Send_Command( psDnldContext, pHwRef, 1816 PHDNLD_CMD_RESET , NULL , 0 ); 1817 /* status = (NFCSTATUS_PENDING == status)? NFCSTATUS_SUCCESS: 1818 status; */ 1819 DNLD_DEBUG(" FW_DNLD: Reset Seq.. Status = %X \n", status); 1820 1821 break; 1822 } 1823 case phDnld_Activate_Patch: 1824 { 1825 uint8_t patch_activate = 0x01; 1826 psDnldContext->next_dnld_seq = 1827 (uint8_t)phDnld_Update_Patch; 1828 #ifdef NXP_FW_DNLD_CHECK_PHASE 1829 gphDnldPhase = NXP_FW_DNLD_SYSTEM_PHASE; 1830 #endif /* NXP_FW_DNLD_CHECK_PHASE */ 1831 1832 status = phDnldNfc_Send_Command( psDnldContext, pHwRef, 1833 PHDNLD_CMD_ACTIVATE_PATCH , &patch_activate, sizeof(patch_activate) ); 1834 DNLD_PRINT(" FW_DNLD: Activate the Patch Update .... \n"); 1835 break; 1836 } 1837 case phDnld_Deactivate_Patch: 1838 { 1839 uint8_t patch_activate = 0x00; 1840 1841 psDnldContext->next_dnld_state = 1842 (uint8_t)phDnld_Reset_State; 1843 1844 status = phDnldNfc_Send_Command( psDnldContext, pHwRef, 1845 PHDNLD_CMD_ACTIVATE_PATCH , &patch_activate, sizeof(patch_activate) ); 1846 DNLD_PRINT(" FW_DNLD: Deactivate the Patch Update .... \n"); 1847 break; 1848 } 1849 case phDnld_Update_Patch: 1850 { 1851 dnld_addr = NXP_DNLD_PATCH_ADDR; 1852 patch_size = sizeof(patch_data) ; 1853 p_data = patch_data; 1854 psDnldContext->next_dnld_seq = 1855 (uint8_t)phDnld_Update_Patchtable; 1856 DNLD_PRINT(" FW_DNLD: Patch Update Seq.... \n"); 1857 break; 1858 } 1859 case phDnld_Update_Patchtable: 1860 { 1861 dnld_addr = NXP_DNLD_PATCH_TABLE_ADDR; 1862 patch_size = sizeof(patch_table) ; 1863 p_data = patch_table; 1864 1865 psDnldContext->next_dnld_state = 1866 (uint8_t)phDnld_Reset_State; 1867 1868 DNLD_PRINT(" FW_DNLD: Patch Table Update Seq.... \n"); 1869 break; 1870 } 1871 case phDnld_Unlock_System: 1872 { 1873 dnld_addr = NXP_DNLD_SM_UNLOCK_ADDR; 1874 patch_size = sizeof(unlock_data) ; 1875 p_data = unlock_data; 1876 #define NXP_FW_PATCH_DISABLE 1877 #ifdef NXP_FW_PATCH_DISABLE 1878 psDnldContext->next_dnld_seq = 1879 (uint8_t)phDnld_Deactivate_Patch; 1880 #else 1881 psDnldContext->next_dnld_state = 1882 (uint8_t)phDnld_Reset_State; 1883 #endif 1884 1885 DNLD_PRINT(" FW_DNLD: System Memory Unlock Seq.... \n"); 1886 break; 1887 } 1888 case phDnld_Lock_System: 1889 { 1890 dnld_addr = NXP_DNLD_SM_UNLOCK_ADDR; 1891 patch_size = sizeof(lock_data) ; 1892 p_data = lock_data; 1893 psDnldContext->next_dnld_state = 1894 (uint8_t) phDnld_Reset_State; 1895 1896 DNLD_PRINT(" FW_DNLD: System Memory Lock Seq.... \n"); 1897 break; 1898 } 1899 case phDnld_Upgrade_Section: 1900 { 1901 status = phDnldNfc_Resume_Write( 1902 psDnldContext, pHwRef ); 1903 break; 1904 } 1905 case phDnld_Verify_Integrity: 1906 { 1907 psDnldContext->next_dnld_state = 1908 (uint8_t) phDnld_Reset_State; 1909 1910 status = phDnldNfc_Send_Command( psDnldContext, pHwRef, 1911 PHDNLD_CMD_CHECK_INTEGRITY , NULL, 0 ); 1912 DNLD_PRINT(" FW_DNLD: System Memory Integrity Check Sequence.... \n"); 1913 break; 1914 } 1915 case phDnld_Verify_Section: 1916 { 1917 break; 1918 } 1919 default: 1920 { 1921 break; 1922 } 1923 } 1924 1925 if( NFCSTATUS_SUCCESS == status) 1926 { 1927 1928 /* Update the LSB of the Data and the Address Parameter*/ 1929 p_data_param->data_addr[i] = (uint8_t)((dnld_addr >> 1930 (BYTE_SIZE + BYTE_SIZE)) 1931 & BYTE_MASK); 1932 p_data_param->data_len[i] = (uint8_t)((patch_size >> BYTE_SIZE) 1933 & BYTE_MASK); 1934 p_dnld_data->frame_length[i] = (uint8_t) 1935 (((patch_size + PHDNLD_CMD_WRITE_MIN_LEN) >> BYTE_SIZE) 1936 & BYTE_MASK); 1937 i++; 1938 /* Update the 2nd byte of the Data and the Address Parameter*/ 1939 p_data_param->data_addr[i] = (uint8_t)((dnld_addr >> BYTE_SIZE) 1940 & BYTE_MASK); 1941 p_data_param->data_len[i] = (uint8_t) (patch_size & BYTE_MASK); 1942 p_dnld_data->frame_length[i] = (uint8_t) 1943 ((patch_size + PHDNLD_CMD_WRITE_MIN_LEN) 1944 & BYTE_MASK); 1945 i++; 1946 /* Update the 3rd byte of the the Address Parameter*/ 1947 p_data_param->data_addr[i] = (uint8_t)(dnld_addr & BYTE_MASK); 1948 1949 status = phDnldNfc_Send_Command( psDnldContext, pHwRef, 1950 PHDNLD_CMD_WRITE,(void *)p_data , (uint8_t)patch_size ); 1951 1952 if (NFCSTATUS_PENDING != status) 1953 { 1954 status = phDnldNfc_Set_Seq(psDnldContext, 1955 DNLD_SEQ_ROLLBACK); 1956 } 1957 } 1958 return status; 1959 } 1960 1961 #define FRAME_HEADER_LEN 0x03U 1962 1963 1964 static 1965 void 1966 phDnldNfc_Tx_Reset(phDnldNfc_sContext_t *psDnldContext) 1967 { 1968 psDnldContext->tx_info.transmit_frame = NULL; 1969 psDnldContext->tx_info.tx_total = 0x00; 1970 psDnldContext->tx_info.tx_offset = 0x00; 1971 psDnldContext->tx_info.tx_len = 0x00; 1972 psDnldContext->tx_info.tx_chain = FALSE; 1973 } 1974 1975 STATIC 1976 bool_t 1977 phDnldNfc_Extract_Chunks( 1978 uint8_t *frame_data, 1979 uint16_t frame_offset, 1980 uint16_t frame_length, 1981 uint16_t max_frame , 1982 uint16_t *chunk_length 1983 ); 1984 1985 1986 STATIC 1987 bool_t 1988 phDnldNfc_Extract_Chunks( 1989 uint8_t *frame_data, 1990 uint16_t frame_offset, 1991 uint16_t frame_length, 1992 uint16_t max_frame , 1993 uint16_t *chunk_length 1994 ) 1995 { 1996 bool_t chunk_present = FALSE; 1997 1998 if( 0 == frame_offset) 1999 { 2000 if( max_frame >= (frame_length 2001 - frame_offset)) 2002 { 2003 *chunk_length = (frame_length - frame_offset); 2004 } 2005 else 2006 { 2007 *chunk_length = max_frame 2008 - FRAME_HEADER_LEN; 2009 chunk_present = TRUE; 2010 } 2011 } 2012 else 2013 { 2014 if( max_frame >= (frame_length 2015 - frame_offset)) 2016 { 2017 *chunk_length = (frame_length - frame_offset); 2018 } 2019 else 2020 { 2021 *chunk_length = max_frame 2022 - FRAME_HEADER_LEN; 2023 chunk_present = TRUE; 2024 } 2025 } 2026 2027 return chunk_present; 2028 } 2029 2030 2031 STATIC 2032 NFCSTATUS 2033 phDnldNfc_Send_Raw( 2034 phDnldNfc_sContext_t *psDnldContext, 2035 void *pHwRef, 2036 uint8_t *raw_frame, 2037 uint16_t frame_offset, 2038 uint16_t frame_length 2039 ) 2040 { 2041 NFCSTATUS status = NFCSTATUS_SUCCESS; 2042 phDnldNfc_sRawHdr_t *raw_frame_hdr = ( phDnldNfc_sRawHdr_t * ) raw_frame; 2043 2044 switch(raw_frame_hdr->frame_type) 2045 { 2046 case PHDNLD_CMD_RESET: 2047 { 2048 break; 2049 } 2050 case PHDNLD_CMD_READ: 2051 { 2052 /* TODO: To Update the length and the buffer to receive data */ 2053 break; 2054 } 2055 case PHDNLD_CMD_WRITE: 2056 { 2057 phDnldNfc_sRawDataHdr_t *raw_data_hdr = 2058 ( phDnldNfc_sRawDataHdr_t * ) (raw_frame + FRAME_HEADER_LEN); 2059 2060 psDnldContext->resp_length = PHDNLD_MIN_PACKET; 2061 2062 break; 2063 } 2064 case PHDNLD_CMD_SEC_WRITE: 2065 { 2066 uint16_t tx_length = 0x00; 2067 uint16_t frame_offset = 2068 psDnldContext->tx_info.tx_offset; 2069 uint16_t chain = 2070 psDnldContext->tx_info.tx_chain; 2071 2072 chain = 2073 phDnldNfc_Extract_Chunks( 2074 raw_frame, 2075 frame_offset, 2076 frame_length, 2077 PHDNLD_FW_TX_RX_LEN, 2078 &tx_length 2079 ); 2080 2081 if( TRUE == chain ) 2082 { 2083 status = phDnldNfc_Send_Command( psDnldContext, 2084 pHwRef, PHDNLD_CMD_ENCAPSULATE, 2085 (raw_frame + frame_offset), 2086 tx_length); 2087 if(NFCSTATUS_PENDING == status) 2088 { 2089 psDnldContext->prev_cmd = raw_frame_hdr->frame_type; 2090 /* TODO: Update for the Chaining */ 2091 psDnldContext->tx_info.tx_offset += tx_length; 2092 psDnldContext->tx_info.tx_chain = chain; 2093 } 2094 } 2095 else if (0 != frame_offset) 2096 { 2097 status = phDnldNfc_Send_Command( psDnldContext, 2098 pHwRef, PHDNLD_CMD_ENCAPSULATE, 2099 (raw_frame + frame_offset), 2100 tx_length); 2101 if(NFCSTATUS_PENDING == status) 2102 { 2103 psDnldContext->prev_cmd = raw_frame_hdr->frame_type; 2104 /* TODO: Update for the Chaining */ 2105 psDnldContext->prev_dnld_size = frame_length; 2106 phDnldNfc_Tx_Reset(psDnldContext); 2107 } 2108 } 2109 else 2110 { 2111 phDnldNfc_sRawDataHdr_t *raw_data_hdr = 2112 ( phDnldNfc_sRawDataHdr_t * ) (raw_frame + FRAME_HEADER_LEN); 2113 psDnldContext->resp_length = PHDNLD_MIN_PACKET; 2114 } 2115 2116 break; 2117 } 2118 case PHDNLD_CMD_CHECK: 2119 { 2120 psDnldContext->resp_length = PHDNLD_MIN_PACKET; 2121 break; 2122 } 2123 case PHDNLD_CMD_SET_HIF: 2124 { 2125 psDnldContext->resp_length = PHDNLD_MIN_PACKET; 2126 break; 2127 } 2128 case PHDNLD_CMD_ACTIVATE_PATCH: 2129 { 2130 psDnldContext->resp_length = PHDNLD_MIN_PACKET; 2131 break; 2132 } 2133 case PHDNLD_CMD_CHECK_INTEGRITY: 2134 { 2135 uint8_t integrity_param = 2136 *(raw_frame + FRAME_HEADER_LEN); 2137 switch(integrity_param) 2138 { 2139 case CHK_INTEGRITY_CONFIG_PAGE_CRC: 2140 case CHK_INTEGRITY_PATCH_TABLE_CRC: 2141 { 2142 psDnldContext->resp_length = PHDNLD_MIN_PACKET 2143 + CHECK_INTEGRITY_RESP_CRC16_LEN; 2144 break; 2145 } 2146 case CHK_INTEGRITY_FLASH_CODE_CRC: 2147 case CHK_INTEGRITY_PATCH_CODE_CRC: 2148 { 2149 psDnldContext->resp_length = PHDNLD_MIN_PACKET 2150 + CHECK_INTEGRITY_RESP_CRC32_LEN; 2151 break; 2152 } 2153 case CHK_INTEGRITY_COMPLETE_CRC: 2154 default: 2155 { 2156 psDnldContext->resp_length = PHDNLD_MIN_PACKET 2157 + CHECK_INTEGRITY_RESP_COMP_LEN; 2158 break; 2159 } 2160 } 2161 break; 2162 } 2163 default: 2164 { 2165 status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FEATURE_NOT_SUPPORTED); 2166 break; 2167 } 2168 } 2169 2170 if (NFCSTATUS_SUCCESS == status) 2171 { 2172 status = phDnldNfc_Send( psDnldContext, pHwRef , 2173 raw_frame, frame_length); 2174 2175 if(NFCSTATUS_PENDING == status) 2176 { 2177 psDnldContext->prev_cmd = raw_frame_hdr->frame_type; 2178 /* TODO: Update for the Chaining */ 2179 psDnldContext->prev_dnld_size = frame_length; 2180 } 2181 } 2182 2183 return status; 2184 } 2185 2186 2187 static 2188 NFCSTATUS 2189 phDnldNfc_Frame_Complete(phDnldNfc_sContext_t *psDnldContext) 2190 { 2191 NFCSTATUS status = NFCSTATUS_SUCCESS; 2192 phDnldNfc_sData_Hdr_t *p_dnld_raw = NULL; 2193 uint32_t dnld_index = psDnldContext->dnld_index; 2194 uint8_t *p_raw_sec_hdr = NULL; 2195 uint16_t tx_length = 0x00; 2196 2197 dnld_index = dnld_index + psDnldContext->prev_dnld_size; 2198 p_raw_sec_hdr = psDnldContext->p_fw_raw + dnld_index; 2199 dnld_index = dnld_index + *p_raw_sec_hdr; 2200 2201 p_dnld_raw = (phDnldNfc_sData_Hdr_t *) (psDnldContext->p_fw_raw + 2202 psDnldContext->dnld_index); 2203 2204 tx_length = ((p_dnld_raw->frame_length[0] << BYTE_SIZE) | 2205 p_dnld_raw->frame_length[1]); 2206 2207 tx_length = tx_length + PHDNLD_MIN_PACKET; 2208 2209 return status; 2210 } 2211 2212 2213 static 2214 NFCSTATUS 2215 phDnldNfc_Raw_Write( 2216 phDnldNfc_sContext_t *psDnldContext, 2217 void *pHwRef 2218 ) 2219 { 2220 NFCSTATUS status = NFCSTATUS_SUCCESS; 2221 uint32_t dnld_index = psDnldContext->dnld_index; 2222 uint32_t tx_length = 0; 2223 uint8_t *p_raw_sec_hdr = NULL; 2224 uint8_t dnld_flag = FALSE; 2225 uint8_t skip_frame = FALSE; 2226 2227 if(NULL != psDnldContext->p_fw_raw) 2228 { 2229 2230 if( (TRUE != psDnldContext->tx_info.tx_chain) 2231 && (0x00 == psDnldContext->dnld_retry) 2232 ) 2233 { 2234 dnld_index = dnld_index + psDnldContext->prev_dnld_size; 2235 p_raw_sec_hdr = psDnldContext->p_fw_raw + dnld_index; 2236 dnld_index = dnld_index + *p_raw_sec_hdr; 2237 } 2238 else 2239 { 2240 phDnldNfc_sData_Hdr_t *p_dnld_raw = (phDnldNfc_sData_Hdr_t *) 2241 (psDnldContext->p_fw_raw + 2242 psDnldContext->dnld_index); 2243 2244 tx_length = ((p_dnld_raw->frame_length[0] << BYTE_SIZE) | 2245 p_dnld_raw->frame_length[1]); 2246 2247 tx_length = tx_length + PHDNLD_MIN_PACKET; 2248 2249 status = phDnldNfc_Send_Raw( psDnldContext, pHwRef, 2250 (uint8_t *)(p_dnld_raw), 2251 psDnldContext->tx_info.tx_offset, 2252 (uint16_t)tx_length); 2253 } 2254 2255 2256 #define PHDNLD_MAJOR_OFFSET 0x04U 2257 #define PHDNLD_MINOR_OFFSET 0x05U 2258 #define PHDNLD_PHASE_OFFSET 0x06U 2259 #define PHDNLD_FRAMETYPE_OFFSET 0x07U 2260 2261 #define PHDNLD_NO_OPERATION 0x00U 2262 #define PHDNLD_NORMAL_OPERATION 0x10U 2263 #define PHDNLD_ADVANCED_OPERATION 0x20U 2264 #define PHDNLD_SETUP_OPERATION 0x40U 2265 #define PHDNLD_RECOVER_OPERATION 0x80U 2266 #define PHDNLD_COMPLETE_OPERATION 0xF0U 2267 2268 #define PHDNLD_TERMINATE_TYPE 0x0EU 2269 2270 #define PHDNLD_MARKER_MASK 0x0FU 2271 2272 while((NFCSTATUS_SUCCESS == status ) 2273 && (FALSE == dnld_flag) 2274 ) 2275 { 2276 phDnldNfc_sData_Hdr_t *p_dnld_raw = (phDnldNfc_sData_Hdr_t *) 2277 (psDnldContext->p_fw_raw + dnld_index); 2278 uint8_t frame_type = *(p_raw_sec_hdr + PHDNLD_FRAMETYPE_OFFSET); 2279 2280 tx_length = ((p_dnld_raw->frame_length[0] << BYTE_SIZE) | 2281 p_dnld_raw->frame_length[1]); 2282 2283 tx_length = tx_length + PHDNLD_MIN_PACKET; 2284 2285 skip_frame = FALSE; 2286 2287 if( (0x00 == *(p_raw_sec_hdr + PHDNLD_PHASE_OFFSET)) 2288 || (0xFF == *(p_raw_sec_hdr + PHDNLD_PHASE_OFFSET)) 2289 || !( psDnldContext->raw_mode_upgrade 2290 & (frame_type & (~PHDNLD_MARKER_MASK)) ) 2291 ) 2292 { 2293 dnld_index = dnld_index + tx_length; 2294 p_raw_sec_hdr = psDnldContext->p_fw_raw + dnld_index; 2295 dnld_index = dnld_index + *p_raw_sec_hdr; 2296 skip_frame = TRUE; 2297 } 2298 if (PHDNLD_TERMINATE_TYPE == 2299 (frame_type & PHDNLD_MARKER_MASK)) 2300 { 2301 if(TRUE != skip_frame) 2302 { 2303 psDnldContext->raw_mode_upgrade = 2304 (psDnldContext->raw_mode_upgrade & 2305 ~(frame_type & ~PHDNLD_MARKER_MASK)); 2306 } 2307 2308 if(PHDNLD_NO_OPERATION == 2309 psDnldContext->raw_mode_upgrade) 2310 { 2311 dnld_flag = TRUE; 2312 } 2313 } 2314 else 2315 { 2316 2317 } 2318 2319 if((FALSE == skip_frame) 2320 && (FALSE == dnld_flag) 2321 ) 2322 { 2323 status = phDnldNfc_Send_Raw( psDnldContext, pHwRef, 2324 (uint8_t *)(p_dnld_raw), 2325 psDnldContext->tx_info.tx_offset, 2326 (uint16_t)tx_length); 2327 } 2328 2329 if( NFCSTATUS_PENDING == status ) 2330 { 2331 psDnldContext->dnld_index = dnld_index; 2332 psDnldContext->cur_frame_info= frame_type; 2333 } 2334 } 2335 } 2336 2337 return status; 2338 } 2339 2340 static 2341 NFCSTATUS 2342 phDnldNfc_Upgrade_Sequence( 2343 phDnldNfc_sContext_t *psDnldContext, 2344 void *pHwRef, 2345 void *pdata, 2346 uint16_t length 2347 ) 2348 { 2349 NFCSTATUS status = NFCSTATUS_SUCCESS; 2350 2351 PHNFC_UNUSED_VARIABLE(pdata); 2352 PHNFC_UNUSED_VARIABLE(length); 2353 2354 if(phDnld_Raw_Upgrade == psDnldContext->cur_dnld_seq) 2355 { 2356 status = phDnldNfc_Raw_Write( psDnldContext, pHwRef ); 2357 } 2358 else 2359 { 2360 status = phDnldNfc_Resume_Write( psDnldContext, pHwRef ); 2361 } 2362 2363 return status; 2364 } 2365 2366 2367 2368 static 2369 NFCSTATUS 2370 phDnldNfc_Resume( 2371 phDnldNfc_sContext_t *psDnldContext, 2372 void *pHwRef, 2373 void *pdata, 2374 uint16_t length 2375 ) 2376 { 2377 NFCSTATUS status = NFCSTATUS_SUCCESS; 2378 phDnldNfc_eState_t dnld_next_state = (phDnldNfc_eState_t) 2379 psDnldContext->cur_dnld_state; 2380 phNfc_sCompletionInfo_t comp_info = {0,0,0}; 2381 2382 switch( dnld_next_state ) 2383 { 2384 case phDnld_Reset_State: 2385 { 2386 status = phDnldNfc_Send_Command( psDnldContext, pHwRef, 2387 PHDNLD_CMD_RESET , NULL, 0 ); 2388 switch( psDnldContext->cur_dnld_seq ) 2389 { 2390 case phDnld_Update_Patchtable: 2391 { 2392 psDnldContext->next_dnld_state = 2393 (uint8_t)phDnld_Unlock_State; 2394 psDnldContext->next_dnld_seq = 2395 (uint8_t)phDnld_Unlock_System; 2396 break; 2397 } 2398 #ifdef NXP_FW_PATCH_DISABLE 2399 case phDnld_Deactivate_Patch: 2400 #else 2401 case phDnld_Unlock_System: 2402 #endif 2403 { 2404 psDnldContext->next_dnld_state = 2405 (uint8_t)phDnld_Upgrade_State; 2406 psDnldContext->next_dnld_seq = 2407 (uint8_t)phDnld_Upgrade_Section; 2408 #ifdef NXP_FW_DNLD_CHECK_PHASE 2409 gphDnldPhase = NXP_FW_DNLD_CFG_PHASE; 2410 #endif /* NXP_FW_DNLD_CHECK_PHASE */ 2411 break; 2412 } 2413 case phDnld_Lock_System: 2414 { 2415 #if (NXP_FW_INTEGRITY_CHK >= 0x01) 2416 psDnldContext->next_dnld_state = 2417 (uint8_t)phDnld_Verify_State; 2418 psDnldContext->next_dnld_seq = 2419 (uint8_t)phDnld_Verify_Integrity; 2420 #else 2421 /* (void ) memset( (void *) &psDnldContext->chk_integrity_crc, 2422 0, sizeof(psDnldContext->chk_integrity_crc)); */ 2423 psDnldContext->next_dnld_state = 2424 (uint8_t) phDnld_Complete_State; 2425 #endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ 2426 break; 2427 } 2428 case phDnld_Verify_Integrity: 2429 { 2430 psDnldContext->next_dnld_state = 2431 (uint8_t) phDnld_Complete_State; 2432 break; 2433 } 2434 default: 2435 { 2436 status = (NFCSTATUS_PENDING == status)? 2437 NFCSTATUS_SUCCESS: status; 2438 break; 2439 } 2440 } 2441 break; 2442 } 2443 case phDnld_Unlock_State: 2444 { 2445 2446 status = phDnldNfc_Sequence( psDnldContext, pHwRef, 2447 pdata, length); 2448 break; 2449 } 2450 case phDnld_Upgrade_State: 2451 { 2452 status = phDnldNfc_Upgrade_Sequence( psDnldContext, pHwRef, 2453 pdata, length); 2454 if ((NFCSTATUS_SUCCESS == status ) 2455 && (phDnld_Complete_State == psDnldContext->next_dnld_state)) 2456 { 2457 #if 0 2458 psDnldContext->cur_dnld_seq = 2459 (uint8_t)phDnld_Lock_System; 2460 psDnldContext->next_dnld_seq = 2461 psDnldContext->cur_dnld_seq; 2462 #endif 2463 #if (NXP_FW_INTEGRITY_CHK >= 0x01) 2464 psDnldContext->next_dnld_state = 2465 (uint8_t)phDnld_Verify_State; 2466 psDnldContext->next_dnld_seq = 2467 (uint8_t)phDnld_Verify_Integrity; 2468 psDnldContext->cur_dnld_seq = 2469 psDnldContext->next_dnld_seq; 2470 status = phDnldNfc_Sequence( psDnldContext, 2471 pHwRef, pdata, length); 2472 #else 2473 /* (void ) memset( (void *) &psDnldContext->chk_integrity_crc, 2474 0, sizeof(psDnldContext->chk_integrity_crc)); */ 2475 psDnldContext->next_dnld_state = 2476 (uint8_t) phDnld_Complete_State; 2477 #endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ 2478 } 2479 break; 2480 } 2481 case phDnld_Verify_State: 2482 { 2483 status = phDnldNfc_Sequence( psDnldContext, 2484 pHwRef, pdata, length); 2485 break; 2486 } 2487 case phDnld_Complete_State: 2488 { 2489 uint8_t integrity_chk = 0xA5; 2490 2491 #if (NXP_FW_INTEGRITY_CHK >= 0x01) 2492 uint8_t verify_crc = 0x96; 2493 2494 if ( (NULL != psDnldContext->p_flash_code_crc) 2495 && (NULL != psDnldContext->p_patch_code_crc) 2496 && (NULL != psDnldContext->p_patch_table_crc) 2497 ) 2498 { 2499 uint8_t crc_i = 0; 2500 uint16_t patch_table_crc = 0; 2501 uint32_t flash_code_crc = 0; 2502 uint32_t patch_code_crc = 0; 2503 2504 for (crc_i = 0; crc_i < DNLD_CRC32_SIZE; crc_i++ ) 2505 { 2506 if (crc_i < DNLD_CRC16_SIZE ) 2507 { 2508 patch_table_crc = patch_table_crc 2509 | psDnldContext->chk_integrity_crc.patch_table.Chk_Crc16[crc_i] 2510 << (crc_i * BYTE_SIZE) ; 2511 } 2512 flash_code_crc = flash_code_crc 2513 | psDnldContext->chk_integrity_crc.flash_code.Chk_Crc32[crc_i] 2514 << (crc_i * BYTE_SIZE) ; 2515 patch_code_crc = patch_code_crc 2516 | psDnldContext->chk_integrity_crc.patch_code.Chk_Crc32[crc_i] 2517 << (crc_i * BYTE_SIZE) ; 2518 } 2519 verify_crc =(uint8_t)( (*((uint32_t *) psDnldContext->p_flash_code_crc)) != 2520 flash_code_crc ); 2521 verify_crc |=(uint8_t)( (*((uint32_t *) psDnldContext->p_patch_code_crc)) != 2522 patch_code_crc ); 2523 verify_crc |=(uint8_t)( (*((uint16_t *) psDnldContext->p_patch_table_crc)) != 2524 patch_table_crc ); 2525 } 2526 else 2527 { 2528 DNLD_PRINT(" FW_DNLD: Flash, Patch code and Patch Table CRC "); 2529 DNLD_PRINT(" Not Available in the Firmware \n"); 2530 } 2531 2532 #endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ 2533 2534 integrity_chk = psDnldContext->chk_integrity_crc.config_page.Chk_status + 2535 psDnldContext->chk_integrity_crc.patch_table.Chk_status + 2536 psDnldContext->chk_integrity_crc.flash_code.Chk_status + 2537 psDnldContext->chk_integrity_crc.patch_code.Chk_status; 2538 2539 if ( ( 0 != integrity_chk ) 2540 #if (NXP_FW_INTEGRITY_CHK >= 0x01) 2541 || ( 0 != verify_crc ) 2542 #endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ 2543 ) 2544 { 2545 status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); 2546 } 2547 break; 2548 } 2549 default: 2550 { 2551 status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED); 2552 break; 2553 } 2554 } 2555 2556 if (NFCSTATUS_PENDING == status) 2557 { 2558 /* Write/Receive is still pending */ 2559 } 2560 else 2561 { 2562 pphNfcIF_Notification_CB_t p_upper_notify = 2563 psDnldContext->p_upper_notify; 2564 void *p_upper_context = 2565 psDnldContext->p_upper_context; 2566 2567 DNLD_DEBUG(" FW_DNLD: Resume Termination Status = %X \n", status); 2568 2569 comp_info.status = status; 2570 2571 (void) phDal4Nfc_Unregister( 2572 psDnldContext->lower_interface.pcontext, pHwRef); 2573 phDnldNfc_Release_Lower(psDnldContext, pHwRef); 2574 phDnldNfc_Release_Resources(&psDnldContext); 2575 #ifndef NFC_TIMER_CONTEXT 2576 gpphDnldContext = psDnldContext; 2577 #endif 2578 /* Notify the Error/Success Scenario to the upper layer */ 2579 phDnldNfc_Notify( p_upper_notify, p_upper_context, pHwRef, (uint8_t) 2580 ((NFCSTATUS_SUCCESS == comp_info.status )? NFC_IO_SUCCESS: NFC_IO_ERROR), 2581 &comp_info ); 2582 } 2583 return status; 2584 } 2585 2586 STATIC 2587 NFCSTATUS 2588 phDnldNfc_Process_Response( 2589 phDnldNfc_sContext_t *psDnldContext, 2590 void *pHwRef, 2591 void *pdata, 2592 uint16_t length 2593 ) 2594 { 2595 NFCSTATUS status = NFCSTATUS_SUCCESS; 2596 phDnldNfc_sData_Hdr_t *resp_data = 2597 (phDnldNfc_sData_Hdr_t *) pdata; 2598 2599 PHNFC_UNUSED_VARIABLE(pHwRef); 2600 DNLD_DEBUG(" FW_DNLD: Receive Length = %X \n", length ); 2601 if(( psDnldContext->rx_info.rx_total == 0 ) 2602 && (PHDNLD_MIN_PACKET <= length) 2603 ) 2604 { 2605 psDnldContext->rx_info.rx_total = 2606 ((uint16_t)resp_data->frame_length[0] << BYTE_SIZE)| 2607 resp_data->frame_length[1]; 2608 if( psDnldContext->rx_info.rx_total + PHDNLD_MIN_PACKET == length ) 2609 { 2610 2611 DNLD_DEBUG(" FW_DNLD: Success Memory Read = %X \n", 2612 psDnldContext->rx_info.rx_total); 2613 #ifndef DNLD_SUMMARY 2614 /* DNLD_PRINT_BUFFER("Receive Buffer",pdata,length); */ 2615 #endif 2616 2617 } 2618 else 2619 { 2620 /* status = phDnldNfc_Receive( psDnldContext, pHwRef, 2621 psDnldContext->p_resp_buffer, 2622 (uint8_t)((psDnldContext->rx_info.rx_total <= PHDNLD_MAX_PACKET)? 2623 psDnldContext->rx_info.rx_total: PHDNLD_MAX_PACKET) ); */ 2624 DNLD_PRINT(" FW_DNLD: Invalid Receive length "); 2625 DNLD_DEBUG(": Length Expected = %X \n", 2626 (psDnldContext->rx_info.rx_total + PHDNLD_MIN_PACKET)); 2627 status = PHNFCSTVAL( CID_NFC_DNLD, 2628 NFCSTATUS_INVALID_RECEIVE_LENGTH ); 2629 } 2630 } 2631 else 2632 { 2633 /*TODO:*/ 2634 psDnldContext->rx_info.rx_total = 0 ; 2635 status = PHNFCSTVAL( CID_NFC_DNLD, 2636 NFCSTATUS_INVALID_RECEIVE_LENGTH ); 2637 } 2638 2639 return status; 2640 } 2641 2642 2643 2644 STATIC 2645 void 2646 phDnldNfc_Receive_Complete ( 2647 void *psContext, 2648 void *pHwRef, 2649 phNfc_sTransactionInfo_t *pInfo 2650 ) 2651 { 2652 NFCSTATUS status = NFCSTATUS_SUCCESS ; 2653 void *pdata = NULL ; 2654 phDnldNfc_sData_Hdr_t *resp_data = NULL; 2655 uint16_t length = 0 ; 2656 phNfc_sCompletionInfo_t comp_info = {0,0,0}; 2657 2658 DNLD_PRINT("\n FW_DNLD: Receive Response .... "); 2659 if ( (NULL != psContext) 2660 && (NULL != pInfo) 2661 && (NULL != pHwRef) 2662 ) 2663 { 2664 phDnldNfc_sContext_t *psDnldContext = 2665 (phDnldNfc_sContext_t *)psContext; 2666 status = pInfo->status ; 2667 length = pInfo->length ; 2668 pdata = pInfo->buffer; 2669 2670 if(status != NFCSTATUS_SUCCESS) 2671 { 2672 DNLD_DEBUG(" Failed. Status = %02X\n",status); 2673 /* Handle the Error Scenario */ 2674 } 2675 else if (NULL == pdata) 2676 { 2677 DNLD_DEBUG(" Failed. No data received. pdata = %02X\n",pdata); 2678 /* Handle the Error Scenario */ 2679 status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_FAILED ); 2680 } 2681 else if ((0 == length) 2682 || (PHDNLD_MIN_PACKET > length )) 2683 { 2684 DNLD_DEBUG(" Receive Response Length = %u .... \n",length); 2685 /* Handle the Error Scenario */ 2686 #ifndef HAL_SW_DNLD_RLEN 2687 status = PHNFCSTVAL( CID_NFC_DNLD, 2688 NFCSTATUS_INVALID_RECEIVE_LENGTH ); 2689 #endif 2690 } 2691 else 2692 { 2693 2694 #if defined(FW_DOWNLOAD_TIMER) && \ 2695 (FW_DOWNLOAD_TIMER == 2) 2696 if ( NXP_INVALID_TIMER_ID != psDnldContext->timer_id ) 2697 { 2698 phOsalNfc_Timer_Stop( psDnldContext->timer_id ); 2699 } 2700 2701 #endif 2702 2703 #ifndef DNLD_SUMMARY 2704 DNLD_PRINT_BUFFER("Receive Buffer",pdata,length); 2705 #endif 2706 DNLD_DEBUG(" Receive Response Length = %X. \n", length); 2707 2708 resp_data = (phDnldNfc_sData_Hdr_t *) pdata; 2709 2710 switch(resp_data->frame_type) 2711 { 2712 case PHDNLD_RESP_SUCCESS: 2713 { 2714 uint16_t resp_length = 2715 ((uint16_t)resp_data->frame_length[0] << BYTE_SIZE)| 2716 resp_data->frame_length[1]; 2717 switch ( psDnldContext->prev_cmd ) 2718 { 2719 case PHDNLD_CMD_READ : 2720 { 2721 if( PHDNLD_NO_OPERATION 2722 == psDnldContext->raw_mode_upgrade) 2723 { 2724 status = phDnldNfc_Process_Response( 2725 psDnldContext, pHwRef, pdata , length); 2726 2727 if (NFCSTATUS_SUCCESS != status) 2728 { 2729 /* psDnldContext->dnld_retry++; */ 2730 psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY; 2731 /* psDnldContext->dnld_retry < NXP_MAX_DNLD_RETRY */ 2732 } 2733 } 2734 else 2735 { 2736 2737 } 2738 break; 2739 } 2740 case PHDNLD_CMD_CHECK_INTEGRITY : 2741 { 2742 if( PHDNLD_NO_OPERATION 2743 == psDnldContext->raw_mode_upgrade) 2744 { 2745 #if (NXP_FW_INTEGRITY_CHK >= 0x01) 2746 phDnldNfc_sChkCrcComplete_t *p_dnld_crc_all = 2747 &psDnldContext->chk_integrity_crc; 2748 switch(psDnldContext->chk_integrity_param) 2749 { 2750 case CHK_INTEGRITY_CONFIG_PAGE_CRC: 2751 { 2752 (void)memcpy(&p_dnld_crc_all->config_page, 2753 (((uint8_t *)pdata) + PHDNLD_MIN_PACKET), resp_length); 2754 break; 2755 } 2756 case CHK_INTEGRITY_PATCH_TABLE_CRC: 2757 { 2758 (void)memcpy(&p_dnld_crc_all->patch_table, 2759 (((uint8_t *)pdata) + PHDNLD_MIN_PACKET), resp_length); 2760 break; 2761 } 2762 case CHK_INTEGRITY_FLASH_CODE_CRC: 2763 { 2764 (void)memcpy(&p_dnld_crc_all->flash_code, 2765 (((uint8_t *)pdata) + PHDNLD_MIN_PACKET), resp_length); 2766 break; 2767 } 2768 case CHK_INTEGRITY_PATCH_CODE_CRC: 2769 { 2770 (void)memcpy(&p_dnld_crc_all->patch_code, 2771 (((uint8_t *)pdata) + PHDNLD_MIN_PACKET), resp_length); 2772 break; 2773 } 2774 case CHK_INTEGRITY_COMPLETE_CRC: 2775 { 2776 (void)memcpy(p_dnld_crc_all, 2777 (((uint8_t *)pdata) + PHDNLD_MIN_PACKET), resp_length); 2778 DNLD_DEBUG(" FW_DNLD: Check Integrity Complete Structure Size = %X \n", 2779 sizeof(psDnldContext->chk_integrity_crc)); 2780 break; 2781 } 2782 default: 2783 { 2784 status = PHNFCSTVAL(CID_NFC_DNLD, 2785 NFCSTATUS_FEATURE_NOT_SUPPORTED); 2786 break; 2787 } 2788 } 2789 #endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ 2790 } 2791 else 2792 { 2793 psDnldContext->raw_mode_upgrade = 2794 (PHDNLD_SETUP_OPERATION | PHDNLD_ADVANCED_OPERATION); 2795 /* psDnldContext->raw_mode_upgrade = 2796 (psDnldContext->raw_mode_upgrade & 2797 ( psDnldContext->cur_frame_info & ~PHDNLD_MARKER_MASK )); */ 2798 } 2799 break; 2800 } 2801 case PHDNLD_CMD_WRITE: 2802 { 2803 psDnldContext->dnld_retry = 0; 2804 break; 2805 } 2806 case PHDNLD_CMD_SEC_WRITE: 2807 { 2808 psDnldContext->dnld_retry = 0; 2809 break; 2810 } 2811 case PHDNLD_CMD_ACTIVATE_PATCH: 2812 case PHDNLD_CMD_CHECK: 2813 default: 2814 { 2815 if( PHDNLD_NO_OPERATION 2816 == psDnldContext->raw_mode_upgrade) 2817 { 2818 if( ( (PHDNLD_MIN_PACKET > length) 2819 || ( 0 != resp_length) ) 2820 ) 2821 { 2822 psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY; 2823 status = PHNFCSTVAL( CID_NFC_DNLD, 2824 NFCSTATUS_INVALID_RECEIVE_LENGTH ); 2825 } 2826 else 2827 { 2828 psDnldContext->dnld_retry = 0; 2829 } 2830 } 2831 else 2832 { 2833 psDnldContext->raw_mode_upgrade = 2834 (psDnldContext->raw_mode_upgrade & ~PHDNLD_RECOVER_OPERATION); 2835 } 2836 break; 2837 } 2838 } /* End of the Previous Command Switch Case */ 2839 break; 2840 }/* Case PHDNLD_RESP_SUCCESS*/ 2841 case PHDNLD_RESP_TIMEOUT: 2842 case PHDNLD_RESP_CRC_ERROR: 2843 case PHDNLD_RESP_WRITE_ERROR: 2844 { 2845 if(psDnldContext->dnld_retry < NXP_MAX_DNLD_RETRY ) 2846 { 2847 psDnldContext->dnld_retry++; 2848 } 2849 status = PHNFCSTVAL(CID_NFC_DNLD, 2850 resp_data->frame_type); 2851 break; 2852 } 2853 /* fall through */ 2854 case PHDNLD_RESP_ACCESS_DENIED: 2855 case PHDNLD_RESP_INVALID_PARAMETER: 2856 case PHDNLD_RESP_INVALID_LENGTH: 2857 /* Initial Frame Checksum */ 2858 case PHDNLD_RESP_CHKSUM_ERROR: 2859 case PHDNLD_RESP_MEMORY_UPDATE_ERROR: 2860 { 2861 psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY; 2862 status = PHNFCSTVAL(CID_NFC_DNLD, 2863 resp_data->frame_type); 2864 break; 2865 } 2866 case PHDNLD_RESP_PROTOCOL_ERROR: 2867 { 2868 if(( PHDNLD_NO_OPERATION 2869 == psDnldContext->raw_mode_upgrade) 2870 || ( PHDNLD_ADVANCED_OPERATION 2871 == psDnldContext->raw_mode_upgrade) 2872 ) 2873 { 2874 psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY; 2875 status = PHNFCSTVAL(CID_NFC_DNLD, 2876 NFCSTATUS_INVALID_FORMAT); 2877 } 2878 else if( (PHDNLD_NORMAL_OPERATION 2879 & psDnldContext->raw_mode_upgrade) 2880 ) 2881 { 2882 psDnldContext->raw_mode_upgrade = 2883 (psDnldContext->raw_mode_upgrade & ~PHDNLD_NORMAL_OPERATION); 2884 } 2885 else if ( PHDNLD_RECOVER_OPERATION 2886 & psDnldContext->raw_mode_upgrade ) 2887 { 2888 psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY; 2889 status = PHNFCSTVAL(CID_NFC_DNLD, 2890 NFCSTATUS_INVALID_FORMAT); 2891 } 2892 else 2893 { 2894 psDnldContext->raw_mode_upgrade = 2895 (psDnldContext->raw_mode_upgrade & 2896 ~( psDnldContext->cur_frame_info & ~PHDNLD_MARKER_MASK )); 2897 } 2898 break; 2899 } 2900 case PHDNLD_RESP_VERSION_UPTODATE: 2901 { 2902 /* TODO: to make sure that the Advance Frames are sent to get 2903 * the updated status */ 2904 if ( PHDNLD_ADVANCED_OPERATION 2905 == psDnldContext->raw_mode_upgrade) 2906 { 2907 status = ( CID_NFC_DNLD << BYTE_SIZE ) ; 2908 } 2909 else if ( PHDNLD_NO_OPERATION 2910 != psDnldContext->raw_mode_upgrade) 2911 { 2912 2913 psDnldContext->raw_mode_upgrade = 2914 (psDnldContext->raw_mode_upgrade & 2915 ~( psDnldContext->cur_frame_info & ~PHDNLD_MARKER_MASK )); 2916 } 2917 else 2918 { 2919 } 2920 break; 2921 } 2922 case PHDNLD_RESP_CMD_NOT_SUPPORTED: 2923 { 2924 2925 if ( PHDNLD_NO_OPERATION 2926 == psDnldContext->raw_mode_upgrade) 2927 { 2928 status = PHNFCSTVAL(CID_NFC_DNLD, 2929 NFCSTATUS_FEATURE_NOT_SUPPORTED); 2930 } 2931 else if ( PHDNLD_ADVANCED_OPERATION 2932 == psDnldContext->raw_mode_upgrade) 2933 { 2934 status = PHNFCSTVAL(CID_NFC_DNLD, 2935 NFCSTATUS_FEATURE_NOT_SUPPORTED); 2936 } 2937 #if 0 2938 else if( (PHDNLD_NORMAL_OPERATION 2939 & psDnldContext->raw_mode_upgrade) 2940 ) 2941 { 2942 psDnldContext->raw_mode_upgrade = 2943 (psDnldContext->raw_mode_upgrade & ~PHDNLD_NORMAL_OPERATION); 2944 } 2945 else if ( PHDNLD_SETUP_OPERATION 2946 & psDnldContext->raw_mode_upgrade ) 2947 { 2948 psDnldContext->raw_mode_upgrade = 2949 (psDnldContext->raw_mode_upgrade & ~PHDNLD_SETUP_OPERATION); 2950 } 2951 #endif 2952 else 2953 { 2954 psDnldContext->raw_mode_upgrade = 2955 (psDnldContext->raw_mode_upgrade & 2956 ~( psDnldContext->cur_frame_info & ~PHDNLD_MARKER_MASK )); 2957 } 2958 break; 2959 } 2960 /* The Chaining of the Command Frame 2961 was Successful in the Download Mode */ 2962 case PHDNLD_RESP_CHAINING_SUCCESS: 2963 { 2964 /* TODO: Handle the Corner Case Scenarios 2965 * the updated status */ 2966 psDnldContext->dnld_retry = 0x00; 2967 break; 2968 } 2969 /* The Error during the Chaining the Command Frame in the Download Mode */ 2970 case PHDNLD_RESP_CHAINING_ERROR: 2971 { 2972 /* TODO: Restart the Chunk in Corner Case 2973 * the updated status */ 2974 psDnldContext->dnld_retry++; 2975 phDnldNfc_Tx_Reset(psDnldContext); 2976 break; 2977 } 2978 /* The Command is not allowed anymore in the Download Mode */ 2979 case PHDNLD_RESP_CMD_NOT_ALLOWED: 2980 default: 2981 { 2982 psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY; 2983 status = PHNFCSTVAL(CID_NFC_DNLD, 2984 NFCSTATUS_NOT_ALLOWED); 2985 break; 2986 } 2987 2988 } /* End of the Response Frame Type Switch */ 2989 2990 if (NFCSTATUS_PENDING != status) 2991 { 2992 if ((NFCSTATUS_SUCCESS != status) && 2993 (psDnldContext->dnld_retry >= NXP_MAX_DNLD_RETRY)) 2994 { 2995 pphNfcIF_Notification_CB_t p_upper_notify = 2996 psDnldContext->p_upper_notify; 2997 void *p_upper_context = 2998 psDnldContext->p_upper_context; 2999 3000 comp_info.status = status; 3001 DNLD_DEBUG(" FW_DNLD: Termination in Receive, Status = %X \n", status); 3002 status = phDal4Nfc_Unregister( 3003 psDnldContext->lower_interface.pcontext, pHwRef); 3004 phDnldNfc_Release_Lower(psDnldContext, pHwRef); 3005 phDnldNfc_Release_Resources(&psDnldContext); 3006 #ifndef NFC_TIMER_CONTEXT 3007 gpphDnldContext = psDnldContext; 3008 #endif 3009 /* Notify the Error/Success Scenario to the upper layer */ 3010 phDnldNfc_Notify( p_upper_notify, p_upper_context, pHwRef, 3011 (uint8_t) NFC_IO_ERROR, &comp_info ); 3012 } 3013 else if ( (NFCSTATUS_SUCCESS != status) && 3014 (NFCSTATUS_SUCCESS == PHNFCSTATUS(status)) 3015 ) 3016 { 3017 pphNfcIF_Notification_CB_t p_upper_notify = 3018 psDnldContext->p_upper_notify; 3019 void *p_upper_context = 3020 psDnldContext->p_upper_context; 3021 3022 comp_info.status = NFCSTATUS_SUCCESS; 3023 DNLD_DEBUG(" FW_DNLD: Termination in Receive, Status = %X \n", status); 3024 status = phDal4Nfc_Unregister( 3025 psDnldContext->lower_interface.pcontext, pHwRef); 3026 phDnldNfc_Release_Lower(psDnldContext, pHwRef); 3027 phDnldNfc_Release_Resources(&psDnldContext); 3028 #ifndef NFC_TIMER_CONTEXT 3029 gpphDnldContext = psDnldContext; 3030 #endif 3031 /* Notify the Error/Success Scenario to the upper layer */ 3032 phDnldNfc_Notify( p_upper_notify, p_upper_context, pHwRef, 3033 (uint8_t) NFC_IO_SUCCESS, &comp_info ); 3034 3035 } 3036 else if (NFCSTATUS_FEATURE_NOT_SUPPORTED == PHNFCSTATUS(status)) 3037 { 3038 pphNfcIF_Notification_CB_t p_upper_notify = 3039 psDnldContext->p_upper_notify; 3040 void *p_upper_context = 3041 psDnldContext->p_upper_context; 3042 3043 comp_info.status = status; 3044 DNLD_DEBUG(" FW_DNLD: Termination in Receive, Status = %X \n", status); 3045 status = phDal4Nfc_Unregister( 3046 psDnldContext->lower_interface.pcontext, pHwRef); 3047 phDnldNfc_Release_Lower(psDnldContext, pHwRef); 3048 phDnldNfc_Release_Resources(&psDnldContext); 3049 #ifndef NFC_TIMER_CONTEXT 3050 gpphDnldContext = psDnldContext; 3051 #endif 3052 /* Notify the Error/Success Scenario to the upper layer */ 3053 phDnldNfc_Notify( p_upper_notify, p_upper_context, pHwRef, 3054 (uint8_t) NFC_IO_SUCCESS, &comp_info ); 3055 3056 } 3057 else 3058 { 3059 /* DNLD_PRINT(" FW_DNLD: Successful.\n"); */ 3060 psDnldContext->resp_length = /* PHDNLD_MIN_PACKET */ 0 ; 3061 status = phDnldNfc_Set_Seq(psDnldContext, 3062 DNLD_SEQ_UPDATE); 3063 status = phDnldNfc_Resume( psDnldContext, 3064 pHwRef, pdata, length ); 3065 } 3066 } 3067 } /* End of status != Success */ 3068 } 3069 } 3070 3071 3072 STATIC 3073 void 3074 phDnldNfc_Send_Complete ( 3075 void *psContext, 3076 void *pHwRef, 3077 phNfc_sTransactionInfo_t *pInfo 3078 ) 3079 { 3080 NFCSTATUS status = NFCSTATUS_SUCCESS ; 3081 uint16_t length = 0; 3082 3083 DNLD_PRINT(" FW_DNLD: Send Data .... "); 3084 if ( (NULL != psContext) 3085 && (NULL != pInfo) 3086 && (NULL != pHwRef) 3087 ) 3088 { 3089 phDnldNfc_sContext_t *psDnldContext = 3090 (phDnldNfc_sContext_t *)psContext; 3091 status = pInfo->status ; 3092 length = pInfo->length ; 3093 if(status != NFCSTATUS_SUCCESS) 3094 { 3095 DNLD_DEBUG(" Failed. Status = %02X\n",status); 3096 /* Handle the Error Scenario */ 3097 } 3098 else 3099 { 3100 DNLD_PRINT(" Successful.\n"); 3101 (void)memset((void *)&psDnldContext->dnld_data, 0, 3102 sizeof(psDnldContext->dnld_data)); 3103 if ((PHDNLD_CMD_SET_HIF != psDnldContext->prev_cmd) 3104 && (PHDNLD_CMD_RESET != psDnldContext->prev_cmd)) 3105 { 3106 psDnldContext->rx_info.rx_total = 0; 3107 status = phDnldNfc_Receive( psDnldContext, pHwRef, 3108 (uint8_t *)(&psDnldContext->dnld_resp), 3109 psDnldContext->resp_length); 3110 } 3111 else 3112 { 3113 psDnldContext->resp_length = 0; 3114 psDnldContext->dnld_retry = 0; 3115 /* clock unstable after SW reset command, especially on UART 3116 * platform because of its sensitivity to clock. Experimentally 3117 * we found clock unstable for 750us. Delay for 5ms to be sure. 3118 */ 3119 if( PHDNLD_CMD_RESET == psDnldContext->prev_cmd ) 3120 { 3121 DO_DELAY(PHDNLD_DNLD_DELAY); 3122 } 3123 #if defined(FW_DOWNLOAD_TIMER) && \ 3124 (FW_DOWNLOAD_TIMER == 2) 3125 3126 if ( NXP_INVALID_TIMER_ID != psDnldContext->timer_id ) 3127 { 3128 phOsalNfc_Timer_Stop( psDnldContext->timer_id ); 3129 } 3130 #endif 3131 3132 status = phDnldNfc_Set_Seq(psDnldContext, 3133 DNLD_SEQ_UPDATE); 3134 } 3135 3136 if(NFCSTATUS_SUCCESS == status ) 3137 { 3138 status = phDnldNfc_Resume( psDnldContext, pHwRef, NULL, length); 3139 } 3140 3141 } /* End of status != Success */ 3142 3143 } /* End of Context != NULL */ 3144 } 3145 3146 3147 3148 STATIC 3149 NFCSTATUS 3150 phDnldNfc_Send_Command( 3151 phDnldNfc_sContext_t *psDnldContext, 3152 void *pHwRef, 3153 uint8_t cmd, 3154 void *params, 3155 uint16_t param_length 3156 ) 3157 { 3158 NFCSTATUS status = NFCSTATUS_SUCCESS; 3159 uint16_t tx_length = 0; 3160 uint16_t rx_length = 0; 3161 uint8_t **pp_resp_data = &psDnldContext->p_resp_buffer; 3162 phDnldNfc_sData_t *p_dnld_data = 3163 (phDnldNfc_sData_t *)psDnldContext->dnld_data; 3164 3165 switch(cmd) 3166 { 3167 case PHDNLD_CMD_RESET: 3168 { 3169 (void)memset((void *)&psDnldContext->dnld_data, 0, 3170 sizeof(psDnldContext->dnld_data)); 3171 break; 3172 } 3173 case PHDNLD_CMD_READ: 3174 { 3175 phDnldNfc_sData_t *p_dnld_data = 3176 (phDnldNfc_sData_t *)psDnldContext->dnld_data; 3177 phDnldNfc_sParam_t *param_info = /* (phDnldNfc_sParam_t *)params */ 3178 &p_dnld_data->param_info.data_param; 3179 tx_length = PHDNLD_CMD_READ_LEN; 3180 if (NULL != *pp_resp_data) 3181 { 3182 phOsalNfc_FreeMemory(*pp_resp_data); 3183 *pp_resp_data = NULL; 3184 } 3185 rx_length = (uint16_t) (((uint16_t)param_info->data_len[0] 3186 << BYTE_SIZE) + param_info->data_len[1]); 3187 3188 psDnldContext->resp_length = 3189 (( rx_length + PHDNLD_MIN_PACKET )); 3190 (void)phDnldNfc_Allocate_Resource( (void **) pp_resp_data, 3191 rx_length); 3192 break; 3193 } 3194 case PHDNLD_CMD_WRITE: 3195 case PHDNLD_CMD_SEC_WRITE: 3196 { 3197 phDnldNfc_sData_t *p_dnld_data = 3198 (phDnldNfc_sData_t *)psDnldContext->dnld_data; 3199 phDnldNfc_sParam_t *param_info = /* (phDnldNfc_sParam_t *)params */ 3200 &p_dnld_data->param_info.data_param; 3201 tx_length = (uint16_t) (((uint16_t)param_info->data_len[0] 3202 << BYTE_SIZE) + param_info->data_len[1] 3203 + PHDNLD_CMD_WRITE_MIN_LEN ); 3204 3205 psDnldContext->resp_length = PHDNLD_MIN_PACKET; 3206 if ((0 != param_length) && (NULL != params)) 3207 { 3208 (void)memcpy(param_info->data_packet, params, param_length); 3209 } 3210 break; 3211 } 3212 case PHDNLD_CMD_CHECK: 3213 { 3214 tx_length = PHDNLD_CMD_CHECK_LEN; 3215 psDnldContext->resp_length = PHDNLD_MIN_PACKET; 3216 break; 3217 } 3218 case PHDNLD_CMD_ENCAPSULATE: 3219 { 3220 uint8_t i = 0x00; 3221 if ((0 != param_length) && (NULL != params)) 3222 { 3223 p_dnld_data->frame_type = 3224 PHDNLD_CMD_ENCAPSULATE; 3225 (void)memcpy((void *)( ((uint8_t *)p_dnld_data) 3226 + PHDNLD_FRAME_DATA_OFFSET) 3227 , params, param_length); 3228 tx_length = param_length; 3229 3230 p_dnld_data->frame_length[i++] = 3231 (uint8_t)(tx_length >> BYTE_SIZE); 3232 p_dnld_data->frame_length[i] = 3233 (uint8_t)( tx_length & BYTE_MASK ); 3234 tx_length += PHDNLD_FRAME_DATA_OFFSET; 3235 3236 psDnldContext->resp_length = PHDNLD_MIN_PACKET; 3237 3238 status = phDnldNfc_Send( psDnldContext, pHwRef , 3239 (uint8_t *)p_dnld_data, tx_length); 3240 } 3241 else 3242 { 3243 status = PHNFCSTVAL(CID_NFC_DNLD, 3244 NFCSTATUS_NOT_ALLOWED); 3245 } 3246 break; 3247 } 3248 case PHDNLD_CMD_SET_HIF: 3249 { 3250 tx_length++; 3251 psDnldContext->resp_length = PHDNLD_MIN_PACKET; 3252 break; 3253 } 3254 case PHDNLD_CMD_ACTIVATE_PATCH: 3255 { 3256 psDnldContext->resp_length = PHDNLD_MIN_PACKET; 3257 if ((NULL != params) && ( param_length > 0 )) 3258 { 3259 p_dnld_data->param_info.cmd_param = 3260 (*(uint8_t *)params); 3261 tx_length = param_length; 3262 } 3263 else 3264 { 3265 p_dnld_data->param_info.cmd_param = FALSE; 3266 tx_length++; 3267 } 3268 break; 3269 } 3270 case PHDNLD_CMD_CHECK_INTEGRITY: 3271 { 3272 #if (NXP_FW_INTEGRITY_CHK >= 0x01) 3273 if ((NULL != params) && ( param_length > 0 )) 3274 { 3275 psDnldContext->chk_integrity_param = 3276 (phDnldNfc_eChkCrc_t)(*(uint8_t *)params); 3277 tx_length = param_length; 3278 } 3279 else 3280 { 3281 psDnldContext->chk_integrity_param = CHK_INTEGRITY_COMPLETE_CRC; 3282 tx_length++; 3283 } 3284 p_dnld_data->param_info.cmd_param = 3285 (uint8_t) psDnldContext->chk_integrity_param; 3286 switch(psDnldContext->chk_integrity_param) 3287 { 3288 case CHK_INTEGRITY_CONFIG_PAGE_CRC: 3289 case CHK_INTEGRITY_PATCH_TABLE_CRC: 3290 { 3291 psDnldContext->resp_length = PHDNLD_MIN_PACKET 3292 + CHECK_INTEGRITY_RESP_CRC16_LEN; 3293 break; 3294 } 3295 case CHK_INTEGRITY_FLASH_CODE_CRC: 3296 case CHK_INTEGRITY_PATCH_CODE_CRC: 3297 { 3298 psDnldContext->resp_length = PHDNLD_MIN_PACKET 3299 + CHECK_INTEGRITY_RESP_CRC32_LEN; 3300 break; 3301 } 3302 case CHK_INTEGRITY_COMPLETE_CRC: 3303 default: 3304 { 3305 psDnldContext->resp_length = PHDNLD_MIN_PACKET 3306 + CHECK_INTEGRITY_RESP_COMP_LEN; 3307 break; 3308 } 3309 } 3310 #else 3311 tx_length++; 3312 p_dnld_data->param_info.cmd_param = 3313 (uint8_t) CHK_INTEGRITY_COMPLETE_CRC; 3314 3315 #endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ 3316 break; 3317 } 3318 default: 3319 { 3320 status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FEATURE_NOT_SUPPORTED); 3321 break; 3322 } 3323 } 3324 if (NFCSTATUS_SUCCESS == status) 3325 { 3326 uint8_t i = 0; 3327 3328 p_dnld_data->frame_type = cmd; 3329 p_dnld_data->frame_length[i++] = 3330 (uint8_t)(tx_length >> BYTE_SIZE); 3331 p_dnld_data->frame_length[i] = 3332 (uint8_t)( tx_length & BYTE_MASK ); 3333 tx_length = tx_length + PHDNLD_MIN_PACKET; 3334 status = phDnldNfc_Send( psDnldContext, pHwRef , 3335 (uint8_t *)p_dnld_data, tx_length); 3336 if(NFCSTATUS_PENDING == status) 3337 { 3338 psDnldContext->prev_cmd = cmd; 3339 3340 if( PHDNLD_CMD_RESET == cmd ) 3341 DO_DELAY(PHDNLD_DNLD_DELAY); //this seems like its on the wrong thread 3342 } 3343 } 3344 3345 return status; 3346 } 3347 3348 static 3349 NFCSTATUS 3350 phDnldNfc_Check_FW( 3351 phHal_sHwReference_t *pHwRef, 3352 fw_data_hdr_t *cur_fw_hdr 3353 ) 3354 { 3355 NFCSTATUS status = NFCSTATUS_FAILED; 3356 3357 if ( !pHwRef->device_info.fw_version ) 3358 { 3359 /* Override the Firmware Version Check and upgrade*/; 3360 DNLD_PRINT(" FW_DNLD_CHK: Forceful Upgrade of the Firmware .... Required \n"); 3361 status = NFCSTATUS_SUCCESS; 3362 } 3363 else if ( (pHwRef->device_info.fw_version >> (BYTE_SIZE * 2)) 3364 != ( cur_fw_hdr->fw_version >> (BYTE_SIZE * 2) )) 3365 { 3366 /* Check for the Compatible Romlib Version for the Hardware */ 3367 DNLD_PRINT(" FW_DNLD: IC Hardware Version Mismatch.. \n"); 3368 status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_NOT_ALLOWED ); 3369 } 3370 else if (( pHwRef->device_info.fw_version < cur_fw_hdr->fw_version ) 3371 ) 3372 { 3373 /* TODO: Firmware Version Check and upgrade*/ 3374 DNLD_PRINT(" FW_DNLD: Older Firmware Upgrading to newerone.... \n"); 3375 status = NFCSTATUS_SUCCESS; 3376 } 3377 #ifdef NXP_FW_CHK_LATEST 3378 else if (( pHwRef->device_info.fw_version > cur_fw_hdr->fw_version ) 3379 ) 3380 { 3381 DNLD_PRINT(" FW_DNLD: Newer than the Stored One .... \n"); 3382 status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_NOT_ALLOWED ); 3383 } 3384 #endif /* NXP_FW_CHK_LATEST */ 3385 else 3386 { 3387 DNLD_PRINT(" FW_DNLD: Already Updated .... \n"); 3388 status = ( CID_NFC_DNLD << BYTE_SIZE ) ; 3389 } 3390 3391 return status; 3392 } 3393 3394 3395 static 3396 NFCSTATUS 3397 phDnldNfc_Process_FW( 3398 phDnldNfc_sContext_t *psDnldContext, 3399 phHal_sHwReference_t *pHwRef 3400 #ifdef NXP_FW_PARAM 3401 ,uint8_t *nxp_nfc_fw 3402 ,uint32_t nxp_fw_len 3403 #endif 3404 ) 3405 { 3406 NFCSTATUS status = NFCSTATUS_FAILED; 3407 section_info_t *p_cur_sec = NULL; 3408 static unsigned sec_type; 3409 uint32_t fw_index = 0; 3410 #ifdef NXP_NFC_MULTIPLE_FW 3411 phDnldNfc_sFwImageInfo_t *p_cur_fw = NULL; 3412 #endif /* #ifdef NXP_NFC_MULTIPLE_FW */ 3413 fw_data_hdr_t *cur_fw_hdr = NULL; 3414 uint8_t sec_index = 0; 3415 uint8_t i = 0; 3416 3417 psDnldContext->p_img_hdr = (img_data_hdr_t *) nxp_nfc_fw; 3418 3419 #ifdef NXP_NFC_MULTIPLE_FW 3420 3421 /* TODO: Create a memory of pointers to store all the Firmwares */ 3422 if( (NXP_NFC_IMAG_FW_MAX > psDnldContext->p_img_hdr->no_of_fw_img) 3423 && (0 != psDnldContext->p_img_hdr->no_of_fw_img) 3424 ) 3425 { 3426 ( void )phDnldNfc_Allocate_Resource((void **)&psDnldContext->p_img_info, 3427 (psDnldContext->p_img_hdr->no_of_fw_img * sizeof(phDnldNfc_sFwImageInfo_t))); 3428 3429 if(NULL != psDnldContext->p_img_info) 3430 { 3431 p_cur_fw = psDnldContext->p_img_info; 3432 } 3433 } 3434 #endif /* #ifdef NXP_NFC_MULTIPLE_FW */ 3435 3436 fw_index = sizeof (img_data_hdr_t); 3437 3438 for ( i=0; i < psDnldContext->p_img_hdr->no_of_fw_img; i++ ) 3439 { 3440 3441 psDnldContext->p_fw_hdr = (fw_data_hdr_t *) ( nxp_nfc_fw + fw_index ); 3442 3443 #ifdef NXP_NFC_MULTIPLE_FW 3444 if(NULL != p_cur_fw) 3445 { 3446 ( p_cur_fw + i)->p_fw_hdr = psDnldContext->p_fw_hdr; 3447 } 3448 #endif /* #ifdef NXP_NFC_MULTIPLE_FW */ 3449 cur_fw_hdr = psDnldContext->p_fw_hdr; 3450 3451 fw_index = fw_index + (cur_fw_hdr->fw_hdr_len * PNDNLD_WORD_LEN); 3452 3453 status = phDnldNfc_Check_FW( pHwRef, cur_fw_hdr); 3454 3455 } 3456 3457 if ( ( NFCSTATUS_SUCCESS == status ) 3458 #if defined (NXP_FW_INTEGRITY_VERIFY) 3459 || (NFCSTATUS_SUCCESS == PHNFCSTATUS(status) ) 3460 #endif /* !defined (NXP_FW_INTEGRITY_VERIFY) */ 3461 ) 3462 { 3463 if( (BYTE_MASK > cur_fw_hdr->no_of_sections) 3464 && (0 != cur_fw_hdr->no_of_sections) 3465 ) 3466 { 3467 (void) phDnldNfc_Allocate_Resource((void **)&psDnldContext->p_fw_sec, 3468 (cur_fw_hdr->no_of_sections * sizeof(section_info_t))); 3469 3470 if(NULL != psDnldContext->p_fw_sec) 3471 { 3472 DNLD_DEBUG(" FW_DNLD: FW Index : %x \n", 3473 fw_index ); 3474 3475 DNLD_DEBUG(" FW_DNLD: No of Sections : %x \n\n", 3476 cur_fw_hdr->no_of_sections); 3477 3478 for(sec_index = 0; sec_index 3479 < cur_fw_hdr->no_of_sections; sec_index++ ) 3480 { 3481 p_cur_sec = ((section_info_t *) 3482 (psDnldContext->p_fw_sec + sec_index )); 3483 3484 p_cur_sec->p_sec_hdr = (section_hdr_t *) 3485 (nxp_nfc_fw + fw_index); 3486 3487 DNLD_DEBUG(" FW_DNLD: Section %x \n", sec_index); 3488 DNLD_DEBUG(" FW_DNLD: Section Header Len : %x ", 3489 p_cur_sec->p_sec_hdr->section_hdr_len); 3490 DNLD_DEBUG(" Section Address : %x ", 3491 p_cur_sec->p_sec_hdr->section_address); 3492 DNLD_DEBUG(" Section Length : %x ", 3493 p_cur_sec->p_sec_hdr->section_length); 3494 DNLD_DEBUG(" Section Memory Type : %x \n", 3495 p_cur_sec->p_sec_hdr->section_mem_type); 3496 3497 sec_type = (unsigned int)p_cur_sec->p_sec_hdr->section_mem_type; 3498 3499 if((sec_type & DNLD_TRIM_MASK)) 3500 { 3501 p_cur_sec->p_trim_data = (uint8_t *) 3502 (nxp_nfc_fw + fw_index + sizeof(section_hdr_t)); 3503 } 3504 else 3505 { 3506 p_cur_sec->p_trim_data = NULL; 3507 } 3508 3509 if (0 == sec_index) 3510 { 3511 if ((sec_type & DNLD_SM_UNLOCK_MASK)) 3512 { 3513 (void)phDnldNfc_Set_Seq(psDnldContext, 3514 DNLD_SEQ_UNLOCK); 3515 } 3516 else 3517 { 3518 (void)phDnldNfc_Set_Seq(psDnldContext, 3519 DNLD_SEQ_INIT); 3520 } 3521 } 3522 p_cur_sec->section_read = FALSE; 3523 3524 p_cur_sec->section_offset = 0; 3525 3526 p_cur_sec->p_sec_data = ((uint8_t *) nxp_nfc_fw) + fw_index + 3527 (p_cur_sec->p_sec_hdr->section_hdr_len * PNDNLD_WORD_LEN); 3528 3529 fw_index = fw_index + 3530 (p_cur_sec->p_sec_hdr->section_hdr_len * PNDNLD_WORD_LEN) 3531 + p_cur_sec->p_sec_hdr->section_length; 3532 3533 3534 if( 0 != p_cur_sec->p_sec_hdr->section_checksum ) 3535 { 3536 DNLD_DEBUG(" FW_DNLD: Section checksum : %x \n", 3537 p_cur_sec->p_sec_hdr->section_checksum ); 3538 3539 p_cur_sec->p_sec_chksum = ( uint8_t *)(nxp_nfc_fw + fw_index); 3540 3541 fw_index = fw_index + 3542 p_cur_sec->p_sec_hdr->section_checksum; 3543 } 3544 3545 DNLD_DEBUG(" FW_DNLD: FW Index : %x \n", fw_index ); 3546 3547 #if (NXP_FW_INTEGRITY_CHK >= 0x01) 3548 switch( p_cur_sec->p_sec_hdr->section_address ) 3549 { 3550 case DNLD_FW_CODE_ADDR: 3551 { 3552 psDnldContext->p_flash_code_crc = 3553 p_cur_sec->p_sec_data 3554 + p_cur_sec->p_sec_hdr->section_length 3555 - DNLD_CRC32_SIZE; 3556 break; 3557 } 3558 case DNLD_PATCH_CODE_ADDR: 3559 { 3560 psDnldContext->p_patch_code_crc = 3561 p_cur_sec->p_sec_data 3562 + p_cur_sec->p_sec_hdr->section_length 3563 - DNLD_CRC32_SIZE; 3564 break; 3565 } 3566 case DNLD_PATCH_TABLE_ADDR: 3567 { 3568 psDnldContext->p_patch_table_crc = 3569 p_cur_sec->p_sec_data 3570 + p_cur_sec->p_sec_hdr->section_length 3571 - DNLD_CRC16_SIZE; 3572 break; 3573 } 3574 default: 3575 { 3576 break; 3577 } 3578 3579 } /* End of Address Switch */ 3580 #endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ 3581 } /* End of For Loop */ 3582 } /* End of the Null Check */ 3583 else 3584 { 3585 status = PHNFCSTVAL(CID_NFC_DNLD, 3586 NFCSTATUS_INSUFFICIENT_RESOURCES); 3587 } 3588 3589 } 3590 else if ( 3591 (0 == cur_fw_hdr->no_of_sections) 3592 && (PHDNLD_FW_PATCH_SEC == cur_fw_hdr->fw_patch) 3593 ) 3594 { 3595 psDnldContext->p_fw_raw = (uint8_t *)(nxp_nfc_fw + fw_index); 3596 3597 psDnldContext->raw_mode_upgrade = PHDNLD_COMPLETE_OPERATION; 3598 3599 (void)phDnldNfc_Set_Seq(psDnldContext, 3600 DNLD_SEQ_RAW); 3601 } 3602 else 3603 { 3604 DNLD_PRINT("********* Empty Section and Firmware ******************\n\n"); 3605 } 3606 3607 DNLD_PRINT("*******************************************\n\n"); 3608 3609 } 3610 return status; 3611 } 3612 3613 #if !defined (NXP_FW_INTEGRITY_VERIFY) 3614 3615 NFCSTATUS 3616 phDnldNfc_Run_Check( 3617 phHal_sHwReference_t *pHwRef 3618 #ifdef NXP_FW_PARAM 3619 ,uint8_t *nxp_nfc_fw 3620 uint32_t fw_length 3621 #endif 3622 ) 3623 { 3624 NFCSTATUS status = NFCSTATUS_FAILED; 3625 uint32_t fw_index = 0; 3626 img_data_hdr_t *p_img_hdr = NULL; 3627 fw_data_hdr_t *p_fw_hdr = NULL; 3628 fw_data_hdr_t *cur_fw_hdr = NULL; 3629 uint8_t i = 0; 3630 3631 p_img_hdr = (img_data_hdr_t *) nxp_nfc_fw; 3632 3633 fw_index = sizeof (img_data_hdr_t); 3634 3635 for ( i=0; i < p_img_hdr->no_of_fw_img; i++ ) 3636 { 3637 p_fw_hdr = (fw_data_hdr_t *) ( nxp_nfc_fw + fw_index ); 3638 /* TODO: Create a memory of pointers to store all the Firmwares */ 3639 cur_fw_hdr = p_fw_hdr; 3640 3641 fw_index = fw_index + (cur_fw_hdr->fw_hdr_len * PNDNLD_WORD_LEN); 3642 3643 status = phDnldNfc_Check_FW( pHwRef, cur_fw_hdr); 3644 } 3645 return status; 3646 } 3647 3648 #endif /* #if !defined (NXP_FW_INTEGRITY_VERIFY) */ 3649 3650 3651 STATIC 3652 void 3653 phDnldNfc_Abort ( 3654 uint32_t abort_id 3655 #ifdef NFC_TIMER_CONTEXT 3656 , void *dnld_cntxt 3657 #endif 3658 ) 3659 { 3660 3661 phNfc_sCompletionInfo_t comp_info = {0,0,0}; 3662 3663 phDnldNfc_sContext_t *p_dnld_context = NULL; 3664 3665 #ifdef NFC_TIMER_CONTEXT 3666 p_dnld_context = (phDnldNfc_sContext_t *)dnld_cntxt; 3667 #else 3668 p_dnld_context = gpphDnldContext; 3669 #endif 3670 3671 if ( ( NULL != p_dnld_context) 3672 && (abort_id == p_dnld_context->timer_id )) 3673 { 3674 pphNfcIF_Notification_CB_t p_upper_notify = 3675 p_dnld_context->p_upper_notify; 3676 void *p_upper_context = 3677 p_dnld_context->p_upper_context; 3678 phHal_sHwReference_t *pHwRef = p_dnld_context->p_hw_ref; 3679 3680 (void)phDal4Nfc_Unregister( 3681 p_dnld_context->lower_interface.pcontext, pHwRef ); 3682 phDnldNfc_Release_Lower(p_dnld_context, pHwRef); 3683 phDnldNfc_Release_Resources(&p_dnld_context); 3684 #ifndef NFC_TIMER_CONTEXT 3685 gpphDnldContext = p_dnld_context; 3686 #endif 3687 3688 /* Notify the Error/Success Scenario to the upper layer */ 3689 DNLD_DEBUG(" FW_DNLD: FW_DNLD Aborted with %x Timer Timeout \n", 3690 abort_id); 3691 comp_info.status = NFCSTATUS_FAILED ; 3692 phDnldNfc_Notify( p_upper_notify, p_upper_context, 3693 pHwRef, (uint8_t) NFC_IO_ERROR, &comp_info ); 3694 } 3695 3696 return ; 3697 } 3698 3699 3700 3701 NFCSTATUS 3702 phDnldNfc_Upgrade ( 3703 phHal_sHwReference_t *pHwRef, 3704 #ifdef NXP_FW_PARAM 3705 uint8_t type, 3706 uint8_t *nxp_nfc_fw, 3707 uint32_t fw_length, 3708 #endif 3709 pphNfcIF_Notification_CB_t upgrade_complete, 3710 void *context 3711 ) 3712 { 3713 phDnldNfc_sContext_t *psDnldContext = NULL; 3714 phNfcIF_sReference_t dnldReference = { NULL,0,0 }; 3715 phNfcIF_sCallBack_t if_callback = { NULL, NULL, NULL, NULL }; 3716 phNfc_sLowerIF_t *plower_if = NULL; 3717 NFCSTATUS status = NFCSTATUS_SUCCESS; 3718 section_info_t *p_cur_sec = NULL; 3719 unsigned sec_type = 0; 3720 3721 if( (NULL == pHwRef) 3722 ) 3723 { 3724 status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER); 3725 } 3726 else 3727 { 3728 DNLD_PRINT(" FW_DNLD: Starting the FW Upgrade Sequence .... \n"); 3729 3730 (void) 3731 phDnldNfc_Allocate_Resource((void **) 3732 &psDnldContext,sizeof(phDnldNfc_sContext_t)); 3733 if(psDnldContext != NULL) 3734 { 3735 #ifndef NFC_TIMER_CONTEXT 3736 gpphDnldContext = psDnldContext; 3737 #endif 3738 psDnldContext->p_hw_ref = pHwRef; 3739 psDnldContext->timer_id = NXP_INVALID_TIMER_ID; 3740 3741 DNLD_PRINT(" FW_DNLD: Initialisation in Progress.... \n"); 3742 3743 if_callback.pif_ctxt = psDnldContext ; 3744 if_callback.send_complete = &phDnldNfc_Send_Complete; 3745 if_callback.receive_complete= &phDnldNfc_Receive_Complete; 3746 /* if_callback.notify = &phDnldNfc_Notify_Event; */ 3747 plower_if = dnldReference.plower_if = &(psDnldContext->lower_interface); 3748 status = phDal4Nfc_Register(&dnldReference, if_callback, 3749 NULL); 3750 DNLD_DEBUG(" FW_DNLD: Lower Layer Register, Status = %02X\n",status); 3751 3752 if( (NFCSTATUS_SUCCESS == status) && (NULL != plower_if->init)) 3753 { 3754 /* psDnldContext->p_config_params = pHwConfig ; */ 3755 status = plower_if->init((void *)plower_if->pcontext, 3756 (void *)pHwRef); 3757 DNLD_DEBUG(" FW_DNLD: Lower Layer Initialisation, Status = %02X\n",status); 3758 } 3759 else 3760 { 3761 /* TODO: Handle Initialisation in the Invalid State */ 3762 } 3763 /* The Lower layer Initialisation successful */ 3764 if (NFCSTATUS_SUCCESS == status) 3765 { 3766 psDnldContext->p_upper_notify = upgrade_complete; 3767 psDnldContext->p_upper_context = context; 3768 3769 status = phDnldNfc_Process_FW( psDnldContext, pHwRef 3770 #ifdef NXP_FW_PARAM 3771 ,*nxp_nfc_fw , fw_length 3772 #endif 3773 ); 3774 3775 if (NFCSTATUS_SUCCESS == status) 3776 { 3777 status = phDnldNfc_Send_Command( psDnldContext, pHwRef, 3778 PHDNLD_CMD_RESET , NULL , 0 ); 3779 if (NFCSTATUS_PENDING == status) 3780 { 3781 DNLD_PRINT("\n FW_DNLD: Initial Reset .... \n"); 3782 3783 #if defined(FW_DOWNLOAD_TIMER) 3784 3785 psDnldContext->timer_id = phOsalNfc_Timer_Create( ); 3786 3787 #if (FW_DOWNLOAD_TIMER < 2) 3788 phOsalNfc_Timer_Start( psDnldContext->timer_id, 3789 NXP_DNLD_COMPLETE_TIMEOUT, 3790 (ppCallBck_t) phDnldNfc_Abort 3791 #ifdef NFC_TIMER_CONTEXT 3792 , (void *) psDnldContext 3793 #endif 3794 ); 3795 3796 #endif /* #if (FW_DOWNLOAD_TIMER < 2) */ 3797 3798 #endif /* #if defined(FW_DOWNLOAD_TIMER) */ 3799 3800 } 3801 } 3802 else if (NFCSTATUS_SUCCESS == PHNFCSTATUS(status)) 3803 { 3804 #if defined (NXP_FW_INTEGRITY_VERIFY) 3805 /* 3806 * To check for the integrity if the firmware is already 3807 * Upgraded. 3808 */ 3809 status = phDnldNfc_Send_Command( psDnldContext, pHwRef, 3810 PHDNLD_CMD_RESET , NULL , 0 ); 3811 if (NFCSTATUS_PENDING == status) 3812 { 3813 DNLD_PRINT("\n FW_DNLD: Integrity Reset .... \n"); 3814 (void)phDnldNfc_Set_Seq(psDnldContext, DNLD_SEQ_COMPLETE); 3815 status = PHNFCSTVAL( CID_NFC_DNLD, 3816 NFCSTATUS_PENDING ); 3817 #if defined(FW_DOWNLOAD_TIMER) 3818 psDnldContext->timer_id = phOsalNfc_Timer_Create( ); 3819 #if (FW_DOWNLOAD_TIMER < 2) 3820 phOsalNfc_Timer_Start( psDnldContext->timer_id, 3821 NXP_DNLD_COMPLETE_TIMEOUT, 3822 (ppCallBck_t) phDnldNfc_Abort 3823 #ifdef NFC_TIMER_CONTEXT 3824 , (void *) psDnldContext 3825 #endif 3826 ); 3827 3828 #endif /* #if (FW_DOWNLOAD_TIMER < 2) */ 3829 3830 #endif /* #if defined(FW_DOWNLOAD_TIMER) */ 3831 } 3832 3833 #else 3834 status = NFCSTATUS_SUCCESS; 3835 3836 #endif /* #if defined (NXP_FW_INTEGRITY_VERIFY) */ 3837 3838 } 3839 else 3840 { 3841 DNLD_PRINT(" FW_DNLD Initialisation in Failed \n"); 3842 } 3843 } 3844 3845 if (NFCSTATUS_PENDING != PHNFCSTATUS(status)) 3846 { 3847 (void)phDal4Nfc_Unregister( 3848 psDnldContext->lower_interface.pcontext, pHwRef); 3849 phDnldNfc_Release_Lower(psDnldContext, pHwRef); 3850 phDnldNfc_Release_Resources(&psDnldContext); 3851 #ifndef NFC_TIMER_CONTEXT 3852 gpphDnldContext = psDnldContext; 3853 #endif 3854 } 3855 } /* End of Status Check for Memory */ 3856 else 3857 { 3858 status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INSUFFICIENT_RESOURCES); 3859 3860 DNLD_PRINT(" FW_DNLD: Memory Allocation of Context Failed\n"); 3861 } 3862 } 3863 3864 return status; 3865 } 3866