Fix fail to write RF parameters

Whenever receive invalid param respons during RF parameter update,
this recovery mechanism includes dummy firmware download
followed by firmware download and then re-update RF parameters.

Bug: 24196800
Change-Id: I8e47a86ff98a9ca8c30be52c231fd284cd825f4d
diff --git a/halimpl/pn54x/common/phNfcStatus.h b/halimpl/pn54x/common/phNfcStatus.h
index fb1d818..5d6c81d 100644
--- a/halimpl/pn54x/common/phNfcStatus.h
+++ b/halimpl/pn54x/common/phNfcStatus.h
@@ -183,6 +183,14 @@
 #define NFCSTATUS_NOT_ALLOWED                                 (0x003A)
 
 /*
+ * FW version error while performing FW download,
+ * FW major version mismatch (cannot downgrade FW major version) or FW version already upto date
+ * User may be trying to flash Mobile FW on top of Infra FW, which is not allowed
+ * Download appropriate version of FW
+ */
+#define NFCSTATUS_FW_VERSION_ERROR                            (0x003C)
+
+/*
  *  The system is busy with the previous operation.
  */
 #define NFCSTATUS_BUSY                                        (0x006F)
diff --git a/halimpl/pn54x/dnld/phDnldNfc.c b/halimpl/pn54x/dnld/phDnldNfc.c
index 512b186..a77f136 100644
--- a/halimpl/pn54x/dnld/phDnldNfc.c
+++ b/halimpl/pn54x/dnld/phDnldNfc.c
@@ -28,6 +28,9 @@
 static void *pFwLibHandle; /* Global firmware lib handle used in this file only */
 uint16_t wMwVer = 0; /* Middleware version no */
 uint16_t wFwVer = 0; /* Firmware version no */
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+uint8_t gRecFWDwnld; // flag set to true to indicate dummy FW download
+#endif
 static pphDnldNfc_DlContext_t gpphDnldContext = NULL; /* Download contex */
 static pphDnldNfc_RspCb_t      UserCb; /* Upper layer call back function */
 static void*                   UserCtxt; /* Pointer to upper layer context */
@@ -869,7 +872,12 @@
     phDnldNfc_SetHwDevHandle();
 
     /* load the library and get the image info pointer */
-    wStatus = phDnldNfc_LoadFW(FW_LIB_PATH, &pImageInfo, &ImageInfoLen);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+    if (gRecFWDwnld == TRUE)
+        wStatus = phDnldNfc_LoadRecoveryFW (FW_LIB_PATH, &pImageInfo, &ImageInfoLen);
+    else
+#endif
+        wStatus = phDnldNfc_LoadFW (FW_LIB_PATH, &pImageInfo, &ImageInfoLen);
 
     NXPLOG_FWDNLD_D("FW Image Length - ImageInfoLen %d",ImageInfoLen);
     NXPLOG_FWDNLD_D("FW Image Info Pointer - pImageInfo %x",(uintptr_t)pImageInfo);
@@ -939,9 +947,12 @@
 
     /* if memory is not allocated then allocate memory for donwload context structure */
     phDnldNfc_SetHwDevHandle();
-
-    wStatus = phDnldNfc_LoadFW(PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen);
-
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+    if (gRecFWDwnld == TRUE)
+        wStatus = phDnldNfc_LoadRecoveryFW (PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen);
+    else
+#endif
+        wStatus = phDnldNfc_LoadFW (PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen);
     if((pImageInfo == NULL) || (ImageInfoLen == 0))
     {
         NXPLOG_FWDNLD_E("Image extraction Failed - invalid imginfo or imginfolen!!");
@@ -997,8 +1008,12 @@
     phDnldNfc_SetHwDevHandle();
 
     /* load the PKU image library */
-    wStatus = phDnldNfc_LoadFW(PKU_LIB_PATH, &pImageInfo, &ImageInfoLen);
-
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+    if (gRecFWDwnld == TRUE)
+        wStatus = phDnldNfc_LoadRecoveryFW (PKU_LIB_PATH, &pImageInfo, &ImageInfoLen);
+    else
+#endif
+        wStatus = phDnldNfc_LoadFW (PKU_LIB_PATH, &pImageInfo, &ImageInfoLen);
     if((pImageInfo == NULL) || (ImageInfoLen == 0))
     {
         NXPLOG_FWDNLD_E("Image extraction Failed - invalid imginfo or imginfolen!!");
@@ -1133,6 +1148,74 @@
     return NFCSTATUS_SUCCESS;
 }
 
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+/*******************************************************************************
+**
+** Function         phDnldNfc_LoadRecoveryFW
+**
+** Description      Load the dummy firmware version form firmware lib for recovery
+**                  This will change the FW version of the NFCC firmware
+**                  and enable flashing of firmware of same version.
+**
+** Parameters       pathName    - Firmware image path
+**                  pImgInfo    - Firmware image handle
+**                  pImgInfoLen - Firmware image length
+**
+** Returns          NFCSTATUS
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_LoadRecoveryFW (const char* pathName, uint8_t **pImgInfo, uint16_t* pImgInfoLen)
+{
+    void* pImageInfo = NULL;
+    void* pImageInfoLen = NULL;
+
+    /* check for path name */
+    if (pathName == NULL)
+    {
+        pathName = "/system/vendor/firmware/libpn548ad_fw.so";
+    }
+
+    /* check if the handle is not NULL then free the library */
+    if (pFwLibHandle != NULL)
+    {
+        phDnldNfc_UnloadFW ();
+        pFwLibHandle = NULL;
+    }
+    /* load the DLL file */
+    pFwLibHandle = dlopen (pathName, RTLD_LAZY);
+    NXPLOG_FWDNLD_D ("phDnldNfc_LoadRecoveryFW %s ", pathName);
+
+    /* if library load failed then handle will be NULL */
+    if (pFwLibHandle == NULL)
+    {
+        NXPLOG_FWDNLD_E("NULL handler : unable to load the library file, specify correct path");
+        return NFCSTATUS_FAILED;
+    }
+
+    dlerror ();    /* Clear any existing error */
+
+    /* load the address of download image pointer and image size */
+    pImageInfo =  (void*)dlsym (pFwLibHandle, "gphDnldNfc_DummyDlSeq");
+
+    if (dlerror() || (NULL == pImageInfo))
+    {
+        NXPLOG_FWDNLD_E ("Problem loading symbol : gphDnldNfc_DummyDlSeq");
+        return NFCSTATUS_FAILED;
+    }
+
+   (*pImgInfo) = (*(uint8_t**)pImageInfo);
+    pImageInfoLen  = (void*)dlsym (pFwLibHandle, "gphDnldNfc_DlSeqDummyFwSz");
+    if (dlerror() ||(NULL == pImageInfoLen))
+    {
+       NXPLOG_FWDNLD_E ("Problem loading symbol : gphDnldNfc_DlSeqDummyFwSz");
+       return NFCSTATUS_FAILED;
+    }
+
+    (*pImgInfoLen) = (uint16_t)(*((uint16_t*)pImageInfoLen));
+
+    return NFCSTATUS_SUCCESS;
+}
+#endif
 
 /*******************************************************************************
 **
diff --git a/halimpl/pn54x/dnld/phDnldNfc.h b/halimpl/pn54x/dnld/phDnldNfc.h
index df95c93..331d39b 100644
--- a/halimpl/pn54x/dnld/phDnldNfc.h
+++ b/halimpl/pn54x/dnld/phDnldNfc.h
@@ -104,5 +104,8 @@
 extern NFCSTATUS phDnldNfc_LoadPKInfo(void);
 extern void phDnldNfc_CloseFwLibHandle(void);
 extern NFCSTATUS phDnldNfc_LoadFW(const char* pathName, uint8_t **pImgInfo, uint16_t* pImgInfoLen);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+extern NFCSTATUS phDnldNfc_LoadRecoveryFW (const char* pathName, uint8_t **pImgInfo, uint16_t* pImgInfoLen);
+#endif
 extern NFCSTATUS phDnldNfc_UnloadFW(void);
 #endif /* PHDNLDNFC_H */
diff --git a/halimpl/pn54x/dnld/phDnldNfc_Internal.c b/halimpl/pn54x/dnld/phDnldNfc_Internal.c
index 628e582..e97dd2f 100644
--- a/halimpl/pn54x/dnld/phDnldNfc_Internal.c
+++ b/halimpl/pn54x/dnld/phDnldNfc_Internal.c
@@ -275,6 +275,8 @@
                         (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessSeqState,
                         (void *)pDlCtxt);
 
+                    /* set read status to pDlCtxt->wCmdSendStatus to enable callback */
+                    pDlCtxt->wCmdSendStatus = wStatus;
                     break;
                 }
                 else
@@ -454,6 +456,8 @@
                         (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessRWSeqState,
                         (void *)pDlCtxt);
 
+                    /* set read status to pDlCtxt->wCmdSendStatus to enable callback */
+                    pDlCtxt->wCmdSendStatus = wStatus;
                     break;
                 }
                 else
@@ -1232,12 +1236,12 @@
             }
             else if(PH_DL_STATUS_FIRMWARE_VERSION_ERROR == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
             {
-                NXPLOG_FWDNLD_E("Firmware Already Up To Date!!");
+                NXPLOG_FWDNLD_E("FW version Error !!!could be either due to FW major version mismatch or Firmware Already Up To Date !!");
                 (pDlContext->tRWInfo.bFirstWrReq) = FALSE;
                 /* resetting wRemBytes to 0 to avoid any further write frames send */
                 (pDlContext->tRWInfo.wRemBytes) = 0;
                 (pDlContext->tRWInfo.wOffset) = 0;
-                wStatus = NFCSTATUS_SUCCESS;
+                wStatus = NFCSTATUS_FW_VERSION_ERROR;
             }
             else if(PH_DL_STATUS_PLL_ERROR == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
             {
diff --git a/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c
index c8acb13..40e7f36 100644
--- a/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c
+++ b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c
@@ -35,7 +35,9 @@
 /* External global variable to get FW version */
 extern uint16_t wFwVer;
 extern uint16_t wMwVer;
-
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+extern uint8_t gRecFWDwnld;
+#endif
 /* RF Configuration structure */
 typedef struct phLibNfc_IoctlSetRfConfig
 {
@@ -179,6 +181,20 @@
     NULL
 };
 
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+/* Array of pointers to start dummy fw download seq */
+static NFCSTATUS (*phNxpNciHal_dummy_rec_dwnld_seqhandler[])(
+        void* pContext, NFCSTATUS status, void* pInfo) = {
+    phNxpNciHal_fw_dnld_normal,
+    phNxpNciHal_fw_dnld_normal,
+    phNxpNciHal_fw_dnld_get_sessn_state,
+    phNxpNciHal_fw_dnld_get_version,
+    phNxpNciHal_fw_dnld_log_read,
+    phNxpNciHal_fw_dnld_write,
+    NULL
+};
+#endif
+
 /* Download Recovery Sequence */
 static NFCSTATUS (*phNxpNciHal_dwnld_rec_seqhandler[])(
         void* pContext, NFCSTATUS status, void* pInfo) = {
@@ -1671,6 +1687,12 @@
         (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE;
         /* Perform the Logging sequence */
         wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_log_seqhandler);
+        if (NFCSTATUS_SUCCESS != gphNxpNciHal_fw_IoctlCtx.bLastStatus)
+        {
+            /* update the previous Download Write status to upper layer and not the status of Log command */
+            wStatus = gphNxpNciHal_fw_IoctlCtx.bLastStatus;
+            NXPLOG_FWDNLD_E ("phNxpNciHal_fw_dnld_complete: Last Download Write Status before Log command bLastStatus = 0x%x", gphNxpNciHal_fw_IoctlCtx.bLastStatus);
+        }
         status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo);
         if (NFCSTATUS_SUCCESS == status)
         {
@@ -1680,7 +1702,6 @@
         {
             NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
         }
-
     }
     else if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery))
     {
@@ -1727,6 +1748,7 @@
     }
     else
     {
+        NXPLOG_FWDNLD_D ("phNxpNciHal_fw_dnld_complete: Download Status = 0x%x", status);
         if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq))
         {
             if(NFCSTATUS_SUCCESS == status)
@@ -1854,7 +1876,16 @@
     if (NFCSTATUS_SUCCESS == phDnldNfc_InitImgInfo())
     {
         NXPLOG_FWDNLD_D("phDnldNfc_InitImgInfo:SUCCESS");
-        status = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+        if (gRecFWDwnld == TRUE)
+        {
+            status = phNxpNciHal_fw_seq_handler (phNxpNciHal_dummy_rec_dwnld_seqhandler);
+        }
+        else
+#endif
+        {
+            status = phNxpNciHal_fw_seq_handler (phNxpNciHal_dwnld_seqhandler);
+        }
     }
     else
     {
diff --git a/halimpl/pn54x/hal/phNxpNciHal.c b/halimpl/pn54x/hal/phNxpNciHal.c
index eb928a1..55e72ec 100644
--- a/halimpl/pn54x/hal/phNxpNciHal.c
+++ b/halimpl/pn54x/hal/phNxpNciHal.c
@@ -55,6 +55,10 @@
 extern int send_to_upper_kovio;
 extern int kovio_detected;
 extern int disable_kovio;
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+extern uint8_t gRecFWDwnld;
+static uint8_t gRecFwRetryCount; //variable to hold dummy FW recovery count
+#endif
 static uint8_t Rx_data[NCI_MAX_DATA_LEN];
 uint8_t discovery_cmd[50] = { 0 };
 uint8_t discovery_cmd_len = 0;
@@ -90,6 +94,10 @@
 static NFCSTATUS phNxpNciHal_set_mw_eeprom (void);
 NFCSTATUS phNxpNciHal_check_clock_config(void);
 NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+static NFCSTATUS phNxpNciHalRFConfigCmdRecSequence ();
+static NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus ();
+#endif
 int  check_config_parameter();
 
 /******************************************************************************
@@ -332,6 +340,12 @@
             NXPLOG_NCIHAL_D("Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE not defiend)");
         }
     }
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+    else if (gRecFWDwnld == TRUE)
+    {
+        status = NFCSTATUS_SUCCESS;
+    }
+#endif
     else if (wFwVerRsp == 0)
     {
         NXPLOG_NCIHAL_E("FW Version not received by NCI command >>> Force Firmware download");
@@ -966,6 +980,9 @@
      int temp_fix = 1;
 #if(NFC_NXP_CHIP_TYPE == PN548C2)
     unsigned long num = 0;
+    //initialize dummy FW recovery variables
+    gRecFwRetryCount = 0;
+    gRecFWDwnld = 0;
 #endif
     // recovery --start
     /*NCI_INIT_CMD*/
@@ -980,7 +997,10 @@
 retry_core_init:
         config_access = FALSE;
         if(buffer != NULL)
+        {
             free(buffer);
+            buffer = NULL;
+        }
         if(retry_core_init_cnt > 3)
         {
             return NFCSTATUS_FAILED;
@@ -1171,11 +1191,28 @@
         }
 #endif
         retlen = 0;
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+        config_access = FALSE;
+#endif
         NXPLOG_NCIHAL_D ("Performing RF Settings BLK 1");
         isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_1, (char *) buffer,
                 bufflen, &retlen);
         if (retlen > 0) {
             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+            if (status == NFCSTATUS_SUCCESS)
+            {
+                status = phNxpNciHal_CheckRFCmdRespStatus ();
+                /*STATUS INVALID PARAM 0x09*/
+                if (status == 0x09)
+                {
+                    phNxpNciHalRFConfigCmdRecSequence ();
+                    retry_core_init_cnt++;
+                    goto retry_core_init;
+                }
+            }
+            else
+#endif
             if (status != NFCSTATUS_SUCCESS) {
                 NXPLOG_NCIHAL_E("RF Settings BLK 1 failed");
                 retry_core_init_cnt++;
@@ -1189,6 +1226,20 @@
                 bufflen, &retlen);
         if (retlen > 0) {
             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+            if (status == NFCSTATUS_SUCCESS)
+            {
+                status = phNxpNciHal_CheckRFCmdRespStatus ();
+                /*STATUS INVALID PARAM 0x09*/
+                if (status == 0x09)
+                {
+                    phNxpNciHalRFConfigCmdRecSequence ();
+                    retry_core_init_cnt++;
+                    goto retry_core_init;
+                }
+            }
+            else
+#endif
             if (status != NFCSTATUS_SUCCESS) {
                 NXPLOG_NCIHAL_E("RF Settings BLK 2 failed");
                 retry_core_init_cnt++;
@@ -1202,6 +1253,20 @@
                 bufflen, &retlen);
         if (retlen > 0) {
             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+            if (status == NFCSTATUS_SUCCESS)
+            {
+                status = phNxpNciHal_CheckRFCmdRespStatus ();
+                /*STATUS INVALID PARAM 0x09*/
+                if (status == 0x09)
+                {
+                    phNxpNciHalRFConfigCmdRecSequence ();
+                    retry_core_init_cnt++;
+                    goto retry_core_init;
+                }
+            }
+            else
+#endif
             if (status != NFCSTATUS_SUCCESS) {
                 NXPLOG_NCIHAL_E("RF Settings BLK 3 failed");
                 retry_core_init_cnt++;
@@ -1215,6 +1280,20 @@
                 bufflen, &retlen);
         if (retlen > 0) {
             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+            if (status == NFCSTATUS_SUCCESS)
+            {
+                status = phNxpNciHal_CheckRFCmdRespStatus ();
+                /*STATUS INVALID PARAM 0x09*/
+                if (status == 0x09)
+                {
+                    phNxpNciHalRFConfigCmdRecSequence ();
+                    retry_core_init_cnt++;
+                    goto retry_core_init;
+                }
+            }
+            else
+#endif
             if (status != NFCSTATUS_SUCCESS) {
                 NXPLOG_NCIHAL_E("RF Settings BLK 4 failed");
                 retry_core_init_cnt++;
@@ -1228,6 +1307,20 @@
                 bufflen, &retlen);
         if (retlen > 0) {
             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+            if (status == NFCSTATUS_SUCCESS)
+            {
+                status = phNxpNciHal_CheckRFCmdRespStatus ();
+                /*STATUS INVALID PARAM 0x09*/
+                if (status == 0x09)
+                {
+                    phNxpNciHalRFConfigCmdRecSequence ();
+                    retry_core_init_cnt++;
+                    goto retry_core_init;
+                }
+            }
+            else
+#endif
             if (status != NFCSTATUS_SUCCESS) {
                 NXPLOG_NCIHAL_E("RF Settings BLK 5 failed");
                 retry_core_init_cnt++;
@@ -1241,6 +1334,20 @@
                 bufflen, &retlen);
         if (retlen > 0) {
             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+            if (status == NFCSTATUS_SUCCESS)
+            {
+                status = phNxpNciHal_CheckRFCmdRespStatus ();
+                /*STATUS INVALID PARAM 0x09*/
+                if (status == 0x09)
+                {
+                    phNxpNciHalRFConfigCmdRecSequence ();
+                    retry_core_init_cnt++;
+                    goto retry_core_init;
+                }
+            }
+            else
+#endif
             if (status != NFCSTATUS_SUCCESS) {
                 NXPLOG_NCIHAL_E("RF Settings BLK 6 failed");
                 retry_core_init_cnt++;
@@ -1248,7 +1355,9 @@
             }
         }
         retlen = 0;
-
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+        config_access = TRUE;
+#endif
         NXPLOG_NCIHAL_D ("Performing NAME_NXP_CORE_CONF_EXTN Settings");
         isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF_EXTN,
                 (char *) buffer, bufflen, &retlen);
@@ -1277,18 +1386,37 @@
         }
 
         retlen = 0;
-
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+        config_access = FALSE;
+#endif
         isfound = GetNxpByteArrayValue(NAME_NXP_CORE_RF_FIELD,
                 (char *) buffer, bufflen, &retlen);
         if (retlen > 0) {
             /* NXP ACT Proprietary Ext */
             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+            if (status == NFCSTATUS_SUCCESS)
+            {
+                status = phNxpNciHal_CheckRFCmdRespStatus ();
+                /*STATUS INVALID PARAM 0x09*/
+                if (status == 0x09)
+                {
+                    phNxpNciHalRFConfigCmdRecSequence ();
+                    retry_core_init_cnt++;
+                    goto retry_core_init;
+                }
+            }
+            else
+#endif
             if (status != NFCSTATUS_SUCCESS) {
                 NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
                 retry_core_init_cnt++;
                 goto retry_core_init;
             }
         }
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+        config_access = TRUE;
+#endif
 #if(NFC_NXP_CHIP_TYPE != PN547C2)
         retlen = 0;
 
@@ -1563,8 +1691,13 @@
     if(buffer)
     {
         free(buffer);
+        buffer = NULL;
     }
-
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+    //initialize dummy FW recovery variables
+    gRecFWDwnld = 0;
+    gRecFwRetryCount = 0;
+#endif
     if(!((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)))
         phNxpNciHal_core_initialized_complete(status);
     else
@@ -1588,7 +1721,96 @@
 #endif
     return NFCSTATUS_SUCCESS;
 }
-
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+/******************************************************************************
+ * Function         phNxpNciHal_CheckRFCmdRespStatus
+ *
+ * Description      This function is called to check the resp status of
+ *                  RF update commands.
+ *
+ * Returns          NFCSTATUS_SUCCESS           if successful,
+ *                  NFCSTATUS_INVALID_PARAMETER if parameter is inavlid
+ *                  NFCSTATUS_FAILED            if failed response
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus ()
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    static uint16_t INVALID_PARAM = 0x09;
+    if ((nxpncihal_ctrl.rx_data_len > 0) && (nxpncihal_ctrl.p_rx_data[2] > 0))
+    {
+        if (nxpncihal_ctrl.p_rx_data[3] == 0x09)
+        {
+            status = INVALID_PARAM;
+        }
+        else if (nxpncihal_ctrl.p_rx_data[3] != NFCSTATUS_SUCCESS)
+        {
+            status = NFCSTATUS_FAILED;
+        }
+    }
+    return status;
+}
+/******************************************************************************
+ * Function         phNxpNciHalRFConfigCmdRecSequence
+ *
+ * Description      This function is called to handle dummy FW recovery sequence
+ *                  Whenever RF settings are failed to apply with invalid param
+ *                  response, recovery mechanism includes dummy firmware download
+ *                  followed by firmware download and then config settings. The dummy
+ *                  firmware changes the major number of the firmware inside NFCC.
+ *                  Then actual firmware dowenload will be successful. This can be
+ *                  retried maximum three times.
+ *
+ * Returns          Always returns NFCSTATUS_SUCCESS
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHalRFConfigCmdRecSequence ()
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    uint16_t recFWState = 1;
+    gRecFWDwnld = TRUE;
+    gRecFwRetryCount++;
+    if (gRecFwRetryCount > 0x03)
+    {
+        NXPLOG_NCIHAL_D ("Max retry count for RF config FW recovery exceeded ");
+        gRecFWDwnld = FALSE;
+        return NFCSTATUS_FAILED;
+    }
+    do {
+        status = phTmlNfc_IoCtl (phTmlNfc_e_ResetDevice);
+        phDnldNfc_InitImgInfo ();
+        if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion ())
+        {
+            fw_download_success = 0;
+            status = phNxpNciHal_fw_download ();
+            if (status == NFCSTATUS_SUCCESS)
+            {
+                fw_download_success = 1;
+                status = phTmlNfc_Read(
+                    nxpncihal_ctrl.p_cmd_data,
+                    NCI_MAX_DATA_LEN,
+                    (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
+                    NULL);
+                if (status != NFCSTATUS_PENDING)
+                {
+                    NXPLOG_NCIHAL_E ("TML Read status error status = %x", status);
+                    phTmlNfc_Shutdown ();
+                    status = NFCSTATUS_FAILED;
+                    break;
+                }
+            }
+            else
+            {
+                status = NFCSTATUS_FAILED;
+                break;
+            }
+        }
+        gRecFWDwnld = FALSE;
+    }while (recFWState--);
+    gRecFWDwnld = FALSE;
+    return status;
+}
+#endif
 /******************************************************************************
  * Function         phNxpNciHal_core_initialized_complete
  *