summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Chaisson <chaisson@broadcom.com>2014-04-23 16:30:37 -0400
committerMartijn Coenen <maco@google.com>2014-06-26 09:26:26 -0700
commitf937782dff072eeea70c04db97bdc76d8b6ef9f2 (patch)
treecf7a3d10367f6c438bc2e236db38455d959f9c6f
parente09fd9c5ce2c1eaef0831d8699a01404bea14894 (diff)
downloadlibnfc-nci-f937782dff072eeea70c04db97bdc76d8b6ef9f2.tar.gz
Add 20795A1 work-around for EEPROM issue
Erase personality data EEPROM as work around, if no patch in NVM and chip id is 20795A1. Change-Id: Ia5b0d305c5e1ba567abe07c4bb00c36f8277c9b0
-rw-r--r--halimpl/bcm2079x/hal/hal/nfc_hal_prm.c146
-rw-r--r--src/hal/int/nfc_brcm_defs.h2
-rw-r--r--src/hal/int/nfc_hal_int.h2
3 files changed, 134 insertions, 16 deletions
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c b/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
index 7c22a79..d1b739c 100644
--- a/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
@@ -30,6 +30,7 @@
#define NFC_HAL_PRM_FLAGS_SIGNATURE_SENT 0x04 /* Signature sent to NFCC */
#define NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED 0x08 /* PreI2C patch required */
#define NFC_HAL_PRM_FLAGS_BCM20791B3 0x10 /* B3 Patch (no RESET_NTF after patch download) */
+#define NFC_HAL_PRM_FLAGS_RM_RF 0x20 /* Erase Personality data */
/* Secure patch download definitions */
#define NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN 7 /* PRJID + MAJORVER + MINORVER + COUNT */
@@ -52,6 +53,20 @@ const UINT8 NFC_HAL_PRM_BCM20791B3_STR[] = "20791B3";
#endif
void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status);
+typedef struct
+{
+ UINT16 offset;
+ UINT8 len;
+} tNFC_HAL_PRM_RM_RF;
+
+const tNFC_HAL_PRM_RM_RF nfc_hal_prm_rm_rf_20795a1 [] =
+{
+ {0x0000, 0xFB},
+ {0x019C, 0x08},
+ {0x05E8, 0xFB},
+ {0, 0}
+};
+static BOOLEAN nfc_hal_prm_nvm_rw_cmd(void);
/*****************************************************************************
** Extern variable from nfc_hal_dm_cfg.c
@@ -293,6 +308,51 @@ void nfc_hal_prm_spd_download_i2c_fix (void)
/*******************************************************************************
**
+** Function nfc_hal_prm_spd_check_version_continue
+**
+** Description Check patchfile version with current downloaded version
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfc_hal_prm_spd_check_version_continue (void)
+{
+ HAL_TRACE_DEBUG1 ("nfc_hal_prm_spd_check_version_continue 0x%02x", nfc_hal_cb.prm.flags);
+ if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_RM_RF)
+ {
+ HAL_TRACE_DEBUG0("erase relevant blocks in NVM");
+ nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_RM_RF;
+ if (!nfc_hal_prm_nvm_rw_cmd())
+ {
+ /* nvm rw started successfully */
+ return;
+ }
+ }
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+ if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED)
+ {
+ HAL_TRACE_DEBUG0 ("I2C patch fix required.");
+ /* Download i2c fix first */
+ nfc_hal_prm_spd_download_i2c_fix ();
+ return;
+ }
+#endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+
+ /* Download first segment */
+ nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
+ if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF))
+ {
+ /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch segment */
+ (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
+ }
+ else
+ {
+ nfc_hal_prm_spd_handle_next_patch_start ();
+ }
+}
+
+/*******************************************************************************
+**
** Function nfc_hal_prm_spd_check_version
**
** Description Check patchfile version with current downloaded version
@@ -386,6 +446,12 @@ void nfc_hal_prm_spd_check_version (void)
{
/* No patch in NVM, need to download all */
nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
+ if (nfc_hal_cb.dev_cb.brcm_hw_id == BRCM_20795A1_ID)
+ {
+ nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_RM_RF;
+ nfc_hal_cb.prm.p_param = (void *)nfc_hal_prm_rm_rf_20795a1;
+ nfc_hal_cb.prm.param_idx = 0;
+ }
HAL_TRACE_DEBUG2 ("No previous patch detected. Downloading patch %i.%i",
patchfile_ver_major, patchfile_ver_minor);
@@ -451,24 +517,9 @@ void nfc_hal_prm_spd_check_version (void)
{
HAL_TRACE_DEBUG0 ("I2C patch fix required.");
nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED;
-
- /* Download i2c fix first */
- nfc_hal_prm_spd_download_i2c_fix ();
- return;
}
#endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
-
- /* Download first segment */
- nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
- if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF))
- {
- /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch segment */
- (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
- }
- else
- {
- nfc_hal_prm_spd_handle_next_patch_start ();
- }
+ nfc_hal_prm_spd_check_version_continue ();
}
else
{
@@ -549,6 +600,53 @@ UINT8 *nfc_hal_prm_spd_status_str (UINT8 spd_status_code)
return ((UINT8*) p_str);
}
#endif /* (NFC_HAL_TRACE_VERBOSE == TRUE) */
+/*******************************************************************************
+**
+** Function nfc_hal_prm_nvm_rw_cmd
+**
+** Description Non Volatile Read Write Command; for now only write zeros
+**
+** Returns TRUE if done.
+**
+*******************************************************************************/
+static BOOLEAN nfc_hal_prm_nvm_rw_cmd(void)
+{
+ tNFC_HAL_PRM_RM_RF *p_param = (tNFC_HAL_PRM_RM_RF *)(nfc_hal_cb.prm.p_param);
+ UINT8 *p_buff, *p, *p_end;
+ UINT8 len = 0;
+ UINT16 cmd_len;
+
+ if (p_param)
+ len = p_param[nfc_hal_cb.prm.param_idx].len;
+ HAL_TRACE_DEBUG2 ("nfc_hal_prm_nvm_rw_cmd: %d/%d", nfc_hal_cb.prm.param_idx, len);
+ if (len == 0)
+ {
+ return TRUE;
+ }
+ cmd_len = len + 7;
+
+ if ((p_buff = (UINT8 *) GKI_getbuf(cmd_len)) == NULL)
+ {
+ HAL_TRACE_ERROR0 ("NVM No buffer");
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+ return TRUE;
+ }
+
+ p = p_buff;
+
+ UINT8_TO_STREAM (p, (NCI_MTS_CMD|NCI_GID_PROP));
+ UINT8_TO_STREAM (p, NCI_MSG_EEPROM_RW);
+ UINT8_TO_STREAM (p, (len+4));
+ UINT8_TO_STREAM (p, 1); /* 1=write 0=read */
+ UINT16_TO_STREAM (p, p_param[nfc_hal_cb.prm.param_idx].offset);
+ UINT8_TO_STREAM (p, len);
+ memset (p, 0, len); /* Fill remaining bytes with zeros*/
+
+ nfc_hal_cb.prm.param_idx++;
+ nfc_hal_dm_send_nci_cmd(p_buff, cmd_len, nfc_hal_prm_nci_command_complete_cback);
+ GKI_freebuf (p_buff);
+ return FALSE;
+}
/*******************************************************************************
**
@@ -695,6 +793,22 @@ void nfc_hal_prm_nci_command_complete_cback (tNFC_HAL_NCI_EVT event, UINT16 data
{
nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
}
+ else if (event == NFC_VS_EEPROM_RW_EVT)
+ {
+ STREAM_TO_UINT8 (status, p);
+ if (status == NCI_STATUS_OK)
+ {
+ if (nfc_hal_prm_nvm_rw_cmd ())
+ {
+ nfc_hal_prm_spd_check_version_continue ();
+ }
+ }
+ else
+ {
+ HAL_TRACE_ERROR0 ("NVM failed");
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+ }
+ }
else
{
/* Invalid response from NFCC during patch download */
diff --git a/src/hal/int/nfc_brcm_defs.h b/src/hal/int/nfc_brcm_defs.h
index 9f8a7e6..6e8670a 100644
--- a/src/hal/int/nfc_brcm_defs.h
+++ b/src/hal/int/nfc_brcm_defs.h
@@ -36,6 +36,7 @@
#define BRCM_43341B0_ID 0x43341b00
#define BRCM_20795T1_ID 0x20795a01
#define BRCM_20795A0_ID 0x20795a00
+#define BRCM_20795A1_ID 0x20795a10
#define BRCM_NFC_GEN_MASK 0xFFFFF000 /* HW generation mask */
#define BRCM_NFC_REV_MASK 0x00000FFF /* HW revision mask */
@@ -141,6 +142,7 @@
#define NFC_VS_GET_PATCH_VERSION_EVT (NCI_RSP_BIT|NCI_MSG_GET_PATCH_VERSION)
#define NFC_VS_SEC_PATCH_DOWNLOAD_EVT (NCI_RSP_BIT|NCI_MSG_SECURE_PATCH_DOWNLOAD)
#define NFC_VS_SEC_PATCH_AUTH_EVT (NCI_NTF_BIT|NCI_MSG_SECURE_PATCH_DOWNLOAD)
+#define NFC_VS_EEPROM_RW_EVT (NCI_RSP_BIT|NCI_MSG_EEPROM_RW)
#define NCI_GET_PATCH_VERSION_NVM_OFFSET 37
diff --git a/src/hal/int/nfc_hal_int.h b/src/hal/int/nfc_hal_int.h
index 3eabf77..05e51b0 100644
--- a/src/hal/int/nfc_hal_int.h
+++ b/src/hal/int/nfc_hal_int.h
@@ -312,6 +312,8 @@ typedef struct
UINT16 cur_patch_offset; /* offset of next byte to process */
UINT32 dest_ram;
TIMER_LIST_ENT timer; /* Timer for patch download */
+ void *p_param; /* general purpose param for PRM */
+ UINT8 param_idx; /* information related to general purpose param*/
/* Secure Patch Download */
UINT32 spd_patch_needed_mask; /* Mask of patches that need to be downloaded */