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