blob: 3d851440d9a1393310e38e05a11cba692ef79082 [file] [log] [blame]
daniel_Tomas5e976052010-12-09 10:46:12 -08001/*
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* *
Nick Pelly8c9b94d2011-07-19 14:35:22 -070027* $Date: Tue Jun 28 14:25:44 2011 $ *
daniel_Tomas5e976052010-12-09 10:46:12 -080028* $Author: ing04880 $ *
Nick Pelly8c9b94d2011-07-19 14:35:22 -070029* $Revision: 1.33 $ *
daniel_Tomas5e976052010-12-09 10:46:12 -080030* $Aliases: $
31* *
32* =========================================================================== *
33*/
34
35
36/*
37################################################################################
38***************************** Header File Inclusion ****************************
39################################################################################
40*/
41#include <stdlib.h>
Nick Pellyf15b4572011-07-14 08:41:52 -070042#include <unistd.h>
daniel_Tomas5e976052010-12-09 10:46:12 -080043#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>
Nick Pelly8c9b94d2011-07-19 14:35:22 -070050#include <utils/Log.h>
daniel_Tomas5e976052010-12-09 10:46:12 -080051/*
52################################################################################
53****************************** Macro Definitions *******************************
54################################################################################
55*/
56
57#ifndef STATIC
58#define STATIC static
59#endif
60
daniel_Tomas5e976052010-12-09 10:46:12 -080061#if defined (DNLD_SUMMARY) && !defined (DNLD_TRACE)
62#define DNLD_TRACE
63#endif
64
65/* #if defined(PHDBG_INFO) && defined (PHDBG_CRITICAL_ERROR) */
66#if defined(DNLD_TRACE)
67extern char phOsalNfc_DbgTraceBuffer[];
68
69#define MAX_TRACE_BUFFER 0x0410
70#define Trace_buffer phOsalNfc_DbgTraceBuffer
71/* #define DNLD_PRINT( str ) phOsalNfc_DbgTrace(str) */
72#define DNLD_PRINT( str ) phOsalNfc_DbgString(str)
73#define DNLD_DEBUG(str, arg) \
74 { \
75 snprintf(Trace_buffer,MAX_TRACE_BUFFER,str,arg); \
76 phOsalNfc_DbgString(Trace_buffer); \
77 }
78#define DNLD_PRINT_BUFFER(msg,buf,len) \
79 { \
80 snprintf(Trace_buffer,MAX_TRACE_BUFFER,"\n\t %s:",msg); \
81 phOsalNfc_DbgString(Trace_buffer); \
82 phOsalNfc_DbgTrace(buf,len); \
83 phOsalNfc_DbgString("\r"); \
84 }
85#else
86#define DNLD_PRINT( str )
87#define DNLD_DEBUG(str, arg)
88#define DNLD_PRINT_BUFFER(msg,buf,len)
89#endif
90
Nick Pelly8c9b94d2011-07-19 14:35:22 -070091#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
Rob von Behren6dd94832011-09-16 15:05:25 -070095//#define PHDNLD_MAX_PACKET 0x0200U /* Max Total Packet Size is 512 */
96#define PHDNLD_MAX_PACKET 32U /* Max Total Packet Size is 512 */
Nick Pelly8c9b94d2011-07-19 14:35:22 -070097#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
Rob von Behren6dd94832011-09-16 15:05:25 -0700101#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
daniel_Tomas5e976052010-12-09 10:46:12 -0800123#define PHDNLD_FRAME_LEN_SIZE 0x02U
124#define PHDNLD_ADDR_SIZE 0x03U
125#define PHDNLD_DATA_LEN_SIZE 0x02U
Rob von Behren6dd94832011-09-16 15:05:25 -0700126#define PHDNLD_FRAME_DATA_OFFSET 0x03U
Nick Pelly8c9b94d2011-07-19 14:35:22 -0700127
Rob von Behren6dd94832011-09-16 15:05:25 -0700128#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
Nick Pelly8c9b94d2011-07-19 14:35:22 -0700138
139#define PHDNLD_PAGE_SIZE 0x80U /* Page Size Configured for 64 Bytes */
daniel_Tomas5e976052010-12-09 10:46:12 -0800140
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
Nick Pelly8c9b94d2011-07-19 14:35:22 -0700147#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
daniel_Tomas5e976052010-12-09 10:46:12 -0800151
152
Rob von Behren6dd94832011-09-16 15:05:25 -0700153/* Raw Command to pass the Data in Download Mode */
154#define PHDNLD_CMD_RAW 0x00U
daniel_Tomas5e976052010-12-09 10:46:12 -0800155/* 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
Rob von Behren6dd94832011-09-16 15:05:25 -0700162#define PHDNLD_CMD_SEC_WRITE 0x0CU
daniel_Tomas5e976052010-12-09 10:46:12 -0800163#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
Rob von Behren6dd94832011-09-16 15:05:25 -0700183/* Command to verify the Integrity of the data written */
184#define PHDNLD_CMD_ENCAPSULATE 0x0DU
185
daniel_Tomas5e976052010-12-09 10:46:12 -0800186#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
Rob von Behren6dd94832011-09-16 15:05:25 -0700203/* Command Not Supported Response to a Command Sent in the Download Mode */
204#define PHDNLD_RESP_CMD_NOT_SUPPORTED 0x13U
daniel_Tomas5e976052010-12-09 10:46:12 -0800205/* Length parameter error Response to a Command Sent in the Download Mode */
206#define PHDNLD_RESP_INVALID_LENGTH 0x18U
Rob von Behren6dd94832011-09-16 15:05:25 -0700207/* 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
daniel_Tomas5e976052010-12-09 10:46:12 -0800220/* 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
Nick Pelly8c9b94d2011-07-19 14:35:22 -0700227#define NXP_MAX_SECTION_WRITE 0x05U
daniel_Tomas5e976052010-12-09 10:46:12 -0800228
229#define NXP_PATCH_VER_INDEX 0x05U
230
231
232/*
233################################################################################
234******************** Enumeration and Structure Definition **********************
235################################################################################
236*/
237
238typedef enum phDnldNfc_eSeqType{
239 DNLD_SEQ_RESET = 0x00U,
240 DNLD_SEQ_INIT,
Rob von Behren6dd94832011-09-16 15:05:25 -0700241 DNLD_SEQ_RAW,
daniel_Tomas5e976052010-12-09 10:46:12 -0800242 DNLD_SEQ_LOCK,
243 DNLD_SEQ_UNLOCK,
244 DNLD_SEQ_UPDATE,
245 DNLD_SEQ_ROLLBACK,
246 DNLD_SEQ_COMPLETE
247} phDnldNfc_eSeqType_t;
248
249typedef enum phDnldNfc_eState
250{
251 phDnld_Reset_State = 0x00,
252 phDnld_Unlock_State,
253 phDnld_Upgrade_State,
254 phDnld_Verify_State,
255 phDnld_Complete_State,
256 phDnld_Invalid_State
257}phDnldNfc_eState_t;
258
259
260typedef enum phDnldNfc_eSeq
261{
262 phDnld_Reset_Seq = 0x00,
Nick Pelly8c9b94d2011-07-19 14:35:22 -0700263 phDnld_Activate_Patch,
264 phDnld_Deactivate_Patch,
daniel_Tomas5e976052010-12-09 10:46:12 -0800265 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,
Rob von Behren6dd94832011-09-16 15:05:25 -0700273 phDnld_Raw_Upgrade,
daniel_Tomas5e976052010-12-09 10:46:12 -0800274 phDnld_Invalid_Seq
275}phDnldNfc_eSeq_t;
276
277typedef enum phDnldNfc_eChkCrc{
278 CHK_INTEGRITY_CONFIG_PAGE_CRC = 0x00U,
279 CHK_INTEGRITY_PATCH_TABLE_CRC = 0x01U,
280 CHK_INTEGRITY_FLASH_CODE_CRC = 0x02U,
281 CHK_INTEGRITY_PATCH_CODE_CRC = 0x03U,
282 CHK_INTEGRITY_COMPLETE_CRC = 0xFFU
283} phDnldNfc_eChkCrc_t;
284
285
286
287typedef struct hw_comp_tbl
288{
289 uint8_t hw_version[3];
290 uint8_t compatibility;
291}hw_comp_tbl_t;
292
293
294typedef struct img_data_hdr
295{
296 /* Image Identification */
297 uint32_t img_id;
298 /* Offset of the Data from the header */
299 uint8_t img_data_offset;
300 /* Number of fimware images available in the img_data */
301 uint8_t no_of_fw_img;
Rob von Behren6dd94832011-09-16 15:05:25 -0700302 /* Fimware image Padding in the img_data */
daniel_Tomas5e976052010-12-09 10:46:12 -0800303 uint8_t fw_img_pad[2];
304 /* HW Compatiblity table for the set of the Hardwares */
305 hw_comp_tbl_t comp_tbl;
306 /* This data consists of the firmware images required to download */
307}img_data_hdr_t;
308
309
310typedef struct fw_data_hdr
311{
312 /* The data offset from the firmware header.
313 * Just in case if in future we require to
314 * add some more information.
315 */
316 uint8_t fw_hdr_len;
317 /* Total size of all the sections which needs to be updated */
318 uint8_t no_of_sections;
319 uint8_t hw_comp_no;
320 uint8_t fw_patch;
321 uint32_t fw_version;
322}fw_data_hdr_t;
323
324
325
326 /* This data consists all the sections that needs to be downloaded */
327typedef struct section_hdr
328{
329 uint8_t section_hdr_len;
330 uint8_t section_mem_type;
Rob von Behren6dd94832011-09-16 15:05:25 -0700331 uint8_t section_checksum;
332 uint8_t section_conf;
daniel_Tomas5e976052010-12-09 10:46:12 -0800333 uint32_t section_address;
334 uint32_t section_length;
335}section_hdr_t;
336
daniel_Tomas5e976052010-12-09 10:46:12 -0800337typedef 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;
Rob von Behren6dd94832011-09-16 15:05:25 -0700345 /* The Section checksum to verify the integrity of the section
346 * data.
347 */
348 uint8_t *p_sec_chksum;
daniel_Tomas5e976052010-12-09 10:46:12 -0800349 /** \internal Index used to refer and process the
350 * Firmware Section Data */
351 volatile uint32_t section_offset;
352
353 /** \internal Section Read Sequence */
354 volatile uint8_t section_read;
355
356 /** \internal Section Write Sequence */
357 volatile uint8_t section_write;
358
359 /** \internal TRIM Write Sequence */
360 volatile uint8_t trim_write;
361
362 volatile uint8_t sec_verify_retry;
363
364}section_info_t;
365
366
367typedef struct phDnldNfc_sParam
368{
369 uint8_t data_addr[PHDNLD_ADDR_SIZE];
370 uint8_t data_len[PHDNLD_DATA_LEN_SIZE];
371 uint8_t data_packet[PHDNLD_DATA_SIZE];
372}phDnldNfc_sParam_t;
373
daniel_Tomas5e976052010-12-09 10:46:12 -0800374typedef struct phDnldNfc_sDataHdr
375{
376 uint8_t frame_type;
377 uint8_t frame_length[PHDNLD_FRAME_LEN_SIZE];
378}phDnldNfc_sData_Hdr_t;
379
Rob von Behren6dd94832011-09-16 15:05:25 -0700380typedef struct phDnldNfc_sRawHdr
381{
382 uint8_t frame_type;
383 uint8_t frame_length[PHDNLD_FRAME_LEN_SIZE];
384}phDnldNfc_sRawHdr_t;
385
386typedef struct phDnldNfc_sRawDataHdr
387{
388 uint8_t data_addr[PHDNLD_ADDR_SIZE];
389 uint8_t data_len[PHDNLD_DATA_LEN_SIZE];
390}phDnldNfc_sRawDataHdr_t;
391
daniel_Tomas5e976052010-12-09 10:46:12 -0800392typedef struct phDnldNfc_sChkCrc16_Resp
393{
394 uint8_t Chk_status;
395 uint8_t Chk_Crc16[2];
396
397}phDnldNfc_sChkCrc16_Resp_t;
398
399typedef struct phDnldNfc_sChkCrc32_Resp
400{
401 uint8_t Chk_status;
402 uint8_t Chk_Crc32[4];
403
404}phDnldNfc_sChkCrc32_Resp_t;
405
406
407typedef struct phDnldNfc_sChkCrcComplete
408{
409 phDnldNfc_sChkCrc16_Resp_t config_page;
410 phDnldNfc_sChkCrc16_Resp_t patch_table;
411 phDnldNfc_sChkCrc32_Resp_t flash_code;
412 phDnldNfc_sChkCrc32_Resp_t patch_code;
413}phDnldNfc_sChkCrcComplete_t;
414
415typedef struct phDnldNfc_sData
416{
417 uint8_t frame_type;
418 uint8_t frame_length[PHDNLD_FRAME_LEN_SIZE];
419 union param
420 {
421 phDnldNfc_sParam_t data_param;
Rob von Behren6dd94832011-09-16 15:05:25 -0700422 uint8_t response_data[PHDNLD_MAX_PACKET];
Nick Pelly8c9b94d2011-07-19 14:35:22 -0700423 uint8_t cmd_param;
daniel_Tomas5e976052010-12-09 10:46:12 -0800424 }param_info;
425}phDnldNfc_sData_t;
426
Rob von Behren6dd94832011-09-16 15:05:25 -0700427#ifdef NXP_NFC_MULTIPLE_FW
428
429typedef struct phDnldNfc_sFwImageInfo
430{
431 /** \internal Data Pointer to the Firmware header section of the Firmware */
432 fw_data_hdr_t *p_fw_hdr;
433 /** \internal Buffer pointer to store the Firmware Section Data */
434 section_info_t *p_fw_sec;
435 /** \internal Buffer pointer to store the Firmware Raw Data */
436 uint8_t *p_fw_raw;
437}phDnldNfc_sFwImageInfo_t;
438
439#endif /* #ifdef NXP_NFC_MULTIPLE_FW */
440
441
442typedef struct phDnldNfc_TxInfo
443{
444 uint8_t *transmit_frame;
445
446 uint16_t tx_offset;
447
448 /** \internal Remaining amount of data to be sent */
449 uint16_t tx_len;
450
451 uint16_t tx_total;
452
453 /** \internal Chain information for the data to be sent */
454 uint8_t tx_chain;
455
456}phDnldNfc_TxInfo_t;
457
458
459typedef struct phDnldNfc_RxInfo
460{
461 /** \internal Total length of the received buffer */
462 uint16_t rx_total;
463 /** \internal Chain information of the received buffer */
464 uint16_t rx_chain;
465 /** \internal Remaining Data information to be read to complete the
466 * Data Information.
467 */
468 uint16_t rx_remain;
469
470 /** \internal Buffer to Send the Raw Data Frame */
471 uint8_t raw_buffer_data[PHDNLD_MAX_PACKET
472 + PHDNLD_PAGE_SIZE];
473}phDnldNfc_RxInfo_t;
474
daniel_Tomas5e976052010-12-09 10:46:12 -0800475
476typedef struct phDnldNfc_sContext
477{
478 /** \internal Structure to store the lower interface operations */
479 phNfc_sLowerIF_t lower_interface;
480
481 phNfc_sData_t *p_fw_version;
482
483 /** \internal Pointer to the Hardware Reference Sturcture */
484 phHal_sHwReference_t *p_hw_ref;
485
486 /** \internal Pointer to the upper layer notification callback function */
487 pphNfcIF_Notification_CB_t p_upper_notify;
488 /** \internal Pointer to the upper layer context */
489 void *p_upper_context;
490
491 /** \internal Timer ID for the Download Abort */
492 uint32_t timer_id;
Rob von Behren6dd94832011-09-16 15:05:25 -0700493 /** \internal Internal Download for the Download Abort */
494 uint32_t dnld_timeout;
daniel_Tomas5e976052010-12-09 10:46:12 -0800495 /** \internal Data Pointer to the Image header section of the Firmware */
496 img_data_hdr_t *p_img_hdr;
Rob von Behren6dd94832011-09-16 15:05:25 -0700497
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
daniel_Tomas5e976052010-12-09 10:46:12 -0800503 /** \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;
Rob von Behren6dd94832011-09-16 15:05:25 -0700507 /** \internal Buffer pointer to store the Firmware Raw Data */
508 uint8_t *p_fw_raw;
daniel_Tomas5e976052010-12-09 10:46:12 -0800509
510 /** \internal Previous Download Size */
511 uint32_t prev_dnld_size;
512
513 /** \internal Single Data Block to download the Firmware */
Rob von Behren6dd94832011-09-16 15:05:25 -0700514 uint8_t dnld_data[PHDNLD_MAX_PACKET
515 + PHDNLD_PAGE_SIZE];
daniel_Tomas5e976052010-12-09 10:46:12 -0800516 /** \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
Rob von Behren6dd94832011-09-16 15:05:25 -0700543 uint8_t vmid_trim_update;
daniel_Tomas5e976052010-12-09 10:46:12 -0800544#endif /* #ifdef NXP_FW_SW_VMID_TRIM */
545
Rob von Behren6dd94832011-09-16 15:05:25 -0700546 uint8_t cur_frame_info;
547
548 uint8_t raw_mode_upgrade;
daniel_Tomas5e976052010-12-09 10:46:12 -0800549
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
daniel_Tomas5e976052010-12-09 10:46:12 -0800558 /** \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
daniel_Tomas5e976052010-12-09 10:46:12 -0800564 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
Rob von Behren6dd94832011-09-16 15:05:25 -0700576 /* \internal Data Transmit information */
577 phDnldNfc_TxInfo_t tx_info;
daniel_Tomas5e976052010-12-09 10:46:12 -0800578
Rob von Behren6dd94832011-09-16 15:05:25 -0700579 /* \internal Data Receive information */
580 phDnldNfc_RxInfo_t rx_info;
581
582
583}phDnldNfc_sContext_t;
daniel_Tomas5e976052010-12-09 10:46:12 -0800584
585
586/*
587################################################################################
588******************** Global and Static Variables Definition ********************
589################################################################################
590*/
Nick Pelly8c9b94d2011-07-19 14:35:22 -0700591
Rob von Behren6dd94832011-09-16 15:05:25 -0700592#ifndef NFC_TIMER_CONTEXT
daniel_Tomas5e976052010-12-09 10:46:12 -0800593static phDnldNfc_sContext_t *gpphDnldContext = NULL;
Rob von Behren6dd94832011-09-16 15:05:25 -0700594#endif
daniel_Tomas5e976052010-12-09 10:46:12 -0800595
Nick Pelly8c9b94d2011-07-19 14:35:22 -0700596#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
Rob von Behren6dd94832011-09-16 15:05:25 -0700602#define NXP_FW_DNLD_RAW_PHASE 0x04U
Nick Pelly8c9b94d2011-07-19 14:35:22 -0700603#define NXP_FW_DNLD_INVALID_PHASE 0xFFU
604
605static uint8_t gphDnldPhase = NXP_FW_DNLD_COMPLETE_PHASE;
606
607#endif /* #ifdef NXP_FW_DNLD_CHECK_PHASE */
608
daniel_Tomas5e976052010-12-09 10:46:12 -0800609/**/
610
611/*
612*************************** Static Function Declaration **************************
613*/
614
615STATIC
616NFCSTATUS
617phDnldNfc_Send_Command(
618 phDnldNfc_sContext_t *psDnldContext,
619 void *pHwRef,
620 uint8_t cmd,
621 void *params,
622 uint16_t param_length
623 );
624
625static
626NFCSTATUS
627phDnldNfc_Process_FW(
628 phDnldNfc_sContext_t *psDnldContext,
629 phHal_sHwReference_t *pHwRef
630#ifdef NXP_FW_PARAM
631 ,
632 uint8_t *nxp_nfc_fw,
633 uint32_t fw_length
634#endif
635 );
636
637STATIC
638void
639phDnldNfc_Send_Complete (
640 void *psContext,
641 void *pHwRef,
642 phNfc_sTransactionInfo_t *pInfo
643 );
644
645STATIC
646void
647phDnldNfc_Receive_Complete (
648 void *psContext,
649 void *pHwRef,
650 phNfc_sTransactionInfo_t *pInfo
651 );
652
653STATIC
654NFCSTATUS
655phDnldNfc_Process_Response(
656 phDnldNfc_sContext_t *psDnldContext,
657 void *pHwRef,
658 void *pdata,
659 uint16_t length
660 );
661
662
663static
664NFCSTATUS
665phDnldNfc_Resume(
666 phDnldNfc_sContext_t *psDnldContext,
667 void *pHwRef,
668 void *pdata,
669 uint16_t length
670 );
671
672static
673NFCSTATUS
674phDnldNfc_Resume_Write(
675 phDnldNfc_sContext_t *psDnldContext,
676 void *pHwRef
677 );
678
679static
680NFCSTATUS
681phDnldNfc_Process_Write(
682 phDnldNfc_sContext_t *psDnldContext,
683 void *pHwRef,
684 section_info_t *p_sec_info,
685 uint32_t *p_sec_offset
686 );
687
688static
689NFCSTATUS
690phDnldNfc_Sequence(
691 phDnldNfc_sContext_t *psDnldContext,
692 void *pHwRef,
693 void *pdata,
694 uint16_t length
695 );
696
697static
698NFCSTATUS
699phDnldNfc_Upgrade_Sequence(
700 phDnldNfc_sContext_t *psDnldContext,
701 void *pHwRef,
702 void *pdata,
703 uint16_t length
704 );
705
706STATIC
707NFCSTATUS
708phDnldNfc_Receive(
709 void *psContext,
710 void *pHwRef,
711 uint8_t *pdata,
712 uint16_t length
713 );
714
715
716STATIC
717NFCSTATUS
718phDnldNfc_Send (
719 void *psContext,
720 void *pHwRef,
721 uint8_t *pdata,
722 uint16_t length
723 );
724
725STATIC
726NFCSTATUS
727phDnldNfc_Set_Seq(
728 phDnldNfc_sContext_t *psDnldContext,
729 phDnldNfc_eSeqType_t seq_type
730 );
731
732static
733void
734phDnldNfc_Notify(
735 pphNfcIF_Notification_CB_t p_upper_notify,
736 void *p_upper_context,
737 void *pHwRef,
738 uint8_t type,
739 void *pInfo
740 );
741
742STATIC
743NFCSTATUS
744phDnldNfc_Allocate_Resource (
745 void **ppBuffer,
746 uint16_t size
747 );
748
749STATIC
750void
751phDnldNfc_Release_Resources (
752 phDnldNfc_sContext_t **ppsDnldContext
753 );
754
755STATIC
756void
757phDnldNfc_Release_Lower(
758 phDnldNfc_sContext_t *psDnldContext,
759 void *pHwRef
760 );
761
762
763static
764NFCSTATUS
765phDnldNfc_Read(
766 phDnldNfc_sContext_t *psDnldContext,
767 void *pHwRef,
768 section_info_t *p_sec_info
769 );
770
771STATIC
772void
773phDnldNfc_Abort (
Rob von Behren6dd94832011-09-16 15:05:25 -0700774 uint32_t abort_id
775#ifdef NFC_TIMER_CONTEXT
776 , void *dnld_cntxt
777#endif
daniel_Tomas5e976052010-12-09 10:46:12 -0800778 );
779
780
781#ifdef DNLD_CRC_CALC
782
783static
784void
785phDnldNfc_UpdateCrc16(
786 uint8_t crcByte,
787 uint16_t *pCrc
788);
789
790STATIC
791uint16_t
792phDnldNfc_ComputeCrc16(
793 uint8_t *pData,
794 uint16_t length
795);
796
797
798/*
799*************************** Function Definitions **************************
800*/
801#define CRC32_POLYNOMIAL 0xEDB88320L
802
803static uint32_t CRC32Table[0x100];
804
805void BuildCRCTable()
806{
807 unsigned long crc;
808 uint8_t i = 0, j = 0;
809
810 for ( i = 0; i <= 0xFF ; i++ )
811 {
812 crc = i;
813 for ( j = 8 ; j> 0; j-- )
814 {
815 if ( crc & 1 )
816 {
817 crc = ( crc>> 1 ) ^ CRC32_POLYNOMIAL;
818 }
819 else
820 {
821 crc>>= 1;
822 }
823 }
824 CRC32Table[ i ] = crc;
825 }
826}
827
828/*
829* This routine calculates the CRC for a block of data using the
830* table lookup method. It accepts an original value for the crc,
831* and returns the updated value.
832*/
833
834uint32_t CalculateCRC32( void *buffer , uint32_t count, uint32_t crc )
835{
836 uint8_t *p;
837 uint32_t temp1;
838 uint32_t temp2;
839
840 p = (uint8_t *) buffer;
841 while ( count-- != 0 ) {
842 temp1 = ( crc>> 8 ) & 0x00FFFFFFL;
843 temp2 = CRC32Table[ ( (int) crc ^ *p++ ) & 0xff ];
844 crc = temp1 ^ temp2;
845 }
846 return( crc );
847}
848
849
850static
851void
852phDnldNfc_UpdateCrc16(
853 uint8_t crcByte,
854 uint16_t *pCrc
855)
856{
857 crcByte = (crcByte ^ (uint8_t)((*pCrc) & 0x00FF));
858 crcByte = (crcByte ^ (uint8_t)(crcByte << 4));
859 *pCrc = (*pCrc >> 8) ^ ((uint16_t)crcByte << 8) ^
860 ((uint16_t)crcByte << 3) ^
861 ((uint16_t)crcByte >> 4);
862}
863
864
865STATIC
866uint16_t
867phDnldNfc_ComputeCrc16(
868 uint8_t *pData,
869 uint16_t length
870)
871{
872 uint8_t crc_byte = 0;
873 uint16_t index = 0;
874 uint16_t crc = 0;
875
876#ifdef CRC_A
877 crc = 0x6363; /* ITU-V.41 */
878#else
879 crc = 0xFFFF; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */
880#endif /* #ifdef CRC_A */
881
882 do
883 {
884 crc_byte = pData[index];
885 phDnldNfc_UpdateCrc16(crc_byte, &crc);
886 index++;
887 } while (index < length);
888
889#ifndef INVERT_CRC
890 crc = ~crc; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */
891#endif /* #ifndef INVERT_CRC */
892
893/* *pCrc1 = (uint8_t) (crc & BYTE_MASK);
894 *pCrc2 = (uint8_t) ((crc >> 8) & BYTE_MASK); */
895 return crc ;
896}
897
898#endif /* #ifdef DNLD_CRC_CALC */
899
900
901/*!
902 * \brief Allocation of the Download Interface resources.
903 *
904 * This function releases and frees all the resources used by Download Mode
905 * Feature.
906 */
907
908STATIC
909NFCSTATUS
910phDnldNfc_Allocate_Resource (
911 void **ppBuffer,
912 uint16_t size
913 )
914{
915 NFCSTATUS status = NFCSTATUS_SUCCESS;
916
917 *ppBuffer = (void *) phOsalNfc_GetMemory(size);
918 if( *ppBuffer != NULL )
919 {
920 (void )memset(((void *)*ppBuffer), 0,
921 size);
922 }
923 else
924 {
925 *ppBuffer = NULL;
926 status = PHNFCSTVAL(CID_NFC_DNLD,
927 NFCSTATUS_INSUFFICIENT_RESOURCES);
928 }
929 return status;
930}
931
932
933/*!
934 * \brief Release of the Download Interface resources.
935 *
936 * This function releases and frees all the resources used by Download layer.
937 */
938
939STATIC
940void
941phDnldNfc_Release_Resources (
942 phDnldNfc_sContext_t **ppsDnldContext
943 )
944{
Rob von Behren6dd94832011-09-16 15:05:25 -0700945
daniel_Tomas5e976052010-12-09 10:46:12 -0800946 if(NULL != (*ppsDnldContext)->p_resp_buffer)
947 {
948 phOsalNfc_FreeMemory((*ppsDnldContext)->p_resp_buffer);
949 (*ppsDnldContext)->p_resp_buffer = NULL;
950 }
951 if(NULL != (*ppsDnldContext)->dnld_store.buffer)
952 {
953 phOsalNfc_FreeMemory((*ppsDnldContext)->dnld_store.buffer);
954 (*ppsDnldContext)->dnld_store.buffer = NULL;
955 (*ppsDnldContext)->dnld_store.length = 0;
956 }
957 if(NULL != (*ppsDnldContext)->trim_store.buffer)
958 {
959 phOsalNfc_FreeMemory((*ppsDnldContext)->trim_store.buffer);
960 (*ppsDnldContext)->trim_store.buffer = NULL;
961 (*ppsDnldContext)->trim_store.length = 0;
962 }
963 if(NULL != (*ppsDnldContext)->p_fw_sec)
964 {
965 phOsalNfc_FreeMemory((*ppsDnldContext)->p_fw_sec);
966 (*ppsDnldContext)->p_fw_sec = NULL;
967 }
968 if ( NXP_INVALID_TIMER_ID != (*ppsDnldContext)->timer_id )
969 {
970 phOsalNfc_Timer_Stop((*ppsDnldContext)->timer_id );
971 phOsalNfc_Timer_Delete((*ppsDnldContext)->timer_id );
972 (*ppsDnldContext)->timer_id = NXP_INVALID_TIMER_ID;
973 }
974
975 phOsalNfc_FreeMemory((*ppsDnldContext));
976 (*ppsDnldContext) = NULL;
977
978 return ;
979}
980
981
982STATIC
983void
984phDnldNfc_Release_Lower(
985 phDnldNfc_sContext_t *psDnldContext,
986 void *pHwRef
987 )
988{
989 phNfc_sLowerIF_t *plower_if =
990 &(psDnldContext->lower_interface);
991 NFCSTATUS status = NFCSTATUS_SUCCESS;
992
993 PHNFC_UNUSED_VARIABLE(status);
994
995 if(NULL != plower_if->release)
996 {
997#ifdef DNLD_LOWER_RELEASE
998 status = plower_if->release((void *)plower_if->pcontext,
999 (void *)pHwRef);
1000#else
1001 PHNFC_UNUSED_VARIABLE(pHwRef);
1002
1003#endif
1004 (void)memset((void *)plower_if,
1005 0, sizeof(phNfc_sLowerIF_t));
1006 DNLD_DEBUG(" FW_DNLD: Releasing the Lower Layer Resources: Status = %02X\n"
1007 ,status);
1008 }
1009
1010 return;
1011}
1012
1013
1014
1015static
1016void
1017phDnldNfc_Notify(
1018 pphNfcIF_Notification_CB_t p_upper_notify,
1019 void *p_upper_context,
1020 void *pHwRef,
1021 uint8_t type,
1022 void *pInfo
1023 )
1024{
1025 if( ( NULL != p_upper_notify) )
1026 {
1027 /* Notify the to the Upper Layer */
1028 (p_upper_notify)(p_upper_context, pHwRef, type, pInfo);
1029 }
1030}
1031
1032
1033STATIC
1034NFCSTATUS
1035phDnldNfc_Set_Seq(
1036 phDnldNfc_sContext_t *psDnldContext,
1037 phDnldNfc_eSeqType_t seq_type
1038 )
1039{
1040 NFCSTATUS status = NFCSTATUS_SUCCESS;
1041 static uint8_t prev_temp_state = 0;
1042 static uint8_t prev_temp_seq =
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001043 (uint8_t) phDnld_Activate_Patch;
daniel_Tomas5e976052010-12-09 10:46:12 -08001044
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;
Rob von Behren6dd94832011-09-16 15:05:25 -07001054 psDnldContext->cur_dnld_seq =
daniel_Tomas5e976052010-12-09 10:46:12 -08001055 (uint8_t)phDnld_Upgrade_Section;
1056 psDnldContext->next_dnld_seq =
1057 psDnldContext->cur_dnld_seq;
1058 break;
1059 }
Rob von Behren6dd94832011-09-16 15:05:25 -07001060 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 }
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001072 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;
Rob von Behren6dd94832011-09-16 15:05:25 -07001082 psDnldContext->cur_dnld_seq =
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001083 (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 }
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001093 psDnldContext->next_dnld_seq =
1094 psDnldContext->cur_dnld_seq;
1095 break;
1096 }
daniel_Tomas5e976052010-12-09 10:46:12 -08001097 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 }
daniel_Tomas5e976052010-12-09 10:46:12 -08001109 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 }
daniel_Tomas5e976052010-12-09 10:46:12 -08001146 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);
Rob von Behren6dd94832011-09-16 15:05:25 -07001187
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) */
daniel_Tomas5e976052010-12-09 10:46:12 -08001217 }
1218
1219 return status;
1220}
1221
1222
1223/*!
1224 * \brief Receives the Download Mode Response from the corresponding peripheral device.
1225 *
1226 * This function receives the Download Command Response to the connected NFC
1227 * Pheripheral device.
1228 */
1229
1230STATIC
1231NFCSTATUS
1232phDnldNfc_Receive(
1233 void *psContext,
1234 void *pHwRef,
1235 uint8_t *pdata,
1236 uint16_t length
1237 )
1238{
1239 phDnldNfc_sContext_t *psDnldContext= (phDnldNfc_sContext_t *)psContext;
1240 phNfc_sLowerIF_t *plower_if = NULL ;
1241 NFCSTATUS status = NFCSTATUS_SUCCESS;
1242
1243 if(NULL == psDnldContext )
1244 {
1245 status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
1246 }
1247 else
1248 {
1249 plower_if = &(psDnldContext->lower_interface);
1250
1251 if( (NULL != plower_if)
1252 && (NULL != plower_if->receive)
1253 )
1254 {
1255 status = plower_if->receive((void *)plower_if->pcontext,
1256 (void *)pHwRef, pdata, length);
1257 }
1258 }
1259 return status;
1260}
1261
1262
1263static
1264NFCSTATUS
1265phDnldNfc_Read(
1266 phDnldNfc_sContext_t *psDnldContext,
1267 void *pHwRef,
1268 section_info_t *p_sec_info
1269 )
1270{
1271 NFCSTATUS status = NFCSTATUS_SUCCESS;
Rob von Behren6dd94832011-09-16 15:05:25 -07001272 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;
daniel_Tomas5e976052010-12-09 10:46:12 -08001276 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 )
Rob von Behren6dd94832011-09-16 15:05:25 -07001285 && ((sec_type & DNLD_TRIM_MASK))
daniel_Tomas5e976052010-12-09 10:46:12 -08001286 && (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 {
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001293 if (( FALSE == p_sec_info->section_read )
Rob von Behren6dd94832011-09-16 15:05:25 -07001294 && ((sec_type & DNLD_VERIFY_MASK))
1295 )
daniel_Tomas5e976052010-12-09 10:46:12 -08001296 {
1297 read_size = (uint16_t)(psDnldContext->prev_dnld_size );
1298 DNLD_DEBUG(" FW_DNLD: Section Read = %X \n", read_size);
1299 }
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001300 else if( ( TRUE == p_sec_info->section_read )
1301 && ( TRUE == p_sec_info->section_write )
1302 )
daniel_Tomas5e976052010-12-09 10:46:12 -08001303 {
1304 /*Already Read the Data Hence Ignore the Read */
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001305 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);
daniel_Tomas5e976052010-12-09 10:46:12 -08001313 }
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
Rob von Behren6dd94832011-09-16 15:05:25 -07001322 p_dnld_data->frame_length[i] = (uint8_t)0;
daniel_Tomas5e976052010-12-09 10:46:12 -08001323 /* Update the LSB of the Data and the Address Parameter*/
Rob von Behren6dd94832011-09-16 15:05:25 -07001324 p_data_param->data_addr[i] = (uint8_t)((read_addr >>
daniel_Tomas5e976052010-12-09 10:46:12 -08001325 (BYTE_SIZE + BYTE_SIZE)) & BYTE_MASK);
Rob von Behren6dd94832011-09-16 15:05:25 -07001326 p_data_param->data_len[i] = (uint8_t)((read_size >>
daniel_Tomas5e976052010-12-09 10:46:12 -08001327 BYTE_SIZE) & BYTE_MASK);
1328 i++;
1329
Rob von Behren6dd94832011-09-16 15:05:25 -07001330 p_dnld_data->frame_length[i] = (uint8_t)
daniel_Tomas5e976052010-12-09 10:46:12 -08001331 ( PHDNLD_CMD_READ_LEN & BYTE_MASK);
1332 /* Update the 2nd byte of the Data and the Address Parameter*/
Rob von Behren6dd94832011-09-16 15:05:25 -07001333 p_data_param->data_addr[i] = (uint8_t)((read_addr >>
daniel_Tomas5e976052010-12-09 10:46:12 -08001334 BYTE_SIZE) & BYTE_MASK);
Rob von Behren6dd94832011-09-16 15:05:25 -07001335 p_data_param->data_len[i] = (uint8_t) (read_size & BYTE_MASK);
daniel_Tomas5e976052010-12-09 10:46:12 -08001336 i++;
1337
1338 /* Update the 3rd byte of the the Address Parameter*/
Rob von Behren6dd94832011-09-16 15:05:25 -07001339 p_data_param->data_addr[i] = (uint8_t)(read_addr & BYTE_MASK);
daniel_Tomas5e976052010-12-09 10:46:12 -08001340
1341 status = phDnldNfc_Send_Command( psDnldContext, pHwRef,
1342 PHDNLD_CMD_READ, NULL , 0 );
1343
1344 if ( NFCSTATUS_PENDING == status )
1345 {
1346 p_sec_info->section_read = TRUE ;
1347 psDnldContext->next_dnld_state = phDnld_Upgrade_State;
1348 DNLD_DEBUG(" FW_DNLD: Memory Read at Address %X : ", read_addr);
1349 DNLD_DEBUG(" of Size %X \n", read_size);
1350 }
1351
1352 }
1353 return status;
1354}
1355
1356
1357
1358static
1359NFCSTATUS
1360phDnldNfc_Process_Write(
1361 phDnldNfc_sContext_t *psDnldContext,
1362 void *pHwRef,
1363 section_info_t *p_sec_info,
1364 uint32_t *p_sec_offset
1365 )
1366{
1367 NFCSTATUS status = NFCSTATUS_SUCCESS;
Rob von Behren6dd94832011-09-16 15:05:25 -07001368 phDnldNfc_sData_t *p_dnld_data =
1369 (phDnldNfc_sData_t *)psDnldContext->dnld_data;
daniel_Tomas5e976052010-12-09 10:46:12 -08001370 phDnldNfc_sParam_t *dnld_data =
Rob von Behren6dd94832011-09-16 15:05:25 -07001371 &p_dnld_data->param_info.data_param;
daniel_Tomas5e976052010-12-09 10:46:12 -08001372 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;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001381 int cmp_val = 0x00;
daniel_Tomas5e976052010-12-09 10:46:12 -08001382
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)
Rob von Behren6dd94832011-09-16 15:05:25 -07001391 && ((sec_type & DNLD_VERIFY_MASK))
daniel_Tomas5e976052010-12-09 10:46:12 -08001392 )
1393 {
daniel_Tomas5e976052010-12-09 10:46:12 -08001394 if(NULL != psDnldContext->trim_store.buffer)
1395 {
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001396 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
daniel_Tomas5e976052010-12-09 10:46:12 -08001404 /* 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]
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001409 ,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);
daniel_Tomas5e976052010-12-09 10:46:12 -08001413 }
daniel_Tomas5e976052010-12-09 10:46:12 -08001414 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 {
daniel_Tomas5e976052010-12-09 10:46:12 -08001419 if((NULL != psDnldContext->dnld_store.buffer)
Rob von Behren6dd94832011-09-16 15:05:25 -07001420 && ((sec_type & DNLD_VERIFY_MASK))
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001421 && (TRUE == p_sec_info->section_write)
1422 && (TRUE == p_sec_info->section_read)
daniel_Tomas5e976052010-12-09 10:46:12 -08001423 )
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);
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001430 p_sec_info->section_read = FALSE;
1431 p_sec_info->section_write = FALSE;
daniel_Tomas5e976052010-12-09 10:46:12 -08001432 DNLD_DEBUG(" FW_DNLD: %X Bytes Write Complete ",
1433 psDnldContext->dnld_store.length);
1434 DNLD_DEBUG(" Comparison Status %X\n", cmp_val);
1435 }
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001436 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 }
daniel_Tomas5e976052010-12-09 10:46:12 -08001445 /* p_sec_info->section_read = FALSE; */
1446 }
1447
1448 if (( 0 == psDnldContext->dnld_retry )
daniel_Tomas5e976052010-12-09 10:46:12 -08001449 && (0 == cmp_val)
daniel_Tomas5e976052010-12-09 10:46:12 -08001450 )
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
daniel_Tomas5e976052010-12-09 10:46:12 -08001485 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);
Rob von Behren6dd94832011-09-16 15:05:25 -07001493 p_dnld_data->frame_length[i] = (uint8_t)
daniel_Tomas5e976052010-12-09 10:46:12 -08001494 (((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);
Rob von Behren6dd94832011-09-16 15:05:25 -07001501 p_dnld_data->frame_length[i] = (uint8_t) ((dnld_size +
daniel_Tomas5e976052010-12-09 10:46:12 -08001502 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,
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001508 (p_sec_info->p_sec_data + *p_sec_offset), dnld_size );
daniel_Tomas5e976052010-12-09 10:46:12 -08001509
Rob von Behren6dd94832011-09-16 15:05:25 -07001510 if( ((sec_type & DNLD_TRIM_MASK))
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001511 && (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 }
Rob von Behren6dd94832011-09-16 15:05:25 -07001518 else if(((sec_type & DNLD_TRIM_MASK))
daniel_Tomas5e976052010-12-09 10:46:12 -08001519 && ( TRUE == p_sec_info->section_read )
1520 )
1521 {
1522 for(i = 0; i < *(p_sec_info->p_trim_data);i++)
1523 {
1524
1525#ifdef NXP_FW_SW_VMID_TRIM
1526
1527/*
1528if(bit 0 of 0x813D is equal to 1) then
1529
1530 Do not overwrite 0x9931 / 0x9981 during download
1531
1532else
1533
1534 @0x9931 = 0x79 // card Mode
1535 @0x9981 = 0x79 // Reader Mode
1536*/
1537 trim_addr = p_sec_info->p_sec_hdr->section_address
1538 + p_sec_info->p_trim_data[i+1];
1539 if (NXP_FW_VMID_TRIM_CHK_ADDR == trim_addr)
1540 {
1541 psDnldContext->vmid_trim_update =
1542 p_sm_trim_data[p_sec_info->p_trim_data[i+1]] ;
1543 }
1544
1545 if((NXP_FW_VMID_CARD_MODE_ADDR == trim_addr)
1546 || (NXP_FW_VMID_RD_MODE_ADDR == trim_addr))
1547 {
1548 if (TRUE == psDnldContext->vmid_trim_update)
1549 {
1550 dnld_data->data_packet[p_sec_info->p_trim_data[i+1]] =
1551 p_sm_trim_data[p_sec_info->p_trim_data[i+1]] ;
1552 }
1553 }
1554 else
1555
1556#endif
1557 {
1558 dnld_data->data_packet[p_sec_info->p_trim_data[i+1]] =
1559 p_sm_trim_data[p_sec_info->p_trim_data[i+1]] ;
1560 }
1561 }
1562 if(NULL != psDnldContext->trim_store.buffer)
1563 {
1564 phOsalNfc_FreeMemory(psDnldContext->trim_store.buffer);
1565 psDnldContext->trim_store.buffer = NULL;
1566 psDnldContext->trim_store.length = 0;
1567 }
Rob von Behren6dd94832011-09-16 15:05:25 -07001568#if 1
1569 (void)
1570 phDnldNfc_Allocate_Resource((void **)
1571 &(psDnldContext->trim_store.buffer),dnld_size);
1572#else
daniel_Tomas5e976052010-12-09 10:46:12 -08001573 psDnldContext->trim_store.buffer =
1574 (uint8_t *) phOsalNfc_GetMemory(dnld_size);
Rob von Behren6dd94832011-09-16 15:05:25 -07001575#endif
daniel_Tomas5e976052010-12-09 10:46:12 -08001576
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 }
Rob von Behren6dd94832011-09-16 15:05:25 -07001598#if 1
1599 (void)
1600 phDnldNfc_Allocate_Resource((void **)
1601 &(psDnldContext->dnld_store.buffer),dnld_size);
1602#else
daniel_Tomas5e976052010-12-09 10:46:12 -08001603 psDnldContext->dnld_store.buffer =
1604 (uint8_t *) phOsalNfc_GetMemory(dnld_size);
Rob von Behren6dd94832011-09-16 15:05:25 -07001605#endif
daniel_Tomas5e976052010-12-09 10:46:12 -08001606 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 }
Rob von Behren6dd94832011-09-16 15:05:25 -07001617
1618 if(PHDNLD_FW_PATCH_SEC != psDnldContext->p_fw_hdr->fw_patch)
1619 {
daniel_Tomas5e976052010-12-09 10:46:12 -08001620 status = phDnldNfc_Send_Command( psDnldContext, pHwRef,
1621 PHDNLD_CMD_WRITE, NULL , 0 );
Rob von Behren6dd94832011-09-16 15:05:25 -07001622 }
1623 else
1624 {
1625 status = phDnldNfc_Send_Command( psDnldContext, pHwRef,
1626 PHDNLD_CMD_SEC_WRITE, NULL , 0 );
1627 }
daniel_Tomas5e976052010-12-09 10:46:12 -08001628
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001629 DNLD_DEBUG(" FW_DNLD: Memory Write Status = %X \n", status);
daniel_Tomas5e976052010-12-09 10:46:12 -08001630 if ( NFCSTATUS_PENDING == status )
1631 {
1632 psDnldContext->prev_dnld_size = dnld_size;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001633 cmp_val = 0x00;
Rob von Behren6dd94832011-09-16 15:05:25 -07001634 if((sec_type & DNLD_TRIM_MASK))
daniel_Tomas5e976052010-12-09 10:46:12 -08001635 {
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 {
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001642 p_sec_info->section_write = TRUE;
daniel_Tomas5e976052010-12-09 10:46:12 -08001643 DNLD_DEBUG(" FW_DNLD: Bytes Downloaded = %X : ",
1644 (*p_sec_offset + dnld_size));
1645 DNLD_DEBUG(" Bytes Remaining = %X \n",
1646 (p_sec_info->p_sec_hdr->section_length -
1647 (*p_sec_offset + dnld_size)));
1648 }
1649
1650 p_sec_info->section_read = FALSE;
1651 }
1652 }
1653 return status;
1654}
1655
1656
1657
1658static
1659NFCSTATUS
1660phDnldNfc_Resume_Write(
1661 phDnldNfc_sContext_t *psDnldContext,
1662 void *pHwRef
1663 )
1664{
1665 NFCSTATUS status = NFCSTATUS_SUCCESS;
1666 uint8_t sec_index = psDnldContext->section_index;
1667 section_info_t *p_sec_info = (psDnldContext->p_fw_sec + sec_index);
1668
1669 while((sec_index < psDnldContext->p_fw_hdr->no_of_sections)
1670 && (NFCSTATUS_SUCCESS == status )
1671 )
1672 {
1673
1674 status = phDnldNfc_Process_Write(psDnldContext, pHwRef,
1675 p_sec_info, (uint32_t *)&(p_sec_info->section_offset));
1676 if (NFCSTATUS_SUCCESS == status)
1677 {
1678 unsigned sec_type = 0;
1679 sec_type = (unsigned int)p_sec_info->p_sec_hdr->section_mem_type;
1680
1681 p_sec_info->section_offset = 0;
1682 p_sec_info->section_read = FALSE;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001683 p_sec_info->section_write = FALSE;
daniel_Tomas5e976052010-12-09 10:46:12 -08001684 p_sec_info->trim_write = FALSE;
1685
1686 DNLD_DEBUG(" FW_DNLD: Section %02X Download Complete\n", sec_index);
Rob von Behren6dd94832011-09-16 15:05:25 -07001687 if((sec_type & DNLD_RESET_MASK))
daniel_Tomas5e976052010-12-09 10:46:12 -08001688 {
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++;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001696
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
daniel_Tomas5e976052010-12-09 10:46:12 -08001705 p_sec_info = (psDnldContext->p_fw_sec + sec_index);
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001706
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
daniel_Tomas5e976052010-12-09 10:46:12 -08001726 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
Rob von Behren6dd94832011-09-16 15:05:25 -07001756#define NXP_DNLD_PATCH_ADDR 0x01A1E0U
daniel_Tomas5e976052010-12-09 10:46:12 -08001757#endif
1758
1759#if (ES_HW_VER <= 30)
1760#define NXP_DNLD_PATCH_TABLE_ADDR 0x008107U
1761#else
1762#define NXP_DNLD_PATCH_TABLE_ADDR 0x00825AU
1763#endif
1764
1765
1766static
1767NFCSTATUS
1768phDnldNfc_Sequence(
1769 phDnldNfc_sContext_t *psDnldContext,
1770 void *pHwRef,
1771 void *pdata,
1772 uint16_t length
1773 )
1774{
1775 NFCSTATUS status = NFCSTATUS_SUCCESS;
1776 uint32_t dnld_addr = 0;
Rob von Behren6dd94832011-09-16 15:05:25 -07001777 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;
daniel_Tomas5e976052010-12-09 10:46:12 -08001781 uint8_t *p_data = NULL;
1782 static uint32_t patch_size = 0;
1783
1784#if (ES_HW_VER == 32)
1785
Rob von Behren6dd94832011-09-16 15:05:25 -07001786 static uint8_t patch_table[] = {0xA0, 0xA1, 0xE0, 0x80, 0xA9, 0x6C };
daniel_Tomas5e976052010-12-09 10:46:12 -08001787 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 }
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001823 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 }
daniel_Tomas5e976052010-12-09 10:46:12 -08001849 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;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001876#define NXP_FW_PATCH_DISABLE
1877#ifdef NXP_FW_PATCH_DISABLE
1878 psDnldContext->next_dnld_seq =
1879 (uint8_t)phDnld_Deactivate_Patch;
1880#else
daniel_Tomas5e976052010-12-09 10:46:12 -08001881 psDnldContext->next_dnld_state =
1882 (uint8_t)phDnld_Reset_State;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07001883#endif
daniel_Tomas5e976052010-12-09 10:46:12 -08001884
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*/
Rob von Behren6dd94832011-09-16 15:05:25 -07001929 p_data_param->data_addr[i] = (uint8_t)((dnld_addr >>
daniel_Tomas5e976052010-12-09 10:46:12 -08001930 (BYTE_SIZE + BYTE_SIZE))
1931 & BYTE_MASK);
Rob von Behren6dd94832011-09-16 15:05:25 -07001932 p_data_param->data_len[i] = (uint8_t)((patch_size >> BYTE_SIZE)
daniel_Tomas5e976052010-12-09 10:46:12 -08001933 & BYTE_MASK);
Rob von Behren6dd94832011-09-16 15:05:25 -07001934 p_dnld_data->frame_length[i] = (uint8_t)
daniel_Tomas5e976052010-12-09 10:46:12 -08001935 (((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*/
Rob von Behren6dd94832011-09-16 15:05:25 -07001939 p_data_param->data_addr[i] = (uint8_t)((dnld_addr >> BYTE_SIZE)
daniel_Tomas5e976052010-12-09 10:46:12 -08001940 & BYTE_MASK);
Rob von Behren6dd94832011-09-16 15:05:25 -07001941 p_data_param->data_len[i] = (uint8_t) (patch_size & BYTE_MASK);
1942 p_dnld_data->frame_length[i] = (uint8_t)
daniel_Tomas5e976052010-12-09 10:46:12 -08001943 ((patch_size + PHDNLD_CMD_WRITE_MIN_LEN)
1944 & BYTE_MASK);
1945 i++;
1946 /* Update the 3rd byte of the the Address Parameter*/
Rob von Behren6dd94832011-09-16 15:05:25 -07001947 p_data_param->data_addr[i] = (uint8_t)(dnld_addr & BYTE_MASK);
daniel_Tomas5e976052010-12-09 10:46:12 -08001948
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
Rob von Behren6dd94832011-09-16 15:05:25 -07001961#define FRAME_HEADER_LEN 0x03U
1962
1963
1964static
1965void
1966phDnldNfc_Tx_Reset(phDnldNfc_sContext_t *psDnldContext)
1967{
1968 psDnldContext->tx_info.transmit_frame = NULL;
1969 psDnldContext->tx_info.tx_total = 0x00;
1970 psDnldContext->tx_info.tx_offset = 0x00;
1971 psDnldContext->tx_info.tx_len = 0x00;
1972 psDnldContext->tx_info.tx_chain = FALSE;
1973}
1974
1975STATIC
1976bool_t
1977phDnldNfc_Extract_Chunks(
1978 uint8_t *frame_data,
1979 uint16_t frame_offset,
1980 uint16_t frame_length,
1981 uint16_t max_frame ,
1982 uint16_t *chunk_length
1983 );
1984
1985
1986STATIC
1987bool_t
1988phDnldNfc_Extract_Chunks(
1989 uint8_t *frame_data,
1990 uint16_t frame_offset,
1991 uint16_t frame_length,
1992 uint16_t max_frame ,
1993 uint16_t *chunk_length
1994 )
1995{
1996 bool_t chunk_present = FALSE;
1997
1998 if( 0 == frame_offset)
1999 {
2000 if( max_frame >= (frame_length
2001 - frame_offset))
2002 {
2003 *chunk_length = (frame_length - frame_offset);
2004 }
2005 else
2006 {
2007 *chunk_length = max_frame
2008 - FRAME_HEADER_LEN;
2009 chunk_present = TRUE;
2010 }
2011 }
2012 else
2013 {
2014 if( max_frame >= (frame_length
2015 - frame_offset))
2016 {
2017 *chunk_length = (frame_length - frame_offset);
2018 }
2019 else
2020 {
2021 *chunk_length = max_frame
2022 - FRAME_HEADER_LEN;
2023 chunk_present = TRUE;
2024 }
2025 }
2026
2027 return chunk_present;
2028}
2029
2030
2031STATIC
2032NFCSTATUS
2033phDnldNfc_Send_Raw(
2034 phDnldNfc_sContext_t *psDnldContext,
2035 void *pHwRef,
2036 uint8_t *raw_frame,
2037 uint16_t frame_offset,
2038 uint16_t frame_length
2039 )
2040{
2041 NFCSTATUS status = NFCSTATUS_SUCCESS;
2042 phDnldNfc_sRawHdr_t *raw_frame_hdr = ( phDnldNfc_sRawHdr_t * ) raw_frame;
2043
2044 switch(raw_frame_hdr->frame_type)
2045 {
2046 case PHDNLD_CMD_RESET:
2047 {
2048 break;
2049 }
2050 case PHDNLD_CMD_READ:
2051 {
2052 /* TODO: To Update the length and the buffer to receive data */
2053 break;
2054 }
2055 case PHDNLD_CMD_WRITE:
2056 {
2057 phDnldNfc_sRawDataHdr_t *raw_data_hdr =
2058 ( phDnldNfc_sRawDataHdr_t * ) (raw_frame + FRAME_HEADER_LEN);
2059
2060 psDnldContext->resp_length = PHDNLD_MIN_PACKET;
2061
2062 break;
2063 }
2064 case PHDNLD_CMD_SEC_WRITE:
2065 {
2066 uint16_t tx_length = 0x00;
2067 uint16_t frame_offset =
2068 psDnldContext->tx_info.tx_offset;
2069 uint16_t chain =
2070 psDnldContext->tx_info.tx_chain;
2071
2072 chain =
2073 phDnldNfc_Extract_Chunks(
2074 raw_frame,
2075 frame_offset,
2076 frame_length,
2077 PHDNLD_FW_TX_RX_LEN,
2078 &tx_length
2079 );
2080
2081 if( TRUE == chain )
2082 {
2083 status = phDnldNfc_Send_Command( psDnldContext,
2084 pHwRef, PHDNLD_CMD_ENCAPSULATE,
2085 (raw_frame + frame_offset),
2086 tx_length);
2087 if(NFCSTATUS_PENDING == status)
2088 {
2089 psDnldContext->prev_cmd = raw_frame_hdr->frame_type;
2090 /* TODO: Update for the Chaining */
2091 psDnldContext->tx_info.tx_offset += tx_length;
2092 psDnldContext->tx_info.tx_chain = chain;
2093 }
2094 }
2095 else if (0 != frame_offset)
2096 {
2097 status = phDnldNfc_Send_Command( psDnldContext,
2098 pHwRef, PHDNLD_CMD_ENCAPSULATE,
2099 (raw_frame + frame_offset),
2100 tx_length);
2101 if(NFCSTATUS_PENDING == status)
2102 {
2103 psDnldContext->prev_cmd = raw_frame_hdr->frame_type;
2104 /* TODO: Update for the Chaining */
2105 psDnldContext->prev_dnld_size = frame_length;
2106 phDnldNfc_Tx_Reset(psDnldContext);
2107 }
2108 }
2109 else
2110 {
2111 phDnldNfc_sRawDataHdr_t *raw_data_hdr =
2112 ( phDnldNfc_sRawDataHdr_t * ) (raw_frame + FRAME_HEADER_LEN);
2113 psDnldContext->resp_length = PHDNLD_MIN_PACKET;
2114 }
2115
2116 break;
2117 }
2118 case PHDNLD_CMD_CHECK:
2119 {
2120 psDnldContext->resp_length = PHDNLD_MIN_PACKET;
2121 break;
2122 }
2123 case PHDNLD_CMD_SET_HIF:
2124 {
2125 psDnldContext->resp_length = PHDNLD_MIN_PACKET;
2126 break;
2127 }
2128 case PHDNLD_CMD_ACTIVATE_PATCH:
2129 {
2130 psDnldContext->resp_length = PHDNLD_MIN_PACKET;
2131 break;
2132 }
2133 case PHDNLD_CMD_CHECK_INTEGRITY:
2134 {
2135 uint8_t integrity_param =
2136 *(raw_frame + FRAME_HEADER_LEN);
2137 switch(integrity_param)
2138 {
2139 case CHK_INTEGRITY_CONFIG_PAGE_CRC:
2140 case CHK_INTEGRITY_PATCH_TABLE_CRC:
2141 {
2142 psDnldContext->resp_length = PHDNLD_MIN_PACKET
2143 + CHECK_INTEGRITY_RESP_CRC16_LEN;
2144 break;
2145 }
2146 case CHK_INTEGRITY_FLASH_CODE_CRC:
2147 case CHK_INTEGRITY_PATCH_CODE_CRC:
2148 {
2149 psDnldContext->resp_length = PHDNLD_MIN_PACKET
2150 + CHECK_INTEGRITY_RESP_CRC32_LEN;
2151 break;
2152 }
2153 case CHK_INTEGRITY_COMPLETE_CRC:
2154 default:
2155 {
2156 psDnldContext->resp_length = PHDNLD_MIN_PACKET
2157 + CHECK_INTEGRITY_RESP_COMP_LEN;
2158 break;
2159 }
2160 }
2161 break;
2162 }
2163 default:
2164 {
2165 status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FEATURE_NOT_SUPPORTED);
2166 break;
2167 }
2168 }
2169
2170 if (NFCSTATUS_SUCCESS == status)
2171 {
2172 status = phDnldNfc_Send( psDnldContext, pHwRef ,
2173 raw_frame, frame_length);
2174
2175 if(NFCSTATUS_PENDING == status)
2176 {
2177 psDnldContext->prev_cmd = raw_frame_hdr->frame_type;
2178 /* TODO: Update for the Chaining */
2179 psDnldContext->prev_dnld_size = frame_length;
2180 }
2181 }
2182
2183 return status;
2184}
2185
2186
2187static
2188NFCSTATUS
2189phDnldNfc_Frame_Complete(phDnldNfc_sContext_t *psDnldContext)
2190{
2191 NFCSTATUS status = NFCSTATUS_SUCCESS;
2192 phDnldNfc_sData_Hdr_t *p_dnld_raw = NULL;
2193 uint32_t dnld_index = psDnldContext->dnld_index;
2194 uint8_t *p_raw_sec_hdr = NULL;
2195 uint16_t tx_length = 0x00;
2196
2197 dnld_index = dnld_index + psDnldContext->prev_dnld_size;
2198 p_raw_sec_hdr = psDnldContext->p_fw_raw + dnld_index;
2199 dnld_index = dnld_index + *p_raw_sec_hdr;
2200
2201 p_dnld_raw = (phDnldNfc_sData_Hdr_t *) (psDnldContext->p_fw_raw +
2202 psDnldContext->dnld_index);
2203
2204 tx_length = ((p_dnld_raw->frame_length[0] << BYTE_SIZE) |
2205 p_dnld_raw->frame_length[1]);
2206
2207 tx_length = tx_length + PHDNLD_MIN_PACKET;
2208
2209 return status;
2210}
2211
2212
2213static
2214NFCSTATUS
2215phDnldNfc_Raw_Write(
2216 phDnldNfc_sContext_t *psDnldContext,
2217 void *pHwRef
2218 )
2219{
2220 NFCSTATUS status = NFCSTATUS_SUCCESS;
2221 uint32_t dnld_index = psDnldContext->dnld_index;
2222 uint32_t tx_length = 0;
2223 uint8_t *p_raw_sec_hdr = NULL;
2224 uint8_t dnld_flag = FALSE;
2225 uint8_t skip_frame = FALSE;
2226
2227 if(NULL != psDnldContext->p_fw_raw)
2228 {
2229
2230 if( (TRUE != psDnldContext->tx_info.tx_chain)
2231 && (0x00 == psDnldContext->dnld_retry)
2232 )
2233 {
2234 dnld_index = dnld_index + psDnldContext->prev_dnld_size;
2235 p_raw_sec_hdr = psDnldContext->p_fw_raw + dnld_index;
2236 dnld_index = dnld_index + *p_raw_sec_hdr;
2237 }
2238 else
2239 {
2240 phDnldNfc_sData_Hdr_t *p_dnld_raw = (phDnldNfc_sData_Hdr_t *)
2241 (psDnldContext->p_fw_raw +
2242 psDnldContext->dnld_index);
2243
2244 tx_length = ((p_dnld_raw->frame_length[0] << BYTE_SIZE) |
2245 p_dnld_raw->frame_length[1]);
2246
2247 tx_length = tx_length + PHDNLD_MIN_PACKET;
2248
2249 status = phDnldNfc_Send_Raw( psDnldContext, pHwRef,
2250 (uint8_t *)(p_dnld_raw),
2251 psDnldContext->tx_info.tx_offset,
2252 (uint16_t)tx_length);
2253 }
2254
2255
2256#define PHDNLD_MAJOR_OFFSET 0x04U
2257#define PHDNLD_MINOR_OFFSET 0x05U
2258#define PHDNLD_PHASE_OFFSET 0x06U
2259#define PHDNLD_FRAMETYPE_OFFSET 0x07U
2260
2261#define PHDNLD_NO_OPERATION 0x00U
2262#define PHDNLD_NORMAL_OPERATION 0x10U
2263#define PHDNLD_ADVANCED_OPERATION 0x20U
2264#define PHDNLD_SETUP_OPERATION 0x40U
2265#define PHDNLD_RECOVER_OPERATION 0x80U
2266#define PHDNLD_COMPLETE_OPERATION 0xF0U
2267
2268#define PHDNLD_TERMINATE_TYPE 0x0EU
2269
2270#define PHDNLD_MARKER_MASK 0x0FU
2271
2272 while((NFCSTATUS_SUCCESS == status )
2273 && (FALSE == dnld_flag)
2274 )
2275 {
2276 phDnldNfc_sData_Hdr_t *p_dnld_raw = (phDnldNfc_sData_Hdr_t *)
2277 (psDnldContext->p_fw_raw + dnld_index);
2278 uint8_t frame_type = *(p_raw_sec_hdr + PHDNLD_FRAMETYPE_OFFSET);
2279
2280 tx_length = ((p_dnld_raw->frame_length[0] << BYTE_SIZE) |
2281 p_dnld_raw->frame_length[1]);
2282
2283 tx_length = tx_length + PHDNLD_MIN_PACKET;
2284
2285 skip_frame = FALSE;
2286
2287 if( (0x00 == *(p_raw_sec_hdr + PHDNLD_PHASE_OFFSET))
2288 || (0xFF == *(p_raw_sec_hdr + PHDNLD_PHASE_OFFSET))
2289 || !( psDnldContext->raw_mode_upgrade
2290 & (frame_type & (~PHDNLD_MARKER_MASK)) )
2291 )
2292 {
2293 dnld_index = dnld_index + tx_length;
2294 p_raw_sec_hdr = psDnldContext->p_fw_raw + dnld_index;
2295 dnld_index = dnld_index + *p_raw_sec_hdr;
2296 skip_frame = TRUE;
2297 }
2298 if (PHDNLD_TERMINATE_TYPE ==
2299 (frame_type & PHDNLD_MARKER_MASK))
2300 {
2301 if(TRUE != skip_frame)
2302 {
2303 psDnldContext->raw_mode_upgrade =
2304 (psDnldContext->raw_mode_upgrade &
2305 ~(frame_type & ~PHDNLD_MARKER_MASK));
2306 }
2307
2308 if(PHDNLD_NO_OPERATION ==
2309 psDnldContext->raw_mode_upgrade)
2310 {
2311 dnld_flag = TRUE;
2312 }
2313 }
2314 else
2315 {
2316
2317 }
2318
2319 if((FALSE == skip_frame)
2320 && (FALSE == dnld_flag)
2321 )
2322 {
2323 status = phDnldNfc_Send_Raw( psDnldContext, pHwRef,
2324 (uint8_t *)(p_dnld_raw),
2325 psDnldContext->tx_info.tx_offset,
2326 (uint16_t)tx_length);
2327 }
2328
2329 if( NFCSTATUS_PENDING == status )
2330 {
2331 psDnldContext->dnld_index = dnld_index;
2332 psDnldContext->cur_frame_info= frame_type;
2333 }
2334 }
2335 }
2336
2337 return status;
2338}
daniel_Tomas5e976052010-12-09 10:46:12 -08002339
2340static
2341NFCSTATUS
2342phDnldNfc_Upgrade_Sequence(
2343 phDnldNfc_sContext_t *psDnldContext,
2344 void *pHwRef,
2345 void *pdata,
2346 uint16_t length
2347 )
2348{
2349 NFCSTATUS status = NFCSTATUS_SUCCESS;
daniel_Tomas5e976052010-12-09 10:46:12 -08002350
2351 PHNFC_UNUSED_VARIABLE(pdata);
2352 PHNFC_UNUSED_VARIABLE(length);
2353
Rob von Behren6dd94832011-09-16 15:05:25 -07002354 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 }
daniel_Tomas5e976052010-12-09 10:46:12 -08002362
2363 return status;
2364}
2365
2366
2367
2368static
2369NFCSTATUS
2370phDnldNfc_Resume(
2371 phDnldNfc_sContext_t *psDnldContext,
2372 void *pHwRef,
2373 void *pdata,
2374 uint16_t length
2375 )
2376{
2377 NFCSTATUS status = NFCSTATUS_SUCCESS;
2378 phDnldNfc_eState_t dnld_next_state = (phDnldNfc_eState_t)
2379 psDnldContext->cur_dnld_state;
Nick Pelly34ff48f2011-06-27 09:01:51 -07002380 phNfc_sCompletionInfo_t comp_info = {0,0,0};
daniel_Tomas5e976052010-12-09 10:46:12 -08002381
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 }
Nick Pelly8c9b94d2011-07-19 14:35:22 -07002398#ifdef NXP_FW_PATCH_DISABLE
2399 case phDnld_Deactivate_Patch:
2400#else
daniel_Tomas5e976052010-12-09 10:46:12 -08002401 case phDnld_Unlock_System:
Nick Pelly8c9b94d2011-07-19 14:35:22 -07002402#endif
daniel_Tomas5e976052010-12-09 10:46:12 -08002403 {
2404 psDnldContext->next_dnld_state =
2405 (uint8_t)phDnld_Upgrade_State;
2406 psDnldContext->next_dnld_seq =
2407 (uint8_t)phDnld_Upgrade_Section;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07002408#ifdef NXP_FW_DNLD_CHECK_PHASE
2409 gphDnldPhase = NXP_FW_DNLD_CFG_PHASE;
2410#endif /* NXP_FW_DNLD_CHECK_PHASE */
daniel_Tomas5e976052010-12-09 10:46:12 -08002411 break;
2412 }
2413 case phDnld_Lock_System:
2414 {
Nick Pelly8c9b94d2011-07-19 14:35:22 -07002415#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
daniel_Tomas5e976052010-12-09 10:46:12 -08002421 /* (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;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07002425#endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */
daniel_Tomas5e976052010-12-09 10:46:12 -08002426 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
Nick Pelly8c9b94d2011-07-19 14:35:22 -07002463#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
daniel_Tomas5e976052010-12-09 10:46:12 -08002473 /* (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;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07002477#endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */
daniel_Tomas5e976052010-12-09 10:46:12 -08002478 }
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 {
Nick Pelly8c9b94d2011-07-19 14:35:22 -07002508 patch_table_crc = patch_table_crc
daniel_Tomas5e976052010-12-09 10:46:12 -08002509 | 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);
Rob von Behren6dd94832011-09-16 15:05:25 -07002575#ifndef NFC_TIMER_CONTEXT
2576 gpphDnldContext = psDnldContext;
2577#endif
daniel_Tomas5e976052010-12-09 10:46:12 -08002578 /* 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 }
daniel_Tomas5e976052010-12-09 10:46:12 -08002583 return status;
2584}
2585
2586STATIC
2587NFCSTATUS
2588phDnldNfc_Process_Response(
2589 phDnldNfc_sContext_t *psDnldContext,
2590 void *pHwRef,
2591 void *pdata,
2592 uint16_t length
2593 )
2594{
2595 NFCSTATUS status = NFCSTATUS_SUCCESS;
2596 phDnldNfc_sData_Hdr_t *resp_data =
2597 (phDnldNfc_sData_Hdr_t *) pdata;
2598
2599 PHNFC_UNUSED_VARIABLE(pHwRef);
Rob von Behren6dd94832011-09-16 15:05:25 -07002600 DNLD_DEBUG(" FW_DNLD: Receive Length = %X \n", length );
2601 if(( psDnldContext->rx_info.rx_total == 0 )
daniel_Tomas5e976052010-12-09 10:46:12 -08002602 && (PHDNLD_MIN_PACKET <= length)
daniel_Tomas5e976052010-12-09 10:46:12 -08002603 )
2604 {
Rob von Behren6dd94832011-09-16 15:05:25 -07002605 psDnldContext->rx_info.rx_total =
daniel_Tomas5e976052010-12-09 10:46:12 -08002606 ((uint16_t)resp_data->frame_length[0] << BYTE_SIZE)|
2607 resp_data->frame_length[1];
Rob von Behren6dd94832011-09-16 15:05:25 -07002608 if( psDnldContext->rx_info.rx_total + PHDNLD_MIN_PACKET == length )
daniel_Tomas5e976052010-12-09 10:46:12 -08002609 {
2610
2611 DNLD_DEBUG(" FW_DNLD: Success Memory Read = %X \n",
Rob von Behren6dd94832011-09-16 15:05:25 -07002612 psDnldContext->rx_info.rx_total);
daniel_Tomas5e976052010-12-09 10:46:12 -08002613#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,
Rob von Behren6dd94832011-09-16 15:05:25 -07002622 (uint8_t)((psDnldContext->rx_info.rx_total <= PHDNLD_MAX_PACKET)?
2623 psDnldContext->rx_info.rx_total: PHDNLD_MAX_PACKET) ); */
daniel_Tomas5e976052010-12-09 10:46:12 -08002624 DNLD_PRINT(" FW_DNLD: Invalid Receive length ");
2625 DNLD_DEBUG(": Length Expected = %X \n",
Rob von Behren6dd94832011-09-16 15:05:25 -07002626 (psDnldContext->rx_info.rx_total + PHDNLD_MIN_PACKET));
daniel_Tomas5e976052010-12-09 10:46:12 -08002627 status = PHNFCSTVAL( CID_NFC_DNLD,
2628 NFCSTATUS_INVALID_RECEIVE_LENGTH );
2629 }
2630 }
2631 else
2632 {
2633 /*TODO:*/
Rob von Behren6dd94832011-09-16 15:05:25 -07002634 psDnldContext->rx_info.rx_total = 0 ;
daniel_Tomas5e976052010-12-09 10:46:12 -08002635 status = PHNFCSTVAL( CID_NFC_DNLD,
2636 NFCSTATUS_INVALID_RECEIVE_LENGTH );
2637 }
2638
2639 return status;
2640}
2641
2642
2643
2644STATIC
2645void
2646phDnldNfc_Receive_Complete (
2647 void *psContext,
2648 void *pHwRef,
2649 phNfc_sTransactionInfo_t *pInfo
2650 )
2651{
2652 NFCSTATUS status = NFCSTATUS_SUCCESS ;
2653 void *pdata = NULL ;
2654 phDnldNfc_sData_Hdr_t *resp_data = NULL;
2655 uint16_t length = 0 ;
Nick Pelly34ff48f2011-06-27 09:01:51 -07002656 phNfc_sCompletionInfo_t comp_info = {0,0,0};
daniel_Tomas5e976052010-12-09 10:46:12 -08002657
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;
Rob von Behren6dd94832011-09-16 15:05:25 -07002669
daniel_Tomas5e976052010-12-09 10:46:12 -08002670 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 }
Rob von Behren6dd94832011-09-16 15:05:25 -07002681 else if ((0 == length)
2682 || (PHDNLD_MIN_PACKET > length ))
daniel_Tomas5e976052010-12-09 10:46:12 -08002683 {
Rob von Behren6dd94832011-09-16 15:05:25 -07002684 DNLD_DEBUG(" Receive Response Length = %u .... \n",length);
daniel_Tomas5e976052010-12-09 10:46:12 -08002685 /* 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
Rob von Behren6dd94832011-09-16 15:05:25 -07002694#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
daniel_Tomas5e976052010-12-09 10:46:12 -08002703#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 {
Rob von Behren6dd94832011-09-16 15:05:25 -07002721 if( PHDNLD_NO_OPERATION
2722 == psDnldContext->raw_mode_upgrade)
2723 {
daniel_Tomas5e976052010-12-09 10:46:12 -08002724 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 }
Rob von Behren6dd94832011-09-16 15:05:25 -07002733 }
2734 else
2735 {
2736
2737 }
daniel_Tomas5e976052010-12-09 10:46:12 -08002738 break;
2739 }
2740 case PHDNLD_CMD_CHECK_INTEGRITY :
2741 {
Rob von Behren6dd94832011-09-16 15:05:25 -07002742 if( PHDNLD_NO_OPERATION
2743 == psDnldContext->raw_mode_upgrade)
2744 {
daniel_Tomas5e976052010-12-09 10:46:12 -08002745#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 }
daniel_Tomas5e976052010-12-09 10:46:12 -08002789#endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */
Rob von Behren6dd94832011-09-16 15:05:25 -07002790 }
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 }
daniel_Tomas5e976052010-12-09 10:46:12 -08002799 break;
2800 }
2801 case PHDNLD_CMD_WRITE:
2802 {
2803 psDnldContext->dnld_retry = 0;
2804 break;
2805 }
Rob von Behren6dd94832011-09-16 15:05:25 -07002806 case PHDNLD_CMD_SEC_WRITE:
2807 {
2808 psDnldContext->dnld_retry = 0;
2809 break;
2810 }
daniel_Tomas5e976052010-12-09 10:46:12 -08002811 case PHDNLD_CMD_ACTIVATE_PATCH:
2812 case PHDNLD_CMD_CHECK:
2813 default:
2814 {
Rob von Behren6dd94832011-09-16 15:05:25 -07002815 if( PHDNLD_NO_OPERATION
2816 == psDnldContext->raw_mode_upgrade)
2817 {
daniel_Tomas5e976052010-12-09 10:46:12 -08002818 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 }
Rob von Behren6dd94832011-09-16 15:05:25 -07002830 }
2831 else
2832 {
2833 psDnldContext->raw_mode_upgrade =
2834 (psDnldContext->raw_mode_upgrade & ~PHDNLD_RECOVER_OPERATION);
2835 }
daniel_Tomas5e976052010-12-09 10:46:12 -08002836 break;
2837 }
2838 } /* End of the Previous Command Switch Case */
2839 break;
2840 }/* Case PHDNLD_RESP_SUCCESS*/
2841 case PHDNLD_RESP_TIMEOUT:
daniel_Tomas5e976052010-12-09 10:46:12 -08002842 case PHDNLD_RESP_CRC_ERROR:
Rob von Behren6dd94832011-09-16 15:05:25 -07002843 case PHDNLD_RESP_WRITE_ERROR:
daniel_Tomas5e976052010-12-09 10:46:12 -08002844 {
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:
daniel_Tomas5e976052010-12-09 10:46:12 -08002855 case PHDNLD_RESP_INVALID_PARAMETER:
2856 case PHDNLD_RESP_INVALID_LENGTH:
Rob von Behren6dd94832011-09-16 15:05:25 -07002857 /* Initial Frame Checksum */
2858 case PHDNLD_RESP_CHKSUM_ERROR:
2859 case PHDNLD_RESP_MEMORY_UPDATE_ERROR:
daniel_Tomas5e976052010-12-09 10:46:12 -08002860 {
2861 psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY;
2862 status = PHNFCSTVAL(CID_NFC_DNLD,
2863 resp_data->frame_type);
2864 break;
2865 }
Rob von Behren6dd94832011-09-16 15:05:25 -07002866 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:
daniel_Tomas5e976052010-12-09 10:46:12 -08002980 default:
2981 {
2982 psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY;
2983 status = PHNFCSTVAL(CID_NFC_DNLD,
Rob von Behren6dd94832011-09-16 15:05:25 -07002984 NFCSTATUS_NOT_ALLOWED);
daniel_Tomas5e976052010-12-09 10:46:12 -08002985 break;
2986 }
Rob von Behren6dd94832011-09-16 15:05:25 -07002987
daniel_Tomas5e976052010-12-09 10:46:12 -08002988 } /* 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);
Rob von Behren6dd94832011-09-16 15:05:25 -07003006#ifndef NFC_TIMER_CONTEXT
3007 gpphDnldContext = psDnldContext;
3008#endif
daniel_Tomas5e976052010-12-09 10:46:12 -08003009 /* 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 }
Rob von Behren6dd94832011-09-16 15:05:25 -07003013 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 }
daniel_Tomas5e976052010-12-09 10:46:12 -08003057 else
3058 {
3059 /* DNLD_PRINT(" FW_DNLD: Successful.\n"); */
3060 psDnldContext->resp_length = /* PHDNLD_MIN_PACKET */ 0 ;
3061 status = phDnldNfc_Set_Seq(psDnldContext,
3062 DNLD_SEQ_UPDATE);
3063 status = phDnldNfc_Resume( psDnldContext,
3064 pHwRef, pdata, length );
3065 }
3066 }
3067 } /* End of status != Success */
3068 }
3069}
3070
3071
3072STATIC
3073void
3074phDnldNfc_Send_Complete (
3075 void *psContext,
3076 void *pHwRef,
3077 phNfc_sTransactionInfo_t *pInfo
3078 )
3079{
3080 NFCSTATUS status = NFCSTATUS_SUCCESS ;
3081 uint16_t length = 0;
3082
3083 DNLD_PRINT(" FW_DNLD: Send Data .... ");
3084 if ( (NULL != psContext)
3085 && (NULL != pInfo)
3086 && (NULL != pHwRef)
3087 )
3088 {
3089 phDnldNfc_sContext_t *psDnldContext =
3090 (phDnldNfc_sContext_t *)psContext;
3091 status = pInfo->status ;
3092 length = pInfo->length ;
3093 if(status != NFCSTATUS_SUCCESS)
3094 {
3095 DNLD_DEBUG(" Failed. Status = %02X\n",status);
3096 /* Handle the Error Scenario */
3097 }
3098 else
3099 {
3100 DNLD_PRINT(" Successful.\n");
3101 (void)memset((void *)&psDnldContext->dnld_data, 0,
3102 sizeof(psDnldContext->dnld_data));
3103 if ((PHDNLD_CMD_SET_HIF != psDnldContext->prev_cmd)
3104 && (PHDNLD_CMD_RESET != psDnldContext->prev_cmd))
3105 {
Rob von Behren6dd94832011-09-16 15:05:25 -07003106 psDnldContext->rx_info.rx_total = 0;
daniel_Tomas5e976052010-12-09 10:46:12 -08003107 status = phDnldNfc_Receive( psDnldContext, pHwRef,
3108 (uint8_t *)(&psDnldContext->dnld_resp),
3109 psDnldContext->resp_length);
daniel_Tomas5e976052010-12-09 10:46:12 -08003110 }
3111 else
3112 {
3113 psDnldContext->resp_length = 0;
3114 psDnldContext->dnld_retry = 0;
Nick Pellyf15b4572011-07-14 08:41:52 -07003115 /* 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 */
Rob von Behren6dd94832011-09-16 15:05:25 -07003119 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
daniel_Tomas5e976052010-12-09 10:46:12 -08003132 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
Rob von Behren6dd94832011-09-16 15:05:25 -07003147
daniel_Tomas5e976052010-12-09 10:46:12 -08003148STATIC
3149NFCSTATUS
3150phDnldNfc_Send_Command(
3151 phDnldNfc_sContext_t *psDnldContext,
3152 void *pHwRef,
3153 uint8_t cmd,
3154 void *params,
3155 uint16_t param_length
3156 )
3157{
3158 NFCSTATUS status = NFCSTATUS_SUCCESS;
3159 uint16_t tx_length = 0;
3160 uint16_t rx_length = 0;
3161 uint8_t **pp_resp_data = &psDnldContext->p_resp_buffer;
Rob von Behren6dd94832011-09-16 15:05:25 -07003162 phDnldNfc_sData_t *p_dnld_data =
3163 (phDnldNfc_sData_t *)psDnldContext->dnld_data;
daniel_Tomas5e976052010-12-09 10:46:12 -08003164
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 {
Rob von Behren6dd94832011-09-16 15:05:25 -07003175 phDnldNfc_sData_t *p_dnld_data =
3176 (phDnldNfc_sData_t *)psDnldContext->dnld_data;
daniel_Tomas5e976052010-12-09 10:46:12 -08003177 phDnldNfc_sParam_t *param_info = /* (phDnldNfc_sParam_t *)params */
Rob von Behren6dd94832011-09-16 15:05:25 -07003178 &p_dnld_data->param_info.data_param;
daniel_Tomas5e976052010-12-09 10:46:12 -08003179 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 =
Rob von Behren6dd94832011-09-16 15:05:25 -07003189 (( rx_length + PHDNLD_MIN_PACKET ));
daniel_Tomas5e976052010-12-09 10:46:12 -08003190 (void)phDnldNfc_Allocate_Resource( (void **) pp_resp_data,
3191 rx_length);
3192 break;
3193 }
3194 case PHDNLD_CMD_WRITE:
Rob von Behren6dd94832011-09-16 15:05:25 -07003195 case PHDNLD_CMD_SEC_WRITE:
daniel_Tomas5e976052010-12-09 10:46:12 -08003196 {
Rob von Behren6dd94832011-09-16 15:05:25 -07003197 phDnldNfc_sData_t *p_dnld_data =
3198 (phDnldNfc_sData_t *)psDnldContext->dnld_data;
daniel_Tomas5e976052010-12-09 10:46:12 -08003199 phDnldNfc_sParam_t *param_info = /* (phDnldNfc_sParam_t *)params */
Rob von Behren6dd94832011-09-16 15:05:25 -07003200 &p_dnld_data->param_info.data_param;
daniel_Tomas5e976052010-12-09 10:46:12 -08003201 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 }
Rob von Behren6dd94832011-09-16 15:05:25 -07003218 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 }
daniel_Tomas5e976052010-12-09 10:46:12 -08003248 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 {
daniel_Tomas5e976052010-12-09 10:46:12 -08003256 psDnldContext->resp_length = PHDNLD_MIN_PACKET;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07003257 if ((NULL != params) && ( param_length > 0 ))
3258 {
Rob von Behren6dd94832011-09-16 15:05:25 -07003259 p_dnld_data->param_info.cmd_param =
Nick Pelly8c9b94d2011-07-19 14:35:22 -07003260 (*(uint8_t *)params);
3261 tx_length = param_length;
3262 }
3263 else
3264 {
Rob von Behren6dd94832011-09-16 15:05:25 -07003265 p_dnld_data->param_info.cmd_param = FALSE;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07003266 tx_length++;
3267 }
daniel_Tomas5e976052010-12-09 10:46:12 -08003268 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);
Nick Pelly8c9b94d2011-07-19 14:35:22 -07003277 tx_length = param_length;
daniel_Tomas5e976052010-12-09 10:46:12 -08003278 }
3279 else
3280 {
3281 psDnldContext->chk_integrity_param = CHK_INTEGRITY_COMPLETE_CRC;
3282 tx_length++;
3283 }
Rob von Behren6dd94832011-09-16 15:05:25 -07003284 p_dnld_data->param_info.cmd_param =
daniel_Tomas5e976052010-12-09 10:46:12 -08003285 (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++;
Rob von Behren6dd94832011-09-16 15:05:25 -07003312 p_dnld_data->param_info.cmd_param =
daniel_Tomas5e976052010-12-09 10:46:12 -08003313 (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
Rob von Behren6dd94832011-09-16 15:05:25 -07003328 p_dnld_data->frame_type = cmd;
3329 p_dnld_data->frame_length[i++] =
daniel_Tomas5e976052010-12-09 10:46:12 -08003330 (uint8_t)(tx_length >> BYTE_SIZE);
Rob von Behren6dd94832011-09-16 15:05:25 -07003331 p_dnld_data->frame_length[i] =
daniel_Tomas5e976052010-12-09 10:46:12 -08003332 (uint8_t)( tx_length & BYTE_MASK );
3333 tx_length = tx_length + PHDNLD_MIN_PACKET;
3334 status = phDnldNfc_Send( psDnldContext, pHwRef ,
Rob von Behren6dd94832011-09-16 15:05:25 -07003335 (uint8_t *)p_dnld_data, tx_length);
daniel_Tomas5e976052010-12-09 10:46:12 -08003336 if(NFCSTATUS_PENDING == status)
3337 {
3338 psDnldContext->prev_cmd = cmd;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07003339
3340 if( PHDNLD_CMD_RESET == cmd )
3341 DO_DELAY(PHDNLD_DNLD_DELAY); //this seems like its on the wrong thread
daniel_Tomas5e976052010-12-09 10:46:12 -08003342 }
daniel_Tomas5e976052010-12-09 10:46:12 -08003343 }
3344
3345 return status;
3346}
3347
3348static
3349NFCSTATUS
Rob von Behren6dd94832011-09-16 15:05:25 -07003350phDnldNfc_Check_FW(
3351 phHal_sHwReference_t *pHwRef,
3352 fw_data_hdr_t *cur_fw_hdr
daniel_Tomas5e976052010-12-09 10:46:12 -08003353 )
3354{
3355 NFCSTATUS status = NFCSTATUS_FAILED;
daniel_Tomas5e976052010-12-09 10:46:12 -08003356
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 )
daniel_Tomas5e976052010-12-09 10:46:12 -08003371 )
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 }
Rob von Behren6dd94832011-09-16 15:05:25 -07003390
3391 return status;
daniel_Tomas5e976052010-12-09 10:46:12 -08003392 }
Rob von Behren6dd94832011-09-16 15:05:25 -07003393
3394
3395static
3396NFCSTATUS
3397phDnldNfc_Process_FW(
3398 phDnldNfc_sContext_t *psDnldContext,
3399 phHal_sHwReference_t *pHwRef
3400#ifdef NXP_FW_PARAM
3401 ,uint8_t *nxp_nfc_fw
3402 ,uint32_t nxp_fw_len
3403#endif
3404 )
3405{
3406 NFCSTATUS status = NFCSTATUS_FAILED;
3407 section_info_t *p_cur_sec = NULL;
3408 static unsigned sec_type;
3409 uint32_t fw_index = 0;
3410#ifdef NXP_NFC_MULTIPLE_FW
3411 phDnldNfc_sFwImageInfo_t *p_cur_fw = NULL;
3412#endif /* #ifdef NXP_NFC_MULTIPLE_FW */
3413 fw_data_hdr_t *cur_fw_hdr = NULL;
3414 uint8_t sec_index = 0;
3415 uint8_t i = 0;
3416
3417 psDnldContext->p_img_hdr = (img_data_hdr_t *) nxp_nfc_fw;
3418
3419#ifdef NXP_NFC_MULTIPLE_FW
3420
3421 /* TODO: Create a memory of pointers to store all the Firmwares */
3422 if( (NXP_NFC_IMAG_FW_MAX > psDnldContext->p_img_hdr->no_of_fw_img)
3423 && (0 != psDnldContext->p_img_hdr->no_of_fw_img)
3424 )
3425 {
3426 ( void )phDnldNfc_Allocate_Resource((void **)&psDnldContext->p_img_info,
3427 (psDnldContext->p_img_hdr->no_of_fw_img * sizeof(phDnldNfc_sFwImageInfo_t)));
3428
3429 if(NULL != psDnldContext->p_img_info)
3430 {
3431 p_cur_fw = psDnldContext->p_img_info;
3432 }
3433 }
3434#endif /* #ifdef NXP_NFC_MULTIPLE_FW */
3435
3436 fw_index = sizeof (img_data_hdr_t);
3437
3438 for ( i=0; i < psDnldContext->p_img_hdr->no_of_fw_img; i++ )
3439 {
3440
3441 psDnldContext->p_fw_hdr = (fw_data_hdr_t *) ( nxp_nfc_fw + fw_index );
3442
3443#ifdef NXP_NFC_MULTIPLE_FW
3444 if(NULL != p_cur_fw)
3445 {
3446 ( p_cur_fw + i)->p_fw_hdr = psDnldContext->p_fw_hdr;
3447 }
3448#endif /* #ifdef NXP_NFC_MULTIPLE_FW */
3449 cur_fw_hdr = psDnldContext->p_fw_hdr;
3450
3451 fw_index = fw_index + (cur_fw_hdr->fw_hdr_len * PNDNLD_WORD_LEN);
3452
3453 status = phDnldNfc_Check_FW( pHwRef, cur_fw_hdr);
3454
3455 }
3456
daniel_Tomas5e976052010-12-09 10:46:12 -08003457 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 {
Rob von Behren6dd94832011-09-16 15:05:25 -07003463 if( (BYTE_MASK > cur_fw_hdr->no_of_sections)
3464 && (0 != cur_fw_hdr->no_of_sections)
3465 )
3466 {
daniel_Tomas5e976052010-12-09 10:46:12 -08003467 (void) phDnldNfc_Allocate_Resource((void **)&psDnldContext->p_fw_sec,
3468 (cur_fw_hdr->no_of_sections * sizeof(section_info_t)));
Rob von Behren6dd94832011-09-16 15:05:25 -07003469
3470 if(NULL != psDnldContext->p_fw_sec)
daniel_Tomas5e976052010-12-09 10:46:12 -08003471 {
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
Rob von Behren6dd94832011-09-16 15:05:25 -07003499 if((sec_type & DNLD_TRIM_MASK))
daniel_Tomas5e976052010-12-09 10:46:12 -08003500 {
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
Rob von Behren6dd94832011-09-16 15:05:25 -07003509 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 }
daniel_Tomas5e976052010-12-09 10:46:12 -08003522 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 +
daniel_Tomas5e976052010-12-09 10:46:12 -08003527 (p_cur_sec->p_sec_hdr->section_hdr_len * PNDNLD_WORD_LEN);
daniel_Tomas5e976052010-12-09 10:46:12 -08003528
3529 fw_index = fw_index +
daniel_Tomas5e976052010-12-09 10:46:12 -08003530 (p_cur_sec->p_sec_hdr->section_hdr_len * PNDNLD_WORD_LEN)
daniel_Tomas5e976052010-12-09 10:46:12 -08003531 + p_cur_sec->p_sec_hdr->section_length;
3532
Rob von Behren6dd94832011-09-16 15:05:25 -07003533
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
daniel_Tomas5e976052010-12-09 10:46:12 -08003545 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 }
Rob von Behren6dd94832011-09-16 15:05:25 -07003578
3579 } /* End of Address Switch */
daniel_Tomas5e976052010-12-09 10:46:12 -08003580#endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */
Rob von Behren6dd94832011-09-16 15:05:25 -07003581 } /* End of For Loop */
3582 } /* End of the Null Check */
3583 else
3584 {
3585 status = PHNFCSTVAL(CID_NFC_DNLD,
3586 NFCSTATUS_INSUFFICIENT_RESOURCES);
3587 }
daniel_Tomas5e976052010-12-09 10:46:12 -08003588
3589 }
Rob von Behren6dd94832011-09-16 15:05:25 -07003590 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 }
daniel_Tomas5e976052010-12-09 10:46:12 -08003606
3607 DNLD_PRINT("*******************************************\n\n");
Rob von Behren6dd94832011-09-16 15:05:25 -07003608
daniel_Tomas5e976052010-12-09 10:46:12 -08003609 }
3610 return status;
3611}
3612
3613#if !defined (NXP_FW_INTEGRITY_VERIFY)
3614
3615NFCSTATUS
3616phDnldNfc_Run_Check(
3617 phHal_sHwReference_t *pHwRef
3618#ifdef NXP_FW_PARAM
3619 ,uint8_t *nxp_nfc_fw
3620 uint32_t fw_length
3621#endif
3622 )
3623{
3624 NFCSTATUS status = NFCSTATUS_FAILED;
3625 uint32_t fw_index = 0;
3626 img_data_hdr_t *p_img_hdr = NULL;
3627 fw_data_hdr_t *p_fw_hdr = NULL;
3628 fw_data_hdr_t *cur_fw_hdr = NULL;
3629 uint8_t i = 0;
3630
3631 p_img_hdr = (img_data_hdr_t *) nxp_nfc_fw;
3632
3633 fw_index = sizeof (img_data_hdr_t);
3634
3635 for ( i=0; i < p_img_hdr->no_of_fw_img; i++ )
3636 {
3637 p_fw_hdr = (fw_data_hdr_t *) ( nxp_nfc_fw + fw_index );
3638 /* TODO: Create a memory of pointers to store all the Firmwares */
3639 cur_fw_hdr = p_fw_hdr;
3640
3641 fw_index = fw_index + (cur_fw_hdr->fw_hdr_len * PNDNLD_WORD_LEN);
3642
Rob von Behren6dd94832011-09-16 15:05:25 -07003643 status = phDnldNfc_Check_FW( pHwRef, cur_fw_hdr);
daniel_Tomas5e976052010-12-09 10:46:12 -08003644 }
3645 return status;
3646}
3647
3648#endif /* #if !defined (NXP_FW_INTEGRITY_VERIFY) */
3649
3650
3651STATIC
3652void
3653phDnldNfc_Abort (
Rob von Behren6dd94832011-09-16 15:05:25 -07003654 uint32_t abort_id
3655#ifdef NFC_TIMER_CONTEXT
3656 , void *dnld_cntxt
3657#endif
daniel_Tomas5e976052010-12-09 10:46:12 -08003658 )
3659{
3660
Nick Pelly34ff48f2011-06-27 09:01:51 -07003661 phNfc_sCompletionInfo_t comp_info = {0,0,0};
daniel_Tomas5e976052010-12-09 10:46:12 -08003662
Rob von Behren6dd94832011-09-16 15:05:25 -07003663 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 ))
daniel_Tomas5e976052010-12-09 10:46:12 -08003673 {
3674 pphNfcIF_Notification_CB_t p_upper_notify =
Rob von Behren6dd94832011-09-16 15:05:25 -07003675 p_dnld_context->p_upper_notify;
daniel_Tomas5e976052010-12-09 10:46:12 -08003676 void *p_upper_context =
Rob von Behren6dd94832011-09-16 15:05:25 -07003677 p_dnld_context->p_upper_context;
3678 phHal_sHwReference_t *pHwRef = p_dnld_context->p_hw_ref;
daniel_Tomas5e976052010-12-09 10:46:12 -08003679
3680 (void)phDal4Nfc_Unregister(
Rob von Behren6dd94832011-09-16 15:05:25 -07003681 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
daniel_Tomas5e976052010-12-09 10:46:12 -08003687
3688 /* Notify the Error/Success Scenario to the upper layer */
3689 DNLD_DEBUG(" FW_DNLD: FW_DNLD Aborted with %x Timer Timeout \n",
3690 abort_id);
3691 comp_info.status = NFCSTATUS_FAILED ;
3692 phDnldNfc_Notify( p_upper_notify, p_upper_context,
3693 pHwRef, (uint8_t) NFC_IO_ERROR, &comp_info );
3694 }
3695
3696 return ;
3697}
3698
3699
3700
3701NFCSTATUS
3702phDnldNfc_Upgrade (
3703 phHal_sHwReference_t *pHwRef,
3704#ifdef NXP_FW_PARAM
Rob von Behren6dd94832011-09-16 15:05:25 -07003705 uint8_t type,
daniel_Tomas5e976052010-12-09 10:46:12 -08003706 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;
Nick Pelly8c9b94d2011-07-19 14:35:22 -07003714 phNfcIF_sReference_t dnldReference = { NULL,0,0 };
daniel_Tomas5e976052010-12-09 10:46:12 -08003715 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");
daniel_Tomas5e976052010-12-09 10:46:12 -08003729
Rob von Behren6dd94832011-09-16 15:05:25 -07003730 (void)
3731 phDnldNfc_Allocate_Resource((void **)
3732 &psDnldContext,sizeof(phDnldNfc_sContext_t));
daniel_Tomas5e976052010-12-09 10:46:12 -08003733 if(psDnldContext != NULL)
3734 {
Rob von Behren6dd94832011-09-16 15:05:25 -07003735#ifndef NFC_TIMER_CONTEXT
daniel_Tomas5e976052010-12-09 10:46:12 -08003736 gpphDnldContext = psDnldContext;
Rob von Behren6dd94832011-09-16 15:05:25 -07003737#endif
daniel_Tomas5e976052010-12-09 10:46:12 -08003738 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
Rob von Behren6dd94832011-09-16 15:05:25 -07003771 ,*nxp_nfc_fw , fw_length
daniel_Tomas5e976052010-12-09 10:46:12 -08003772#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");
daniel_Tomas5e976052010-12-09 10:46:12 -08003782
Rob von Behren6dd94832011-09-16 15:05:25 -07003783#if defined(FW_DOWNLOAD_TIMER)
3784
daniel_Tomas5e976052010-12-09 10:46:12 -08003785 psDnldContext->timer_id = phOsalNfc_Timer_Create( );
Rob von Behren6dd94832011-09-16 15:05:25 -07003786
3787#if (FW_DOWNLOAD_TIMER < 2)
daniel_Tomas5e976052010-12-09 10:46:12 -08003788 phOsalNfc_Timer_Start( psDnldContext->timer_id,
Rob von Behren6dd94832011-09-16 15:05:25 -07003789 NXP_DNLD_COMPLETE_TIMEOUT,
3790 (ppCallBck_t) phDnldNfc_Abort
3791#ifdef NFC_TIMER_CONTEXT
3792 , (void *) psDnldContext
daniel_Tomas5e976052010-12-09 10:46:12 -08003793#endif
Rob von Behren6dd94832011-09-16 15:05:25 -07003794 );
3795
3796#endif /* #if (FW_DOWNLOAD_TIMER < 2) */
3797
3798#endif /* #if defined(FW_DOWNLOAD_TIMER) */
3799
daniel_Tomas5e976052010-12-09 10:46:12 -08003800 }
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 );
Rob von Behren6dd94832011-09-16 15:05:25 -07003817#if defined(FW_DOWNLOAD_TIMER)
daniel_Tomas5e976052010-12-09 10:46:12 -08003818 psDnldContext->timer_id = phOsalNfc_Timer_Create( );
Rob von Behren6dd94832011-09-16 15:05:25 -07003819#if (FW_DOWNLOAD_TIMER < 2)
daniel_Tomas5e976052010-12-09 10:46:12 -08003820 phOsalNfc_Timer_Start( psDnldContext->timer_id,
Rob von Behren6dd94832011-09-16 15:05:25 -07003821 NXP_DNLD_COMPLETE_TIMEOUT,
3822 (ppCallBck_t) phDnldNfc_Abort
3823#ifdef NFC_TIMER_CONTEXT
3824 , (void *) psDnldContext
daniel_Tomas5e976052010-12-09 10:46:12 -08003825#endif
Rob von Behren6dd94832011-09-16 15:05:25 -07003826 );
3827
3828#endif /* #if (FW_DOWNLOAD_TIMER < 2) */
3829
3830#endif /* #if defined(FW_DOWNLOAD_TIMER) */
daniel_Tomas5e976052010-12-09 10:46:12 -08003831 }
3832
3833#else
3834 status = NFCSTATUS_SUCCESS;
Rob von Behren6dd94832011-09-16 15:05:25 -07003835
3836#endif /* #if defined (NXP_FW_INTEGRITY_VERIFY) */
3837
daniel_Tomas5e976052010-12-09 10:46:12 -08003838 }
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(
Rob von Behren6dd94832011-09-16 15:05:25 -07003848 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
daniel_Tomas5e976052010-12-09 10:46:12 -08003854 }
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 }