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
BuildCRCTable()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
CalculateCRC32(void * buffer,uint32_t count,uint32_t crc)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
phDnldNfc_UpdateCrc16(uint8_t crcByte,uint16_t * pCrc)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
phDnldNfc_ComputeCrc16(uint8_t * pData,uint16_t length)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
phDnldNfc_Allocate_Resource(void ** ppBuffer,uint16_t size)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
phDnldNfc_Release_Resources(phDnldNfc_sContext_t ** ppsDnldContext)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
phDnldNfc_Release_Lower(phDnldNfc_sContext_t * psDnldContext,void * pHwRef)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
phDnldNfc_Notify(pphNfcIF_Notification_CB_t p_upper_notify,void * p_upper_context,void * pHwRef,uint8_t type,void * pInfo)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
phDnldNfc_Set_Seq(phDnldNfc_sContext_t * psDnldContext,phDnldNfc_eSeqType_t seq_type)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
phDnldNfc_Send(void * psContext,void * pHwRef,uint8_t * pdata,uint16_t length)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
phDnldNfc_Receive(void * psContext,void * pHwRef,uint8_t * pdata,uint16_t length)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
phDnldNfc_Read(phDnldNfc_sContext_t * psDnldContext,void * pHwRef,section_info_t * p_sec_info)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
phDnldNfc_Process_Write(phDnldNfc_sContext_t * psDnldContext,void * pHwRef,section_info_t * p_sec_info,uint32_t * p_sec_offset)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
phDnldNfc_Resume_Write(phDnldNfc_sContext_t * psDnldContext,void * pHwRef)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
phDnldNfc_Sequence(phDnldNfc_sContext_t * psDnldContext,void * pHwRef,void * pdata,uint16_t length)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
phDnldNfc_Tx_Reset(phDnldNfc_sContext_t * psDnldContext)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
phDnldNfc_Extract_Chunks(uint8_t * frame_data,uint16_t frame_offset,uint16_t frame_length,uint16_t max_frame,uint16_t * chunk_length)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
phDnldNfc_Send_Raw(phDnldNfc_sContext_t * psDnldContext,void * pHwRef,uint8_t * raw_frame,uint16_t frame_offset,uint16_t frame_length)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
phDnldNfc_Frame_Complete(phDnldNfc_sContext_t * psDnldContext)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
phDnldNfc_Raw_Write(phDnldNfc_sContext_t * psDnldContext,void * pHwRef)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
phDnldNfc_Upgrade_Sequence(phDnldNfc_sContext_t * psDnldContext,void * pHwRef,void * pdata,uint16_t length)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
phDnldNfc_Resume(phDnldNfc_sContext_t * psDnldContext,void * pHwRef,void * pdata,uint16_t length)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
phDnldNfc_Process_Response(phDnldNfc_sContext_t * psDnldContext,void * pHwRef,void * pdata,uint16_t length)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
phDnldNfc_Receive_Complete(void * psContext,void * pHwRef,phNfc_sTransactionInfo_t * pInfo)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
phDnldNfc_Send_Complete(void * psContext,void * pHwRef,phNfc_sTransactionInfo_t * pInfo)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
phDnldNfc_Send_Command(phDnldNfc_sContext_t * psDnldContext,void * pHwRef,uint8_t cmd,void * params,uint16_t param_length)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
phDnldNfc_Check_FW(phHal_sHwReference_t * pHwRef,fw_data_hdr_t * cur_fw_hdr)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
phDnldNfc_Process_FW(phDnldNfc_sContext_t * psDnldContext,phHal_sHwReference_t * pHwRef,uint8_t * nxp_nfc_fw,uint32_t nxp_fw_len)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
phDnldNfc_Run_Check(phHal_sHwReference_t * pHwRef,uint8_t * nxp_nfc_fw uint32_t fw_length)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
phDnldNfc_Abort(uint32_t abort_id,void * dnld_cntxt)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
phDnldNfc_Upgrade(phHal_sHwReference_t * pHwRef,uint8_t type,uint8_t * nxp_nfc_fw,uint32_t fw_length,pphNfcIF_Notification_CB_t upgrade_complete,void * context)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