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