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