1 /*
2  * Copyright (C) 2012-2014 NXP Semiconductors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <sys/stat.h>
18 #include <phNxpNciHal.h>
19 #include <phNxpNciHal_ext.h>
20 #include <phNxpNciHal_Dnld.h>
21 #include <phNxpNciHal_Adaptation.h>
22 #include <phTmlNfc.h>
23 #include <phDnldNfc.h>
24 #include <phDal4Nfc_messageQueueLib.h>
25 #include <phNxpLog.h>
26 #include <phNxpConfig.h>
27 #include <phNxpNciHal_NfcDepSWPrio.h>
28 #include <phNxpNciHal_Kovio.h>
29 /*********************** Global Variables *************************************/
30 #define PN547C2_CLOCK_SETTING
31 #undef  PN547C2_FACTORY_RESET_DEBUG
32 #define CORE_RES_STATUS_BYTE 3
33 
34 /* Processing of ISO 15693 EOF */
35 extern uint8_t icode_send_eof;
36 static uint8_t cmd_icode_eof[] = { 0x00, 0x00, 0x00 };
37 
38 /* FW download success flag */
39 static uint8_t fw_download_success = 0;
40 
41 static uint8_t config_access = FALSE;
42 /* NCI HAL Control structure */
43 phNxpNciHal_Control_t nxpncihal_ctrl;
44 
45 /* NXP Poll Profile structure */
46 phNxpNciProfile_Control_t nxpprofile_ctrl;
47 
48 /* TML Context */
49 extern phTmlNfc_Context_t *gpphTmlNfc_Context;
50 extern void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result);
51 /* global variable to get FW version from NCI response*/
52 uint32_t wFwVerRsp;
53 /* External global variable to get FW version */
54 extern uint16_t wFwVer;
55 extern int send_to_upper_kovio;
56 extern int kovio_detected;
57 extern int disable_kovio;
58 #if(NFC_NXP_CHIP_TYPE == PN548C2)
59 extern uint8_t gRecFWDwnld;
60 static uint8_t gRecFwRetryCount; //variable to hold dummy FW recovery count
61 #endif
62 static uint8_t Rx_data[NCI_MAX_DATA_LEN];
63 uint8_t discovery_cmd[50] = { 0 };
64 uint8_t discovery_cmd_len = 0;
65 extern bool_t rf_deactive_cmd;
66 
67 uint32_t timeoutTimerId = 0;
68 phNxpNciHal_Sem_t config_data;
69 
70 phNxpNciClock_t phNxpNciClock={0,};
71 
72 phNxpNciRfSetting_t phNxpNciRfSet={0,};
73 
74 phNxpNciMwEepromArea_t phNxpNciMwEepromArea = {0};
75 
76 /**************** local methods used in this file only ************************/
77 static NFCSTATUS phNxpNciHal_fw_download(void);
78 static void phNxpNciHal_open_complete(NFCSTATUS status);
79 static void phNxpNciHal_write_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
80 static void phNxpNciHal_read_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
81 static void phNxpNciHal_close_complete(NFCSTATUS status);
82 static void phNxpNciHal_core_initialized_complete(NFCSTATUS status);
83 static void phNxpNciHal_pre_discover_complete(NFCSTATUS status);
84 static void phNxpNciHal_power_cycle_complete(NFCSTATUS status);
85 static void phNxpNciHal_kill_client_thread(phNxpNciHal_Control_t *p_nxpncihal_ctrl);
86 static void *phNxpNciHal_client_thread(void *arg);
87 static void phNxpNciHal_get_clk_freq(void);
88 static void phNxpNciHal_set_clock(void);
89 static void phNxpNciHal_check_factory_reset(void);
90 static void phNxpNciHal_print_res_status( uint8_t *p_rx_data, uint16_t *p_len);
91 static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void);
92 static void phNxpNciHal_enable_i2c_fragmentation();
93 static NFCSTATUS phNxpNciHal_get_mw_eeprom (void);
94 static NFCSTATUS phNxpNciHal_set_mw_eeprom (void);
95 NFCSTATUS phNxpNciHal_check_clock_config(void);
96 NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void);
97 #if(NFC_NXP_CHIP_TYPE == PN548C2)
98 static NFCSTATUS phNxpNciHalRFConfigCmdRecSequence ();
99 static NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus ();
100 #endif
101 int  check_config_parameter();
102 
103 /******************************************************************************
104  * Function         phNxpNciHal_client_thread
105  *
106  * Description      This function is a thread handler which handles all TML and
107  *                  NCI messages.
108  *
109  * Returns          void
110  *
111  ******************************************************************************/
phNxpNciHal_client_thread(void * arg)112 static void *phNxpNciHal_client_thread(void *arg)
113 {
114     phNxpNciHal_Control_t *p_nxpncihal_ctrl = (phNxpNciHal_Control_t *) arg;
115     phLibNfc_Message_t msg;
116 
117     NXPLOG_NCIHAL_D("thread started");
118 
119     p_nxpncihal_ctrl->thread_running = 1;
120 
121     while (p_nxpncihal_ctrl->thread_running == 1)
122     {
123         /* Fetch next message from the NFC stack message queue */
124         if (phDal4Nfc_msgrcv(p_nxpncihal_ctrl->gDrvCfg.nClientId,
125                 &msg, 0, 0) == -1)
126         {
127             NXPLOG_NCIHAL_E("NFC client received bad message");
128             continue;
129         }
130 
131         if(p_nxpncihal_ctrl->thread_running == 0){
132             break;
133         }
134 
135         switch (msg.eMsgType)
136         {
137             case PH_LIBNFC_DEFERREDCALL_MSG:
138             {
139                 phLibNfc_DeferredCall_t *deferCall =
140                         (phLibNfc_DeferredCall_t *) (msg.pMsgData);
141 
142                 REENTRANCE_LOCK();
143                 deferCall->pCallback(deferCall->pParameter);
144                 REENTRANCE_UNLOCK();
145 
146             break;
147         }
148 
149         case NCI_HAL_OPEN_CPLT_MSG:
150         {
151             REENTRANCE_LOCK();
152             if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
153             {
154                 /* Send the event */
155                 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT,
156                         HAL_NFC_STATUS_OK);
157             }
158             REENTRANCE_UNLOCK();
159             break;
160         }
161 
162         case NCI_HAL_CLOSE_CPLT_MSG:
163         {
164             REENTRANCE_LOCK();
165             if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
166             {
167                 /* Send the event */
168                 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_CLOSE_CPLT_EVT,
169                         HAL_NFC_STATUS_OK);
170                 phNxpNciHal_kill_client_thread(&nxpncihal_ctrl);
171             }
172             REENTRANCE_UNLOCK();
173             break;
174         }
175 
176         case NCI_HAL_POST_INIT_CPLT_MSG:
177         {
178             REENTRANCE_LOCK();
179             if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
180             {
181                 /* Send the event */
182                 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_POST_INIT_CPLT_EVT,
183                         HAL_NFC_STATUS_OK);
184             }
185             REENTRANCE_UNLOCK();
186             break;
187         }
188 
189         case NCI_HAL_PRE_DISCOVER_CPLT_MSG:
190         {
191             REENTRANCE_LOCK();
192             if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
193             {
194                 /* Send the event */
195                 (*nxpncihal_ctrl.p_nfc_stack_cback)(
196                         HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_OK);
197             }
198             REENTRANCE_UNLOCK();
199             break;
200         }
201 
202         case NCI_HAL_ERROR_MSG:
203         {
204             REENTRANCE_LOCK();
205             if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
206             {
207                 /* Send the event */
208                 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ERROR_EVT,
209                         HAL_NFC_STATUS_FAILED);
210             }
211             REENTRANCE_UNLOCK();
212             break;
213         }
214 
215         case NCI_HAL_RX_MSG:
216         {
217             REENTRANCE_LOCK();
218             if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL)
219             {
220                 (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
221                         nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
222             }
223             REENTRANCE_UNLOCK();
224             break;
225         }
226         }
227     }
228 
229     NXPLOG_NCIHAL_D("NxpNciHal thread stopped");
230 
231     return NULL;
232 }
233 
234 /******************************************************************************
235  * Function         phNxpNciHal_kill_client_thread
236  *
237  * Description      This function safely kill the client thread and clean all
238  *                  resources.
239  *
240  * Returns          void.
241  *
242  ******************************************************************************/
phNxpNciHal_kill_client_thread(phNxpNciHal_Control_t * p_nxpncihal_ctrl)243 static void phNxpNciHal_kill_client_thread(phNxpNciHal_Control_t *p_nxpncihal_ctrl)
244 {
245     NXPLOG_NCIHAL_D("Terminating phNxpNciHal client thread...");
246 
247     p_nxpncihal_ctrl->p_nfc_stack_cback = NULL;
248     p_nxpncihal_ctrl->p_nfc_stack_data_cback = NULL;
249     p_nxpncihal_ctrl->thread_running = 0;
250 
251     return;
252 }
253 
254 /******************************************************************************
255  * Function         phNxpNciHal_fw_download
256  *
257  * Description      This function download the PN54X secure firmware to IC. If
258  *                  firmware version in Android filesystem and firmware in the
259  *                  IC is same then firmware download will return with success
260  *                  without downloading the firmware.
261  *
262  * Returns          NFCSTATUS_SUCCESS if firmware download successful
263  *                  NFCSTATUS_FAILED in case of failure
264  *
265  ******************************************************************************/
phNxpNciHal_fw_download(void)266 static NFCSTATUS phNxpNciHal_fw_download(void)
267 {
268     NFCSTATUS status = NFCSTATUS_FAILED;
269 
270     phNxpNciHal_get_clk_freq();
271     status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
272     if (NFCSTATUS_SUCCESS == status)
273     {
274         /* Set the obtained device handle to download module */
275         phDnldNfc_SetHwDevHandle();
276         NXPLOG_NCIHAL_D("Calling Seq handler for FW Download \n");
277         status = phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal, nxpprofile_ctrl.bClkFreqVal);
278         phDnldNfc_ReSetHwDevHandle();
279     }
280     else
281     {
282         status = NFCSTATUS_FAILED;
283     }
284 
285     return status;
286 }
287 
288 /******************************************************************************
289  * Function         phNxpNciHal_CheckValidFwVersion
290  *
291  * Description      This function checks the valid FW for Mobile device.
292  *                  If the FW doesn't belong the Mobile device it further
293  *                  checks nxp config file to override.
294  *
295  * Returns          NFCSTATUS_SUCCESS if valid fw version found
296  *                  NFCSTATUS_NOT_ALLOWED in case of FW not valid for mobile
297  *                  device
298  *
299  ******************************************************************************/
phNxpNciHal_CheckValidFwVersion(void)300 static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void)
301 {
302     NFCSTATUS status = NFCSTATUS_NOT_ALLOWED;
303     const unsigned char sfw_mobile_major_no = 0x01;
304     const unsigned char sfw_infra_major_no = 0x02;
305     unsigned char ufw_current_major_no = 0x00;
306     unsigned long num = 0;
307     int isfound = 0;
308 
309     /* extract the firmware's major no */
310     ufw_current_major_no = ((0x00FF) & (wFwVer >> 8U));
311 
312     NXPLOG_NCIHAL_D("%s current_major_no = 0x%x", __FUNCTION__,ufw_current_major_no );
313     if ( ufw_current_major_no == sfw_mobile_major_no)
314     {
315         status = NFCSTATUS_SUCCESS;
316     }
317     else if (ufw_current_major_no == sfw_infra_major_no)
318     {
319         /* Check the nxp config file if still want to go for download */
320         /* By default NAME_NXP_FW_PROTECION_OVERRIDE will not be defined in config file.
321            If user really want to override the Infra firmware over mobile firmware, please
322            put "NXP_FW_PROTECION_OVERRIDE=0x01" in libnfc-nxp.conf file.
323            Please note once Infra firmware downloaded to Mobile device, The device
324            can never be updated to Mobile firmware*/
325         isfound = GetNxpNumValue(NAME_NXP_FW_PROTECION_OVERRIDE, &num, sizeof(num));
326         if (isfound > 0)
327         {
328             if (num == 0x01)
329             {
330                 NXPLOG_NCIHAL_D("Override Infra FW over Mobile");
331                 status = NFCSTATUS_SUCCESS;
332             }
333             else
334             {
335                 NXPLOG_NCIHAL_D("Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE invalid value)");
336             }
337         }
338         else
339         {
340             NXPLOG_NCIHAL_D("Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE not defiend)");
341         }
342     }
343 #if(NFC_NXP_CHIP_TYPE == PN548C2)
344     else if (gRecFWDwnld == TRUE)
345     {
346         status = NFCSTATUS_SUCCESS;
347     }
348 #endif
349     else if (wFwVerRsp == 0)
350     {
351         NXPLOG_NCIHAL_E("FW Version not received by NCI command >>> Force Firmware download");
352         status = NFCSTATUS_SUCCESS;
353     }
354     else
355     {
356         NXPLOG_NCIHAL_E("Wrong FW Version >>> Firmware download not allowed");
357     }
358 
359     return status;
360 }
361 
phNxpNciHal_get_clk_freq(void)362 static void phNxpNciHal_get_clk_freq(void)
363 {
364     unsigned long num = 0;
365     int isfound = 0;
366 
367     nxpprofile_ctrl.bClkSrcVal = 0;
368     nxpprofile_ctrl.bClkFreqVal = 0;
369     nxpprofile_ctrl.bTimeout = 0;
370 
371     isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &num, sizeof(num));
372     if (isfound > 0)
373     {
374         nxpprofile_ctrl.bClkSrcVal = num;
375     }
376 
377     num = 0;
378     isfound = 0;
379     isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &num, sizeof(num));
380     if (isfound > 0)
381     {
382         nxpprofile_ctrl.bClkFreqVal = num;
383     }
384 
385     num = 0;
386     isfound = 0;
387     isfound = GetNxpNumValue(NAME_NXP_SYS_CLOCK_TO_CFG, &num, sizeof(num));
388     if (isfound > 0)
389     {
390         nxpprofile_ctrl.bTimeout = num;
391     }
392 
393     NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkSrcVal = 0x%x", nxpprofile_ctrl.bClkSrcVal);
394     NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x", nxpprofile_ctrl.bClkFreqVal);
395     NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x", nxpprofile_ctrl.bTimeout);
396 
397     if ((nxpprofile_ctrl.bClkSrcVal < CLK_SRC_XTAL) ||
398             (nxpprofile_ctrl.bClkSrcVal > CLK_SRC_PLL))
399     {
400         NXPLOG_FWDNLD_E("Clock source value is wrong in config file, setting it as default");
401         nxpprofile_ctrl.bClkSrcVal = NXP_SYS_CLK_SRC_SEL;
402     }
403     if ((nxpprofile_ctrl.bClkFreqVal < CLK_FREQ_13MHZ) ||
404             (nxpprofile_ctrl.bClkFreqVal > CLK_FREQ_52MHZ))
405     {
406         NXPLOG_FWDNLD_E("Clock frequency value is wrong in config file, setting it as default");
407         nxpprofile_ctrl.bClkFreqVal = NXP_SYS_CLK_FREQ_SEL;
408     }
409     if ((nxpprofile_ctrl.bTimeout < CLK_TO_CFG_DEF) || (nxpprofile_ctrl.bTimeout > CLK_TO_CFG_MAX))
410     {
411         NXPLOG_FWDNLD_E("Clock timeout value is wrong in config file, setting it as default");
412         nxpprofile_ctrl.bTimeout = CLK_TO_CFG_DEF;
413     }
414 
415 }
416 
417 /******************************************************************************
418  * Function         phNxpNciHal_open
419  *
420  * Description      This function is called by libnfc-nci during the
421  *                  initialization of the NFCC. It opens the physical connection
422  *                  with NFCC (PN54X) and creates required client thread for
423  *                  operation.
424  *                  After open is complete, status is informed to libnfc-nci
425  *                  through callback function.
426  *
427  * Returns          This function return NFCSTATUS_SUCCES (0) in case of success
428  *                  In case of failure returns other failure value.
429  *
430  ******************************************************************************/
phNxpNciHal_open(nfc_stack_callback_t * p_cback,nfc_stack_data_callback_t * p_data_cback)431 int phNxpNciHal_open(nfc_stack_callback_t *p_cback, nfc_stack_data_callback_t *p_data_cback)
432 {
433     phOsalNfc_Config_t tOsalConfig;
434     phTmlNfc_Config_t tTmlConfig;
435     NFCSTATUS wConfigStatus = NFCSTATUS_SUCCESS;
436     NFCSTATUS status = NFCSTATUS_SUCCESS;
437     /*NCI_INIT_CMD*/
438     static uint8_t cmd_init_nci[] = {0x20,0x01,0x00};
439     /*NCI_RESET_CMD*/
440     static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x01};
441     /* reset config cache */
442     resetNxpConfig();
443 
444     int init_retry_cnt=0;
445 
446     /* initialize trace level */
447     phNxpLog_InitializeLogLevel();
448 
449     /*Create the timer for extns write response*/
450     timeoutTimerId = phOsalNfc_Timer_Create();
451 
452     if (phNxpNciHal_init_monitor() == NULL)
453     {
454         NXPLOG_NCIHAL_E("Init monitor failed");
455         return NFCSTATUS_FAILED;
456     }
457 
458     CONCURRENCY_LOCK();
459 
460     memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
461     memset(&tOsalConfig, 0x00, sizeof(tOsalConfig));
462     memset(&tTmlConfig, 0x00, sizeof(tTmlConfig));
463     memset (&nxpprofile_ctrl, 0, sizeof(phNxpNciProfile_Control_t));
464 
465     /* By default HAL status is HAL_STATUS_OPEN */
466     nxpncihal_ctrl.halStatus = HAL_STATUS_OPEN;
467 
468     nxpncihal_ctrl.p_nfc_stack_cback = p_cback;
469     nxpncihal_ctrl.p_nfc_stack_data_cback = p_data_cback;
470 
471     /* Configure hardware link */
472     nxpncihal_ctrl.gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
473     nxpncihal_ctrl.gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C;/* For PN54X */
474     tTmlConfig.pDevName = (int8_t *) "/dev/pn54x";
475     tOsalConfig.dwCallbackThreadId
476     = (uintptr_t) nxpncihal_ctrl.gDrvCfg.nClientId;
477     tOsalConfig.pLogFile = NULL;
478     tTmlConfig.dwGetMsgThreadId = (uintptr_t) nxpncihal_ctrl.gDrvCfg.nClientId;
479 
480     memset (discovery_cmd, 0, sizeof(discovery_cmd));
481     discovery_cmd_len = 0;
482 
483     /* Initialize TML layer */
484     wConfigStatus = phTmlNfc_Init(&tTmlConfig);
485     if (wConfigStatus != NFCSTATUS_SUCCESS)
486     {
487         NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
488         goto clean_and_return;
489     }
490 
491     /* Create the client thread */
492     pthread_attr_t attr;
493     pthread_attr_init(&attr);
494     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
495     if (pthread_create(&nxpncihal_ctrl.client_thread, &attr,
496             phNxpNciHal_client_thread, &nxpncihal_ctrl) != 0)
497     {
498         NXPLOG_NCIHAL_E("pthread_create failed");
499         wConfigStatus = phTmlNfc_Shutdown();
500         goto clean_and_return;
501     }
502 
503     CONCURRENCY_UNLOCK();
504 
505     /* call read pending */
506     status = phTmlNfc_Read(
507             nxpncihal_ctrl.p_cmd_data,
508             NCI_MAX_DATA_LEN,
509             (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
510             NULL);
511     if (status != NFCSTATUS_PENDING)
512     {
513         NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
514         wConfigStatus = phTmlNfc_Shutdown();
515         wConfigStatus = NFCSTATUS_FAILED;
516         goto clean_and_return;
517     }
518 
519 init_retry:
520 
521     phNxpNciHal_ext_init();
522 
523     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
524     if((status != NFCSTATUS_SUCCESS) && (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT))
525     {
526         NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
527         wConfigStatus = NFCSTATUS_FAILED;
528         goto force_download;
529     }
530     else if(status != NFCSTATUS_SUCCESS)
531     {
532         NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
533         if(init_retry_cnt < 3) {
534             init_retry_cnt++;
535             (void)phNxpNciHal_power_cycle();
536             goto init_retry;
537         } else
538             init_retry_cnt = 0;
539         wConfigStatus = phTmlNfc_Shutdown();
540         wConfigStatus = NFCSTATUS_FAILED;
541         goto clean_and_return;
542     }
543 
544     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci),cmd_init_nci);
545     if(status != NFCSTATUS_SUCCESS)
546     {
547         NXPLOG_NCIHAL_E ("NCI_CORE_INIT : Failed");
548         if(init_retry_cnt < 3) {
549             init_retry_cnt++;
550             (void)phNxpNciHal_power_cycle();
551             goto init_retry;
552         } else
553             init_retry_cnt = 0;
554         wConfigStatus = phTmlNfc_Shutdown();
555         wConfigStatus = NFCSTATUS_FAILED;
556         goto clean_and_return;
557     }
558     phNxpNciHal_enable_i2c_fragmentation();
559     /*Get FW version from device*/
560     status = phDnldNfc_InitImgInfo();
561     NXPLOG_NCIHAL_D ("FW version for FW file = 0x%x", wFwVer);
562     NXPLOG_NCIHAL_D ("FW version from device = 0x%x", wFwVerRsp);
563     if ((wFwVerRsp & 0x0000FFFF) == wFwVer)
564     {
565         NXPLOG_NCIHAL_D ("FW uptodate not required");
566         phDnldNfc_ReSetHwDevHandle();
567     }
568     else
569     {
570 force_download:
571         if (wFwVerRsp == 0)
572         {
573             phDnldNfc_InitImgInfo();
574         }
575         if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion())
576         {
577             NXPLOG_NCIHAL_D ("FW update required");
578             fw_download_success = 0;
579             status = phNxpNciHal_fw_download();
580             if (status != NFCSTATUS_SUCCESS)
581             {
582                 NXPLOG_NCIHAL_E ("FW Download failed - NFCC init will continue");
583             }
584             else
585             {
586                 wConfigStatus = NFCSTATUS_SUCCESS;
587                 fw_download_success = 1;
588                 /* call read pending */
589                 status = phTmlNfc_Read(
590                 nxpncihal_ctrl.p_cmd_data,
591                 NCI_MAX_DATA_LEN,
592                    (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
593                         NULL);
594                 if (status != NFCSTATUS_PENDING)
595                 {
596                     NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
597                     wConfigStatus = phTmlNfc_Shutdown();
598                     wConfigStatus = NFCSTATUS_FAILED;
599                     goto clean_and_return;
600                 }
601             }
602         }
603         else
604         {
605             if (wFwVerRsp == 0)
606                phDnldNfc_ReSetHwDevHandle();
607         }
608     }
609     /* Call open complete */
610     phNxpNciHal_open_complete(wConfigStatus);
611 
612     return wConfigStatus;
613 
614     clean_and_return:
615     CONCURRENCY_UNLOCK();
616     /* Report error status */
617     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT,
618             HAL_NFC_STATUS_FAILED);
619 
620     nxpncihal_ctrl.p_nfc_stack_cback = NULL;
621     nxpncihal_ctrl.p_nfc_stack_data_cback = NULL;
622     phNxpNciHal_cleanup_monitor();
623     nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
624     return NFCSTATUS_FAILED;
625 }
626 
627 /******************************************************************************
628  * Function         phNxpNciHal_open_complete
629  *
630  * Description      This function inform the status of phNxpNciHal_open
631  *                  function to libnfc-nci.
632  *
633  * Returns          void.
634  *
635  ******************************************************************************/
phNxpNciHal_open_complete(NFCSTATUS status)636 static void phNxpNciHal_open_complete(NFCSTATUS status)
637 {
638     static phLibNfc_Message_t msg;
639 
640     if (status == NFCSTATUS_SUCCESS)
641     {
642         msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
643         nxpncihal_ctrl.hal_open_status = TRUE;
644     }
645     else
646     {
647         msg.eMsgType = NCI_HAL_ERROR_MSG;
648     }
649 
650     msg.pMsgData = NULL;
651     msg.Size = 0;
652 
653     phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
654             (phLibNfc_Message_t *) &msg);
655 
656     return;
657 }
658 
659 /******************************************************************************
660  * Function         phNxpNciHal_write
661  *
662  * Description      This function write the data to NFCC through physical
663  *                  interface (e.g. I2C) using the PN54X driver interface.
664  *                  Before sending the data to NFCC, phNxpNciHal_write_ext
665  *                  is called to check if there is any extension processing
666  *                  is required for the NCI packet being sent out.
667  *
668  * Returns          It returns number of bytes successfully written to NFCC.
669  *
670  ******************************************************************************/
phNxpNciHal_write(uint16_t data_len,const uint8_t * p_data)671 int phNxpNciHal_write(uint16_t data_len, const uint8_t *p_data)
672 {
673     NFCSTATUS status = NFCSTATUS_FAILED;
674     static phLibNfc_Message_t msg;
675 
676     /* Create local copy of cmd_data */
677     memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
678     nxpncihal_ctrl.cmd_len = data_len;
679 
680 #ifdef P2P_PRIO_LOGIC_HAL_IMP
681     /* Specific logic to block RF disable when P2P priority logic is busy */
682     if (p_data[0] == 0x21&&
683         p_data[1] == 0x06 &&
684         p_data[2] == 0x01 &&
685         EnableP2P_PrioLogic == TRUE)
686     {
687         NXPLOG_NCIHAL_D ("P2P priority logic busy: Disable it.");
688         phNxpNciHal_clean_P2P_Prio();
689     }
690 #endif
691     /* Specific logic to block RF disable when Kovio detection logic is active */
692     if (p_data[0] == 0x21&&
693         p_data[1] == 0x06 &&
694         p_data[2] == 0x01)
695     {
696         rf_deactive_cmd = TRUE;
697         if (kovio_detected == TRUE)
698         {
699             NXPLOG_NCIHAL_D ("Kovio detection logic is active: Set Flag to disable it.");
700             disable_kovio = 0x01;
701         }
702     }
703 
704     /* Check for NXP ext before sending write */
705     status = phNxpNciHal_write_ext(&nxpncihal_ctrl.cmd_len,
706             nxpncihal_ctrl.p_cmd_data, &nxpncihal_ctrl.rsp_len,
707             nxpncihal_ctrl.p_rsp_data);
708     if (status != NFCSTATUS_SUCCESS)
709     {
710         /* Do not send packet to PN54X, send response directly */
711         msg.eMsgType = NCI_HAL_RX_MSG;
712         msg.pMsgData = NULL;
713         msg.Size = 0;
714 
715         phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
716                 (phLibNfc_Message_t *) &msg);
717         goto clean_and_return;
718     }
719 
720     CONCURRENCY_LOCK();
721     data_len = phNxpNciHal_write_unlocked(nxpncihal_ctrl.cmd_len,
722             nxpncihal_ctrl.p_cmd_data);
723     CONCURRENCY_UNLOCK();
724 
725     if (icode_send_eof == 1)
726     {
727         usleep (10000);
728         icode_send_eof = 2;
729         phNxpNciHal_send_ext_cmd (3, cmd_icode_eof);
730     }
731 
732     clean_and_return:
733     /* No data written */
734     return data_len;
735 }
736 
737 /******************************************************************************
738  * Function         phNxpNciHal_write_unlocked
739  *
740  * Description      This is the actual function which is being called by
741  *                  phNxpNciHal_write. This function writes the data to NFCC.
742  *                  It waits till write callback provide the result of write
743  *                  process.
744  *
745  * Returns          It returns number of bytes successfully written to NFCC.
746  *
747  ******************************************************************************/
phNxpNciHal_write_unlocked(uint16_t data_len,const uint8_t * p_data)748 int phNxpNciHal_write_unlocked(uint16_t data_len, const uint8_t *p_data)
749 {
750     NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER;
751     phNxpNciHal_Sem_t cb_data;
752     nxpncihal_ctrl.retry_cnt = 0;
753     static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00, 0xC7, 0xD4, 0x00, 0x00};
754 
755     /* Create the local semaphore */
756     if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
757     {
758         NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked Create cb data failed");
759         data_len = 0;
760         goto clean_and_return;
761     }
762 
763     /* Create local copy of cmd_data */
764     memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
765     nxpncihal_ctrl.cmd_len = data_len;
766 
767     retry:
768 
769     data_len = nxpncihal_ctrl.cmd_len;
770 
771     status = phTmlNfc_Write( (uint8_t *) nxpncihal_ctrl.p_cmd_data,
772             (uint16_t) nxpncihal_ctrl.cmd_len,
773             (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_write_complete,
774             (void *) &cb_data);
775     if (status != NFCSTATUS_PENDING)
776     {
777         NXPLOG_NCIHAL_E("write_unlocked status error");
778         data_len = 0;
779         goto clean_and_return;
780     }
781 
782     /* Wait for callback response */
783     if (SEM_WAIT(cb_data))
784     {
785         NXPLOG_NCIHAL_E("write_unlocked semaphore error");
786         data_len = 0;
787         goto clean_and_return;
788     }
789 
790     if (cb_data.status != NFCSTATUS_SUCCESS)
791     {
792         data_len = 0;
793         if(nxpncihal_ctrl.retry_cnt++ < MAX_RETRY_COUNT)
794         {
795             NXPLOG_NCIHAL_E("write_unlocked failed - PN54X Maybe in Standby Mode - Retry");
796             /* 1ms delay to give NFCC wake up delay */
797             usleep(1000);
798             goto retry;
799         }
800         else
801         {
802 
803             NXPLOG_NCIHAL_E("write_unlocked failed - PN54X Maybe in Standby Mode (max count = 0x%x)", nxpncihal_ctrl.retry_cnt);
804 
805             status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
806 
807             if(NFCSTATUS_SUCCESS == status)
808             {
809                 NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
810             }
811             else
812             {
813                 NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
814             }
815             if (nxpncihal_ctrl.p_nfc_stack_data_cback!= NULL &&
816                 nxpncihal_ctrl.p_rx_data!= NULL &&
817                 nxpncihal_ctrl.hal_open_status == TRUE)
818             {
819                 NXPLOG_NCIHAL_D("Send the Core Reset NTF to upper layer, which will trigger the recovery\n");
820                 //Send the Core Reset NTF to upper layer, which will trigger the recovery.
821                 nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf);
822                 memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf));
823                 (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
824             }
825         }
826     }
827 
828     clean_and_return:
829     phNxpNciHal_cleanup_cb_data(&cb_data);
830     return data_len;
831 }
832 
833 /******************************************************************************
834  * Function         phNxpNciHal_write_complete
835  *
836  * Description      This function handles write callback.
837  *
838  * Returns          void.
839  *
840  ******************************************************************************/
phNxpNciHal_write_complete(void * pContext,phTmlNfc_TransactInfo_t * pInfo)841 static void phNxpNciHal_write_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
842 {
843     phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
844 
845     if (pInfo->wStatus == NFCSTATUS_SUCCESS)
846     {
847         NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus);
848     }
849     else
850     {
851         NXPLOG_NCIHAL_E("write error status = 0x%x", pInfo->wStatus);
852     }
853 
854     p_cb_data->status = pInfo->wStatus;
855 
856     SEM_POST(p_cb_data);
857 
858     return;
859 }
860 
861 /******************************************************************************
862  * Function         phNxpNciHal_read_complete
863  *
864  * Description      This function is called whenever there is an NCI packet
865  *                  received from NFCC. It could be RSP or NTF packet. This
866  *                  function provide the received NCI packet to libnfc-nci
867  *                  using data callback of libnfc-nci.
868  *                  There is a pending read called from each
869  *                  phNxpNciHal_read_complete so each a packet received from
870  *                  NFCC can be provide to libnfc-nci.
871  *
872  * Returns          void.
873  *
874  ******************************************************************************/
phNxpNciHal_read_complete(void * pContext,phTmlNfc_TransactInfo_t * pInfo)875 static void phNxpNciHal_read_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
876 {
877     NFCSTATUS status = NFCSTATUS_FAILED;
878     UNUSED(pContext);
879     if(nxpncihal_ctrl.read_retry_cnt == 1)
880     {
881         nxpncihal_ctrl.read_retry_cnt = 0;
882     }
883 
884     if (pInfo->wStatus == NFCSTATUS_SUCCESS)
885     {
886         NXPLOG_NCIHAL_D("read successful status = 0x%x", pInfo->wStatus);
887 
888         nxpncihal_ctrl.p_rx_data = pInfo->pBuff;
889         nxpncihal_ctrl.rx_data_len = pInfo->wLength;
890 
891         status = phNxpNciHal_process_ext_rsp (nxpncihal_ctrl.p_rx_data, &nxpncihal_ctrl.rx_data_len);
892 
893         phNxpNciHal_print_res_status(nxpncihal_ctrl.p_rx_data,  &nxpncihal_ctrl.rx_data_len);
894         /* Check if response should go to hal module only */
895         if (nxpncihal_ctrl.hal_ext_enabled == 1
896                 && (nxpncihal_ctrl.p_rx_data[0x00] & 0x40) == 0x40)
897         {
898             if(status == NFCSTATUS_FAILED)
899             {
900                 NXPLOG_NCIHAL_D("enter into NFCC init recovery");
901                 nxpncihal_ctrl.ext_cb_data.status = status;
902             }
903             /* Unlock semaphore */
904             SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
905         }
906         /* Read successful send the event to higher layer */
907         else if ((nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) &&
908                 (status == NFCSTATUS_SUCCESS)&&(send_to_upper_kovio==1))
909         {
910             (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
911                     nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
912         }
913     }
914     else
915     {
916         NXPLOG_NCIHAL_E("read error status = 0x%x", pInfo->wStatus);
917     }
918 
919     if(nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE)
920     {
921         return;
922     }
923     /* Read again because read must be pending always.*/
924     status = phTmlNfc_Read(
925             Rx_data,
926             NCI_MAX_DATA_LEN,
927             (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
928             NULL);
929     if (status != NFCSTATUS_PENDING)
930     {
931         NXPLOG_NCIHAL_E("read status error status = %x", status);
932         /* TODO: Not sure how to handle this ? */
933     }
934 
935     return;
936 }
937 
read_retry()938 void read_retry()
939 {
940     /* Read again because read must be pending always.*/
941     NFCSTATUS status = phTmlNfc_Read(
942             Rx_data,
943             NCI_MAX_DATA_LEN,
944             (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
945             NULL);
946     if (status != NFCSTATUS_PENDING)
947     {
948         NXPLOG_NCIHAL_E("read status error status = %x", status);
949         /* TODO: Not sure how to handle this ? */
950     }
951 }
952 /******************************************************************************
953  * Function         phNxpNciHal_core_initialized
954  *
955  * Description      This function is called by libnfc-nci after successful open
956  *                  of NFCC. All proprietary setting for PN54X are done here.
957  *                  After completion of proprietary settings notification is
958  *                  provided to libnfc-nci through callback function.
959  *
960  * Returns          Always returns NFCSTATUS_SUCCESS (0).
961  *
962  ******************************************************************************/
phNxpNciHal_core_initialized(uint8_t * p_core_init_rsp_params)963 int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params)
964 {
965     NFCSTATUS status = NFCSTATUS_SUCCESS;
966     static uint8_t p2p_listen_mode_routing_cmd[] = { 0x21, 0x01, 0x07, 0x00, 0x01,
967                                                 0x01, 0x03, 0x00, 0x01, 0x05 };
968 
969     uint8_t swp_full_pwr_mode_on_cmd[] = { 0x20, 0x02, 0x05, 0x01, 0xA0,
970                                            0xF1,0x01,0x01 };
971 
972     static uint8_t android_l_aid_matching_mode_on_cmd[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x91, 0x01, 0x01};
973     static uint8_t swp_switch_timeout_cmd[] = {0x20, 0x02, 0x06, 0x01, 0xA0, 0xF3, 0x02, 0x00, 0x00};
974 
975     uint8_t *buffer = NULL;
976     long bufflen = 260;
977     long retlen = 0;
978     int isfound;
979     /* Temp fix to re-apply the proper clock setting */
980      int temp_fix = 1;
981 #if(NFC_NXP_CHIP_TYPE == PN548C2)
982     unsigned long num = 0;
983     //initialize dummy FW recovery variables
984     gRecFwRetryCount = 0;
985     gRecFWDwnld = 0;
986 #endif
987     // recovery --start
988     /*NCI_INIT_CMD*/
989     static uint8_t cmd_init_nci[] = {0x20,0x01,0x00};
990     /*NCI_RESET_CMD*/
991     static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x00}; //keep configuration
992     /* reset config cache */
993     static uint8_t retry_core_init_cnt;
994 
995     if((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)) //initializing for recovery.
996     {
997 retry_core_init:
998         config_access = FALSE;
999         if(buffer != NULL)
1000         {
1001             free(buffer);
1002             buffer = NULL;
1003         }
1004         if(retry_core_init_cnt > 3)
1005         {
1006             return NFCSTATUS_FAILED;
1007         }
1008 
1009         status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1010         if(NFCSTATUS_SUCCESS == status) { NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n"); }
1011         else { NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n"); }
1012 
1013         status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
1014         if((status != NFCSTATUS_SUCCESS) && (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT))
1015         {
1016             NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
1017             retry_core_init_cnt++;
1018             goto retry_core_init;
1019         }
1020         else if(status != NFCSTATUS_SUCCESS)
1021         {
1022             NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
1023             retry_core_init_cnt++;
1024             goto retry_core_init;
1025 
1026         }
1027 
1028         if(*p_core_init_rsp_params == 2) {
1029             NXPLOG_NCIHAL_E(" Last command is CORE_RESET!!");
1030             goto invoke_callback;
1031         }
1032 
1033         status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci),cmd_init_nci);
1034         if(status != NFCSTATUS_SUCCESS)
1035         {
1036             NXPLOG_NCIHAL_E ("NCI_CORE_INIT : Failed");
1037             retry_core_init_cnt++;
1038             goto retry_core_init;
1039         }
1040 
1041         if(*p_core_init_rsp_params == 3) {
1042             NXPLOG_NCIHAL_E(" Last command is CORE_INIT!!");
1043             goto invoke_callback;
1044         }
1045     }
1046 // recovery --end
1047 
1048 
1049     buffer = (uint8_t*) malloc(bufflen*sizeof(uint8_t));
1050     if(NULL == buffer)
1051     {
1052         return NFCSTATUS_FAILED;
1053     }
1054     config_access = TRUE;
1055     retlen = 0;
1056     isfound = GetNxpByteArrayValue(NAME_NXP_ACT_PROP_EXTN, (char *) buffer,
1057             bufflen, &retlen);
1058     if (retlen > 0) {
1059         /* NXP ACT Proprietary Ext */
1060         status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1061         if (status != NFCSTATUS_SUCCESS) {
1062             NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
1063             retry_core_init_cnt++;
1064             goto retry_core_init;
1065         }
1066     }
1067 
1068     // Check if firmware download success
1069     status = phNxpNciHal_get_mw_eeprom ();
1070     if (status != NFCSTATUS_SUCCESS)
1071     {
1072         NXPLOG_NCIHAL_E ("NXP GET MW EEPROM AREA Proprietary Ext failed");
1073         retry_core_init_cnt++;
1074         goto retry_core_init;
1075     }
1076 
1077     //
1078     status = phNxpNciHal_check_clock_config();
1079     if (status != NFCSTATUS_SUCCESS) {
1080         NXPLOG_NCIHAL_E("phNxpNciHal_check_clock_config failed");
1081         retry_core_init_cnt++;
1082         goto retry_core_init;
1083     }
1084 
1085 #ifdef PN547C2_CLOCK_SETTING
1086     if (isNxpConfigModified() || (fw_download_success == 1) || (phNxpNciClock.issetConfig)
1087 #if(NFC_NXP_HFO_SETTINGS == TRUE)
1088         || temp_fix == 1
1089 #endif
1090         )
1091     {
1092         //phNxpNciHal_get_clk_freq();
1093         phNxpNciHal_set_clock();
1094         phNxpNciClock.issetConfig = FALSE;
1095 #if(NFC_NXP_HFO_SETTINGS == TRUE)
1096         if (temp_fix == 1 )
1097         {
1098             NXPLOG_NCIHAL_D("Applying Default Clock setting and DPLL register at power on");
1099             /*
1100             # A0, 0D, 06, 06, 83, 55, 2A, 04, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_GEAR_REG
1101             # A0, 0D, 06, 06, 82, 33, 14, 17, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_REG
1102             # A0, 0D, 06, 06, 84, AA, 85, 00, 80 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_FREQ_REG
1103             # A0, 0D, 06, 06, 81, 63, 00, 00, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_CONTROL_REG
1104             */
1105             static uint8_t cmd_dpll_set_reg_nci[] = {0x20, 0x02, 0x25, 0x04,
1106                                                                             0xA0, 0x0D, 0x06, 0x06, 0x83, 0x55, 0x2A, 0x04, 0x00,
1107                                                                             0xA0, 0x0D, 0x06, 0x06, 0x82, 0x33, 0x14, 0x17, 0x00,
1108                                                                             0xA0, 0x0D, 0x06, 0x06, 0x84, 0xAA, 0x85, 0x00, 0x80,
1109                                                                             0xA0, 0x0D, 0x06, 0x06, 0x81, 0x63, 0x00, 0x00, 0x00};
1110 
1111             status = phNxpNciHal_send_ext_cmd(sizeof(cmd_dpll_set_reg_nci), cmd_dpll_set_reg_nci);
1112             if (status != NFCSTATUS_SUCCESS) {
1113                 NXPLOG_NCIHAL_E("NXP DPLL REG ACT Proprietary Ext failed");
1114                 retry_core_init_cnt++;
1115                 goto retry_core_init;
1116             }
1117             /* reset the NFCC after applying the clock setting and DPLL setting */
1118             //phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1119             temp_fix = 0;
1120             goto retry_core_init;
1121         }
1122 #endif
1123     }
1124 #endif
1125 
1126     phNxpNciHal_check_factory_reset();
1127     retlen = 0;
1128     config_access = TRUE;
1129     isfound = GetNxpByteArrayValue(NAME_NXP_NFC_PROFILE_EXTN, (char *) buffer,
1130             bufflen, &retlen);
1131     if (retlen > 0) {
1132         /* NXP ACT Proprietary Ext */
1133         status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1134         if (status != NFCSTATUS_SUCCESS) {
1135             NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
1136             retry_core_init_cnt++;
1137             goto retry_core_init;
1138         }
1139     }
1140 
1141     if(isNxpConfigModified() || (fw_download_success == 1))
1142     {
1143 
1144         retlen = 0;
1145         fw_download_success = 0;
1146 
1147 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1148         NXPLOG_NCIHAL_D ("Performing TVDD Settings");
1149         isfound = GetNxpNumValue(NAME_NXP_EXT_TVDD_CFG, &num, sizeof(num));
1150         if (isfound > 0) {
1151             if(num == 1) {
1152                 isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_1, (char *) buffer,
1153                         bufflen, &retlen);
1154                 if (retlen > 0) {
1155                     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1156                     if (status != NFCSTATUS_SUCCESS) {
1157                         NXPLOG_NCIHAL_E("EXT TVDD CFG 1 Settings failed");
1158                         retry_core_init_cnt++;
1159                         goto retry_core_init;
1160                     }
1161                 }
1162             }
1163             else if(num == 2) {
1164                 isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_2, (char *) buffer,
1165                         bufflen, &retlen);
1166                     if (retlen > 0) {
1167                     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1168                     if (status != NFCSTATUS_SUCCESS) {
1169                         NXPLOG_NCIHAL_E("EXT TVDD CFG 2 Settings failed");
1170                         retry_core_init_cnt++;
1171                         goto retry_core_init;
1172                     }
1173                 }
1174             }
1175             else if(num == 3) {
1176                 isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_3, (char *) buffer,
1177                         bufflen, &retlen);
1178                     if (retlen > 0) {
1179                     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1180                     if (status != NFCSTATUS_SUCCESS) {
1181                         NXPLOG_NCIHAL_E("EXT TVDD CFG 3 Settings failed");
1182                         retry_core_init_cnt++;
1183                         goto retry_core_init;
1184                     }
1185                 }
1186             }
1187             else {
1188                 NXPLOG_NCIHAL_E("Wrong Configuration Value %ld", num);
1189             }
1190 
1191         }
1192 #endif
1193         retlen = 0;
1194 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1195         config_access = FALSE;
1196 #endif
1197         NXPLOG_NCIHAL_D ("Performing RF Settings BLK 1");
1198         isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_1, (char *) buffer,
1199                 bufflen, &retlen);
1200         if (retlen > 0) {
1201             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1202 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1203             if (status == NFCSTATUS_SUCCESS)
1204             {
1205                 status = phNxpNciHal_CheckRFCmdRespStatus ();
1206                 /*STATUS INVALID PARAM 0x09*/
1207                 if (status == 0x09)
1208                 {
1209                     phNxpNciHalRFConfigCmdRecSequence ();
1210                     retry_core_init_cnt++;
1211                     goto retry_core_init;
1212                 }
1213             }
1214             else
1215 #endif
1216             if (status != NFCSTATUS_SUCCESS) {
1217                 NXPLOG_NCIHAL_E("RF Settings BLK 1 failed");
1218                 retry_core_init_cnt++;
1219                 goto retry_core_init;
1220             }
1221         }
1222         retlen = 0;
1223 
1224         NXPLOG_NCIHAL_D ("Performing RF Settings BLK 2");
1225         isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_2, (char *) buffer,
1226                 bufflen, &retlen);
1227         if (retlen > 0) {
1228             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1229 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1230             if (status == NFCSTATUS_SUCCESS)
1231             {
1232                 status = phNxpNciHal_CheckRFCmdRespStatus ();
1233                 /*STATUS INVALID PARAM 0x09*/
1234                 if (status == 0x09)
1235                 {
1236                     phNxpNciHalRFConfigCmdRecSequence ();
1237                     retry_core_init_cnt++;
1238                     goto retry_core_init;
1239                 }
1240             }
1241             else
1242 #endif
1243             if (status != NFCSTATUS_SUCCESS) {
1244                 NXPLOG_NCIHAL_E("RF Settings BLK 2 failed");
1245                 retry_core_init_cnt++;
1246                 goto retry_core_init;
1247             }
1248         }
1249         retlen = 0;
1250 
1251         NXPLOG_NCIHAL_D ("Performing RF Settings BLK 3");
1252         isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_3, (char *) buffer,
1253                 bufflen, &retlen);
1254         if (retlen > 0) {
1255             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1256 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1257             if (status == NFCSTATUS_SUCCESS)
1258             {
1259                 status = phNxpNciHal_CheckRFCmdRespStatus ();
1260                 /*STATUS INVALID PARAM 0x09*/
1261                 if (status == 0x09)
1262                 {
1263                     phNxpNciHalRFConfigCmdRecSequence ();
1264                     retry_core_init_cnt++;
1265                     goto retry_core_init;
1266                 }
1267             }
1268             else
1269 #endif
1270             if (status != NFCSTATUS_SUCCESS) {
1271                 NXPLOG_NCIHAL_E("RF Settings BLK 3 failed");
1272                 retry_core_init_cnt++;
1273                 goto retry_core_init;
1274             }
1275         }
1276         retlen = 0;
1277 
1278         NXPLOG_NCIHAL_D ("Performing RF Settings BLK 4");
1279         isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_4, (char *) buffer,
1280                 bufflen, &retlen);
1281         if (retlen > 0) {
1282             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1283 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1284             if (status == NFCSTATUS_SUCCESS)
1285             {
1286                 status = phNxpNciHal_CheckRFCmdRespStatus ();
1287                 /*STATUS INVALID PARAM 0x09*/
1288                 if (status == 0x09)
1289                 {
1290                     phNxpNciHalRFConfigCmdRecSequence ();
1291                     retry_core_init_cnt++;
1292                     goto retry_core_init;
1293                 }
1294             }
1295             else
1296 #endif
1297             if (status != NFCSTATUS_SUCCESS) {
1298                 NXPLOG_NCIHAL_E("RF Settings BLK 4 failed");
1299                 retry_core_init_cnt++;
1300                 goto retry_core_init;
1301             }
1302         }
1303         retlen = 0;
1304 
1305         NXPLOG_NCIHAL_D ("Performing RF Settings BLK 5");
1306         isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_5, (char *) buffer,
1307                 bufflen, &retlen);
1308         if (retlen > 0) {
1309             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1310 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1311             if (status == NFCSTATUS_SUCCESS)
1312             {
1313                 status = phNxpNciHal_CheckRFCmdRespStatus ();
1314                 /*STATUS INVALID PARAM 0x09*/
1315                 if (status == 0x09)
1316                 {
1317                     phNxpNciHalRFConfigCmdRecSequence ();
1318                     retry_core_init_cnt++;
1319                     goto retry_core_init;
1320                 }
1321             }
1322             else
1323 #endif
1324             if (status != NFCSTATUS_SUCCESS) {
1325                 NXPLOG_NCIHAL_E("RF Settings BLK 5 failed");
1326                 retry_core_init_cnt++;
1327                 goto retry_core_init;
1328             }
1329         }
1330         retlen = 0;
1331 
1332         NXPLOG_NCIHAL_D ("Performing RF Settings BLK 6");
1333         isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_6, (char *) buffer,
1334                 bufflen, &retlen);
1335         if (retlen > 0) {
1336             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1337 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1338             if (status == NFCSTATUS_SUCCESS)
1339             {
1340                 status = phNxpNciHal_CheckRFCmdRespStatus ();
1341                 /*STATUS INVALID PARAM 0x09*/
1342                 if (status == 0x09)
1343                 {
1344                     phNxpNciHalRFConfigCmdRecSequence ();
1345                     retry_core_init_cnt++;
1346                     goto retry_core_init;
1347                 }
1348             }
1349             else
1350 #endif
1351             if (status != NFCSTATUS_SUCCESS) {
1352                 NXPLOG_NCIHAL_E("RF Settings BLK 6 failed");
1353                 retry_core_init_cnt++;
1354                 goto retry_core_init;
1355             }
1356         }
1357         retlen = 0;
1358 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1359         config_access = TRUE;
1360 #endif
1361         NXPLOG_NCIHAL_D ("Performing NAME_NXP_CORE_CONF_EXTN Settings");
1362         isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF_EXTN,
1363                 (char *) buffer, bufflen, &retlen);
1364         if (retlen > 0) {
1365             /* NXP ACT Proprietary Ext */
1366             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1367             if (status != NFCSTATUS_SUCCESS) {
1368                 NXPLOG_NCIHAL_E("NXP Core configuration failed");
1369                 retry_core_init_cnt++;
1370                 goto retry_core_init;
1371             }
1372         }
1373 
1374         retlen = 0;
1375 
1376         isfound = GetNxpByteArrayValue(NAME_NXP_CORE_MFCKEY_SETTING,
1377                 (char *) buffer, bufflen, &retlen);
1378         if (retlen > 0) {
1379             /* NXP ACT Proprietary Ext */
1380             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1381             if (status != NFCSTATUS_SUCCESS) {
1382                 NXPLOG_NCIHAL_E("Setting mifare keys failed");
1383                 retry_core_init_cnt++;
1384                 goto retry_core_init;
1385             }
1386         }
1387 
1388         retlen = 0;
1389 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1390         config_access = FALSE;
1391 #endif
1392         isfound = GetNxpByteArrayValue(NAME_NXP_CORE_RF_FIELD,
1393                 (char *) buffer, bufflen, &retlen);
1394         if (retlen > 0) {
1395             /* NXP ACT Proprietary Ext */
1396             status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1397 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1398             if (status == NFCSTATUS_SUCCESS)
1399             {
1400                 status = phNxpNciHal_CheckRFCmdRespStatus ();
1401                 /*STATUS INVALID PARAM 0x09*/
1402                 if (status == 0x09)
1403                 {
1404                     phNxpNciHalRFConfigCmdRecSequence ();
1405                     retry_core_init_cnt++;
1406                     goto retry_core_init;
1407                 }
1408             }
1409             else
1410 #endif
1411             if (status != NFCSTATUS_SUCCESS) {
1412                 NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
1413                 retry_core_init_cnt++;
1414                 goto retry_core_init;
1415             }
1416         }
1417 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1418         config_access = TRUE;
1419 #endif
1420 #if(NFC_NXP_CHIP_TYPE != PN547C2)
1421         retlen = 0;
1422 
1423         /* NXP SWP switch timeout Setting*/
1424         if(GetNxpNumValue(NAME_NXP_SWP_SWITCH_TIMEOUT, (void *)&retlen, sizeof(retlen)))
1425         {
1426             //Check the permissible range [0 - 60]
1427             if(0 <= retlen && retlen <= 60)
1428             {
1429                 if( 0 < retlen)
1430                 {
1431                     uint16_t timeout = retlen * 1000;
1432                     uint16_t timeoutHx = 0x0000;
1433 
1434                     uint8_t buffer[10];
1435                     snprintf ( buffer, 10, "%04x", timeout );
1436                     sscanf (buffer,"%x",&timeoutHx);
1437 
1438                     swp_switch_timeout_cmd[7]= (timeoutHx & 0xFF);
1439                     swp_switch_timeout_cmd[8]=  ((timeoutHx & 0xFF00) >> 8);
1440                 }
1441 
1442                 status = phNxpNciHal_send_ext_cmd (sizeof(swp_switch_timeout_cmd),
1443                                                           swp_switch_timeout_cmd);
1444                 if (status != NFCSTATUS_SUCCESS)
1445                 {
1446                    NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed");
1447                    retry_core_init_cnt++;
1448                    goto retry_core_init;
1449                 }
1450             }
1451             else
1452             {
1453                 NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed - out of range!");
1454             }
1455 
1456         }
1457 
1458         status = phNxpNciHal_china_tianjin_rf_setting();
1459         if (status != NFCSTATUS_SUCCESS)
1460         {
1461             NXPLOG_NCIHAL_E("phNxpNciHal_china_tianjin_rf_setting failed");
1462             return NFCSTATUS_FAILED;
1463         }
1464 #endif
1465         // Update eeprom value
1466         status = phNxpNciHal_set_mw_eeprom ();
1467         if (status != NFCSTATUS_SUCCESS)
1468         {
1469             NXPLOG_NCIHAL_E ("NXP Update MW EEPROM Proprietary Ext failed");
1470         }
1471     }
1472 
1473     retlen = 0;
1474 
1475     isfound = GetNxpByteArrayValue(NAME_NXP_CORE_STANDBY, (char *) buffer,bufflen, &retlen);
1476     if (retlen > 0) {
1477         /* NXP ACT Proprietary Ext */
1478         status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1479         if (status != NFCSTATUS_SUCCESS) {
1480             NXPLOG_NCIHAL_E("Stand by mode enable failed");
1481             retry_core_init_cnt++;
1482             goto retry_core_init;
1483         }
1484     }
1485     retlen = 0;
1486 
1487     isfound =  GetNxpByteArrayValue(NAME_NXP_CORE_CONF,(char *)buffer,bufflen,&retlen);
1488     if(retlen > 0)
1489     {
1490         /* NXP ACT Proprietary Ext */
1491         status = phNxpNciHal_send_ext_cmd(retlen,buffer);
1492         if (status != NFCSTATUS_SUCCESS)
1493         {
1494             NXPLOG_NCIHAL_E("Core Set Config failed");
1495             retry_core_init_cnt++;
1496             goto retry_core_init;
1497         }
1498     }
1499 
1500     config_access = FALSE;
1501     //if length of last command is 0 then only reset the P2P listen mode routing.
1502     if(p_core_init_rsp_params[35] == 0)
1503     {
1504         /* P2P listen mode routing */
1505         status = phNxpNciHal_send_ext_cmd (sizeof (p2p_listen_mode_routing_cmd), p2p_listen_mode_routing_cmd);
1506         if (status != NFCSTATUS_SUCCESS)
1507         {
1508             NXPLOG_NCIHAL_E("P2P listen mode routing failed");
1509             retry_core_init_cnt++;
1510             goto retry_core_init;
1511         }
1512     }
1513 
1514     retlen = 0;
1515 
1516     /* SWP FULL PWR MODE SETTING ON */
1517     if(GetNxpNumValue(NAME_NXP_SWP_FULL_PWR_ON, (void *)&retlen, sizeof(retlen)))
1518     {
1519         if(1 == retlen)
1520         {
1521             status = phNxpNciHal_send_ext_cmd (sizeof(swp_full_pwr_mode_on_cmd),
1522                                                       swp_full_pwr_mode_on_cmd);
1523             if (status != NFCSTATUS_SUCCESS)
1524             {
1525                NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING ON CMD FAILED");
1526                 retry_core_init_cnt++;
1527                 goto retry_core_init;
1528             }
1529         }
1530         else
1531         {
1532             swp_full_pwr_mode_on_cmd[7]=0x00;
1533             status = phNxpNciHal_send_ext_cmd (sizeof(swp_full_pwr_mode_on_cmd),
1534                                                       swp_full_pwr_mode_on_cmd);
1535             if (status != NFCSTATUS_SUCCESS)
1536             {
1537                 NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING OFF CMD FAILED");
1538                 retry_core_init_cnt++;
1539                 goto retry_core_init;
1540             }
1541         }
1542     }
1543 
1544     /* Android L AID Matching Platform Setting*/
1545     if(GetNxpNumValue(NAME_AID_MATCHING_PLATFORM, (void *)&retlen, sizeof(retlen)))
1546     {
1547         if(1 == retlen)
1548         {
1549             status = phNxpNciHal_send_ext_cmd (sizeof(android_l_aid_matching_mode_on_cmd),
1550                     android_l_aid_matching_mode_on_cmd);
1551             if (status != NFCSTATUS_SUCCESS)
1552             {
1553                NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
1554                 retry_core_init_cnt++;
1555                 goto retry_core_init;
1556             }
1557         }
1558         else if (2 == retlen)
1559         {
1560             android_l_aid_matching_mode_on_cmd[7]=0x00;
1561             status = phNxpNciHal_send_ext_cmd (sizeof(android_l_aid_matching_mode_on_cmd),
1562                     android_l_aid_matching_mode_on_cmd);
1563             if (status != NFCSTATUS_SUCCESS)
1564             {
1565                 NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
1566                 retry_core_init_cnt++;
1567                 goto retry_core_init;
1568             }
1569         }
1570     }
1571 
1572     if((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4))
1573     {
1574         static phLibNfc_Message_t msg;
1575         uint16_t tmp_len = 0;
1576         uint8_t uicc_set_mode[] = {0x22, 0x01, 0x02, 0x02, 0x01};
1577         uint8_t set_screen_state[] = {0x2F, 0x15, 01, 00};      //SCREEN ON
1578         uint8_t nfcc_core_conn_create[] = {0x20, 0x04, 0x06, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01};
1579         uint8_t nfcc_mode_set_on[] = {0x22, 0x01, 0x02, 0x01, 0x01};
1580 
1581         NXPLOG_NCIHAL_E("Sending DH and NFCC core connection command as raw packet!!");
1582         status = phNxpNciHal_send_ext_cmd (sizeof(nfcc_core_conn_create), nfcc_core_conn_create);
1583 
1584         if (status != NFCSTATUS_SUCCESS)
1585         {
1586             NXPLOG_NCIHAL_E("Sending DH and NFCC core connection command as raw packet!! Failed");
1587             retry_core_init_cnt++;
1588             goto retry_core_init;
1589         }
1590 
1591         NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!!");
1592         status = phNxpNciHal_send_ext_cmd (sizeof(nfcc_mode_set_on), nfcc_mode_set_on);
1593 
1594         if (status != NFCSTATUS_SUCCESS)
1595         {
1596             NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!! Failed");
1597             retry_core_init_cnt++;
1598             goto retry_core_init;
1599         }
1600 
1601         NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!!");
1602         status = phNxpNciHal_send_ext_cmd (sizeof(uicc_set_mode),
1603                                       uicc_set_mode);
1604         if (status != NFCSTATUS_SUCCESS)
1605         {
1606             NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!! Failed");
1607             retry_core_init_cnt++;
1608             goto retry_core_init;
1609         }
1610 
1611         if(*(p_core_init_rsp_params + 1) == 1) // RF state is Discovery!!
1612         {
1613             NXPLOG_NCIHAL_E("Sending Set Screen ON State Command as raw packet!!");
1614             status = phNxpNciHal_send_ext_cmd (sizeof(set_screen_state),
1615                                           set_screen_state);
1616             if (status != NFCSTATUS_SUCCESS)
1617             {
1618                 NXPLOG_NCIHAL_E("Sending Set Screen ON State Command as raw packet!! Failed");
1619                 retry_core_init_cnt++;
1620                 goto retry_core_init;
1621             }
1622 
1623             NXPLOG_NCIHAL_E("Sending discovery as raw packet!!");
1624             status = phNxpNciHal_send_ext_cmd (p_core_init_rsp_params[2],
1625                                                       (uint8_t *)&p_core_init_rsp_params[3]);
1626             if (status != NFCSTATUS_SUCCESS)
1627             {
1628                 NXPLOG_NCIHAL_E("Sending discovery as raw packet Failed");
1629                 retry_core_init_cnt++;
1630                 goto retry_core_init;
1631             }
1632 
1633         }
1634         else
1635         {
1636             NXPLOG_NCIHAL_E("Sending Set Screen OFF State Command as raw packet!!");
1637             set_screen_state[3] = 0x01; //Screen OFF
1638             status = phNxpNciHal_send_ext_cmd (sizeof(set_screen_state),
1639                                           set_screen_state);
1640             if (status != NFCSTATUS_SUCCESS)
1641             {
1642                 NXPLOG_NCIHAL_E("Sending Set Screen OFF State Command as raw packet!! Failed");
1643                 retry_core_init_cnt++;
1644                 goto retry_core_init;
1645             }
1646 
1647         }
1648         NXPLOG_NCIHAL_E("Sending last command for Recovery ");
1649 
1650         if(p_core_init_rsp_params[35] > 0)
1651         {  //if length of last command is 0 then it doesn't need to send last command.
1652             if( !(((p_core_init_rsp_params[36] == 0x21) && (p_core_init_rsp_params[37] == 0x03))
1653                 && (*(p_core_init_rsp_params + 1) == 1))&&
1654                     !((p_core_init_rsp_params[36] == 0x21) && (p_core_init_rsp_params[37] == 0x06)))
1655                 //if last command is discovery and RF staus is also discovery state, then it doesn't need to execute.
1656             {
1657                 tmp_len = p_core_init_rsp_params[35];
1658 
1659                 /* Check for NXP ext before sending write */
1660                 status = phNxpNciHal_write_ext(&tmp_len,
1661                         (uint8_t *)&p_core_init_rsp_params[36], &nxpncihal_ctrl.rsp_len,
1662                         nxpncihal_ctrl.p_rsp_data);
1663                 if (status != NFCSTATUS_SUCCESS)
1664                 {
1665                     /* Do not send packet to PN54X, send response directly */
1666                     msg.eMsgType = NCI_HAL_RX_MSG;
1667                     msg.pMsgData = NULL;
1668                     msg.Size = 0;
1669 
1670                     phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1671                             (phLibNfc_Message_t *) &msg);
1672                     return NFCSTATUS_SUCCESS;
1673                 }
1674 
1675                 p_core_init_rsp_params[35] = (uint8_t)tmp_len;
1676 
1677                 status = phNxpNciHal_send_ext_cmd (p_core_init_rsp_params[35],
1678                                                           (uint8_t *)&p_core_init_rsp_params[36]);
1679                 if (status != NFCSTATUS_SUCCESS)
1680                 {
1681                     NXPLOG_NCIHAL_E("Sending last command for Recovery Failed");
1682                     retry_core_init_cnt++;
1683                     goto retry_core_init;
1684                 }
1685             }
1686         }
1687     }
1688 
1689     retry_core_init_cnt = 0;
1690 
1691     if(buffer)
1692     {
1693         free(buffer);
1694         buffer = NULL;
1695     }
1696 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1697     //initialize dummy FW recovery variables
1698     gRecFWDwnld = 0;
1699     gRecFwRetryCount = 0;
1700 #endif
1701     if(!((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)))
1702         phNxpNciHal_core_initialized_complete(status);
1703     else
1704     {
1705 invoke_callback:
1706         config_access = FALSE;
1707         if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL)
1708         {
1709             *p_core_init_rsp_params = 0;
1710             NXPLOG_NCIHAL_E("Invoking data callback!!");
1711             (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
1712                     nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
1713         }
1714     }
1715 
1716 #ifdef PN547C2_CLOCK_SETTING
1717     if (isNxpConfigModified())
1718     {
1719         updateNxpConfigTimestamp();
1720     }
1721 #endif
1722     return NFCSTATUS_SUCCESS;
1723 }
1724 #if(NFC_NXP_CHIP_TYPE == PN548C2)
1725 /******************************************************************************
1726  * Function         phNxpNciHal_CheckRFCmdRespStatus
1727  *
1728  * Description      This function is called to check the resp status of
1729  *                  RF update commands.
1730  *
1731  * Returns          NFCSTATUS_SUCCESS           if successful,
1732  *                  NFCSTATUS_INVALID_PARAMETER if parameter is inavlid
1733  *                  NFCSTATUS_FAILED            if failed response
1734  *
1735  ******************************************************************************/
phNxpNciHal_CheckRFCmdRespStatus()1736 NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus ()
1737 {
1738     NFCSTATUS status = NFCSTATUS_SUCCESS;
1739     static uint16_t INVALID_PARAM = 0x09;
1740     if ((nxpncihal_ctrl.rx_data_len > 0) && (nxpncihal_ctrl.p_rx_data[2] > 0))
1741     {
1742         if (nxpncihal_ctrl.p_rx_data[3] == 0x09)
1743         {
1744             status = INVALID_PARAM;
1745         }
1746         else if (nxpncihal_ctrl.p_rx_data[3] != NFCSTATUS_SUCCESS)
1747         {
1748             status = NFCSTATUS_FAILED;
1749         }
1750     }
1751     return status;
1752 }
1753 /******************************************************************************
1754  * Function         phNxpNciHalRFConfigCmdRecSequence
1755  *
1756  * Description      This function is called to handle dummy FW recovery sequence
1757  *                  Whenever RF settings are failed to apply with invalid param
1758  *                  response, recovery mechanism includes dummy firmware download
1759  *                  followed by firmware download and then config settings. The dummy
1760  *                  firmware changes the major number of the firmware inside NFCC.
1761  *                  Then actual firmware dowenload will be successful. This can be
1762  *                  retried maximum three times.
1763  *
1764  * Returns          Always returns NFCSTATUS_SUCCESS
1765  *
1766  ******************************************************************************/
phNxpNciHalRFConfigCmdRecSequence()1767 NFCSTATUS phNxpNciHalRFConfigCmdRecSequence ()
1768 {
1769     NFCSTATUS status = NFCSTATUS_SUCCESS;
1770     uint16_t recFWState = 1;
1771     gRecFWDwnld = TRUE;
1772     gRecFwRetryCount++;
1773     if (gRecFwRetryCount > 0x03)
1774     {
1775         NXPLOG_NCIHAL_D ("Max retry count for RF config FW recovery exceeded ");
1776         gRecFWDwnld = FALSE;
1777         return NFCSTATUS_FAILED;
1778     }
1779     do {
1780         status = phTmlNfc_IoCtl (phTmlNfc_e_ResetDevice);
1781         phDnldNfc_InitImgInfo ();
1782         if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion ())
1783         {
1784             fw_download_success = 0;
1785             status = phNxpNciHal_fw_download ();
1786             if (status == NFCSTATUS_SUCCESS)
1787             {
1788                 fw_download_success = 1;
1789                 status = phTmlNfc_Read(
1790                     nxpncihal_ctrl.p_cmd_data,
1791                     NCI_MAX_DATA_LEN,
1792                     (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
1793                     NULL);
1794                 if (status != NFCSTATUS_PENDING)
1795                 {
1796                     NXPLOG_NCIHAL_E ("TML Read status error status = %x", status);
1797                     phTmlNfc_Shutdown ();
1798                     status = NFCSTATUS_FAILED;
1799                     break;
1800                 }
1801             }
1802             else
1803             {
1804                 status = NFCSTATUS_FAILED;
1805                 break;
1806             }
1807         }
1808         gRecFWDwnld = FALSE;
1809     }while (recFWState--);
1810     gRecFWDwnld = FALSE;
1811     return status;
1812 }
1813 #endif
1814 /******************************************************************************
1815  * Function         phNxpNciHal_core_initialized_complete
1816  *
1817  * Description      This function is called when phNxpNciHal_core_initialized
1818  *                  complete all proprietary command exchanges. This function
1819  *                  informs libnfc-nci about completion of core initialize
1820  *                  and result of that through callback.
1821  *
1822  * Returns          void.
1823  *
1824  ******************************************************************************/
phNxpNciHal_core_initialized_complete(NFCSTATUS status)1825 static void phNxpNciHal_core_initialized_complete(NFCSTATUS status)
1826 {
1827     static phLibNfc_Message_t msg;
1828 
1829     if (status == NFCSTATUS_SUCCESS)
1830     {
1831         msg.eMsgType = NCI_HAL_POST_INIT_CPLT_MSG;
1832     }
1833     else
1834     {
1835         msg.eMsgType = NCI_HAL_ERROR_MSG;
1836     }
1837     msg.pMsgData = NULL;
1838     msg.Size = 0;
1839 
1840     phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1841             (phLibNfc_Message_t *) &msg);
1842 
1843     return;
1844 }
1845 
1846 /******************************************************************************
1847  * Function         phNxpNciHal_pre_discover
1848  *
1849  * Description      This function is called by libnfc-nci to perform any
1850  *                  proprietary exchange before RF discovery. When proprietary
1851  *                  exchange is over completion is informed to libnfc-nci
1852  *                  through phNxpNciHal_pre_discover_complete function.
1853  *
1854  * Returns          It always returns NFCSTATUS_SUCCESS (0).
1855  *
1856  ******************************************************************************/
phNxpNciHal_pre_discover(void)1857 int phNxpNciHal_pre_discover(void)
1858 {
1859     /* Nothing to do here for initial version */
1860     return NFCSTATUS_SUCCESS;
1861 }
1862 
1863 /******************************************************************************
1864  * Function         phNxpNciHal_pre_discover_complete
1865  *
1866  * Description      This function informs libnfc-nci about completion and
1867  *                  status of phNxpNciHal_pre_discover through callback.
1868  *
1869  * Returns          void.
1870  *
1871  ******************************************************************************/
phNxpNciHal_pre_discover_complete(NFCSTATUS status)1872 static void phNxpNciHal_pre_discover_complete(NFCSTATUS status)
1873 {
1874     static phLibNfc_Message_t msg;
1875 
1876     if (status == NFCSTATUS_SUCCESS)
1877     {
1878         msg.eMsgType = NCI_HAL_PRE_DISCOVER_CPLT_MSG;
1879     }
1880     else
1881     {
1882         msg.eMsgType = NCI_HAL_ERROR_MSG;
1883     }
1884     msg.pMsgData = NULL;
1885     msg.Size = 0;
1886 
1887     phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1888             &msg);
1889 
1890     return;
1891 }
1892 
1893 /******************************************************************************
1894  * Function         phNxpNciHal_close
1895  *
1896  * Description      This function close the NFCC interface and free all
1897  *                  resources.This is called by libnfc-nci on NFC service stop.
1898  *
1899  * Returns          Always return NFCSTATUS_SUCCESS (0).
1900  *
1901  ******************************************************************************/
phNxpNciHal_close(void)1902 int phNxpNciHal_close(void)
1903 {
1904     NFCSTATUS status;
1905     /*NCI_RESET_CMD*/
1906     static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x00};
1907 
1908     static uint8_t cmd_ce_disc_nci[] = {0x21,0x03,0x07,0x03,0x80,0x01,0x81,0x01,0x82,0x01};
1909 
1910     CONCURRENCY_LOCK();
1911 
1912     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_disc_nci),cmd_ce_disc_nci);
1913     if(status != NFCSTATUS_SUCCESS)
1914     {
1915         NXPLOG_NCIHAL_E ("CMD_CE_DISC_NCI: Failed");
1916     }
1917 
1918     nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
1919 
1920     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
1921     if(status != NFCSTATUS_SUCCESS)
1922     {
1923         NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
1924     }
1925 
1926     if (NULL != gpphTmlNfc_Context->pDevHandle)
1927     {
1928         phNxpNciHal_close_complete(NFCSTATUS_SUCCESS);
1929         /* Abort any pending read and write */
1930         status = phTmlNfc_ReadAbort();
1931         status = phTmlNfc_WriteAbort();
1932 
1933         phOsalNfc_Timer_Cleanup();
1934 
1935         status = phTmlNfc_Shutdown();
1936 
1937         phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
1938 
1939 
1940         memset (&nxpncihal_ctrl, 0x00, sizeof (nxpncihal_ctrl));
1941 
1942         NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed");
1943     }
1944 
1945     CONCURRENCY_UNLOCK();
1946 
1947     phNxpNciHal_cleanup_monitor();
1948 
1949     /* Return success always */
1950     return NFCSTATUS_SUCCESS;
1951 }
1952 
1953 /******************************************************************************
1954  * Function         phNxpNciHal_close_complete
1955  *
1956  * Description      This function inform libnfc-nci about result of
1957  *                  phNxpNciHal_close.
1958  *
1959  * Returns          void.
1960  *
1961  ******************************************************************************/
phNxpNciHal_close_complete(NFCSTATUS status)1962 void phNxpNciHal_close_complete(NFCSTATUS status)
1963 {
1964     static phLibNfc_Message_t msg;
1965 
1966     if (status == NFCSTATUS_SUCCESS)
1967     {
1968         msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
1969     }
1970     else
1971     {
1972         msg.eMsgType = NCI_HAL_ERROR_MSG;
1973     }
1974     msg.pMsgData = NULL;
1975     msg.Size = 0;
1976 
1977     phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1978             &msg);
1979 
1980     return;
1981 }
1982 /******************************************************************************
1983  * Function         phNxpNciHal_notify_i2c_fragmentation
1984  *
1985  * Description      This function can be used by HAL to inform
1986  *                 libnfc-nci that i2c fragmentation is enabled/disabled
1987  *
1988  * Returns          void.
1989  *
1990  ******************************************************************************/
phNxpNciHal_notify_i2c_fragmentation(void)1991 void phNxpNciHal_notify_i2c_fragmentation(void)
1992 {
1993     if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
1994     {
1995         /*inform libnfc-nci that i2c fragmentation is enabled/disabled */
1996         (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT,
1997                 HAL_NFC_STATUS_OK);
1998     }
1999 }
2000 /******************************************************************************
2001  * Function         phNxpNciHal_control_granted
2002  *
2003  * Description      Called by libnfc-nci when NFCC control is granted to HAL.
2004  *
2005  * Returns          Always returns NFCSTATUS_SUCCESS (0).
2006  *
2007  ******************************************************************************/
phNxpNciHal_control_granted(void)2008 int phNxpNciHal_control_granted(void)
2009 {
2010     /* Take the concurrency lock so no other calls from upper layer
2011      * will be allowed
2012      */
2013     CONCURRENCY_LOCK();
2014 
2015     if(NULL != nxpncihal_ctrl.p_control_granted_cback)
2016     {
2017         (*nxpncihal_ctrl.p_control_granted_cback)();
2018     }
2019     /* At the end concurrency unlock so calls from upper layer will
2020      * be allowed
2021      */
2022     CONCURRENCY_UNLOCK();
2023     return NFCSTATUS_SUCCESS;
2024 }
2025 
2026 /******************************************************************************
2027  * Function         phNxpNciHal_request_control
2028  *
2029  * Description      This function can be used by HAL to request control of
2030  *                  NFCC to libnfc-nci. When control is provided to HAL it is
2031  *                  notified through phNxpNciHal_control_granted.
2032  *
2033  * Returns          void.
2034  *
2035  ******************************************************************************/
phNxpNciHal_request_control(void)2036 void phNxpNciHal_request_control(void)
2037 {
2038     if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
2039     {
2040         /* Request Control of NCI Controller from NCI NFC Stack */
2041         (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_REQUEST_CONTROL_EVT,
2042                 HAL_NFC_STATUS_OK);
2043     }
2044 
2045     return;
2046 }
2047 
2048 /******************************************************************************
2049  * Function         phNxpNciHal_release_control
2050  *
2051  * Description      This function can be used by HAL to release the control of
2052  *                  NFCC back to libnfc-nci.
2053  *
2054  * Returns          void.
2055  *
2056  ******************************************************************************/
phNxpNciHal_release_control(void)2057 void phNxpNciHal_release_control(void)
2058 {
2059     if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
2060     {
2061         /* Release Control of NCI Controller to NCI NFC Stack */
2062         (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_RELEASE_CONTROL_EVT,
2063                 HAL_NFC_STATUS_OK);
2064     }
2065 
2066     return;
2067 }
2068 
2069 /******************************************************************************
2070  * Function         phNxpNciHal_power_cycle
2071  *
2072  * Description      This function is called by libnfc-nci when power cycling is
2073  *                  performed. When processing is complete it is notified to
2074  *                  libnfc-nci through phNxpNciHal_power_cycle_complete.
2075  *
2076  * Returns          Always return NFCSTATUS_SUCCESS (0).
2077  *
2078  ******************************************************************************/
phNxpNciHal_power_cycle(void)2079 int phNxpNciHal_power_cycle(void)
2080 {
2081     NXPLOG_NCIHAL_D("Power Cycle");
2082 
2083     NFCSTATUS status = NFCSTATUS_FAILED;
2084 
2085     status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
2086 
2087     if(NFCSTATUS_SUCCESS == status)
2088     {
2089         NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
2090     }
2091     else
2092     {
2093         NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
2094     }
2095 
2096     phNxpNciHal_power_cycle_complete(NFCSTATUS_SUCCESS);
2097 
2098     return NFCSTATUS_SUCCESS;
2099 }
2100 
2101 /******************************************************************************
2102  * Function         phNxpNciHal_power_cycle_complete
2103  *
2104  * Description      This function is called to provide the status of
2105  *                  phNxpNciHal_power_cycle to libnfc-nci through callback.
2106  *
2107  * Returns          void.
2108  *
2109  ******************************************************************************/
phNxpNciHal_power_cycle_complete(NFCSTATUS status)2110 static void phNxpNciHal_power_cycle_complete(NFCSTATUS status)
2111 {
2112     static phLibNfc_Message_t msg;
2113 
2114     if (status == NFCSTATUS_SUCCESS)
2115     {
2116         msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
2117     }
2118     else
2119     {
2120         msg.eMsgType = NCI_HAL_ERROR_MSG;
2121     }
2122     msg.pMsgData = NULL;
2123     msg.Size = 0;
2124 
2125     phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
2126             &msg);
2127 
2128     return;
2129 }
2130 
2131 /******************************************************************************
2132  * Function         phNxpNciHal_get_mw_eeprom
2133  *
2134  * Description      This function is called to retreive data in mw eeprom area
2135  *
2136  * Returns          NFCSTATUS.
2137  *
2138  ******************************************************************************/
phNxpNciHal_get_mw_eeprom(void)2139 static NFCSTATUS phNxpNciHal_get_mw_eeprom (void)
2140 {
2141     NFCSTATUS status = NFCSTATUS_SUCCESS;
2142     uint8_t retry_cnt = 0;
2143     static uint8_t get_mw_eeprom_cmd[] = { 0x20, 0x03,0x03, 0x01, 0xA0, 0x0F };
2144     uint8_t bConfig;
2145 
2146 retry_send_ext:
2147     if (retry_cnt > 3)
2148     {
2149         return NFCSTATUS_FAILED;
2150     }
2151 
2152     phNxpNciMwEepromArea.isGetEepromArea = TRUE;
2153     status = phNxpNciHal_send_ext_cmd (sizeof(get_mw_eeprom_cmd), get_mw_eeprom_cmd);
2154     if (status != NFCSTATUS_SUCCESS)
2155     {
2156         NXPLOG_NCIHAL_E ("unable to get the mw eeprom data");
2157         phNxpNciMwEepromArea.isGetEepromArea = FALSE;
2158         retry_cnt++;
2159         goto retry_send_ext;
2160     }
2161     phNxpNciMwEepromArea.isGetEepromArea = FALSE;
2162 
2163     if (phNxpNciMwEepromArea.p_rx_data[12])
2164     {
2165         fw_download_success = 1;
2166     }
2167     return status;
2168 }
2169 
2170 /******************************************************************************
2171  * Function         phNxpNciHal_set_mw_eeprom
2172  *
2173  * Description      This function is called to update data in mw eeprom area
2174  *
2175  * Returns          void.
2176  *
2177  ******************************************************************************/
phNxpNciHal_set_mw_eeprom(void)2178 static NFCSTATUS phNxpNciHal_set_mw_eeprom (void)
2179 {
2180     NFCSTATUS status = NFCSTATUS_SUCCESS;
2181     uint8_t retry_cnt = 0;
2182     uint8_t set_mw_eeprom_cmd[39] = {0};
2183     uint8_t cmd_header[] = { 0x20, 0x02,0x24, 0x01, 0xA0, 0x0F, 0x20 };
2184 
2185     memcpy (set_mw_eeprom_cmd, cmd_header, sizeof(cmd_header));
2186     phNxpNciMwEepromArea.p_rx_data[12] = 0;
2187     memcpy (set_mw_eeprom_cmd + sizeof(cmd_header), phNxpNciMwEepromArea.p_rx_data, sizeof(phNxpNciMwEepromArea.p_rx_data));
2188 
2189 retry_send_ext:
2190     if (retry_cnt > 3)
2191     {
2192         return NFCSTATUS_FAILED;
2193     }
2194 
2195     status = phNxpNciHal_send_ext_cmd (sizeof(set_mw_eeprom_cmd), set_mw_eeprom_cmd);
2196     if (status != NFCSTATUS_SUCCESS)
2197     {
2198         NXPLOG_NCIHAL_E ("unable to update the mw eeprom data");
2199         retry_cnt++;
2200         goto retry_send_ext;
2201     }
2202     return status;
2203 }
2204 
2205 /******************************************************************************
2206  * Function         phNxpNciHal_set_clock
2207  *
2208  * Description      This function is called after successfull download
2209  *                  to apply the clock setting provided in config file
2210  *
2211  * Returns          void.
2212  *
2213  ******************************************************************************/
phNxpNciHal_set_clock(void)2214 static void phNxpNciHal_set_clock(void)
2215 {
2216     NFCSTATUS status = NFCSTATUS_FAILED;
2217     int retryCount = 0;
2218 
2219 retrySetclock:
2220     phNxpNciClock.isClockSet = TRUE;
2221     if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL)
2222     {
2223         static uint8_t set_clock_cmd[] = {0x20, 0x02,0x09, 0x02, 0xA0, 0x03, 0x01, 0x11,
2224                                                                0xA0, 0x04, 0x01, 0x01};
2225         uint8_t param_clock_src = CLK_SRC_PLL;
2226         param_clock_src = param_clock_src << 3;
2227 
2228         if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ)
2229         {
2230             param_clock_src |= 0x00;
2231         }
2232         else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ)
2233         {
2234             param_clock_src |= 0x01;
2235         }
2236         else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ)
2237         {
2238             param_clock_src |= 0x02;
2239         }
2240         else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ)
2241         {
2242             param_clock_src |= 0x03;
2243         }
2244         else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ)
2245         {
2246             param_clock_src |= 0x04;
2247         }
2248         else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ)
2249         {
2250             param_clock_src |= 0x05;
2251         }
2252         else
2253         {
2254             NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
2255             param_clock_src = 0x11;
2256         }
2257 
2258         set_clock_cmd[7] = param_clock_src;
2259         set_clock_cmd[11] = nxpprofile_ctrl.bTimeout;
2260         status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
2261         if (status != NFCSTATUS_SUCCESS)
2262         {
2263             NXPLOG_NCIHAL_E("PLL colck setting failed !!");
2264         }
2265     }
2266     else if(nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL)
2267     {
2268         static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x03, 0x01, 0x08};
2269         status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
2270         if (status != NFCSTATUS_SUCCESS)
2271         {
2272             NXPLOG_NCIHAL_E("XTAL colck setting failed !!");
2273         }
2274     }
2275     else
2276     {
2277         NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
2278     }
2279 
2280    // Checking for SET CONFG SUCCESS, re-send the command  if not.
2281     phNxpNciClock.isClockSet = FALSE;
2282     if(phNxpNciClock.p_rx_data[3]   != NFCSTATUS_SUCCESS )
2283     {
2284         if(retryCount++  < 3)
2285         {
2286             NXPLOG_NCIHAL_E("Set-clk failed retry again ");
2287             goto retrySetclock;
2288         }
2289         else
2290         {
2291             NXPLOG_NCIHAL_D("Set clk  failed -  max count = 0x%x exceeded ", retryCount);
2292 //            NXPLOG_NCIHAL_E("Set Config is failed for Clock Due to elctrical disturbances, aborting the NFC process");
2293 //            abort ();
2294        }
2295     }
2296 }
2297 
2298 /******************************************************************************
2299  * Function         phNxpNciHal_check_clock_config
2300  *
2301  * Description      This function is called after successfull download
2302  *                  to check if clock settings in config file and chip
2303  *                  is same
2304  *
2305  * Returns          void.
2306  *
2307  ******************************************************************************/
phNxpNciHal_check_clock_config(void)2308 NFCSTATUS phNxpNciHal_check_clock_config(void)
2309 {
2310     NFCSTATUS status = NFCSTATUS_SUCCESS;
2311     uint8_t param_clock_src;
2312     static uint8_t get_clock_cmd[] = {0x20, 0x03,0x07, 0x03, 0xA0, 0x02,
2313             0xA0, 0x03, 0xA0, 0x04};
2314     phNxpNciClock.isClockSet = TRUE;
2315     phNxpNciHal_get_clk_freq();
2316     status = phNxpNciHal_send_ext_cmd(sizeof(get_clock_cmd),get_clock_cmd);
2317 
2318     if(status != NFCSTATUS_SUCCESS)
2319     {
2320         NXPLOG_NCIHAL_E("unable to retrieve get_clk_src_sel");
2321         return status;
2322     }
2323     param_clock_src = check_config_parameter();
2324     if( phNxpNciClock.p_rx_data[12] == param_clock_src &&  phNxpNciClock.p_rx_data[16] == nxpprofile_ctrl.bTimeout)
2325     {
2326         phNxpNciClock.issetConfig = FALSE;
2327     }else {
2328         phNxpNciClock.issetConfig = TRUE;
2329     }
2330     phNxpNciClock.isClockSet = FALSE;
2331 
2332     return status;
2333 }
2334 
2335 /******************************************************************************
2336  * Function         phNxpNciHal_china_tianjin_rf_setting
2337  *
2338  * Description      This function is called to check RF Setting
2339  *
2340  * Returns          Status.
2341  *
2342  ******************************************************************************/
phNxpNciHal_china_tianjin_rf_setting(void)2343 NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void)
2344 {
2345     NFCSTATUS status = NFCSTATUS_SUCCESS;
2346     int isfound = 0;
2347     int rf_enable = FALSE;
2348     int rf_val = 0;
2349     int send_flag;
2350     uint8_t retry_cnt =0;
2351     int enable_bit =0;
2352     static uint8_t get_rf_cmd[] = {0x20, 0x03,0x03, 0x01, 0xA0, 0x85};
2353 
2354 retry_send_ext:
2355     if(retry_cnt > 3)
2356     {
2357         return NFCSTATUS_FAILED;
2358     }
2359     send_flag = TRUE;
2360     phNxpNciRfSet.isGetRfSetting = TRUE;
2361     status = phNxpNciHal_send_ext_cmd(sizeof(get_rf_cmd),get_rf_cmd);
2362     if(status != NFCSTATUS_SUCCESS)
2363     {
2364         NXPLOG_NCIHAL_E("unable to get the RF setting");
2365         phNxpNciRfSet.isGetRfSetting = FALSE;
2366         retry_cnt++;
2367         goto retry_send_ext;
2368     }
2369     phNxpNciRfSet.isGetRfSetting = FALSE;
2370     if(phNxpNciRfSet.p_rx_data[3] != 0x00)
2371     {
2372         NXPLOG_NCIHAL_E("GET_CONFIG_RSP is FAILED for CHINA TIANJIN");
2373         return status;
2374     }
2375     rf_val = phNxpNciRfSet.p_rx_data[10];
2376     isfound = (GetNxpNumValue(NAME_NXP_CHINA_TIANJIN_RF_ENABLED, (void *)&rf_enable, sizeof(rf_enable)));
2377     if(isfound >0)
2378     {
2379         enable_bit = rf_val & 0x40;
2380         if((enable_bit != 0x40) && (rf_enable == 1))
2381         {
2382             phNxpNciRfSet.p_rx_data[10] |= 0x40;   // Enable if it is disabled
2383         }
2384         else if((enable_bit == 0x40) && (rf_enable == 0))
2385         {
2386             phNxpNciRfSet.p_rx_data[10] &= 0xBF;  // Disable if it is Enabled
2387         }
2388         else
2389         {
2390             send_flag = FALSE;  // No need to change in RF setting
2391         }
2392 
2393         if(send_flag == TRUE)
2394         {
2395             static uint8_t set_rf_cmd[] = {0x20, 0x02, 0x08, 0x01, 0xA0, 0x85, 0x04, 0x50, 0x08, 0x68, 0x00};
2396             memcpy(&set_rf_cmd[4],&phNxpNciRfSet.p_rx_data[5],7);
2397             status = phNxpNciHal_send_ext_cmd(sizeof(set_rf_cmd),set_rf_cmd);
2398             if(status != NFCSTATUS_SUCCESS)
2399             {
2400                 NXPLOG_NCIHAL_E("unable to set the RF setting");
2401                 retry_cnt++;
2402                 goto retry_send_ext;
2403             }
2404         }
2405     }
2406 
2407     return status;
2408 }
2409 
check_config_parameter()2410 int  check_config_parameter()
2411 {
2412     NFCSTATUS status = NFCSTATUS_FAILED;
2413     uint8_t param_clock_src = CLK_SRC_PLL;
2414     if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL)
2415     {
2416         param_clock_src = param_clock_src << 3;
2417 
2418         if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ)
2419         {
2420             param_clock_src |= 0x00;
2421         }
2422         else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ)
2423         {
2424             param_clock_src |= 0x01;
2425         }
2426         else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ)
2427         {
2428             param_clock_src |= 0x02;
2429         }
2430         else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ)
2431         {
2432             param_clock_src |= 0x03;
2433         }
2434         else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ)
2435         {
2436             param_clock_src |= 0x04;
2437         }
2438         else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ)
2439         {
2440             param_clock_src |= 0x05;
2441         }
2442         else
2443         {
2444             NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
2445             param_clock_src = 0x11;
2446         }
2447     }
2448     else if(nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL)
2449     {
2450         param_clock_src = 0x08;
2451 
2452     }
2453     else
2454     {
2455         NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
2456     }
2457     return param_clock_src;
2458 }
2459 /******************************************************************************
2460  * Function         phNxpNciHal_enable_i2c_fragmentation
2461  *
2462  * Description      This function is called to process the response status
2463  *                  and print the status byte.
2464  *
2465  * Returns          void.
2466  *
2467  ******************************************************************************/
phNxpNciHal_enable_i2c_fragmentation()2468 void phNxpNciHal_enable_i2c_fragmentation()
2469 {
2470     NFCSTATUS status = NFCSTATUS_FAILED;
2471     static uint8_t fragmentation_enable_config_cmd[] = { 0x20, 0x02, 0x05, 0x01, 0xA0, 0x05, 0x01, 0x10};
2472     int isfound = 0;
2473     long i2c_status = 0x00;
2474     long config_i2c_vlaue = 0xff;
2475     /*NCI_RESET_CMD*/
2476     static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x01};
2477     /*NCI_INIT_CMD*/
2478     static uint8_t cmd_init_nci[] = {0x20,0x01,0x00};
2479     static uint8_t get_i2c_fragmentation_cmd[] = {0x20, 0x03, 0x03, 0x01 ,0xA0 ,0x05};
2480     isfound = (GetNxpNumValue(NAME_NXP_I2C_FRAGMENTATION_ENABLED, (void *)&i2c_status, sizeof(i2c_status)));
2481     status = phNxpNciHal_send_ext_cmd(sizeof(get_i2c_fragmentation_cmd),get_i2c_fragmentation_cmd);
2482     if(status != NFCSTATUS_SUCCESS)
2483     {
2484         NXPLOG_NCIHAL_E("unable to retrieve  get_i2c_fragmentation_cmd");
2485     }
2486     else
2487     {
2488         if(nxpncihal_ctrl.p_rx_data[8] == 0x10)
2489         {
2490             config_i2c_vlaue = 0x01;
2491             phNxpNciHal_notify_i2c_fragmentation();
2492             phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
2493         }
2494         else if(nxpncihal_ctrl.p_rx_data[8] == 0x00)
2495         {
2496             config_i2c_vlaue = 0x00;
2497         }
2498         if( config_i2c_vlaue == i2c_status)
2499         {
2500             NXPLOG_NCIHAL_E("i2c_fragmentation_status existing");
2501         }
2502         else
2503         {
2504             if (i2c_status == 0x01)
2505             {
2506                 /* NXP I2C fragmenation enabled*/
2507                 status = phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd), fragmentation_enable_config_cmd);
2508                 if (status != NFCSTATUS_SUCCESS)
2509                 {
2510                     NXPLOG_NCIHAL_E("NXP fragmentation enable failed");
2511                 }
2512             }
2513             else if (i2c_status == 0x00 || config_i2c_vlaue == 0xff)
2514             {
2515                 fragmentation_enable_config_cmd[7] = 0x00;
2516                 /* NXP I2C fragmentation disabled*/
2517                 status = phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd), fragmentation_enable_config_cmd);
2518                 if (status != NFCSTATUS_SUCCESS)
2519                 {
2520                     NXPLOG_NCIHAL_E("NXP fragmentation disable failed");
2521                 }
2522             }
2523             status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
2524             if(status != NFCSTATUS_SUCCESS)
2525             {
2526                 NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
2527             }
2528             status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci),cmd_init_nci);
2529             if(status != NFCSTATUS_SUCCESS)
2530             {
2531                 NXPLOG_NCIHAL_E ("NCI_CORE_INIT : Failed");
2532             }
2533             else if(i2c_status == 0x01)
2534             {
2535                 phNxpNciHal_notify_i2c_fragmentation();
2536                 phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
2537             }
2538         }
2539     }
2540 }
2541 /******************************************************************************
2542  * Function         phNxpNciHal_check_factory_reset
2543  *
2544  * Description      This function is called at init time to check
2545  *                  the presence of ese related info. If file are not
2546  *                  present set the SWP_INT_SESSION_ID_CFG to FF to
2547  *                  force the NFCEE to re-run its initialization sequence.
2548  *
2549  * Returns          void.
2550  *
2551  ******************************************************************************/
phNxpNciHal_check_factory_reset(void)2552 static void phNxpNciHal_check_factory_reset(void)
2553 {
2554     struct stat st;
2555     int ret = 0;
2556     NFCSTATUS status = NFCSTATUS_FAILED;
2557     const char config_eseinfo_path[] = "/data/nfc/nfaStorage.bin1";
2558     static uint8_t reset_ese_session_identity_set[] = { 0x20, 0x02, 0x17, 0x02,
2559                                       0xA0, 0xEA, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
2560                                       0xA0, 0xEB, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2561 #ifdef PN547C2_FACTORY_RESET_DEBUG
2562     static uint8_t reset_ese_session_identity[] = { 0x20, 0x03, 0x05, 0x02,
2563                                           0xA0, 0xEA, 0xA0, 0xEB};
2564 #endif
2565     if (stat(config_eseinfo_path, &st) == -1)
2566     {
2567         NXPLOG_NCIHAL_D("%s file not present = %s", __FUNCTION__, config_eseinfo_path);
2568         ret = -1;
2569     }
2570     else
2571     {
2572         ret = 0;
2573     }
2574 
2575     if(ret == -1)
2576     {
2577 #ifdef PN547C2_FACTORY_RESET_DEBUG
2578         /* NXP ACT Proprietary Ext */
2579         status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity),
2580                                            reset_ese_session_identity);
2581         if (status != NFCSTATUS_SUCCESS) {
2582             NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed");
2583         }
2584 #endif
2585         status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity_set),
2586                                            reset_ese_session_identity_set);
2587         if (status != NFCSTATUS_SUCCESS) {
2588             NXPLOG_NCIHAL_E("NXP reset_ese_session_identity_set command failed");
2589         }
2590 #ifdef PN547C2_FACTORY_RESET_DEBUG
2591         /* NXP ACT Proprietary Ext */
2592         status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity),
2593                                            reset_ese_session_identity);
2594         if (status != NFCSTATUS_SUCCESS) {
2595             NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed");
2596         }
2597 #endif
2598 
2599     }
2600 }
2601 
2602 /******************************************************************************
2603  * Function         phNxpNciHal_print_res_status
2604  *
2605  * Description      This function is called to process the response status
2606  *                  and print the status byte.
2607  *
2608  * Returns          void.
2609  *
2610  ******************************************************************************/
phNxpNciHal_print_res_status(uint8_t * p_rx_data,uint16_t * p_len)2611 static void phNxpNciHal_print_res_status( uint8_t *p_rx_data, uint16_t *p_len)
2612 {
2613     static uint8_t response_buf[][30] = {"STATUS_OK",
2614                                      "STATUS_REJECTED",
2615                                      "STATUS_RF_FRAME_CORRUPTED" ,
2616                                      "STATUS_FAILED" ,
2617                                      "STATUS_NOT_INITIALIZED" ,
2618                                      "STATUS_SYNTAX_ERROR",
2619                                      "STATUS_SEMANTIC_ERROR",
2620                                      "RFU",
2621                                      "RFU",
2622                                      "STATUS_INVALID_PARAM",
2623                                      "STATUS_MESSAGE_SIZE_EXCEEDED",
2624                                      "STATUS_UNDEFINED"};
2625     int status_byte;
2626     if(p_rx_data[0] == 0x40 && (p_rx_data[1] == 0x02 || p_rx_data[1] == 0x03))
2627     {
2628         if(p_rx_data[2] &&  p_rx_data[3]<=10)
2629         {
2630             status_byte = p_rx_data[CORE_RES_STATUS_BYTE];
2631             NXPLOG_NCIHAL_D("%s: response status =%s",__FUNCTION__,response_buf[status_byte]);
2632         }
2633         else
2634         {
2635             NXPLOG_NCIHAL_D("%s: response status =%s",__FUNCTION__,response_buf[11]);
2636         }
2637         if(phNxpNciClock.isClockSet)
2638         {
2639             int i;
2640             for(i=0; i<* p_len; i++)
2641             {
2642                 phNxpNciClock.p_rx_data[i] = p_rx_data[i];
2643             }
2644         }
2645 
2646         else if(phNxpNciRfSet.isGetRfSetting)
2647         {
2648             int i;
2649             for(i=0; i<* p_len; i++)
2650             {
2651                 phNxpNciRfSet.p_rx_data[i] = p_rx_data[i];
2652                 //NXPLOG_NCIHAL_D("%s: response status =0x%x",__FUNCTION__,p_rx_data[i]);
2653             }
2654         }
2655         else if (phNxpNciMwEepromArea.isGetEepromArea)
2656         {
2657             int i;
2658             for (i = 8; i < *p_len; i++)
2659             {
2660                 phNxpNciMwEepromArea.p_rx_data[i - 8] = p_rx_data[i];
2661             }
2662         }
2663     }
2664 
2665     if (p_rx_data[2] && (config_access == TRUE))
2666     {
2667         if (p_rx_data[3] != NFCSTATUS_SUCCESS)
2668         {
2669             NXPLOG_NCIHAL_W ("Invalid Data from config file . Aborting..");
2670             phNxpNciHal_close ();
2671         }
2672     }
2673 }
2674 
phNxpNciHal_core_reset_recovery()2675 NFCSTATUS phNxpNciHal_core_reset_recovery ()
2676 {
2677     NFCSTATUS status = NFCSTATUS_FAILED;
2678 
2679     uint8_t buffer[260];
2680     long bufflen = 260;
2681 
2682     /*NCI_INIT_CMD*/
2683     static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
2684     /*NCI_RESET_CMD*/
2685     static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00}; //keep configuration
2686 
2687     /* reset config cache */
2688     uint8_t retry_core_init_cnt = 0;
2689 
2690     if (discovery_cmd_len == 0)
2691     {
2692         goto FAILURE;
2693     }
2694     NXPLOG_NCIHAL_D ("%s: recovery", __FUNCTION__);
2695 
2696 retry_core_init:
2697     if (retry_core_init_cnt > 3)
2698     {
2699         goto FAILURE;
2700     }
2701 
2702     status = phTmlNfc_IoCtl (phTmlNfc_e_ResetDevice);
2703     if (status != NFCSTATUS_SUCCESS)
2704     {
2705         NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
2706         goto FAILURE;
2707     }
2708     status = phNxpNciHal_send_ext_cmd (sizeof(cmd_reset_nci), cmd_reset_nci);
2709     if ((status != NFCSTATUS_SUCCESS) && (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT))
2710     {
2711         retry_core_init_cnt++;
2712         goto retry_core_init;
2713     }
2714     else if (status != NFCSTATUS_SUCCESS)
2715     {
2716         NXPLOG_NCIHAL_D ("NCI_CORE_RESET: Failed");
2717         retry_core_init_cnt++;
2718         goto retry_core_init;
2719     }
2720     status = phNxpNciHal_send_ext_cmd (sizeof(cmd_init_nci), cmd_init_nci);
2721     if (status != NFCSTATUS_SUCCESS)
2722     {
2723         NXPLOG_NCIHAL_D ("NCI_CORE_INIT : Failed");
2724         retry_core_init_cnt++;
2725         goto retry_core_init;
2726     }
2727 
2728     status = phNxpNciHal_send_ext_cmd (discovery_cmd_len, discovery_cmd);
2729     if (status != NFCSTATUS_SUCCESS)
2730     {
2731         NXPLOG_NCIHAL_D ("RF_DISCOVERY : Failed");
2732         retry_core_init_cnt++;
2733         goto retry_core_init;
2734     }
2735     return NFCSTATUS_SUCCESS;
2736 FAILURE:
2737     abort ();
2738 }
2739 
phNxpNciHal_discovery_cmd_ext(uint8_t * p_cmd_data,uint16_t cmd_len)2740 void phNxpNciHal_discovery_cmd_ext (uint8_t *p_cmd_data, uint16_t cmd_len)
2741 {
2742     NXPLOG_NCIHAL_D ("phNxpNciHal_discovery_cmd_ext");
2743     if (cmd_len > 0 && cmd_len <= sizeof(discovery_cmd))
2744     {
2745         memcpy (discovery_cmd, p_cmd_data, cmd_len);
2746         discovery_cmd_len = cmd_len;
2747     }
2748 }
2749