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