diff options
-rw-r--r-- | Android.mk | 2 | ||||
-rw-r--r-- | inc/phNfcConfig.h | 9 | ||||
-rw-r--r-- | inc/phNfcHalTypes.h | 21 | ||||
-rwxr-xr-x | src/phDnldNfc.c | 1387 | ||||
-rw-r--r-- | src/phHal4Nfc.c | 67 | ||||
-rw-r--r-- | src/phHciNfc.h | 20 | ||||
-rw-r--r-- | src/phHciNfc_DevMgmt.c | 58 | ||||
-rw-r--r-- | src/phHciNfc_Generic.h | 5 | ||||
-rw-r--r-- | src/phHciNfc_Sequence.c | 150 | ||||
-rw-r--r-- | src/phLibNfc_Ioctl.c | 7 |
10 files changed, 1390 insertions, 336 deletions
@@ -104,7 +104,7 @@ LOCAL_SRC_FILES += Linux_x86/phDal4Nfc.c LOCAL_SRC_FILES += Linux_x86/phDal4Nfc_i2c.c LOCAL_SRC_FILES += Linux_x86/phDal4Nfc_messageQueueLib.c -LOCAL_CFLAGS += -DNXP_MESSAGING -DANDROID -fno-strict-aliasing +LOCAL_CFLAGS += -DNXP_MESSAGING -DANDROID -DNFC_TIMER_CONTEXT -fno-strict-aliasing # Uncomment for Chipset command/responses # Or use "setprop debug.nfc.LOW_LEVEL_TRACES" at run-time diff --git a/inc/phNfcConfig.h b/inc/phNfcConfig.h index e7386d9..bcefaec 100644 --- a/inc/phNfcConfig.h +++ b/inc/phNfcConfig.h @@ -375,11 +375,15 @@ /**< Macro to Enable the Card Emulation Feature */ /* #define HOST_EMULATION */ +#define NXP_HAL_VERIFY_EEPROM_CRC 0x01U + /**< Macro to Enable the Download Mode Feature */ #define FW_DOWNLOAD /**< Macro to Enable the Firmware Download Timer */ -#define FW_DOWNLOAD_TIMER +/* 0x01U to use overall timeout */ +/* 0x02U to use per frame timeout */ +#define FW_DOWNLOAD_TIMER 0x02U /**< Macro to Verify the Firmware Download */ /* #define FW_DOWNLOAD_VERIFY */ @@ -388,6 +392,9 @@ #define NXP_FW_INTEGRITY_CHK 1 #endif +/* To specify the Maximum TX/RX Len */ +#define NXP_FW_MAX_TX_RX_LEN 0x200 + #define UICC_CONNECTIVITY_PATCH /* Work around to Delay the initiator activation */ diff --git a/inc/phNfcHalTypes.h b/inc/phNfcHalTypes.h index a242450..522df6d 100644 --- a/inc/phNfcHalTypes.h +++ b/inc/phNfcHalTypes.h @@ -47,6 +47,26 @@ #include <phNfcCompId.h> #include <phNfcConfig.h> +#ifndef NXP_HAL_MEM_INFO_SIZE +#define NXP_HAL_MEM_INFO_SIZE 0x01U +#endif + +#if (NXP_HAL_MEM_INFO_SIZE > 0x01) +#define NXP_FW_UPLOAD_PROGRESS 0x965AU +#define NXP_FW_UPLOAD_SUCCESS 0x0000U +#else +#define NXP_FW_UPLOAD_PROGRESS 0x5AU +#define NXP_FW_UPLOAD_SUCCESS 0x00U +#endif + + +typedef struct phHal_sMemInfo +{ + uint16_t fw_magic; + uint16_t fw_rfu; + uint32_t hal_version; +}phHal_sMemInfo_t; + /** \ingroup grp_hal_common * @@ -836,6 +856,7 @@ typedef enum phHal_Event { NFC_INFO_TXLDO_OVERCUR = 0x71U, NFC_INFO_MEM_VIOLATION = 0x73U, NFC_INFO_TEMP_OVERHEAT = 0x74U, + NFC_INFO_LLC_ERROR = 0x75U, /* NXP EVENTS */ NFC_EVT_MIFARE_ACCESS = 0x35, diff --git a/src/phDnldNfc.c b/src/phDnldNfc.c index 796653e..3d85144 100755 --- a/src/phDnldNfc.c +++ b/src/phDnldNfc.c @@ -58,8 +58,6 @@ #define STATIC static #endif -#define SECTION_HDR - #if defined (DNLD_SUMMARY) && !defined (DNLD_TRACE) #define DNLD_TRACE #endif @@ -94,15 +92,49 @@ extern char phOsalNfc_DbgTraceBuffer[]; /* delay after SW reset cmd in ms, required on uart for XTAL stability */ #define PHDNLD_DNLD_DELAY 5000 -#define PHDNLD_MAX_PACKET 0x0200U /* Max Total Packet Size is 512 */ +//#define PHDNLD_MAX_PACKET 0x0200U /* Max Total Packet Size is 512 */ +#define PHDNLD_MAX_PACKET 32U /* Max Total Packet Size is 512 */ #define PHDNLD_DATA_SIZE ((PHDNLD_MAX_PACKET)- 8U) /* 0x01F8U */ /* Max Data Size is 504 */ #define PHDNLD_MIN_PACKET 0x03U /* Minimum Packet Size is 3*/ +#define DNLD_DEFAULT_RESPONSE_TIMEOUT 0x4000U + +#define NXP_FW_MIN_TX_RX_LEN 0x0AU + + +#if defined( NXP_FW_MAX_TX_RX_LEN ) && \ + ( NXP_FW_MAX_TX_RX_LEN > NXP_FW_MIN_TX_RX_LEN ) + +#define PHDNLD_FW_TX_RX_LEN NXP_FW_MAX_TX_RX_LEN + +#elif !defined( NXP_FW_MAX_TX_RX_LEN ) + +/* To specify the Maximum TX/RX Len */ +#define NXP_FW_MAX_TX_RX_LEN 0x200 +#define PHDNLD_FW_TX_RX_LEN NXP_FW_MAX_TX_RX_LEN + +#else + +#define PHDNLD_FW_TX_RX_LEN NXP_FW_MIN_TX_RX_LEN + +#endif + #define PHDNLD_FRAME_LEN_SIZE 0x02U #define PHDNLD_ADDR_SIZE 0x03U #define PHDNLD_DATA_LEN_SIZE 0x02U +#define PHDNLD_FRAME_DATA_OFFSET 0x03U + +#define DNLD_SM_UNLOCK_MASK 0x01U +#define DNLD_TRIM_MASK 0x02U +#define DNLD_RESET_MASK 0x04U +#define DNLD_VERIFY_MASK 0x08U +#define DNLD_CRITICAL_MASK 0x10U + +#define NXP_NFC_IMAG_FW_MAX 0x05U + +#define PHDNLD_FW_PATCH_SEC 0x5FU #define PHDNLD_PAGE_SIZE 0x80U /* Page Size Configured for 64 Bytes */ @@ -118,6 +150,8 @@ extern char phOsalNfc_DbgTraceBuffer[]; #define DNLD_PATCH_TABLE_ADDR 0x00008200U +/* Raw Command to pass the Data in Download Mode */ +#define PHDNLD_CMD_RAW 0x00U /* Command to Reset the Device in Download Mode */ #define PHDNLD_CMD_RESET 0x01U /* Command to Read from the Address specified in Download Mode */ @@ -125,6 +159,7 @@ extern char phOsalNfc_DbgTraceBuffer[]; #define PHDNLD_CMD_READ_LEN 0x0005U /* Command to write to the Address specified in Download Mode */ #define PHDNLD_CMD_WRITE 0x08U +#define PHDNLD_CMD_SEC_WRITE 0x0CU #define PHDNLD_CMD_WRITE_MIN_LEN 0x0005U #define PHDNLD_CMD_WRITE_MAX_LEN PHDNLD_DATA_SIZE /* Command to verify the data written */ @@ -145,6 +180,9 @@ extern char phOsalNfc_DbgTraceBuffer[]; /* Command to verify the Integrity of the data written */ #define PHDNLD_CMD_CHECK_INTEGRITY 0x0BU +/* Command to verify the Integrity of the data written */ +#define PHDNLD_CMD_ENCAPSULATE 0x0DU + #define CHECK_INTEGRITY_RESP_CRC16_LEN 0x03U #define CHECK_INTEGRITY_RESP_CRC32_LEN 0x05U #define CHECK_INTEGRITY_RESP_COMP_LEN 0x10U @@ -162,8 +200,23 @@ extern char phOsalNfc_DbgTraceBuffer[]; #define PHDNLD_RESP_PROTOCOL_ERROR 0x0BU /* Invalid parameter Response to a Command Sent in the Download Mode */ #define PHDNLD_RESP_INVALID_PARAMETER 0x11U +/* Command Not Supported Response to a Command Sent in the Download Mode */ +#define PHDNLD_RESP_CMD_NOT_SUPPORTED 0x13U /* Length parameter error Response to a Command Sent in the Download Mode */ #define PHDNLD_RESP_INVALID_LENGTH 0x18U +/* Checksum Error Response to a Command Sent in the Download Mode */ +#define PHDNLD_RESP_CHKSUM_ERROR 0x19U +/* Version already uptodate Response to a Command Sent in the Download Mode */ +#define PHDNLD_RESP_VERSION_UPTODATE 0x1DU +/* Memory operation error during the processing of + the Command Frame in the Download Mode */ +#define PHDNLD_RESP_MEMORY_UPDATE_ERROR 0x20U +/* The Chaining of the Command Frame was Successful in the Download Mode */ +#define PHDNLD_RESP_CHAINING_SUCCESS 0x21U +/* The Command is not allowed anymore in the Download Mode */ +#define PHDNLD_RESP_CMD_NOT_ALLOWED 0xE0U +/* The Error during the Chaining the Command Frame in the Download Mode */ +#define PHDNLD_RESP_CHAINING_ERROR 0xE6U /* Write Error Response to a Command Sent in the Download Mode */ #define PHDNLD_RESP_WRITE_ERROR 0x74U @@ -185,6 +238,7 @@ extern char phOsalNfc_DbgTraceBuffer[]; typedef enum phDnldNfc_eSeqType{ DNLD_SEQ_RESET = 0x00U, DNLD_SEQ_INIT, + DNLD_SEQ_RAW, DNLD_SEQ_LOCK, DNLD_SEQ_UNLOCK, DNLD_SEQ_UPDATE, @@ -216,6 +270,7 @@ typedef enum phDnldNfc_eSeq phDnld_Verify_Integrity, phDnld_Verify_Section, phDnld_Complete_Seq, + phDnld_Raw_Upgrade, phDnld_Invalid_Seq }phDnldNfc_eSeq_t; @@ -244,7 +299,7 @@ typedef struct img_data_hdr uint8_t img_data_offset; /* Number of fimware images available in the img_data */ uint8_t no_of_fw_img; - /* Number of fimware images available in the img_data */ + /* Fimware image Padding in the img_data */ uint8_t fw_img_pad[2]; /* HW Compatiblity table for the set of the Hardwares */ hw_comp_tbl_t comp_tbl; @@ -273,25 +328,12 @@ typedef struct section_hdr { uint8_t section_hdr_len; uint8_t section_mem_type; - uint16_t section_data_crc; + uint8_t section_checksum; + uint8_t section_conf; uint32_t section_address; uint32_t section_length; }section_hdr_t; - -typedef struct section_type -{ - unsigned system_mem_unlock:1; - unsigned trim_val:1; - unsigned reset_required:1; - unsigned verify_mem:1; - unsigned critical_section:1; - unsigned section_crc_check:1; - unsigned section_type_rfu:2; - unsigned section_type_pad:24; - -}section_type_t; - typedef struct section_info { section_hdr_t *p_sec_hdr; @@ -300,6 +342,10 @@ typedef struct section_info * to be loaded to the particular address. */ uint8_t *p_sec_data; + /* The Section checksum to verify the integrity of the section + * data. + */ + uint8_t *p_sec_chksum; /** \internal Index used to refer and process the * Firmware Section Data */ volatile uint32_t section_offset; @@ -325,13 +371,24 @@ typedef struct phDnldNfc_sParam uint8_t data_packet[PHDNLD_DATA_SIZE]; }phDnldNfc_sParam_t; - typedef struct phDnldNfc_sDataHdr { uint8_t frame_type; uint8_t frame_length[PHDNLD_FRAME_LEN_SIZE]; }phDnldNfc_sData_Hdr_t; +typedef struct phDnldNfc_sRawHdr +{ + uint8_t frame_type; + uint8_t frame_length[PHDNLD_FRAME_LEN_SIZE]; +}phDnldNfc_sRawHdr_t; + +typedef struct phDnldNfc_sRawDataHdr +{ + uint8_t data_addr[PHDNLD_ADDR_SIZE]; + uint8_t data_len[PHDNLD_DATA_LEN_SIZE]; +}phDnldNfc_sRawDataHdr_t; + typedef struct phDnldNfc_sChkCrc16_Resp { uint8_t Chk_status; @@ -362,11 +419,59 @@ typedef struct phDnldNfc_sData union param { phDnldNfc_sParam_t data_param; - uint8_t response_data[PHDNLD_MAX_PACKET + 0]; + uint8_t response_data[PHDNLD_MAX_PACKET]; uint8_t cmd_param; }param_info; }phDnldNfc_sData_t; +#ifdef NXP_NFC_MULTIPLE_FW + +typedef struct phDnldNfc_sFwImageInfo +{ + /** \internal Data Pointer to the Firmware header section of the Firmware */ + fw_data_hdr_t *p_fw_hdr; + /** \internal Buffer pointer to store the Firmware Section Data */ + section_info_t *p_fw_sec; + /** \internal Buffer pointer to store the Firmware Raw Data */ + uint8_t *p_fw_raw; +}phDnldNfc_sFwImageInfo_t; + +#endif /* #ifdef NXP_NFC_MULTIPLE_FW */ + + +typedef struct phDnldNfc_TxInfo +{ + uint8_t *transmit_frame; + + uint16_t tx_offset; + + /** \internal Remaining amount of data to be sent */ + uint16_t tx_len; + + uint16_t tx_total; + + /** \internal Chain information for the data to be sent */ + uint8_t tx_chain; + +}phDnldNfc_TxInfo_t; + + +typedef struct phDnldNfc_RxInfo +{ + /** \internal Total length of the received buffer */ + uint16_t rx_total; + /** \internal Chain information of the received buffer */ + uint16_t rx_chain; + /** \internal Remaining Data information to be read to complete the + * Data Information. + */ + uint16_t rx_remain; + + /** \internal Buffer to Send the Raw Data Frame */ + uint8_t raw_buffer_data[PHDNLD_MAX_PACKET + + PHDNLD_PAGE_SIZE]; +}phDnldNfc_RxInfo_t; + typedef struct phDnldNfc_sContext { @@ -385,18 +490,29 @@ typedef struct phDnldNfc_sContext /** \internal Timer ID for the Download Abort */ uint32_t timer_id; + /** \internal Internal Download for the Download Abort */ + uint32_t dnld_timeout; /** \internal Data Pointer to the Image header section of the Firmware */ img_data_hdr_t *p_img_hdr; + +#ifdef NXP_NFC_MULTIPLE_FW + /** \internal Data Pointer to the Firmware Image Information */ + phDnldNfc_sFwImageInfo_t *p_img_info; +#endif /* #ifdef NXP_NFC_MULTIPLE_FW */ + /** \internal Data Pointer to the Firmware header section of the Firmware */ fw_data_hdr_t *p_fw_hdr; /** \internal Buffer pointer to store the Firmware Data */ section_info_t *p_fw_sec; + /** \internal Buffer pointer to store the Firmware Raw Data */ + uint8_t *p_fw_raw; /** \internal Previous Download Size */ uint32_t prev_dnld_size; /** \internal Single Data Block to download the Firmware */ - phDnldNfc_sData_t dnld_data; + uint8_t dnld_data[PHDNLD_MAX_PACKET + + PHDNLD_PAGE_SIZE]; /** \internal Index used to refer and process the Download Data */ volatile uint32_t dnld_index; @@ -424,11 +540,12 @@ typedef struct phDnldNfc_sContext #define NXP_FW_VMID_CARD_MODE_ADDR 0x00009931U #define NXP_FW_VMID_RD_MODE_ADDR 0x00009981U - unsigned vmid_trim_update:1; - unsigned trim_bits_rfu:31; + uint8_t vmid_trim_update; #endif /* #ifdef NXP_FW_SW_VMID_TRIM */ - uint8_t *p_system_mem_crc; + uint8_t cur_frame_info; + + uint8_t raw_mode_upgrade; uint8_t *p_patch_table_crc; @@ -438,18 +555,12 @@ typedef struct phDnldNfc_sContext uint16_t resp_length; - /** \internal Total length of the received buffer */ - volatile uint16_t rx_total; - /** \internal Current FW Section in Process */ volatile uint8_t section_index; /** \internal Previous Command sent */ volatile uint8_t prev_cmd; - /** \internal Download Response pending */ - volatile uint8_t recv_pending; - uint8_t dnld_retry; /** \internal Current Download State */ @@ -462,8 +573,14 @@ typedef struct phDnldNfc_sContext /** \internal Next step in Download Sequence */ volatile uint8_t next_dnld_seq; -}phDnldNfc_sContext_t; + /* \internal Data Transmit information */ + phDnldNfc_TxInfo_t tx_info; + /* \internal Data Receive information */ + phDnldNfc_RxInfo_t rx_info; + + +}phDnldNfc_sContext_t; /* @@ -472,7 +589,9 @@ typedef struct phDnldNfc_sContext ################################################################################ */ +#ifndef NFC_TIMER_CONTEXT static phDnldNfc_sContext_t *gpphDnldContext = NULL; +#endif #ifdef NXP_FW_DNLD_CHECK_PHASE @@ -480,6 +599,7 @@ static phDnldNfc_sContext_t *gpphDnldContext = NULL; #define NXP_FW_DNLD_SYSTEM_PHASE 0x01U #define NXP_FW_DNLD_CFG_PHASE 0x02U #define NXP_FW_DNLD_DATA_PHASE 0x03U +#define NXP_FW_DNLD_RAW_PHASE 0x04U #define NXP_FW_DNLD_INVALID_PHASE 0xFFU static uint8_t gphDnldPhase = NXP_FW_DNLD_COMPLETE_PHASE; @@ -651,8 +771,10 @@ phDnldNfc_Read( STATIC void phDnldNfc_Abort ( - uint32_t abort_id, - void *pContext + uint32_t abort_id +#ifdef NFC_TIMER_CONTEXT + , void *dnld_cntxt +#endif ); @@ -820,6 +942,7 @@ phDnldNfc_Release_Resources ( phDnldNfc_sContext_t **ppsDnldContext ) { + if(NULL != (*ppsDnldContext)->p_resp_buffer) { phOsalNfc_FreeMemory((*ppsDnldContext)->p_resp_buffer); @@ -928,12 +1051,24 @@ phDnldNfc_Set_Seq( (uint8_t) phDnld_Reset_State; psDnldContext->next_dnld_state = (uint8_t)phDnld_Upgrade_State; - psDnldContext->next_dnld_seq = + psDnldContext->cur_dnld_seq = (uint8_t)phDnld_Upgrade_Section; psDnldContext->next_dnld_seq = psDnldContext->cur_dnld_seq; break; } + case DNLD_SEQ_RAW: + { + psDnldContext->cur_dnld_state = + (uint8_t) phDnld_Reset_State; + psDnldContext->next_dnld_state = + (uint8_t)phDnld_Upgrade_State; + psDnldContext->cur_dnld_seq = + (uint8_t)phDnld_Raw_Upgrade; + psDnldContext->next_dnld_seq = + psDnldContext->cur_dnld_seq; + break; + } case DNLD_SEQ_UNLOCK: { psDnldContext->cur_dnld_state = @@ -944,7 +1079,7 @@ phDnldNfc_Set_Seq( { psDnldContext->next_dnld_state = (uint8_t)phDnld_Upgrade_State; - psDnldContext->next_dnld_seq = + psDnldContext->cur_dnld_seq = (uint8_t)phDnld_Upgrade_Section; } else @@ -955,7 +1090,6 @@ phDnldNfc_Set_Seq( psDnldContext->cur_dnld_seq = (uint8_t) phDnld_Activate_Patch; } - psDnldContext->next_dnld_seq = psDnldContext->cur_dnld_seq; break; @@ -1009,26 +1143,6 @@ phDnldNfc_Set_Seq( psDnldContext->cur_dnld_seq ; break; } -#if 0 - case DNLD_UPDATE_STATE1: - { - prev_temp_state = (uint8_t) psDnldContext->cur_dnld_state; - psDnldContext->cur_dnld_state = - psDnldContext->next_dnld_state; - /* psDnldContext->next_dnld_state = - (uint8_t)phDnld_Invalid_State ; */ - break; - } - case DNLD_ROLLBACK_STATE1: - { - psDnldContext->cur_dnld_state = (uint8_t) prev_temp_state; - /* psDnldContext->next_dnld_state = - (uint8_t)phDnld_Invalid_State ; */ - prev_temp_state = 0; - - break; - } -#endif default: { break; @@ -1070,6 +1184,36 @@ phDnldNfc_Set_Seq( #endif status = plower_if->send((void *)plower_if->pcontext, (void *)pHwRef, pdata, length); + +#if defined(FW_DOWNLOAD_TIMER) && \ + (FW_DOWNLOAD_TIMER == 2) + if ( + (NFCSTATUS_PENDING == status) + && ( NXP_INVALID_TIMER_ID != psDnldContext->timer_id ) + ) + { + psDnldContext->dnld_timeout = NXP_DNLD_COMPLETE_TIMEOUT; + + if ( psDnldContext->dnld_timeout + < DNLD_DEFAULT_RESPONSE_TIMEOUT) + { + psDnldContext->dnld_timeout + = DNLD_DEFAULT_RESPONSE_TIMEOUT; + } + /* Start the Download Timer */ + phOsalNfc_Timer_Start( psDnldContext->timer_id, + psDnldContext->dnld_timeout, + (ppCallBck_t) phDnldNfc_Abort +#ifdef NFC_TIMER_CONTEXT + , (void *) psDnldContext +#endif + ); + + DNLD_DEBUG(" DNLD : Timer %X Started ", psDnldContext->timer_id); + DNLD_DEBUG(" \t\t With %U Timeout \n", psDnldContext->dnld_timeout); + } + +#endif /* (NXP_NFC_DNLD_TIMER == 1) */ } return status; @@ -1125,8 +1269,10 @@ phDnldNfc_Read( ) { NFCSTATUS status = NFCSTATUS_SUCCESS; - phDnldNfc_sParam_t *p_dnld_data = - &psDnldContext->dnld_data.param_info.data_param; + phDnldNfc_sData_t *p_dnld_data = + (phDnldNfc_sData_t *)psDnldContext->dnld_data; + phDnldNfc_sParam_t *p_data_param = + &p_dnld_data->param_info.data_param; uint32_t read_addr = (p_sec_info->p_sec_hdr->section_address + p_sec_info->section_offset); static unsigned sec_type = 0; @@ -1136,7 +1282,7 @@ phDnldNfc_Read( sec_type = (unsigned int)p_sec_info->p_sec_hdr->section_mem_type; if( ( FALSE == p_sec_info->section_read ) - && (TRUE == ((section_type_t *)(&sec_type))->trim_val) + && ((sec_type & DNLD_TRIM_MASK)) && (FALSE == p_sec_info->trim_write) ) { read_size = (uint16_t) p_sec_info->p_sec_hdr->section_length; @@ -1145,7 +1291,8 @@ phDnldNfc_Read( else { if (( FALSE == p_sec_info->section_read ) - && (TRUE == ((section_type_t *)(&sec_type))->verify_mem )) + && ((sec_type & DNLD_VERIFY_MASK)) + ) { read_size = (uint16_t)(psDnldContext->prev_dnld_size ); DNLD_DEBUG(" FW_DNLD: Section Read = %X \n", read_size); @@ -1172,24 +1319,24 @@ phDnldNfc_Read( read_size = (uint16_t)((PHDNLD_DATA_SIZE >= read_size)? read_size: PHDNLD_DATA_SIZE); - psDnldContext->dnld_data.frame_length[i] = (uint8_t)0; + p_dnld_data->frame_length[i] = (uint8_t)0; /* Update the LSB of the Data and the Address Parameter*/ - p_dnld_data->data_addr[i] = (uint8_t)((read_addr >> + p_data_param->data_addr[i] = (uint8_t)((read_addr >> (BYTE_SIZE + BYTE_SIZE)) & BYTE_MASK); - p_dnld_data->data_len[i] = (uint8_t)((read_size >> + p_data_param->data_len[i] = (uint8_t)((read_size >> BYTE_SIZE) & BYTE_MASK); i++; - psDnldContext->dnld_data.frame_length[i] = (uint8_t) + p_dnld_data->frame_length[i] = (uint8_t) ( PHDNLD_CMD_READ_LEN & BYTE_MASK); /* Update the 2nd byte of the Data and the Address Parameter*/ - p_dnld_data->data_addr[i] = (uint8_t)((read_addr >> + p_data_param->data_addr[i] = (uint8_t)((read_addr >> BYTE_SIZE) & BYTE_MASK); - p_dnld_data->data_len[i] = (uint8_t) (read_size & BYTE_MASK); + p_data_param->data_len[i] = (uint8_t) (read_size & BYTE_MASK); i++; /* Update the 3rd byte of the the Address Parameter*/ - p_dnld_data->data_addr[i] = (uint8_t)(read_addr & BYTE_MASK); + p_data_param->data_addr[i] = (uint8_t)(read_addr & BYTE_MASK); status = phDnldNfc_Send_Command( psDnldContext, pHwRef, PHDNLD_CMD_READ, NULL , 0 ); @@ -1218,8 +1365,10 @@ phDnldNfc_Process_Write( ) { NFCSTATUS status = NFCSTATUS_SUCCESS; + phDnldNfc_sData_t *p_dnld_data = + (phDnldNfc_sData_t *)psDnldContext->dnld_data; phDnldNfc_sParam_t *dnld_data = - &psDnldContext->dnld_data.param_info.data_param; + &p_dnld_data->param_info.data_param; uint8_t *p_sm_trim_data = (uint8_t *)psDnldContext-> dnld_resp.param_info.response_data; uint32_t dnld_addr = 0; @@ -1239,7 +1388,7 @@ phDnldNfc_Process_Write( { if( (TRUE == p_sec_info->trim_write) && (TRUE == p_sec_info->section_read) - && (TRUE == ((section_type_t *)(&sec_type))->verify_mem ) + && ((sec_type & DNLD_VERIFY_MASK)) ) { if(NULL != psDnldContext->trim_store.buffer) @@ -1268,7 +1417,7 @@ phDnldNfc_Process_Write( else { if((NULL != psDnldContext->dnld_store.buffer) - && (TRUE == ((section_type_t *)(&sec_type))->verify_mem ) + && ((sec_type & DNLD_VERIFY_MASK)) && (TRUE == p_sec_info->section_write) && (TRUE == p_sec_info->section_read) ) @@ -1333,7 +1482,6 @@ phDnldNfc_Process_Write( if (dnld_size != 0) { - dnld_size = (uint16_t)((PHDNLD_DATA_SIZE >= dnld_size)? dnld_size: PHDNLD_DATA_SIZE); @@ -1342,7 +1490,7 @@ phDnldNfc_Process_Write( (BYTE_SIZE + BYTE_SIZE)) & BYTE_MASK); dnld_data->data_len[i] = (uint8_t)((dnld_size >> BYTE_SIZE) & BYTE_MASK); - psDnldContext->dnld_data.frame_length[i] = (uint8_t) + p_dnld_data->frame_length[i] = (uint8_t) (((dnld_size + PHDNLD_CMD_WRITE_MIN_LEN) >> BYTE_SIZE) & BYTE_MASK); i++; @@ -1350,7 +1498,7 @@ phDnldNfc_Process_Write( dnld_data->data_addr[i] = (uint8_t)((dnld_addr >> BYTE_SIZE) & BYTE_MASK); dnld_data->data_len[i] = (uint8_t) (dnld_size & BYTE_MASK); - psDnldContext->dnld_data.frame_length[i] = (uint8_t) ((dnld_size + + p_dnld_data->frame_length[i] = (uint8_t) ((dnld_size + PHDNLD_CMD_WRITE_MIN_LEN) & BYTE_MASK); i++; /* Update the 3rd byte of the the Address Parameter*/ @@ -1359,7 +1507,7 @@ phDnldNfc_Process_Write( (void)memcpy( dnld_data->data_packet, (p_sec_info->p_sec_data + *p_sec_offset), dnld_size ); - if((TRUE == ((section_type_t *)(&sec_type))->trim_val ) + if( ((sec_type & DNLD_TRIM_MASK)) && (p_sec_info->sec_verify_retry != 0) && (NULL != psDnldContext->trim_store.buffer) ) @@ -1367,7 +1515,7 @@ phDnldNfc_Process_Write( (void)memcpy( dnld_data->data_packet, psDnldContext->trim_store.buffer, dnld_size ); } - else if((TRUE == ((section_type_t *)(&sec_type))->trim_val ) + else if(((sec_type & DNLD_TRIM_MASK)) && ( TRUE == p_sec_info->section_read ) ) { @@ -1417,8 +1565,14 @@ else psDnldContext->trim_store.buffer = NULL; psDnldContext->trim_store.length = 0; } +#if 1 + (void) + phDnldNfc_Allocate_Resource((void **) + &(psDnldContext->trim_store.buffer),dnld_size); +#else psDnldContext->trim_store.buffer = (uint8_t *) phOsalNfc_GetMemory(dnld_size); +#endif if(NULL != psDnldContext->trim_store.buffer) { @@ -1441,8 +1595,14 @@ else psDnldContext->dnld_store.buffer = NULL; psDnldContext->dnld_store.length = 0; } +#if 1 + (void) + phDnldNfc_Allocate_Resource((void **) + &(psDnldContext->dnld_store.buffer),dnld_size); +#else psDnldContext->dnld_store.buffer = (uint8_t *) phOsalNfc_GetMemory(dnld_size); +#endif if(NULL != psDnldContext->dnld_store.buffer) { (void )memset((void *)psDnldContext->dnld_store.buffer,0, @@ -1454,15 +1614,24 @@ else DNLD_DEBUG(" of Size %X ", dnld_size ); } } + + if(PHDNLD_FW_PATCH_SEC != psDnldContext->p_fw_hdr->fw_patch) + { status = phDnldNfc_Send_Command( psDnldContext, pHwRef, PHDNLD_CMD_WRITE, NULL , 0 ); + } + else + { + status = phDnldNfc_Send_Command( psDnldContext, pHwRef, + PHDNLD_CMD_SEC_WRITE, NULL , 0 ); + } DNLD_DEBUG(" FW_DNLD: Memory Write Status = %X \n", status); if ( NFCSTATUS_PENDING == status ) { psDnldContext->prev_dnld_size = dnld_size; cmp_val = 0x00; - if(TRUE == ((section_type_t *)(&sec_type))->trim_val ) + if((sec_type & DNLD_TRIM_MASK)) { p_sec_info->trim_write = TRUE; DNLD_DEBUG(" FW_DNLD: Bytes Downloaded (Trimming Values) = %X Bytes \n", @@ -1515,7 +1684,7 @@ phDnldNfc_Resume_Write( p_sec_info->trim_write = FALSE; DNLD_DEBUG(" FW_DNLD: Section %02X Download Complete\n", sec_index); - if(TRUE == ((section_type_t *)(&sec_type))->reset_required ) + if((sec_type & DNLD_RESET_MASK)) { DNLD_DEBUG(" FW_DNLD: Reset After Section %02X Download \n", sec_index); status = phDnldNfc_Send_Command( psDnldContext, pHwRef, @@ -1584,7 +1753,7 @@ phDnldNfc_Resume_Write( #if (ES_HW_VER <= 30) #define NXP_DNLD_PATCH_ADDR 0x01AFFFU #else -#define NXP_DNLD_PATCH_ADDR 0x01AFE0U +#define NXP_DNLD_PATCH_ADDR 0x01A1E0U #endif #if (ES_HW_VER <= 30) @@ -1605,14 +1774,16 @@ phDnldNfc_Sequence( { NFCSTATUS status = NFCSTATUS_SUCCESS; uint32_t dnld_addr = 0; - phDnldNfc_sParam_t *dnld_data = &psDnldContext->dnld_data - .param_info.data_param; + phDnldNfc_sData_t *p_dnld_data = + (phDnldNfc_sData_t *)psDnldContext->dnld_data; + phDnldNfc_sParam_t *p_data_param = + & p_dnld_data->param_info.data_param; uint8_t *p_data = NULL; static uint32_t patch_size = 0; #if (ES_HW_VER == 32) - static uint8_t patch_table[] = {0xA0, 0xAF, 0xE0, 0x80, 0xA9, 0x6C }; + static uint8_t patch_table[] = {0xA0, 0xA1, 0xE0, 0x80, 0xA9, 0x6C }; static uint8_t patch_data[] = {0xA5, 0xD0, 0xFE, 0xA5, 0xD0, 0xFD, 0xA5, 0xD0, 0xFC, 0xA5, 0x02, 0x80, 0xA9, 0x75}; @@ -1755,25 +1926,25 @@ phDnldNfc_Sequence( { /* Update the LSB of the Data and the Address Parameter*/ - dnld_data->data_addr[i] = (uint8_t)((dnld_addr >> + p_data_param->data_addr[i] = (uint8_t)((dnld_addr >> (BYTE_SIZE + BYTE_SIZE)) & BYTE_MASK); - dnld_data->data_len[i] = (uint8_t)((patch_size >> BYTE_SIZE) + p_data_param->data_len[i] = (uint8_t)((patch_size >> BYTE_SIZE) & BYTE_MASK); - psDnldContext->dnld_data.frame_length[i] = (uint8_t) + p_dnld_data->frame_length[i] = (uint8_t) (((patch_size + PHDNLD_CMD_WRITE_MIN_LEN) >> BYTE_SIZE) & BYTE_MASK); i++; /* Update the 2nd byte of the Data and the Address Parameter*/ - dnld_data->data_addr[i] = (uint8_t)((dnld_addr >> BYTE_SIZE) + p_data_param->data_addr[i] = (uint8_t)((dnld_addr >> BYTE_SIZE) & BYTE_MASK); - dnld_data->data_len[i] = (uint8_t) (patch_size & BYTE_MASK); - psDnldContext->dnld_data.frame_length[i] = (uint8_t) + p_data_param->data_len[i] = (uint8_t) (patch_size & BYTE_MASK); + p_dnld_data->frame_length[i] = (uint8_t) ((patch_size + PHDNLD_CMD_WRITE_MIN_LEN) & BYTE_MASK); i++; /* Update the 3rd byte of the the Address Parameter*/ - dnld_data->data_addr[i] = (uint8_t)(dnld_addr & BYTE_MASK); + p_data_param->data_addr[i] = (uint8_t)(dnld_addr & BYTE_MASK); status = phDnldNfc_Send_Command( psDnldContext, pHwRef, PHDNLD_CMD_WRITE,(void *)p_data , (uint8_t)patch_size ); @@ -1787,6 +1958,384 @@ phDnldNfc_Sequence( return status; } +#define FRAME_HEADER_LEN 0x03U + + +static +void +phDnldNfc_Tx_Reset(phDnldNfc_sContext_t *psDnldContext) +{ + psDnldContext->tx_info.transmit_frame = NULL; + psDnldContext->tx_info.tx_total = 0x00; + psDnldContext->tx_info.tx_offset = 0x00; + psDnldContext->tx_info.tx_len = 0x00; + psDnldContext->tx_info.tx_chain = FALSE; +} + +STATIC +bool_t +phDnldNfc_Extract_Chunks( + uint8_t *frame_data, + uint16_t frame_offset, + uint16_t frame_length, + uint16_t max_frame , + uint16_t *chunk_length + ); + + +STATIC +bool_t +phDnldNfc_Extract_Chunks( + uint8_t *frame_data, + uint16_t frame_offset, + uint16_t frame_length, + uint16_t max_frame , + uint16_t *chunk_length + ) +{ + bool_t chunk_present = FALSE; + + if( 0 == frame_offset) + { + if( max_frame >= (frame_length + - frame_offset)) + { + *chunk_length = (frame_length - frame_offset); + } + else + { + *chunk_length = max_frame + - FRAME_HEADER_LEN; + chunk_present = TRUE; + } + } + else + { + if( max_frame >= (frame_length + - frame_offset)) + { + *chunk_length = (frame_length - frame_offset); + } + else + { + *chunk_length = max_frame + - FRAME_HEADER_LEN; + chunk_present = TRUE; + } + } + + return chunk_present; +} + + +STATIC +NFCSTATUS +phDnldNfc_Send_Raw( + phDnldNfc_sContext_t *psDnldContext, + void *pHwRef, + uint8_t *raw_frame, + uint16_t frame_offset, + uint16_t frame_length + ) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + phDnldNfc_sRawHdr_t *raw_frame_hdr = ( phDnldNfc_sRawHdr_t * ) raw_frame; + + switch(raw_frame_hdr->frame_type) + { + case PHDNLD_CMD_RESET: + { + break; + } + case PHDNLD_CMD_READ: + { + /* TODO: To Update the length and the buffer to receive data */ + break; + } + case PHDNLD_CMD_WRITE: + { + phDnldNfc_sRawDataHdr_t *raw_data_hdr = + ( phDnldNfc_sRawDataHdr_t * ) (raw_frame + FRAME_HEADER_LEN); + + psDnldContext->resp_length = PHDNLD_MIN_PACKET; + + break; + } + case PHDNLD_CMD_SEC_WRITE: + { + uint16_t tx_length = 0x00; + uint16_t frame_offset = + psDnldContext->tx_info.tx_offset; + uint16_t chain = + psDnldContext->tx_info.tx_chain; + + chain = + phDnldNfc_Extract_Chunks( + raw_frame, + frame_offset, + frame_length, + PHDNLD_FW_TX_RX_LEN, + &tx_length + ); + + if( TRUE == chain ) + { + status = phDnldNfc_Send_Command( psDnldContext, + pHwRef, PHDNLD_CMD_ENCAPSULATE, + (raw_frame + frame_offset), + tx_length); + if(NFCSTATUS_PENDING == status) + { + psDnldContext->prev_cmd = raw_frame_hdr->frame_type; + /* TODO: Update for the Chaining */ + psDnldContext->tx_info.tx_offset += tx_length; + psDnldContext->tx_info.tx_chain = chain; + } + } + else if (0 != frame_offset) + { + status = phDnldNfc_Send_Command( psDnldContext, + pHwRef, PHDNLD_CMD_ENCAPSULATE, + (raw_frame + frame_offset), + tx_length); + if(NFCSTATUS_PENDING == status) + { + psDnldContext->prev_cmd = raw_frame_hdr->frame_type; + /* TODO: Update for the Chaining */ + psDnldContext->prev_dnld_size = frame_length; + phDnldNfc_Tx_Reset(psDnldContext); + } + } + else + { + phDnldNfc_sRawDataHdr_t *raw_data_hdr = + ( phDnldNfc_sRawDataHdr_t * ) (raw_frame + FRAME_HEADER_LEN); + psDnldContext->resp_length = PHDNLD_MIN_PACKET; + } + + break; + } + case PHDNLD_CMD_CHECK: + { + psDnldContext->resp_length = PHDNLD_MIN_PACKET; + break; + } + case PHDNLD_CMD_SET_HIF: + { + psDnldContext->resp_length = PHDNLD_MIN_PACKET; + break; + } + case PHDNLD_CMD_ACTIVATE_PATCH: + { + psDnldContext->resp_length = PHDNLD_MIN_PACKET; + break; + } + case PHDNLD_CMD_CHECK_INTEGRITY: + { + uint8_t integrity_param = + *(raw_frame + FRAME_HEADER_LEN); + switch(integrity_param) + { + case CHK_INTEGRITY_CONFIG_PAGE_CRC: + case CHK_INTEGRITY_PATCH_TABLE_CRC: + { + psDnldContext->resp_length = PHDNLD_MIN_PACKET + + CHECK_INTEGRITY_RESP_CRC16_LEN; + break; + } + case CHK_INTEGRITY_FLASH_CODE_CRC: + case CHK_INTEGRITY_PATCH_CODE_CRC: + { + psDnldContext->resp_length = PHDNLD_MIN_PACKET + + CHECK_INTEGRITY_RESP_CRC32_LEN; + break; + } + case CHK_INTEGRITY_COMPLETE_CRC: + default: + { + psDnldContext->resp_length = PHDNLD_MIN_PACKET + + CHECK_INTEGRITY_RESP_COMP_LEN; + break; + } + } + break; + } + default: + { + status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FEATURE_NOT_SUPPORTED); + break; + } + } + + if (NFCSTATUS_SUCCESS == status) + { + status = phDnldNfc_Send( psDnldContext, pHwRef , + raw_frame, frame_length); + + if(NFCSTATUS_PENDING == status) + { + psDnldContext->prev_cmd = raw_frame_hdr->frame_type; + /* TODO: Update for the Chaining */ + psDnldContext->prev_dnld_size = frame_length; + } + } + + return status; +} + + +static +NFCSTATUS +phDnldNfc_Frame_Complete(phDnldNfc_sContext_t *psDnldContext) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + phDnldNfc_sData_Hdr_t *p_dnld_raw = NULL; + uint32_t dnld_index = psDnldContext->dnld_index; + uint8_t *p_raw_sec_hdr = NULL; + uint16_t tx_length = 0x00; + + dnld_index = dnld_index + psDnldContext->prev_dnld_size; + p_raw_sec_hdr = psDnldContext->p_fw_raw + dnld_index; + dnld_index = dnld_index + *p_raw_sec_hdr; + + p_dnld_raw = (phDnldNfc_sData_Hdr_t *) (psDnldContext->p_fw_raw + + psDnldContext->dnld_index); + + tx_length = ((p_dnld_raw->frame_length[0] << BYTE_SIZE) | + p_dnld_raw->frame_length[1]); + + tx_length = tx_length + PHDNLD_MIN_PACKET; + + return status; +} + + +static +NFCSTATUS +phDnldNfc_Raw_Write( + phDnldNfc_sContext_t *psDnldContext, + void *pHwRef + ) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint32_t dnld_index = psDnldContext->dnld_index; + uint32_t tx_length = 0; + uint8_t *p_raw_sec_hdr = NULL; + uint8_t dnld_flag = FALSE; + uint8_t skip_frame = FALSE; + + if(NULL != psDnldContext->p_fw_raw) + { + + if( (TRUE != psDnldContext->tx_info.tx_chain) + && (0x00 == psDnldContext->dnld_retry) + ) + { + dnld_index = dnld_index + psDnldContext->prev_dnld_size; + p_raw_sec_hdr = psDnldContext->p_fw_raw + dnld_index; + dnld_index = dnld_index + *p_raw_sec_hdr; + } + else + { + phDnldNfc_sData_Hdr_t *p_dnld_raw = (phDnldNfc_sData_Hdr_t *) + (psDnldContext->p_fw_raw + + psDnldContext->dnld_index); + + tx_length = ((p_dnld_raw->frame_length[0] << BYTE_SIZE) | + p_dnld_raw->frame_length[1]); + + tx_length = tx_length + PHDNLD_MIN_PACKET; + + status = phDnldNfc_Send_Raw( psDnldContext, pHwRef, + (uint8_t *)(p_dnld_raw), + psDnldContext->tx_info.tx_offset, + (uint16_t)tx_length); + } + + +#define PHDNLD_MAJOR_OFFSET 0x04U +#define PHDNLD_MINOR_OFFSET 0x05U +#define PHDNLD_PHASE_OFFSET 0x06U +#define PHDNLD_FRAMETYPE_OFFSET 0x07U + +#define PHDNLD_NO_OPERATION 0x00U +#define PHDNLD_NORMAL_OPERATION 0x10U +#define PHDNLD_ADVANCED_OPERATION 0x20U +#define PHDNLD_SETUP_OPERATION 0x40U +#define PHDNLD_RECOVER_OPERATION 0x80U +#define PHDNLD_COMPLETE_OPERATION 0xF0U + +#define PHDNLD_TERMINATE_TYPE 0x0EU + +#define PHDNLD_MARKER_MASK 0x0FU + + while((NFCSTATUS_SUCCESS == status ) + && (FALSE == dnld_flag) + ) + { + phDnldNfc_sData_Hdr_t *p_dnld_raw = (phDnldNfc_sData_Hdr_t *) + (psDnldContext->p_fw_raw + dnld_index); + uint8_t frame_type = *(p_raw_sec_hdr + PHDNLD_FRAMETYPE_OFFSET); + + tx_length = ((p_dnld_raw->frame_length[0] << BYTE_SIZE) | + p_dnld_raw->frame_length[1]); + + tx_length = tx_length + PHDNLD_MIN_PACKET; + + skip_frame = FALSE; + + if( (0x00 == *(p_raw_sec_hdr + PHDNLD_PHASE_OFFSET)) + || (0xFF == *(p_raw_sec_hdr + PHDNLD_PHASE_OFFSET)) + || !( psDnldContext->raw_mode_upgrade + & (frame_type & (~PHDNLD_MARKER_MASK)) ) + ) + { + dnld_index = dnld_index + tx_length; + p_raw_sec_hdr = psDnldContext->p_fw_raw + dnld_index; + dnld_index = dnld_index + *p_raw_sec_hdr; + skip_frame = TRUE; + } + if (PHDNLD_TERMINATE_TYPE == + (frame_type & PHDNLD_MARKER_MASK)) + { + if(TRUE != skip_frame) + { + psDnldContext->raw_mode_upgrade = + (psDnldContext->raw_mode_upgrade & + ~(frame_type & ~PHDNLD_MARKER_MASK)); + } + + if(PHDNLD_NO_OPERATION == + psDnldContext->raw_mode_upgrade) + { + dnld_flag = TRUE; + } + } + else + { + + } + + if((FALSE == skip_frame) + && (FALSE == dnld_flag) + ) + { + status = phDnldNfc_Send_Raw( psDnldContext, pHwRef, + (uint8_t *)(p_dnld_raw), + psDnldContext->tx_info.tx_offset, + (uint16_t)tx_length); + } + + if( NFCSTATUS_PENDING == status ) + { + psDnldContext->dnld_index = dnld_index; + psDnldContext->cur_frame_info= frame_type; + } + } + } + + return status; +} static NFCSTATUS @@ -1798,13 +2347,18 @@ phDnldNfc_Upgrade_Sequence( ) { NFCSTATUS status = NFCSTATUS_SUCCESS; - /* section_info_t *p_cur_sec = psDnldContext->p_fw_sec + - psDnldContext->section_index; */ PHNFC_UNUSED_VARIABLE(pdata); PHNFC_UNUSED_VARIABLE(length); - status = phDnldNfc_Resume_Write( psDnldContext, pHwRef ); + if(phDnld_Raw_Upgrade == psDnldContext->cur_dnld_seq) + { + status = phDnldNfc_Raw_Write( psDnldContext, pHwRef ); + } + else + { + status = phDnldNfc_Resume_Write( psDnldContext, pHwRef ); + } return status; } @@ -2018,12 +2572,14 @@ phDnldNfc_Resume( psDnldContext->lower_interface.pcontext, pHwRef); phDnldNfc_Release_Lower(psDnldContext, pHwRef); phDnldNfc_Release_Resources(&psDnldContext); +#ifndef NFC_TIMER_CONTEXT + gpphDnldContext = psDnldContext; +#endif /* Notify the Error/Success Scenario to the upper layer */ phDnldNfc_Notify( p_upper_notify, p_upper_context, pHwRef, (uint8_t) ((NFCSTATUS_SUCCESS == comp_info.status )? NFC_IO_SUCCESS: NFC_IO_ERROR), &comp_info ); } - return status; } @@ -2041,20 +2597,19 @@ phDnldNfc_Process_Response( (phDnldNfc_sData_Hdr_t *) pdata; PHNFC_UNUSED_VARIABLE(pHwRef); - /* DNLD_DEBUG(" FW_DNLD: Receive Length = %X \n", length ); */ - if(( psDnldContext->rx_total == 0 ) + DNLD_DEBUG(" FW_DNLD: Receive Length = %X \n", length ); + if(( psDnldContext->rx_info.rx_total == 0 ) && (PHDNLD_MIN_PACKET <= length) - /* && (FALSE == psDnldContext->recv_pending) */ ) { - psDnldContext->rx_total = + psDnldContext->rx_info.rx_total = ((uint16_t)resp_data->frame_length[0] << BYTE_SIZE)| resp_data->frame_length[1]; - if( psDnldContext->rx_total + PHDNLD_MIN_PACKET == length ) + if( psDnldContext->rx_info.rx_total + PHDNLD_MIN_PACKET == length ) { DNLD_DEBUG(" FW_DNLD: Success Memory Read = %X \n", - psDnldContext->rx_total); + psDnldContext->rx_info.rx_total); #ifndef DNLD_SUMMARY /* DNLD_PRINT_BUFFER("Receive Buffer",pdata,length); */ #endif @@ -2064,13 +2619,11 @@ phDnldNfc_Process_Response( { /* status = phDnldNfc_Receive( psDnldContext, pHwRef, psDnldContext->p_resp_buffer, - (uint8_t)((psDnldContext->rx_total <= PHDNLD_MAX_PACKET)? - psDnldContext->rx_total: PHDNLD_MAX_PACKET) ); - psDnldContext->recv_pending = - (uint8_t)( NFCSTATUS_PENDING == status); */ + (uint8_t)((psDnldContext->rx_info.rx_total <= PHDNLD_MAX_PACKET)? + psDnldContext->rx_info.rx_total: PHDNLD_MAX_PACKET) ); */ DNLD_PRINT(" FW_DNLD: Invalid Receive length "); DNLD_DEBUG(": Length Expected = %X \n", - (psDnldContext->rx_total + PHDNLD_MIN_PACKET)); + (psDnldContext->rx_info.rx_total + PHDNLD_MIN_PACKET)); status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_INVALID_RECEIVE_LENGTH ); } @@ -2078,7 +2631,7 @@ phDnldNfc_Process_Response( else { /*TODO:*/ - psDnldContext->rx_total = 0 ; + psDnldContext->rx_info.rx_total = 0 ; status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_INVALID_RECEIVE_LENGTH ); } @@ -2113,6 +2666,7 @@ phDnldNfc_Receive_Complete ( status = pInfo->status ; length = pInfo->length ; pdata = pInfo->buffer; + if(status != NFCSTATUS_SUCCESS) { DNLD_DEBUG(" Failed. Status = %02X\n",status); @@ -2124,9 +2678,10 @@ phDnldNfc_Receive_Complete ( /* Handle the Error Scenario */ status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_FAILED ); } - else if (0 == length) + else if ((0 == length) + || (PHDNLD_MIN_PACKET > length )) { - DNLD_PRINT(" Receive Response Length = 0 .... \n"); + DNLD_DEBUG(" Receive Response Length = %u .... \n",length); /* Handle the Error Scenario */ #ifndef HAL_SW_DNLD_RLEN status = PHNFCSTVAL( CID_NFC_DNLD, @@ -2136,6 +2691,15 @@ phDnldNfc_Receive_Complete ( else { +#if defined(FW_DOWNLOAD_TIMER) && \ + (FW_DOWNLOAD_TIMER == 2) + if ( NXP_INVALID_TIMER_ID != psDnldContext->timer_id ) + { + phOsalNfc_Timer_Stop( psDnldContext->timer_id ); + } + +#endif + #ifndef DNLD_SUMMARY DNLD_PRINT_BUFFER("Receive Buffer",pdata,length); #endif @@ -2154,6 +2718,9 @@ phDnldNfc_Receive_Complete ( { case PHDNLD_CMD_READ : { + if( PHDNLD_NO_OPERATION + == psDnldContext->raw_mode_upgrade) + { status = phDnldNfc_Process_Response( psDnldContext, pHwRef, pdata , length); @@ -2163,10 +2730,18 @@ phDnldNfc_Receive_Complete ( psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY; /* psDnldContext->dnld_retry < NXP_MAX_DNLD_RETRY */ } + } + else + { + + } break; } case PHDNLD_CMD_CHECK_INTEGRITY : { + if( PHDNLD_NO_OPERATION + == psDnldContext->raw_mode_upgrade) + { #if (NXP_FW_INTEGRITY_CHK >= 0x01) phDnldNfc_sChkCrcComplete_t *p_dnld_crc_all = &psDnldContext->chk_integrity_crc; @@ -2211,8 +2786,16 @@ phDnldNfc_Receive_Complete ( break; } } - #endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ + } + else + { + psDnldContext->raw_mode_upgrade = + (PHDNLD_SETUP_OPERATION | PHDNLD_ADVANCED_OPERATION); + /* psDnldContext->raw_mode_upgrade = + (psDnldContext->raw_mode_upgrade & + ( psDnldContext->cur_frame_info & ~PHDNLD_MARKER_MASK )); */ + } break; } case PHDNLD_CMD_WRITE: @@ -2220,10 +2803,18 @@ phDnldNfc_Receive_Complete ( psDnldContext->dnld_retry = 0; break; } + case PHDNLD_CMD_SEC_WRITE: + { + psDnldContext->dnld_retry = 0; + break; + } case PHDNLD_CMD_ACTIVATE_PATCH: case PHDNLD_CMD_CHECK: default: { + if( PHDNLD_NO_OPERATION + == psDnldContext->raw_mode_upgrade) + { if( ( (PHDNLD_MIN_PACKET > length) || ( 0 != resp_length) ) ) @@ -2236,14 +2827,20 @@ phDnldNfc_Receive_Complete ( { psDnldContext->dnld_retry = 0; } + } + else + { + psDnldContext->raw_mode_upgrade = + (psDnldContext->raw_mode_upgrade & ~PHDNLD_RECOVER_OPERATION); + } break; } } /* End of the Previous Command Switch Case */ break; }/* Case PHDNLD_RESP_SUCCESS*/ case PHDNLD_RESP_TIMEOUT: - case PHDNLD_RESP_WRITE_ERROR: case PHDNLD_RESP_CRC_ERROR: + case PHDNLD_RESP_WRITE_ERROR: { if(psDnldContext->dnld_retry < NXP_MAX_DNLD_RETRY ) { @@ -2255,22 +2852,139 @@ phDnldNfc_Receive_Complete ( } /* fall through */ case PHDNLD_RESP_ACCESS_DENIED: - case PHDNLD_RESP_PROTOCOL_ERROR: case PHDNLD_RESP_INVALID_PARAMETER: case PHDNLD_RESP_INVALID_LENGTH: + /* Initial Frame Checksum */ + case PHDNLD_RESP_CHKSUM_ERROR: + case PHDNLD_RESP_MEMORY_UPDATE_ERROR: { psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY; status = PHNFCSTVAL(CID_NFC_DNLD, resp_data->frame_type); break; } + case PHDNLD_RESP_PROTOCOL_ERROR: + { + if(( PHDNLD_NO_OPERATION + == psDnldContext->raw_mode_upgrade) + || ( PHDNLD_ADVANCED_OPERATION + == psDnldContext->raw_mode_upgrade) + ) + { + psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY; + status = PHNFCSTVAL(CID_NFC_DNLD, + NFCSTATUS_INVALID_FORMAT); + } + else if( (PHDNLD_NORMAL_OPERATION + & psDnldContext->raw_mode_upgrade) + ) + { + psDnldContext->raw_mode_upgrade = + (psDnldContext->raw_mode_upgrade & ~PHDNLD_NORMAL_OPERATION); + } + else if ( PHDNLD_RECOVER_OPERATION + & psDnldContext->raw_mode_upgrade ) + { + psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY; + status = PHNFCSTVAL(CID_NFC_DNLD, + NFCSTATUS_INVALID_FORMAT); + } + else + { + psDnldContext->raw_mode_upgrade = + (psDnldContext->raw_mode_upgrade & + ~( psDnldContext->cur_frame_info & ~PHDNLD_MARKER_MASK )); + } + break; + } + case PHDNLD_RESP_VERSION_UPTODATE: + { + /* TODO: to make sure that the Advance Frames are sent to get + * the updated status */ + if ( PHDNLD_ADVANCED_OPERATION + == psDnldContext->raw_mode_upgrade) + { + status = ( CID_NFC_DNLD << BYTE_SIZE ) ; + } + else if ( PHDNLD_NO_OPERATION + != psDnldContext->raw_mode_upgrade) + { + + psDnldContext->raw_mode_upgrade = + (psDnldContext->raw_mode_upgrade & + ~( psDnldContext->cur_frame_info & ~PHDNLD_MARKER_MASK )); + } + else + { + } + break; + } + case PHDNLD_RESP_CMD_NOT_SUPPORTED: + { + + if ( PHDNLD_NO_OPERATION + == psDnldContext->raw_mode_upgrade) + { + status = PHNFCSTVAL(CID_NFC_DNLD, + NFCSTATUS_FEATURE_NOT_SUPPORTED); + } + else if ( PHDNLD_ADVANCED_OPERATION + == psDnldContext->raw_mode_upgrade) + { + status = PHNFCSTVAL(CID_NFC_DNLD, + NFCSTATUS_FEATURE_NOT_SUPPORTED); + } +#if 0 + else if( (PHDNLD_NORMAL_OPERATION + & psDnldContext->raw_mode_upgrade) + ) + { + psDnldContext->raw_mode_upgrade = + (psDnldContext->raw_mode_upgrade & ~PHDNLD_NORMAL_OPERATION); + } + else if ( PHDNLD_SETUP_OPERATION + & psDnldContext->raw_mode_upgrade ) + { + psDnldContext->raw_mode_upgrade = + (psDnldContext->raw_mode_upgrade & ~PHDNLD_SETUP_OPERATION); + } +#endif + else + { + psDnldContext->raw_mode_upgrade = + (psDnldContext->raw_mode_upgrade & + ~( psDnldContext->cur_frame_info & ~PHDNLD_MARKER_MASK )); + } + break; + } + /* The Chaining of the Command Frame + was Successful in the Download Mode */ + case PHDNLD_RESP_CHAINING_SUCCESS: + { + /* TODO: Handle the Corner Case Scenarios + * the updated status */ + psDnldContext->dnld_retry = 0x00; + break; + } +/* The Error during the Chaining the Command Frame in the Download Mode */ + case PHDNLD_RESP_CHAINING_ERROR: + { + /* TODO: Restart the Chunk in Corner Case + * the updated status */ + psDnldContext->dnld_retry++; + phDnldNfc_Tx_Reset(psDnldContext); + break; + } +/* The Command is not allowed anymore in the Download Mode */ + case PHDNLD_RESP_CMD_NOT_ALLOWED: default: { psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY; status = PHNFCSTVAL(CID_NFC_DNLD, - NFCSTATUS_FEATURE_NOT_SUPPORTED); + NFCSTATUS_NOT_ALLOWED); break; } + } /* End of the Response Frame Type Switch */ if (NFCSTATUS_PENDING != status) @@ -2289,10 +3003,57 @@ phDnldNfc_Receive_Complete ( psDnldContext->lower_interface.pcontext, pHwRef); phDnldNfc_Release_Lower(psDnldContext, pHwRef); phDnldNfc_Release_Resources(&psDnldContext); +#ifndef NFC_TIMER_CONTEXT + gpphDnldContext = psDnldContext; +#endif /* Notify the Error/Success Scenario to the upper layer */ phDnldNfc_Notify( p_upper_notify, p_upper_context, pHwRef, (uint8_t) NFC_IO_ERROR, &comp_info ); } + else if ( (NFCSTATUS_SUCCESS != status) && + (NFCSTATUS_SUCCESS == PHNFCSTATUS(status)) + ) + { + pphNfcIF_Notification_CB_t p_upper_notify = + psDnldContext->p_upper_notify; + void *p_upper_context = + psDnldContext->p_upper_context; + + comp_info.status = NFCSTATUS_SUCCESS; + DNLD_DEBUG(" FW_DNLD: Termination in Receive, Status = %X \n", status); + status = phDal4Nfc_Unregister( + psDnldContext->lower_interface.pcontext, pHwRef); + phDnldNfc_Release_Lower(psDnldContext, pHwRef); + phDnldNfc_Release_Resources(&psDnldContext); +#ifndef NFC_TIMER_CONTEXT + gpphDnldContext = psDnldContext; +#endif + /* Notify the Error/Success Scenario to the upper layer */ + phDnldNfc_Notify( p_upper_notify, p_upper_context, pHwRef, + (uint8_t) NFC_IO_SUCCESS, &comp_info ); + + } + else if (NFCSTATUS_FEATURE_NOT_SUPPORTED == PHNFCSTATUS(status)) + { + pphNfcIF_Notification_CB_t p_upper_notify = + psDnldContext->p_upper_notify; + void *p_upper_context = + psDnldContext->p_upper_context; + + comp_info.status = status; + DNLD_DEBUG(" FW_DNLD: Termination in Receive, Status = %X \n", status); + status = phDal4Nfc_Unregister( + psDnldContext->lower_interface.pcontext, pHwRef); + phDnldNfc_Release_Lower(psDnldContext, pHwRef); + phDnldNfc_Release_Resources(&psDnldContext); +#ifndef NFC_TIMER_CONTEXT + gpphDnldContext = psDnldContext; +#endif + /* Notify the Error/Success Scenario to the upper layer */ + phDnldNfc_Notify( p_upper_notify, p_upper_context, pHwRef, + (uint8_t) NFC_IO_SUCCESS, &comp_info ); + + } else { /* DNLD_PRINT(" FW_DNLD: Successful.\n"); */ @@ -2342,12 +3103,10 @@ phDnldNfc_Send_Complete ( if ((PHDNLD_CMD_SET_HIF != psDnldContext->prev_cmd) && (PHDNLD_CMD_RESET != psDnldContext->prev_cmd)) { - psDnldContext->rx_total = 0; + psDnldContext->rx_info.rx_total = 0; status = phDnldNfc_Receive( psDnldContext, pHwRef, (uint8_t *)(&psDnldContext->dnld_resp), psDnldContext->resp_length); - /* psDnldContext->recv_pending = - (uint8_t)( NFCSTATUS_PENDING == status); */ } else { @@ -2357,7 +3116,19 @@ phDnldNfc_Send_Complete ( * platform because of its sensitivity to clock. Experimentally * we found clock unstable for 750us. Delay for 5ms to be sure. */ - usleep(5000); + if( PHDNLD_CMD_RESET == psDnldContext->prev_cmd ) + { + DO_DELAY(PHDNLD_DNLD_DELAY); + } +#if defined(FW_DOWNLOAD_TIMER) && \ + (FW_DOWNLOAD_TIMER == 2) + + if ( NXP_INVALID_TIMER_ID != psDnldContext->timer_id ) + { + phOsalNfc_Timer_Stop( psDnldContext->timer_id ); + } +#endif + status = phDnldNfc_Set_Seq(psDnldContext, DNLD_SEQ_UPDATE); } @@ -2373,6 +3144,7 @@ phDnldNfc_Send_Complete ( } + STATIC NFCSTATUS phDnldNfc_Send_Command( @@ -2387,6 +3159,8 @@ phDnldNfc_Send_Command( uint16_t tx_length = 0; uint16_t rx_length = 0; uint8_t **pp_resp_data = &psDnldContext->p_resp_buffer; + phDnldNfc_sData_t *p_dnld_data = + (phDnldNfc_sData_t *)psDnldContext->dnld_data; switch(cmd) { @@ -2398,8 +3172,10 @@ phDnldNfc_Send_Command( } case PHDNLD_CMD_READ: { + phDnldNfc_sData_t *p_dnld_data = + (phDnldNfc_sData_t *)psDnldContext->dnld_data; phDnldNfc_sParam_t *param_info = /* (phDnldNfc_sParam_t *)params */ - &psDnldContext->dnld_data.param_info.data_param; + &p_dnld_data->param_info.data_param; tx_length = PHDNLD_CMD_READ_LEN; if (NULL != *pp_resp_data) { @@ -2410,21 +3186,18 @@ phDnldNfc_Send_Command( << BYTE_SIZE) + param_info->data_len[1]); psDnldContext->resp_length = -#if 0 - (((rx_length > PHDNLD_DATA_SIZE)? - PHDNLD_DATA_SIZE + PHDNLD_MIN_PACKET: -#else - (( -#endif - rx_length + PHDNLD_MIN_PACKET )); + (( rx_length + PHDNLD_MIN_PACKET )); (void)phDnldNfc_Allocate_Resource( (void **) pp_resp_data, rx_length); break; } case PHDNLD_CMD_WRITE: + case PHDNLD_CMD_SEC_WRITE: { + phDnldNfc_sData_t *p_dnld_data = + (phDnldNfc_sData_t *)psDnldContext->dnld_data; phDnldNfc_sParam_t *param_info = /* (phDnldNfc_sParam_t *)params */ - &psDnldContext->dnld_data.param_info.data_param; + &p_dnld_data->param_info.data_param; tx_length = (uint16_t) (((uint16_t)param_info->data_len[0] << BYTE_SIZE) + param_info->data_len[1] + PHDNLD_CMD_WRITE_MIN_LEN ); @@ -2442,6 +3215,36 @@ phDnldNfc_Send_Command( psDnldContext->resp_length = PHDNLD_MIN_PACKET; break; } + case PHDNLD_CMD_ENCAPSULATE: + { + uint8_t i = 0x00; + if ((0 != param_length) && (NULL != params)) + { + p_dnld_data->frame_type = + PHDNLD_CMD_ENCAPSULATE; + (void)memcpy((void *)( ((uint8_t *)p_dnld_data) + + PHDNLD_FRAME_DATA_OFFSET) + , params, param_length); + tx_length = param_length; + + p_dnld_data->frame_length[i++] = + (uint8_t)(tx_length >> BYTE_SIZE); + p_dnld_data->frame_length[i] = + (uint8_t)( tx_length & BYTE_MASK ); + tx_length += PHDNLD_FRAME_DATA_OFFSET; + + psDnldContext->resp_length = PHDNLD_MIN_PACKET; + + status = phDnldNfc_Send( psDnldContext, pHwRef , + (uint8_t *)p_dnld_data, tx_length); + } + else + { + status = PHNFCSTVAL(CID_NFC_DNLD, + NFCSTATUS_NOT_ALLOWED); + } + break; + } case PHDNLD_CMD_SET_HIF: { tx_length++; @@ -2453,13 +3256,13 @@ phDnldNfc_Send_Command( psDnldContext->resp_length = PHDNLD_MIN_PACKET; if ((NULL != params) && ( param_length > 0 )) { - psDnldContext->dnld_data.param_info.cmd_param = + p_dnld_data->param_info.cmd_param = (*(uint8_t *)params); tx_length = param_length; } else { - psDnldContext->dnld_data.param_info.cmd_param = FALSE; + p_dnld_data->param_info.cmd_param = FALSE; tx_length++; } break; @@ -2478,7 +3281,7 @@ phDnldNfc_Send_Command( psDnldContext->chk_integrity_param = CHK_INTEGRITY_COMPLETE_CRC; tx_length++; } - psDnldContext->dnld_data.param_info.cmd_param = + p_dnld_data->param_info.cmd_param = (uint8_t) psDnldContext->chk_integrity_param; switch(psDnldContext->chk_integrity_param) { @@ -2506,7 +3309,7 @@ phDnldNfc_Send_Command( } #else tx_length++; - psDnldContext->dnld_data.param_info.cmd_param = + p_dnld_data->param_info.cmd_param = (uint8_t) CHK_INTEGRITY_COMPLETE_CRC; #endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ @@ -2522,14 +3325,14 @@ phDnldNfc_Send_Command( { uint8_t i = 0; - psDnldContext->dnld_data.frame_type = cmd; - psDnldContext->dnld_data.frame_length[i++] = + p_dnld_data->frame_type = cmd; + p_dnld_data->frame_length[i++] = (uint8_t)(tx_length >> BYTE_SIZE); - psDnldContext->dnld_data.frame_length[i] = + p_dnld_data->frame_length[i] = (uint8_t)( tx_length & BYTE_MASK ); tx_length = tx_length + PHDNLD_MIN_PACKET; status = phDnldNfc_Send( psDnldContext, pHwRef , - (uint8_t *)(&psDnldContext->dnld_data), tx_length); + (uint8_t *)p_dnld_data, tx_length); if(NFCSTATUS_PENDING == status) { psDnldContext->prev_cmd = cmd; @@ -2537,43 +3340,19 @@ phDnldNfc_Send_Command( if( PHDNLD_CMD_RESET == cmd ) DO_DELAY(PHDNLD_DNLD_DELAY); //this seems like its on the wrong thread } - } return status; } - static NFCSTATUS -phDnldNfc_Process_FW( - phDnldNfc_sContext_t *psDnldContext, - phHal_sHwReference_t *pHwRef -#ifdef NXP_FW_PARAM - ,uint8_t *nxp_nfc_fw -#endif +phDnldNfc_Check_FW( + phHal_sHwReference_t *pHwRef, + fw_data_hdr_t *cur_fw_hdr ) { NFCSTATUS status = NFCSTATUS_FAILED; - section_info_t *p_cur_sec = NULL; - static unsigned sec_type; - uint32_t fw_index = 0; - fw_data_hdr_t *cur_fw_hdr = NULL; - uint8_t sec_index = 0; - uint8_t i = 0; - - psDnldContext->p_img_hdr = (img_data_hdr_t *) nxp_nfc_fw; - - fw_index = sizeof (img_data_hdr_t); - - for ( i=0; i < psDnldContext->p_img_hdr->no_of_fw_img; i++ ) - { - - psDnldContext->p_fw_hdr = (fw_data_hdr_t *) ( nxp_nfc_fw + fw_index ); - /* TODO: Create a memory of pointers to store all the Firmwares */ - cur_fw_hdr = psDnldContext->p_fw_hdr; - - fw_index = fw_index + (cur_fw_hdr->fw_hdr_len * PNDNLD_WORD_LEN); if ( !pHwRef->device_info.fw_version ) { @@ -2589,9 +3368,6 @@ phDnldNfc_Process_FW( status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_NOT_ALLOWED ); } else if (( pHwRef->device_info.fw_version < cur_fw_hdr->fw_version ) -#ifdef NXP_FW_PATCH_VERIFY - && (pHwRef->device_info.full_version[NXP_PATCH_VER_INDEX] < cur_fw_hdr->fw_patch ) -#endif ) { /* TODO: Firmware Version Check and upgrade*/ @@ -2611,22 +3387,87 @@ phDnldNfc_Process_FW( DNLD_PRINT(" FW_DNLD: Already Updated .... \n"); status = ( CID_NFC_DNLD << BYTE_SIZE ) ; } + + return status; + } + + +static +NFCSTATUS +phDnldNfc_Process_FW( + phDnldNfc_sContext_t *psDnldContext, + phHal_sHwReference_t *pHwRef +#ifdef NXP_FW_PARAM + ,uint8_t *nxp_nfc_fw + ,uint32_t nxp_fw_len +#endif + ) +{ + NFCSTATUS status = NFCSTATUS_FAILED; + section_info_t *p_cur_sec = NULL; + static unsigned sec_type; + uint32_t fw_index = 0; +#ifdef NXP_NFC_MULTIPLE_FW + phDnldNfc_sFwImageInfo_t *p_cur_fw = NULL; +#endif /* #ifdef NXP_NFC_MULTIPLE_FW */ + fw_data_hdr_t *cur_fw_hdr = NULL; + uint8_t sec_index = 0; + uint8_t i = 0; + + psDnldContext->p_img_hdr = (img_data_hdr_t *) nxp_nfc_fw; + +#ifdef NXP_NFC_MULTIPLE_FW + + /* TODO: Create a memory of pointers to store all the Firmwares */ + if( (NXP_NFC_IMAG_FW_MAX > psDnldContext->p_img_hdr->no_of_fw_img) + && (0 != psDnldContext->p_img_hdr->no_of_fw_img) + ) + { + ( void )phDnldNfc_Allocate_Resource((void **)&psDnldContext->p_img_info, + (psDnldContext->p_img_hdr->no_of_fw_img * sizeof(phDnldNfc_sFwImageInfo_t))); + + if(NULL != psDnldContext->p_img_info) + { + p_cur_fw = psDnldContext->p_img_info; + } } +#endif /* #ifdef NXP_NFC_MULTIPLE_FW */ + + fw_index = sizeof (img_data_hdr_t); + + for ( i=0; i < psDnldContext->p_img_hdr->no_of_fw_img; i++ ) + { + + psDnldContext->p_fw_hdr = (fw_data_hdr_t *) ( nxp_nfc_fw + fw_index ); + +#ifdef NXP_NFC_MULTIPLE_FW + if(NULL != p_cur_fw) + { + ( p_cur_fw + i)->p_fw_hdr = psDnldContext->p_fw_hdr; + } +#endif /* #ifdef NXP_NFC_MULTIPLE_FW */ + cur_fw_hdr = psDnldContext->p_fw_hdr; + + fw_index = fw_index + (cur_fw_hdr->fw_hdr_len * PNDNLD_WORD_LEN); + + status = phDnldNfc_Check_FW( pHwRef, cur_fw_hdr); + + } + if ( ( NFCSTATUS_SUCCESS == status ) #if defined (NXP_FW_INTEGRITY_VERIFY) || (NFCSTATUS_SUCCESS == PHNFCSTATUS(status) ) #endif /* !defined (NXP_FW_INTEGRITY_VERIFY) */ ) { - + if( (BYTE_MASK > cur_fw_hdr->no_of_sections) + && (0 != cur_fw_hdr->no_of_sections) + ) + { (void) phDnldNfc_Allocate_Resource((void **)&psDnldContext->p_fw_sec, (cur_fw_hdr->no_of_sections * sizeof(section_info_t))); - if(NULL == psDnldContext->p_fw_sec) - { - status = PHNFCSTVAL(CID_NFC_DNLD, - NFCSTATUS_INSUFFICIENT_RESOURCES); - } - else + + if(NULL != psDnldContext->p_fw_sec) { DNLD_DEBUG(" FW_DNLD: FW Index : %x \n", fw_index ); @@ -2655,7 +3496,7 @@ phDnldNfc_Process_FW( sec_type = (unsigned int)p_cur_sec->p_sec_hdr->section_mem_type; - if(TRUE == ((section_type_t *)(&sec_type))->trim_val ) + if((sec_type & DNLD_TRIM_MASK)) { p_cur_sec->p_trim_data = (uint8_t *) (nxp_nfc_fw + fw_index + sizeof(section_hdr_t)); @@ -2665,25 +3506,42 @@ phDnldNfc_Process_FW( p_cur_sec->p_trim_data = NULL; } + if (0 == sec_index) + { + if ((sec_type & DNLD_SM_UNLOCK_MASK)) + { + (void)phDnldNfc_Set_Seq(psDnldContext, + DNLD_SEQ_UNLOCK); + } + else + { + (void)phDnldNfc_Set_Seq(psDnldContext, + DNLD_SEQ_INIT); + } + } p_cur_sec->section_read = FALSE; p_cur_sec->section_offset = 0; p_cur_sec->p_sec_data = ((uint8_t *) nxp_nfc_fw) + fw_index + -#ifdef SECTION_HDR (p_cur_sec->p_sec_hdr->section_hdr_len * PNDNLD_WORD_LEN); -#else - sizeof (section_hdr_t) ; -#endif fw_index = fw_index + -#ifdef SECTION_HDR (p_cur_sec->p_sec_hdr->section_hdr_len * PNDNLD_WORD_LEN) -#else - sizeof (section_hdr_t) -#endif + p_cur_sec->p_sec_hdr->section_length; + + if( 0 != p_cur_sec->p_sec_hdr->section_checksum ) + { + DNLD_DEBUG(" FW_DNLD: Section checksum : %x \n", + p_cur_sec->p_sec_hdr->section_checksum ); + + p_cur_sec->p_sec_chksum = ( uint8_t *)(nxp_nfc_fw + fw_index); + + fw_index = fw_index + + p_cur_sec->p_sec_hdr->section_checksum; + } + DNLD_DEBUG(" FW_DNLD: FW Index : %x \n", fw_index ); #if (NXP_FW_INTEGRITY_CHK >= 0x01) @@ -2717,13 +3575,37 @@ phDnldNfc_Process_FW( { break; } - } + + } /* End of Address Switch */ #endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ + } /* End of For Loop */ + } /* End of the Null Check */ + else + { + status = PHNFCSTVAL(CID_NFC_DNLD, + NFCSTATUS_INSUFFICIENT_RESOURCES); + } } + else if ( + (0 == cur_fw_hdr->no_of_sections) + && (PHDNLD_FW_PATCH_SEC == cur_fw_hdr->fw_patch) + ) + { + psDnldContext->p_fw_raw = (uint8_t *)(nxp_nfc_fw + fw_index); - DNLD_PRINT("*******************************************\n\n"); + psDnldContext->raw_mode_upgrade = PHDNLD_COMPLETE_OPERATION; + + (void)phDnldNfc_Set_Seq(psDnldContext, + DNLD_SEQ_RAW); + } + else + { + DNLD_PRINT("********* Empty Section and Firmware ******************\n\n"); } + + DNLD_PRINT("*******************************************\n\n"); + } return status; } @@ -2758,45 +3640,7 @@ phDnldNfc_Run_Check( fw_index = fw_index + (cur_fw_hdr->fw_hdr_len * PNDNLD_WORD_LEN); - if ( !pHwRef->device_info.fw_version ) - { - /* Override the Firmware Version Check and upgrade*/; - DNLD_PRINT(" FW_DNLD_CHK: Forceful Upgrade of the Firmware .... Required \n"); - status = NFCSTATUS_SUCCESS; - } - else if ( (pHwRef->device_info.fw_version >> (BYTE_SIZE * 2)) - != ( cur_fw_hdr->fw_version >> (BYTE_SIZE * 2) )) - { - /* Check for the Compatible Romlib Version for the Hardware */ - DNLD_PRINT(" FW_DNLD: IC Hardware Version Mismatch.. \n"); - status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_NOT_ALLOWED ); - } - else if (( pHwRef->device_info.fw_version < cur_fw_hdr->fw_version ) -#ifdef NXP_FW_PATCH_VERIFY - && (pHwRef->device_info.full_version[NXP_PATCH_VER_INDEX] < cur_fw_hdr->fw_patch ) -#endif - ) - { - /* TODO: Firmware Version Check and upgrade*/ - DNLD_PRINT(" FW_DNLD_CHK: Older Firmware. Upgrading to newer one.... \n"); - status = NFCSTATUS_SUCCESS; - } -#ifdef NXP_FW_CHK_LATEST - else if (( pHwRef->device_info.fw_version > cur_fw_hdr->fw_version ) - ) - { - DNLD_PRINT(" FW_DNLD: Newer than the Stored One .... \n"); - status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_NOT_ALLOWED ); - } -#endif /* NXP_FW_CHK_LATEST */ - else - { - DNLD_PRINT(" FW_DNLD_CHK: Already Updated .... \n"); - status = ( CID_NFC_DNLD << BYTE_SIZE ) ; - } - } - if( NFCSTATUS_SUCCESS == status ) - { + status = phDnldNfc_Check_FW( pHwRef, cur_fw_hdr); } return status; } @@ -2807,26 +3651,39 @@ phDnldNfc_Run_Check( STATIC void phDnldNfc_Abort ( - uint32_t abort_id, - void *pContext + uint32_t abort_id +#ifdef NFC_TIMER_CONTEXT + , void *dnld_cntxt +#endif ) { phNfc_sCompletionInfo_t comp_info = {0,0,0}; - if ( ( NULL != gpphDnldContext) - && (abort_id == gpphDnldContext->timer_id )) + phDnldNfc_sContext_t *p_dnld_context = NULL; + +#ifdef NFC_TIMER_CONTEXT + p_dnld_context = (phDnldNfc_sContext_t *)dnld_cntxt; +#else + p_dnld_context = gpphDnldContext; +#endif + + if ( ( NULL != p_dnld_context) + && (abort_id == p_dnld_context->timer_id )) { pphNfcIF_Notification_CB_t p_upper_notify = - gpphDnldContext->p_upper_notify; + p_dnld_context->p_upper_notify; void *p_upper_context = - gpphDnldContext->p_upper_context; - phHal_sHwReference_t *pHwRef = gpphDnldContext->p_hw_ref; + p_dnld_context->p_upper_context; + phHal_sHwReference_t *pHwRef = p_dnld_context->p_hw_ref; (void)phDal4Nfc_Unregister( - gpphDnldContext->lower_interface.pcontext, pHwRef ); - phDnldNfc_Release_Lower(gpphDnldContext, pHwRef); - phDnldNfc_Release_Resources(&gpphDnldContext); + p_dnld_context->lower_interface.pcontext, pHwRef ); + phDnldNfc_Release_Lower(p_dnld_context, pHwRef); + phDnldNfc_Release_Resources(&p_dnld_context); +#ifndef NFC_TIMER_CONTEXT + gpphDnldContext = p_dnld_context; +#endif /* Notify the Error/Success Scenario to the upper layer */ DNLD_DEBUG(" FW_DNLD: FW_DNLD Aborted with %x Timer Timeout \n", @@ -2845,6 +3702,7 @@ NFCSTATUS phDnldNfc_Upgrade ( phHal_sHwReference_t *pHwRef, #ifdef NXP_FW_PARAM + uint8_t type, uint8_t *nxp_nfc_fw, uint32_t fw_length, #endif @@ -2868,16 +3726,15 @@ phDnldNfc_Upgrade ( else { DNLD_PRINT(" FW_DNLD: Starting the FW Upgrade Sequence .... \n"); - /* Create the memory for Download Mgmt Context */ - psDnldContext = (phDnldNfc_sContext_t *) - phOsalNfc_GetMemory(sizeof(phDnldNfc_sContext_t)); + (void) + phDnldNfc_Allocate_Resource((void **) + &psDnldContext,sizeof(phDnldNfc_sContext_t)); if(psDnldContext != NULL) { - (void ) memset((void *)psDnldContext,0, - sizeof(phDnldNfc_sContext_t)); - +#ifndef NFC_TIMER_CONTEXT gpphDnldContext = psDnldContext; +#endif psDnldContext->p_hw_ref = pHwRef; psDnldContext->timer_id = NXP_INVALID_TIMER_ID; @@ -2911,7 +3768,7 @@ phDnldNfc_Upgrade ( status = phDnldNfc_Process_FW( psDnldContext, pHwRef #ifdef NXP_FW_PARAM - ,*nxp_nfc_fw /*, fw_length */ + ,*nxp_nfc_fw , fw_length #endif ); @@ -2922,27 +3779,24 @@ phDnldNfc_Upgrade ( if (NFCSTATUS_PENDING == status) { DNLD_PRINT("\n FW_DNLD: Initial Reset .... \n"); - p_cur_sec = ((section_info_t *) - (psDnldContext->p_fw_sec )); - sec_type = (unsigned ) - (p_cur_sec->p_sec_hdr->section_mem_type); - if(TRUE == ((section_type_t *) - (&sec_type))->system_mem_unlock ) - { - (void)phDnldNfc_Set_Seq(psDnldContext, - DNLD_SEQ_UNLOCK); - } - else - { - (void)phDnldNfc_Set_Seq(psDnldContext, - DNLD_SEQ_INIT); - } -#ifdef FW_DOWNLOAD_TIMER +#if defined(FW_DOWNLOAD_TIMER) + psDnldContext->timer_id = phOsalNfc_Timer_Create( ); + +#if (FW_DOWNLOAD_TIMER < 2) phOsalNfc_Timer_Start( psDnldContext->timer_id, - NXP_DNLD_COMPLETE_TIMEOUT, phDnldNfc_Abort, NULL ); + NXP_DNLD_COMPLETE_TIMEOUT, + (ppCallBck_t) phDnldNfc_Abort +#ifdef NFC_TIMER_CONTEXT + , (void *) psDnldContext #endif + ); + +#endif /* #if (FW_DOWNLOAD_TIMER < 2) */ + +#endif /* #if defined(FW_DOWNLOAD_TIMER) */ + } } else if (NFCSTATUS_SUCCESS == PHNFCSTATUS(status)) @@ -2954,23 +3808,33 @@ phDnldNfc_Upgrade ( */ status = phDnldNfc_Send_Command( psDnldContext, pHwRef, PHDNLD_CMD_RESET , NULL , 0 ); - if (NFCSTATUS_PENDING == status) { DNLD_PRINT("\n FW_DNLD: Integrity Reset .... \n"); (void)phDnldNfc_Set_Seq(psDnldContext, DNLD_SEQ_COMPLETE); status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_PENDING ); -#ifdef FW_DOWNLOAD_TIMER +#if defined(FW_DOWNLOAD_TIMER) psDnldContext->timer_id = phOsalNfc_Timer_Create( ); +#if (FW_DOWNLOAD_TIMER < 2) phOsalNfc_Timer_Start( psDnldContext->timer_id, - NXP_DNLD_COMPLETE_TIMEOUT, phDnldNfc_Abort, NULL ); + NXP_DNLD_COMPLETE_TIMEOUT, + (ppCallBck_t) phDnldNfc_Abort +#ifdef NFC_TIMER_CONTEXT + , (void *) psDnldContext #endif + ); + +#endif /* #if (FW_DOWNLOAD_TIMER < 2) */ + +#endif /* #if defined(FW_DOWNLOAD_TIMER) */ } #else status = NFCSTATUS_SUCCESS; -#endif + +#endif /* #if defined (NXP_FW_INTEGRITY_VERIFY) */ + } else { @@ -2981,9 +3845,12 @@ phDnldNfc_Upgrade ( if (NFCSTATUS_PENDING != PHNFCSTATUS(status)) { (void)phDal4Nfc_Unregister( - gpphDnldContext->lower_interface.pcontext, pHwRef); - phDnldNfc_Release_Lower(gpphDnldContext, pHwRef); - phDnldNfc_Release_Resources(&gpphDnldContext); + psDnldContext->lower_interface.pcontext, pHwRef); + phDnldNfc_Release_Lower(psDnldContext, pHwRef); + phDnldNfc_Release_Resources(&psDnldContext); +#ifndef NFC_TIMER_CONTEXT + gpphDnldContext = psDnldContext; +#endif } } /* End of Status Check for Memory */ else diff --git a/src/phHal4Nfc.c b/src/phHal4Nfc.c index 341f183..a579811 100644 --- a/src/phHal4Nfc.c +++ b/src/phHal4Nfc.c @@ -153,7 +153,11 @@ static void phHal4Nfc_OpenComplete( gpphHal4Nfc_Hwref = NULL; PHDBG_INFO("Hal4:Open Failed"); /*Call upper layer's Open Cb with error status*/ - (*pUpper_OpenCb)(pUpper_Context,status); + if(NULL != pUpper_OpenCb) + { + /*Upper layer's Open Cb*/ + (*pUpper_OpenCb)(pUpper_Context,status); + } } return; } @@ -406,7 +410,7 @@ NFCSTATUS phHal4Nfc_Open( if( openRetVal == NFCSTATUS_SUCCESS ) { /*update Next state*/ - Hal4Ctxt->Hal4NextState = (HCI_SELF_TEST == eHciInitType? + Hal4Ctxt->Hal4NextState = (HCI_NFC_DEVICE_TEST == eHciInitType? eHal4StateSelfTestMode:eHal4StateOpenAndReady); /*Store callback and context ,and set Default settings in Context*/ Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb = pOpenCallback; @@ -470,13 +474,17 @@ NFCSTATUS phHal4Nfc_Ioctl( else if(NULL == psHwReference->hal_context) { #ifdef FW_DOWNLOAD + +#if !defined (NXP_FW_INTEGRITY_VERIFY) if(NFC_FW_DOWNLOAD_CHECK == IoctlCode) { RetStatus = phDnldNfc_Run_Check( psHwReference ); } - else if((NFC_FW_DOWNLOAD == IoctlCode) + else +#endif /* !defined (NXP_FW_INTEGRITY_VERIFY) */ + if((NFC_FW_DOWNLOAD == IoctlCode) &&(NULL == gpphHal4Nfc_Hwref))/*Indicates current state is shutdown*/ { Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *) @@ -505,7 +513,9 @@ NFCSTATUS phHal4Nfc_Ioctl( phHal4Nfc_DownloadComplete, Hal4Ctxt ); - if(NFCSTATUS_SUCCESS == RetStatus) + if((NFCSTATUS_SUCCESS == RetStatus) + || (NFCSTATUS_PENDING != PHNFCSTATUS(RetStatus)) + ) { phOsalNfc_FreeMemory(Hal4Ctxt); ((phHal_sHwReference_t *)psHwReference)->hal_context = NULL; @@ -1008,10 +1018,15 @@ static void phHal4Nfc_LowerNotificationHandler( break; case NFC_NOTIFY_DEVICE_ERROR: { + NFCSTATUS status = NFCSTATUS_BOARD_COMMUNICATION_ERROR; + pphHal4Nfc_GenCallback_t pUpper_OpenCb + = Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb; + void *pUpper_Context + = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt; static phHal4Nfc_NotificationInfo_t uNotificationInfo; - Hal4Ctxt->Hal4NextState = eHal4StateInvalid; if(NULL != Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler) { + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler( Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt, NFC_EVENT_NOTIFICATION, @@ -1019,8 +1034,31 @@ static void phHal4Nfc_LowerNotificationHandler( NFCSTATUS_BOARD_COMMUNICATION_ERROR ); } + else if (( eHal4StateSelfTestMode == Hal4Ctxt->Hal4NextState ) + || ( eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState ) ) + { + Hal4Ctxt->Hal4CurrentState = eHal4StateClosed; + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + (void)phHciNfc_Release((void *)Hal4Ctxt->psHciHandle, + pHwRef, (pphNfcIF_Notification_CB_t)NULL, + (void *)Hal4Ctxt);/*Clean up Hci*/ + Hal4Ctxt->psHciHandle = NULL; + phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg); + Hal4Ctxt->pHal4Nfc_LayerCfg = NULL; + phOsalNfc_FreeMemory((void *)Hal4Ctxt); + gpphHal4Nfc_Hwref->hal_context = NULL; + gpphHal4Nfc_Hwref = NULL; + PHDBG_INFO("Hal4:Open Failed"); + /*Call upper layer's Open Cb with error status*/ + if(NULL != pUpper_OpenCb) + { + /*Upper layer's Open Cb*/ + (*pUpper_OpenCb)(pUpper_Context,status); + } + } else { + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1); } break; @@ -1218,6 +1256,7 @@ static void phHal4Nfc_HandleEvent( case NFC_INFO_TXLDO_OVERCUR: case NFC_INFO_MEM_VIOLATION: case NFC_INFO_TEMP_OVERHEAT: + case NFC_INFO_LLC_ERROR: { sNotificationInfo.info = psEventInfo; sNotificationInfo.status = NFCSTATUS_SUCCESS; @@ -1294,10 +1333,23 @@ static void phHal4Nfc_SelfTestComplete( = Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb; void *pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt; /*check for Success*/ - if((SelfTestResults->length > 0) && (0 == SelfTestResults->buffer[0])) + if(( DEVMGMT_SWP_TEST == Hal4Ctxt->Ioctl_Type ) + || ( DEVMGMT_ANTENNA_TEST == Hal4Ctxt->Ioctl_Type )) { status = NFCSTATUS_SUCCESS; } + else if((SelfTestResults->length > 0) && (0 == SelfTestResults->buffer[0])) + { + status = NFCSTATUS_SUCCESS; + } + else + { + if (NULL != pInfo) + { + status = ((phNfc_sCompletionInfo_t *)pInfo)->status; + } + } + /*Copy response buffer and length*/ (void)memcpy(Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam->buffer, SelfTestResults->buffer, @@ -1356,7 +1408,8 @@ static void phHal4Nfc_IoctlComplete( { /*for NFC_MEM_READ and NFC_GPIO_READ ,provide one Byte Response*/ if ((NFC_MEM_READ == Hal4Ctxt->Ioctl_Type) - || (NFC_GPIO_READ == Hal4Ctxt->Ioctl_Type)) + || (NFC_GPIO_READ == Hal4Ctxt->Ioctl_Type) + ) { Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam->length = sizeof (uint8_t); diff --git a/src/phHciNfc.h b/src/phHciNfc.h index f360413..4f52b4a 100644 --- a/src/phHciNfc.h +++ b/src/phHciNfc.h @@ -78,8 +78,9 @@ typedef enum phHciNfc_Init { HCI_SESSION = 0x00, - HCI_SELF_TEST, - HCI_CUSTOM_INIT + HCI_NFC_DEVICE_TEST, + HCI_CUSTOM_INIT, + HCI_SELF_TEST }phHciNfc_Init_t; /** \ingroup grp_hal_hci @@ -263,7 +264,7 @@ phHciNfc_Config_Discovery ( * of the HCI Layer. * \param[in] pHwRef pHwRef is the Information of * the Device Interface Link . - * \param[in] re_poll If True: Start re-polling of the target + * \param[in] discovery_type If True: Start re-polling of the target * after the Target Device is de-activated * or else - continue discovery with next * technology. @@ -279,7 +280,7 @@ phHciNfc_Config_Discovery ( phHciNfc_Restart_Discovery ( void *psHciHandle, void *pHwRef, - uint8_t repoll + uint8_t discovery_type ); @@ -495,10 +496,11 @@ phHciNfc_Config_Discovery ( * of the HCI Layer. * \param[in] pHwRef pHwRef is the Information of * the Device Interface Link . - * \param[in] re_poll If True: Start re-polling of the target - * after the Target Device is de-activated - * or else - continue discovery with next - * technology. + * \param[in] discovery_type If NFC_RF_DISCOVERY_REPOLL: Start re-polling of + * the target after the Target Device is + * de-activatedor if NFC_RF_DISCOVERY_CONTINUE - + * continue discovery with next technology or + * stop the discovery wheel. * * \retval NFCSTATUS_PENDING To De-select the remote target pending. * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters @@ -512,7 +514,7 @@ phHciNfc_Config_Discovery ( phHciNfc_Disconnect ( void *psHciHandle, void *pHwRef, - uint8_t re_poll + uint8_t discovery_type ); diff --git a/src/phHciNfc_DevMgmt.c b/src/phHciNfc_DevMgmt.c index ef3aa78..9517741 100644 --- a/src/phHciNfc_DevMgmt.c +++ b/src/phHciNfc_DevMgmt.c @@ -71,6 +71,7 @@ #define NXP_EVT_INFO_EXT_RF_FIELD 0x12U #define NXP_EVT_INFO_MEM_VIOLATION 0x13U #define NXP_EVT_INFO_TEMP_OVERHEAT 0x14U +#define NXP_EVT_INFO_LLC_ERROR 0x15U #define NFC_DEV_TXLDO_MASK 0x03U @@ -578,7 +579,9 @@ phHciNfc_DevMgmt_Initialise( NFC_FELICA_RC_ADDR , config ); if(NFCSTATUS_PENDING == status ) { - if (HCI_SELF_TEST == psHciContext->init_mode ) + + if ((HCI_SELF_TEST == psHciContext->init_mode ) + || (HCI_NFC_DEVICE_TEST == psHciContext->init_mode )) { p_device_mgmt_info->next_seq = DEV_MGMT_GPIO_PDIR; @@ -653,18 +656,27 @@ phHciNfc_DevMgmt_Initialise( #endif /* #if ( NXP_NFC_IFC_TIMEOUT & 0x01 ) */ case DEV_MGMT_TX_LDO: { - config = (NFC_DEV_HWCONF_DEFAULT | +#if ( NXP_HAL_VERIFY_EEPROM_CRC & 0x01U ) + if (0 != p_device_mgmt_info->eeprom_crc) + { + status = NFCSTATUS_FAILED; + } + else +#endif + { + config = (NFC_DEV_HWCONF_DEFAULT | (NXP_DEFAULT_TX_LDO & NFC_DEV_TXLDO_MASK)); - status = phHciNfc_DevMgmt_Configure( psHciContext, pHwRef, + status = phHciNfc_DevMgmt_Configure( psHciContext, pHwRef, NFC_ADDRESS_HW_CONF , config ); - if(NFCSTATUS_PENDING == status ) - { + if(NFCSTATUS_PENDING == status ) + { #if ( SW_TYPE_RF_TUNING_BF & 0x01) - p_device_mgmt_info->next_seq = DEV_MGMT_ANAIRQ_CONF; + p_device_mgmt_info->next_seq = DEV_MGMT_ANAIRQ_CONF; #else - p_device_mgmt_info->next_seq = DEV_MGMT_CLK_REQ; + p_device_mgmt_info->next_seq = DEV_MGMT_CLK_REQ; #endif - /* status = NFCSTATUS_SUCCESS; */ + /* status = NFCSTATUS_SUCCESS; */ + } } break; } @@ -1064,17 +1076,20 @@ phHciNfc_DevMgmt_Update_Sequence( { p_device_mgmt_info->current_seq = DEV_MGMT_PIPE_OPEN; p_device_mgmt_info->next_seq = DEV_MGMT_PIPE_OPEN ; - }break; + break; + } case UPDATE_SEQ: { p_device_mgmt_info->current_seq = p_device_mgmt_info->next_seq; - }break; + break; + } case REL_SEQ: { p_device_mgmt_info->current_seq = DEV_MGMT_EVT_AUTONOMOUS; p_device_mgmt_info->next_seq = DEV_MGMT_EVT_AUTONOMOUS ; - }break; + break; + } default: { break; @@ -1119,6 +1134,8 @@ phHciNfc_DevMgmt_Test( } else { + phHciNfc_DevMgmt_Info_t *p_device_mgmt_info = (phHciNfc_DevMgmt_Info_t *) + psHciContext->p_device_mgmt_info ; p_pipe_info = ((phHciNfc_DevMgmt_Info_t *) psHciContext->p_device_mgmt_info)->p_pipe_info ; switch(test_type) @@ -1136,6 +1153,8 @@ phHciNfc_DevMgmt_Test( p_pipe_info->param_info = test_param->buffer; p_pipe_info->param_length = (uint8_t)test_param->length; } + p_device_mgmt_info->test_result.buffer = NULL; + p_device_mgmt_info->test_result.length = 0; status = phHciNfc_Send_DevMgmt_Command( psHciContext, pHwRef, pipe_id, (uint8_t)test_type ); @@ -1225,15 +1244,15 @@ phHciNfc_Recv_DevMgmt_Response( break; } case NXP_DBG_READ: - { - *p_device_mgmt_info->p_val = (uint8_t)( length > HCP_HEADER_LEN ) ? - pResponse[HCP_HEADER_LEN]: 0; - p_device_mgmt_info->p_val = NULL; - - } /* fall through */ case NXP_DBG_WRITE: { + if( NULL != p_device_mgmt_info->p_val ) + { + *p_device_mgmt_info->p_val = (uint8_t)( length > HCP_HEADER_LEN ) ? + pResponse[HCP_HEADER_LEN]: 0; + p_device_mgmt_info->p_val = NULL; + } break; } /* Self Test Commands */ @@ -1363,6 +1382,11 @@ phHciNfc_Recv_DevMgmt_Event( p_device_mgmt_info->overheat_status; break; } + case NXP_EVT_INFO_LLC_ERROR: + { + event_info.eventType = NFC_INFO_LLC_ERROR; + break; + } default: { status = PHNFCSTVAL(CID_NFC_HCI, diff --git a/src/phHciNfc_Generic.h b/src/phHciNfc_Generic.h index 16ffa0e..1d7b522 100644 --- a/src/phHciNfc_Generic.h +++ b/src/phHciNfc_Generic.h @@ -454,6 +454,7 @@ typedef enum phHciNfc_eSeq{ /* HCI Device Management Sequence */ DEV_INIT_SEQ, + DEV_HAL_INFO_SEQ, DEV_CONFIG_SEQ, DEV_REL_SEQ, @@ -607,8 +608,8 @@ typedef struct phHciNfc_sContext{ /** \internal Mode of HCI Initialisation */ phHciNfc_Init_t init_mode; - /** \internal Mode of HCI Initialisation */ - void *p_io_params; + /** \internal Memory Information for HCI Initialisation */ + uint8_t hal_mem_info[NXP_HAL_MEM_INFO_SIZE]; /** \internal HCI Configuration Type */ phHciNfc_eConfigType_t config_type; diff --git a/src/phHciNfc_Sequence.c b/src/phHciNfc_Sequence.c index 73d7b79..1926c6c 100644 --- a/src/phHciNfc_Sequence.c +++ b/src/phHciNfc_Sequence.c @@ -65,6 +65,10 @@ ################################################################################ */ +/* Address Definitions for HAL Configuration */ +#define NFC_ADDRESS_HAL_CONF 0x9FD0U + + /* ################################################################################ ********************** Structure/Enumeration Definitions *********************** @@ -243,8 +247,10 @@ phHciNfc_FSM_Validate( /* Initialise to Perform Test on the Antenna/SWP Link */ case hciState_Test: + { status = NFCSTATUS_SUCCESS; break; + } default: break; } @@ -266,8 +272,10 @@ phHciNfc_FSM_Validate( case hciState_Listen: /* Specifies the Starting of the Release Sequence */ case hciState_Release: + { status = NFCSTATUS_SUCCESS; break; + } default: break; } @@ -306,8 +314,10 @@ phHciNfc_FSM_Validate( case hciState_Connect: /* Specifies the Starting of the Release Sequence */ case hciState_Release: + { status = NFCSTATUS_SUCCESS; break; + } default: break; } @@ -338,8 +348,10 @@ phHciNfc_FSM_Validate( case hciState_Disconnect: /* Specifies the Starting of the Release Sequence */ case hciState_Release: + { status = NFCSTATUS_SUCCESS; break; + } default: break; } @@ -363,8 +375,10 @@ phHciNfc_FSM_Validate( case hciState_Transact: /* Specifies the Starting of the Release Sequence */ case hciState_Release: + { status = NFCSTATUS_SUCCESS; break; + } default: break; } @@ -386,8 +400,10 @@ phHciNfc_FSM_Validate( case hciState_Config: /* Specifies the Starting of the Release Sequence */ case hciState_Release: + { status = NFCSTATUS_SUCCESS; break; + } default: break; } @@ -412,11 +428,15 @@ phHciNfc_FSM_Validate( case hciState_Listen: /* Specifies the Starting of the Release Sequence */ case hciState_Release: + { status = NFCSTATUS_SUCCESS; break; + } default: + { break; } + } break; } #ifdef USE_M5 @@ -640,7 +660,7 @@ phHciNfc_Error_Sequence( { if (hciState_Reset == psHciContext->hci_state.cur_state) { - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; phHciNfc_Release_Lower( psHciContext, pHwRef ); /* Release all the resources and @@ -654,7 +674,7 @@ phHciNfc_Error_Sequence( { /* Notify the Poll/Emulation Configure failure to the upper layer */ - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; comp_info.status = error_status ; @@ -671,7 +691,8 @@ phHciNfc_Error_Sequence( { /* Notify the Poll Configure failure to the upper layer */ - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; + psHciContext->error_status = error_status; status = phHciNfc_Pending_Sequence(psHciContext, pHwRef ); @@ -700,7 +721,7 @@ phHciNfc_Error_Sequence( case hciState_Config: { /* Notify the Configure failure to the upper layer */ - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; psHciContext->error_status = error_status; status = phHciNfc_Pending_Sequence(psHciContext, pHwRef ); @@ -716,7 +737,7 @@ phHciNfc_Error_Sequence( case hciState_Select: { /* Notify the Configure failure to the upper layer */ - phNfc_sCompletionInfo_t comp_info={0,0,0}; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; /* Rollback the FSM as the Target Discovery Failed */ phHciNfc_FSM_Rollback(psHciContext); @@ -742,7 +763,7 @@ phHciNfc_Error_Sequence( case hciState_Transact: /* Notify the Transceive failure to the upper layer */ { - phNfc_sTransactionInfo_t transact_info; + phNfc_sTransactionInfo_t transact_info={FALSE,0,NULL,NULL,0}; /* Rollback the FSM as the Transceive Failed */ phHciNfc_FSM_Rollback(psHciContext); @@ -759,7 +780,7 @@ phHciNfc_Error_Sequence( case hciState_Connect: { /* Notify the General failure to the upper layer */ - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; /* psHciContext->host_rf_type = phHal_eUnknown_DevType; */ status = phHciNfc_ReaderMgmt_Update_Sequence( @@ -776,7 +797,7 @@ phHciNfc_Error_Sequence( case hciState_Reactivate: { /* Notify the General failure to the upper layer */ - phNfc_sCompletionInfo_t comp_info={FALSE, 0, 0}; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; /* psHciContext->host_rf_type = phHal_eUnknown_DevType; status = phHciNfc_ReaderMgmt_Update_Sequence( @@ -792,7 +813,7 @@ phHciNfc_Error_Sequence( } case hciState_Presence: { - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; /* Roll Back to Connect State as Presence Check is Complete */ phHciNfc_FSM_Rollback(psHciContext); @@ -809,7 +830,7 @@ phHciNfc_Error_Sequence( case hciState_Disconnect: { /* Notify the General failure to the upper layer */ - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; phHciNfc_FSM_Rollback(psHciContext); comp_info.status = error_status ; @@ -823,7 +844,7 @@ phHciNfc_Error_Sequence( #ifdef NXP_HCI_SHUTDOWN_OVERRIDE status = phHciNfc_Release_Sequence(psHciContext ,pHwRef); #else - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; phHciNfc_Release_Lower( psHciContext, pHwRef ); /* Release all the resources and @@ -838,7 +859,7 @@ phHciNfc_Error_Sequence( default: { /* Notify the General failure to the upper layer */ - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; phHciNfc_FSM_Rollback(psHciContext); comp_info.status = error_status ; @@ -859,8 +880,7 @@ phHciNfc_Error_Sequence( else { /* Notify the General failure to the upper layer */ - phNfc_sCompletionInfo_t comp_info; - + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; phHciNfc_FSM_Rollback(psHciContext); comp_info.status = error_status ; /* Disable the Notification to the Upper Layer */ @@ -926,7 +946,7 @@ phHciNfc_Resume_Sequence( case hciState_Select: case hciState_Connect: { - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; /* Update to the Intialise state as the discovery wheel is * restarted. @@ -983,7 +1003,7 @@ phHciNfc_Resume_Sequence( } case hciState_Presence: { - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; /* Roll Back to Connect State as Presence Check is Complete */ phHciNfc_FSM_Rollback(psHciContext); @@ -1102,7 +1122,7 @@ phHciNfc_Initialise_Sequence( } else { -#ifdef ESTABLISH_SESSION +#if defined( ESTABLISH_SESSION ) NFCSTATUS info_status = NFCSTATUS_SUCCESS; PHNFC_UNUSED_VARIABLE(info_status); info_status = phHciNfc_IDMgmt_Update_Sequence( @@ -1110,7 +1130,11 @@ phHciNfc_Initialise_Sequence( if(NFCSTATUS_SUCCESS == info_status) { +#if ( NXP_HAL_MEM_INFO_SIZE > 0x00U ) + psHciContext->hci_seq = DEV_HAL_INFO_SEQ; +#else psHciContext->hci_seq = IDENTITY_INFO_SEQ; +#endif /* #if ( NXP_HAL_MEM_INFO_SIZE > 0x00U ) */ } else { @@ -1118,10 +1142,11 @@ phHciNfc_Initialise_Sequence( status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_SEQUENCE); } +#elif ( NXP_HAL_MEM_INFO_SIZE > 0x00U ) + psHciContext->hci_seq = DEV_HAL_INFO_SEQ; #else psHciContext->hci_seq = HCI_END_SEQ; - -#endif +#endif /* #ifdef ESTABLISH_SESSION */ } } @@ -1158,8 +1183,10 @@ phHciNfc_Initialise_Sequence( status = phHciNfc_EmuMgmt_Initialise( psHciContext,pHwRef ); if(NFCSTATUS_SUCCESS == status) { -#ifdef ESTABLISH_SESSION +#if defined( ESTABLISH_SESSION ) psHciContext->hci_seq = ADMIN_SESSION_SEQ; +#elif ( NXP_HAL_MEM_INFO_SIZE > 0x00U ) + psHciContext->hci_seq = DEV_HAL_INFO_SEQ; #else psHciContext->hci_seq = HCI_END_SEQ; #endif @@ -1172,7 +1199,11 @@ phHciNfc_Initialise_Sequence( status = phHciNfc_Admin_Initialise( psHciContext,pHwRef ); if(NFCSTATUS_SUCCESS == status) { +#if ( NXP_HAL_MEM_INFO_SIZE > 0x00U ) + psHciContext->hci_seq = DEV_HAL_INFO_SEQ; +#else psHciContext->hci_seq = IDENTITY_INFO_SEQ; +#endif /* #if ( NXP_HAL_MEM_INFO_SIZE > 0x00U ) */ } break; } @@ -1182,11 +1213,13 @@ phHciNfc_Initialise_Sequence( psHciContext, pHwRef ); if(NFCSTATUS_SUCCESS == status) { -#ifdef SW_AUTO_ACTIVATION +#if defined( SW_AUTO_ACTIVATION ) psHciContext->hci_seq = READER_SW_AUTO_SEQ; +#elif ( NXP_HAL_MEM_INFO_SIZE > 0x00U ) + psHciContext->hci_seq = DEV_HAL_INFO_SEQ; #else psHciContext->hci_seq = IDENTITY_INFO_SEQ; -#endif +#endif /* #if ( NXP_HAL_MEM_INFO_SIZE > 0x00U ) */ } break; } @@ -1219,7 +1252,8 @@ phHciNfc_Initialise_Sequence( { if ((HCI_SELF_TEST != psHciContext->init_mode) /* && ( TRUE == ((phHal_sHwReference_t *)pHwRef)->se_detect ) */ - && (HCI_CUSTOM_INIT != psHciContext->init_mode)) + && (HCI_CUSTOM_INIT != psHciContext->init_mode) + && (HCI_NFC_DEVICE_TEST != psHciContext->init_mode)) { NFCSTATUS info_status = NFCSTATUS_SUCCESS; PHNFC_UNUSED_VARIABLE(info_status); @@ -1247,10 +1281,42 @@ phHciNfc_Initialise_Sequence( } break; } -#endif +#endif /* #ifdef ESTABLISH_SESSION */ + +#if ( NXP_HAL_MEM_INFO_SIZE > 0x00U ) + case DEV_HAL_INFO_SEQ: + { + static uint8_t mem_index = 0; + status = phHciNfc_DevMgmt_Get_Info(psHciContext, pHwRef, + (NFC_ADDRESS_HAL_CONF + mem_index), + (psHciContext->hal_mem_info + mem_index)); + if(NFCSTATUS_PENDING == status) + { + mem_index++; + if (NXP_HAL_MEM_INFO_SIZE <= mem_index ) + { + NFCSTATUS info_status = NFCSTATUS_SUCCESS; + PHNFC_UNUSED_VARIABLE(info_status); + info_status = phHciNfc_IDMgmt_Update_Sequence( + psHciContext, INFO_SEQ ); + mem_index = 0; + psHciContext->hci_seq = IDENTITY_INFO_SEQ; + /* psHciContext->hci_seq = + (HCI_SELF_TEST != psHciContext->init_mode)? + IDENTITY_INFO_SEQ : HCI_END_SEQ; */ + } + } + break; + } +#endif /* #if ( NXP_HAL_MEM_INFO_SIZE > 0x00U ) */ case HCI_END_SEQ: { - if (HCI_SELF_TEST == psHciContext->init_mode ) + phHal_sMemInfo_t *p_mem_info = + (phHal_sMemInfo_t *) ( psHciContext->hal_mem_info ); + if ( + (HCI_SELF_TEST == psHciContext->init_mode ) + || (HCI_NFC_DEVICE_TEST == psHciContext->init_mode ) + ) { psHciContext->hci_state.next_state = (uint8_t) hciState_Test; @@ -1260,10 +1326,17 @@ phHciNfc_Initialise_Sequence( phHciNfc_Uicc_Connectivity( psHciContext, pHwRef ); #endif /* #ifdef UICC_CONNECTIVITY_PATCH */ +#if ( NXP_HAL_MEM_INFO_SIZE > 0x00U ) + if(NXP_FW_UPLOAD_SUCCESS != p_mem_info->fw_magic ) + { + status = PHNFCSTVAL( CID_NFC_HCI, NFCSTATUS_FAILED ); + } +#endif /* #if ( NXP_HAL_MEM_INFO_SIZE > 0x00U ) */ + /* Initialisation Complete Notification to the Upper Layer */ if(NFCSTATUS_SUCCESS == status) { - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info={FALSE,0, NULL}; comp_info.status = status; phHciNfc_Notify(psHciContext->p_upper_notify, @@ -1333,6 +1406,10 @@ phHciNfc_Release_Sequence( } case DEV_REL_SEQ: { + NFCSTATUS info_status = NFCSTATUS_SUCCESS; + PHNFC_UNUSED_VARIABLE(info_status); + info_status = phHciNfc_DevMgmt_Update_Sequence( + psHciContext, REL_SEQ ); status = phHciNfc_DevMgmt_Release( psHciContext, pHwRef ); if(NFCSTATUS_SUCCESS == status) { @@ -1434,7 +1511,7 @@ phHciNfc_Config_Sequence( ) { NFCSTATUS status = NFCSTATUS_SUCCESS; - phNfc_sCompletionInfo_t comp_info; + phNfc_sCompletionInfo_t comp_info = {FALSE,0,NULL}; switch(psHciContext->config_type) { @@ -1760,7 +1837,7 @@ phHciNfc_EmulationCfg_Sequence( ) { NFCSTATUS status = NFCSTATUS_SUCCESS; - static phNfc_sCompletionInfo_t comp_info; + static phNfc_sCompletionInfo_t comp_info = {FALSE,0,NULL}; #if defined(HOST_EMULATION) phHciNfc_GateID_t ce_gate = phHciNfc_UnknownGate; #endif /* #ifdef HOST_EMULATION */ @@ -1907,8 +1984,7 @@ phHciNfc_SmartMx_Mode_Sequence( NFCSTATUS status = NFCSTATUS_SUCCESS; phHal_sADD_Cfg_t *p_poll_config = (phHal_sADD_Cfg_t * ) psHciContext->p_config_params; - phNfc_sCompletionInfo_t comp_info; - + phNfc_sCompletionInfo_t comp_info = {FALSE,0,NULL}; if (NULL != p_poll_config) { switch(psHciContext->hci_seq) @@ -2014,7 +2090,7 @@ phHciNfc_Connect_Sequence( ) { NFCSTATUS status = NFCSTATUS_SUCCESS; - static phNfc_sCompletionInfo_t comp_info; + static phNfc_sCompletionInfo_t comp_info = {FALSE,0,NULL}; phHal_eRemDevType_t target_type = phHal_eUnknown_DevType; if( NULL != psHciContext->p_target_info ) @@ -2126,7 +2202,7 @@ phHciNfc_Disconnect_Sequence( ) { NFCSTATUS status = NFCSTATUS_SUCCESS; - static phNfc_sCompletionInfo_t comp_info; + static phNfc_sCompletionInfo_t comp_info = {FALSE, 0 , NULL}; phHal_eRemDevType_t target_type = phHal_eUnknown_DevType; uint8_t re_poll = 0; @@ -2210,7 +2286,7 @@ phHciNfc_Transact_Sequence( void *pHwRef ) { - static phNfc_sTransactionInfo_t transact_info; + static phNfc_sTransactionInfo_t transact_info = {FALSE,0,NULL,NULL,0}; pphNfcIF_Notification_CB_t p_upper_notify = psHciContext->p_upper_notify; void *pcontext = psHciContext->p_upper_context; @@ -2357,8 +2433,8 @@ phHciNfc_Test_Sequence( ) { NFCSTATUS status = NFCSTATUS_SUCCESS; - static phNfc_sCompletionInfo_t comp_info; - static phNfc_sData_t test_result; + static phNfc_sCompletionInfo_t comp_info = {0}; + static phNfc_sData_t test_result= {NULL,0}; /* Complete the Test Sequence and notify the HAL */ status = phHciNfc_FSM_Complete ( psHciContext ); @@ -2380,7 +2456,7 @@ phHciNfc_Test_Sequence( phHciNfc_Notify(psHciContext->p_upper_notify, psHciContext->p_upper_context, pHwRef, NFC_NOTIFY_RESULT , &comp_info); - HCI_PRINT(" HCI System Test Completed. \n"); + HCI_DEBUG(" HCI System Test Completed : Status = %u\n", test_status); } else { @@ -2406,7 +2482,7 @@ phHciNfc_IO_Sequence( ) { NFCSTATUS status = NFCSTATUS_SUCCESS; - static phNfc_sCompletionInfo_t comp_info; + static phNfc_sCompletionInfo_t comp_info = {0}; /* To remove "warning (VS 4100) : unreferenced formal parameter" */ PHNFC_UNUSED_VARIABLE(pdata); diff --git a/src/phLibNfc_Ioctl.c b/src/phLibNfc_Ioctl.c index 9983c60..08f34b5 100644 --- a/src/phLibNfc_Ioctl.c +++ b/src/phLibNfc_Ioctl.c @@ -238,8 +238,11 @@ STATIC void phLibNfc_Ioctl_Mgmt_CB(void *context, NFCSTATUS status ) { phLibNfc_Ioctl_Cntx_t *pIoctlCntx=NULL; - - if(PHNFCSTATUS(status)!=NFCSTATUS_SUCCESS) + if(PHNFCSTATUS(status) == NFCSTATUS_FEATURE_NOT_SUPPORTED) + { + status = NFCSTATUS_FEATURE_NOT_SUPPORTED; + } + else if(PHNFCSTATUS(status)!=NFCSTATUS_SUCCESS) { status = NFCSTATUS_FAILED; } |