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