Upgrade to new stack.

Improve reliability when creating NCI connection for HCP.
Improve firmware download during error condition.

Change-Id: I5655d4a66d04debd4a2a91c706393e8a45d6dc59
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c b/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c
index 58482c5..0d0d15e 100644
--- a/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c
@@ -607,6 +607,9 @@
 
             /* Get chip version string */
             STREAM_TO_UINT8 (u8, p);
+            if (u8 > NFC_HAL_PRM_MAX_CHIP_VER_LEN)
+                u8 = NFC_HAL_PRM_MAX_CHIP_VER_LEN;
+            memcpy (nfc_hal_cb.nvm_cb.chip_ver, p, u8);
             p += NCI_PATCH_INFO_VERSION_LEN;
 
             /* Get major/minor version */
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c b/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
index f8bf1a7..27555b5 100644
--- a/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
@@ -128,6 +128,12 @@
         /* Check if patch is for BCM20791B3 */
         p_src += NCI_SPD_HEADER_OFFSET_CHIPVERLEN;
         STREAM_TO_UINT8 (chipverlen, p_src);
+        if (memcmp (nfc_hal_cb.nvm_cb.chip_ver, p_src, chipverlen) != 0)
+        {
+            HAL_TRACE_ERROR0 ("Unexpected chip ver.");
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+            return;
+        }
         STREAM_TO_ARRAY (chipverstr, p_src, NCI_SPD_HEADER_CHIPVER_LEN);
 
         if (memcmp (NFC_HAL_PRM_BCM20791B3_STR, chipverstr, NFC_HAL_PRM_BCM20791B3_STR_LEN) == 0)
@@ -297,6 +303,7 @@
 void nfc_hal_prm_spd_check_version (void)
 {
     UINT8 *p, *p_start, i;
+    UINT32 nvm_patch_present_mask = 0;
     UINT32 patchfile_patch_present_mask;
     UINT16 patchfile_project_id = 0;
     UINT16 patchfile_ver_major = 0;
@@ -309,6 +316,13 @@
     p = p_start = NULL;
     patchfile_patchsize = 0;
 
+    /* the good patches in NVM */
+    if (nfc_hal_cb.nvm_cb.lpm_size && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_LPM_BAD)))
+        nvm_patch_present_mask  |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_LPM);
+
+    if (nfc_hal_cb.nvm_cb.fpm_size && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_FPM_BAD)))
+        nvm_patch_present_mask  |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_FPM);
+
     /* Get patchfile version */
     if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN)
     {
@@ -358,27 +372,54 @@
         nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start);       /* Adjust size of patchfile                        */
 
 
+        HAL_TRACE_DEBUG4 ("NVM Patch info: flags=0x%04x,   Ver=%i.%i, PatchMask=0x%08x",
+            nfc_hal_cb.nvm_cb.flags, nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor, nvm_patch_present_mask );
         HAL_TRACE_DEBUG6 ("Patchfile info: ProjID=0x%04x,  Ver=%i.%i, Num patches=%i, PatchMask=0x%08x, PatchSize=%i",
                            patchfile_project_id, patchfile_ver_major, patchfile_ver_minor,
                            nfc_hal_cb.prm.spd_patch_count, patchfile_patch_present_mask, patchfile_patchsize);
 
         /*********************************************************************
         * Version check of patchfile against NVM
-        *********************************************************************/
-        if (  (nfc_hal_cb.nvm_cb.ver_major == patchfile_ver_major)
-            &&(nfc_hal_cb.nvm_cb.ver_minor == patchfile_ver_minor)
-            && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_FPM_BAD | NFC_HAL_NVM_FLAGS_LPM_BAD))  )
+        ********************************************************************
+        /* Download the patchfile if no patches in NVM */
+        if ((nfc_hal_cb.nvm_cb.project_id == 0) || !(nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_PATCH_PRESENT))
         {
-            HAL_TRACE_DEBUG0 ("NVM contains the same patch version as in the patch file. Skip");
+            /* No patch in NVM, need to download all */
+            nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
+
+            HAL_TRACE_DEBUG2 ("No previous patch detected. Downloading patch %i.%i",
+                              patchfile_ver_major, patchfile_ver_minor);
+        }
+        /* Skip download if project ID of patchfile does not match NVM */
+        else if (nfc_hal_cb.nvm_cb.project_id != patchfile_project_id)
+        {
+            /* Project IDs mismatch */
+            HAL_TRACE_DEBUG2 ("Patch download skipped: Mismatched Project ID (NVM ProjId: 0x%04x, Patchfile ProjId: 0x%04x)",
+                              nfc_hal_cb.nvm_cb.project_id, patchfile_project_id);
+
+            return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT;
+        }
+        /* Skip download if version of patchfile is equal to version in NVM */
+        /*                  and patches of the power modes are the same as the good patches in NVM */
+        else if (  (nfc_hal_cb.nvm_cb.ver_major == patchfile_ver_major)
+                 &&(nfc_hal_cb.nvm_cb.ver_minor == patchfile_ver_minor)
+                 &&((nvm_patch_present_mask | patchfile_patch_present_mask) == nvm_patch_present_mask)  ) /* if the NVM patch include all the patched in file */
+        {
+            HAL_TRACE_DEBUG2 ("Patch download skipped. NVM patch (version %i.%i) is the same than the patchfile ",
+                              nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
+
             return_code = NFC_HAL_PRM_COMPLETE_EVT;
         }
+        /* Remaining cases: Download all patches in the patchfile */
         else
         {
-            HAL_TRACE_DEBUG5 ("NVM patch version %i.%i. Downloading version %i.%i flags:0x%x",
-                nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor,
-                patchfile_ver_major, patchfile_ver_minor, nfc_hal_cb.nvm_cb.flags);
             nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
+
+            HAL_TRACE_DEBUG4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
+                              patchfile_ver_major, patchfile_ver_minor,
+                              nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
         }
+
     }
     else
     {
diff --git a/src/hal/int/nfc_hal_int.h b/src/hal/int/nfc_hal_int.h
index cf821f3..4f72eff 100644
--- a/src/hal/int/nfc_hal_int.h
+++ b/src/hal/int/nfc_hal_int.h
@@ -296,6 +296,7 @@
 /* Maximum number of patches (currently 2: LPM and FPM) */
 #define NFC_HAL_PRM_MAX_PATCH_COUNT    2
 #define NFC_HAL_PRM_PATCH_MASK_ALL     0xFFFFFFFF
+#define NFC_HAL_PRM_MAX_CHIP_VER_LEN   8
 
 /* Structures for PRM Control Block */
 typedef struct
@@ -341,6 +342,7 @@
     UINT16              lpm_size;               /* Current size of LPM patch in nvm         */
     UINT8               flags;                  /* See NFC_HAL_NVM_FLAGS_* flag definitions */
     UINT8               nvm_type;               /* Current NVM Type - UICC/EEPROM           */
+    UINT8               chip_ver[NFC_HAL_PRM_MAX_CHIP_VER_LEN]; /* patch chip version       */
 } tNFC_HAL_NVM;
 
 /* Patch for I2C fix */
diff --git a/src/nfa/hci/nfa_hci_main.c b/src/nfa/hci/nfa_hci_main.c
index 7188f84..c596426 100644
--- a/src/nfa/hci/nfa_hci_main.c
+++ b/src/nfa/hci/nfa_hci_main.c
@@ -96,12 +96,16 @@
     switch (status)
     {
     case NFA_EE_DISC_STS_ON:
-        /* NFCEE Discovery is in progress */
-        nfa_hci_cb.ee_disc_cmplt      = TRUE;
-        nfa_hci_cb.num_ee_dis_req_ntf = 0;
-        nfa_hci_cb.num_hot_plug_evts  = 0;
-        nfa_hci_cb.conn_id            = 0;
-        nfa_hci_startup ();
+        if (  (!nfa_hci_cb.ee_disc_cmplt)
+            &&((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) || (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE))  )
+        {
+            /* NFCEE Discovery is in progress */
+            nfa_hci_cb.ee_disc_cmplt      = TRUE;
+            nfa_hci_cb.num_ee_dis_req_ntf = 0;
+            nfa_hci_cb.num_hot_plug_evts  = 0;
+            nfa_hci_cb.conn_id            = 0;
+            nfa_hci_startup ();
+        }
         break;
 
     case NFA_EE_DISC_STS_OFF: