phNxpNciHal.c revision 63f0a64a173a498d11e559b83b7c681ce77f939e
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 */
35extern uint8_t icode_send_eof;
36extern uint8_t icode_detected;
37static uint8_t cmd_icode_eof[] = {0x00, 0x00, 0x00};
38
39/* FW download success flag */
40static uint8_t fw_download_success = 0;
41
42static uint8_t config_access = false;
43/* NCI HAL Control structure */
44phNxpNciHal_Control_t nxpncihal_ctrl;
45
46/* NXP Poll Profile structure */
47phNxpNciProfile_Control_t nxpprofile_ctrl;
48
49/* TML Context */
50extern phTmlNfc_Context_t* gpphTmlNfc_Context;
51extern void phTmlNfc_set_fragmentation_enabled(
52    phTmlNfc_i2cfragmentation_t result);
53/* global variable to get FW version from NCI response*/
54uint32_t wFwVerRsp;
55/* External global variable to get FW version */
56extern uint16_t wFwVer;
57
58extern uint16_t fw_maj_ver;
59extern uint16_t rom_version;
60extern int send_to_upper_kovio;
61extern int kovio_detected;
62extern int disable_kovio;
63#if (NFC_NXP_CHIP_TYPE != PN547C2)
64extern uint8_t gRecFWDwnld;
65static uint8_t gRecFwRetryCount;  // variable to hold dummy FW recovery count
66#endif
67static uint8_t Rx_data[NCI_MAX_DATA_LEN];
68
69#if (NFC_NXP_CHIP_TYPE == PN548C2)
70uint8_t discovery_cmd[50] = {0};
71uint8_t discovery_cmd_len = 0;
72#endif
73extern bool_t rf_deactive_cmd;
74uint32_t timeoutTimerId = 0;
75phNxpNciHal_Sem_t config_data;
76
77phNxpNciClock_t phNxpNciClock = {0, {0}, false};
78
79phNxpNciRfSetting_t phNxpNciRfSet = {false, {0}};
80
81phNxpNciMwEepromArea_t phNxpNciMwEepromArea = {false, {0}};
82
83/**************** local methods used in this file only ************************/
84static NFCSTATUS phNxpNciHal_fw_download(void);
85static void phNxpNciHal_open_complete(NFCSTATUS status);
86static void phNxpNciHal_write_complete(void* pContext,
87                                       phTmlNfc_TransactInfo_t* pInfo);
88static void phNxpNciHal_read_complete(void* pContext,
89                                      phTmlNfc_TransactInfo_t* pInfo);
90static void phNxpNciHal_close_complete(NFCSTATUS status);
91static void phNxpNciHal_core_initialized_complete(NFCSTATUS status);
92static void phNxpNciHal_pre_discover_complete(NFCSTATUS status);
93static void phNxpNciHal_power_cycle_complete(NFCSTATUS status);
94static void phNxpNciHal_kill_client_thread(
95    phNxpNciHal_Control_t* p_nxpncihal_ctrl);
96static void* phNxpNciHal_client_thread(void* arg);
97static void phNxpNciHal_get_clk_freq(void);
98static void phNxpNciHal_set_clock(void);
99static void phNxpNciHal_check_factory_reset(void);
100static void phNxpNciHal_print_res_status(uint8_t* p_rx_data, uint16_t* p_len);
101static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void);
102static void phNxpNciHal_enable_i2c_fragmentation();
103static NFCSTATUS phNxpNciHal_get_mw_eeprom(void);
104static NFCSTATUS phNxpNciHal_set_mw_eeprom(void);
105static int phNxpNciHal_fw_mw_ver_check();
106NFCSTATUS phNxpNciHal_check_clock_config(void);
107NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void);
108#if (NFC_NXP_CHIP_TYPE != PN547C2)
109static NFCSTATUS phNxpNciHalRFConfigCmdRecSequence();
110static NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus();
111#endif
112int 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 ******************************************************************************/
123static 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 ******************************************************************************/
237static 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 ******************************************************************************/
260static 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 ******************************************************************************/
291static 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
350static 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 ******************************************************************************/
418int 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
528init_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
616clean_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 ******************************************************************************/
642int 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 ******************************************************************************/
665static 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 ******************************************************************************/
696int 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
753clean_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 ******************************************************************************/
769int 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
787retry:
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
845clean_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 ******************************************************************************/
858static 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 ******************************************************************************/
889static 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
947void 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 ******************************************************************************/
968int 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 (isNxpConfigModified() || (fw_download_success == 1) ||
1091      (phNxpNciClock.issetConfig)
1092#if (NFC_NXP_HFO_SETTINGS == TRUE)
1093      || temp_fix == 1
1094#endif
1095      ) {
1096    // phNxpNciHal_get_clk_freq();
1097    phNxpNciHal_set_clock();
1098    phNxpNciClock.issetConfig = false;
1099#if (NFC_NXP_HFO_SETTINGS == TRUE)
1100    if (temp_fix == 1) {
1101      NXPLOG_NCIHAL_D(
1102          "Applying Default Clock setting and DPLL register at power on");
1103      /*
1104      # A0, 0D, 06, 06, 83, 55, 2A, 04, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_GEAR_REG
1105      # A0, 0D, 06, 06, 82, 33, 14, 17, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_REG
1106      # A0, 0D, 06, 06, 84, AA, 85, 00, 80 RF_CLIF_CFG_TARGET
1107      CLIF_DPLL_INIT_FREQ_REG
1108      # A0, 0D, 06, 06, 81, 63, 00, 00, 00 RF_CLIF_CFG_TARGET
1109      CLIF_DPLL_CONTROL_REG
1110      */
1111      static uint8_t cmd_dpll_set_reg_nci[] = {
1112          0x20, 0x02, 0x25, 0x04, 0xA0, 0x0D, 0x06, 0x06, 0x83, 0x55,
1113          0x2A, 0x04, 0x00, 0xA0, 0x0D, 0x06, 0x06, 0x82, 0x33, 0x14,
1114          0x17, 0x00, 0xA0, 0x0D, 0x06, 0x06, 0x84, 0xAA, 0x85, 0x00,
1115          0x80, 0xA0, 0x0D, 0x06, 0x06, 0x81, 0x63, 0x00, 0x00, 0x00};
1116
1117      status = phNxpNciHal_send_ext_cmd(sizeof(cmd_dpll_set_reg_nci),
1118                                        cmd_dpll_set_reg_nci);
1119      if (status != NFCSTATUS_SUCCESS) {
1120        NXPLOG_NCIHAL_E("NXP DPLL REG ACT Proprietary Ext failed");
1121        retry_core_init_cnt++;
1122        goto retry_core_init;
1123      }
1124      /* reset the NFCC after applying the clock setting and DPLL setting */
1125      // phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1126      temp_fix = 0;
1127      goto retry_core_init;
1128    }
1129#endif
1130  }
1131#endif
1132
1133  phNxpNciHal_check_factory_reset();
1134  retlen = 0;
1135  config_access = true;
1136  isfound = GetNxpByteArrayValue(NAME_NXP_NFC_PROFILE_EXTN, (char*)buffer,
1137                                 bufflen, &retlen);
1138  if (retlen > 0) {
1139    /* NXP ACT Proprietary Ext */
1140    status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1141    if (status != NFCSTATUS_SUCCESS) {
1142      NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
1143      retry_core_init_cnt++;
1144      goto retry_core_init;
1145    }
1146  }
1147
1148  if (isNxpConfigModified() || (fw_download_success == 1)) {
1149    retlen = 0;
1150    fw_download_success = 0;
1151
1152#if (NFC_NXP_CHIP_TYPE != PN547C2)
1153    NXPLOG_NCIHAL_D("Performing TVDD Settings");
1154    isfound = GetNxpNumValue(NAME_NXP_EXT_TVDD_CFG, &num, sizeof(num));
1155    if (isfound > 0) {
1156      if (num == 1) {
1157        isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_1, (char*)buffer,
1158                                       bufflen, &retlen);
1159        if (retlen > 0) {
1160          status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1161          if (status != NFCSTATUS_SUCCESS) {
1162            NXPLOG_NCIHAL_E("EXT TVDD CFG 1 Settings failed");
1163            retry_core_init_cnt++;
1164            goto retry_core_init;
1165          }
1166        }
1167      } else if (num == 2) {
1168        isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_2, (char*)buffer,
1169                                       bufflen, &retlen);
1170        if (retlen > 0) {
1171          status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1172          if (status != NFCSTATUS_SUCCESS) {
1173            NXPLOG_NCIHAL_E("EXT TVDD CFG 2 Settings failed");
1174            retry_core_init_cnt++;
1175            goto retry_core_init;
1176          }
1177        }
1178      } else if (num == 3) {
1179        isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_3, (char*)buffer,
1180                                       bufflen, &retlen);
1181        if (retlen > 0) {
1182          status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1183          if (status != NFCSTATUS_SUCCESS) {
1184            NXPLOG_NCIHAL_E("EXT TVDD CFG 3 Settings failed");
1185            retry_core_init_cnt++;
1186            goto retry_core_init;
1187          }
1188        }
1189      } else {
1190        NXPLOG_NCIHAL_E("Wrong Configuration Value %ld", num);
1191      }
1192    }
1193#endif
1194    retlen = 0;
1195#if (NFC_NXP_CHIP_TYPE != PN547C2)
1196    config_access = false;
1197#endif
1198    NXPLOG_NCIHAL_D("Performing RF Settings BLK 1");
1199    isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_1, (char*)buffer,
1200                                   bufflen, &retlen);
1201    if (retlen > 0) {
1202      status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1203#if (NFC_NXP_CHIP_TYPE != PN547C2)
1204      if (status == NFCSTATUS_SUCCESS) {
1205        status = phNxpNciHal_CheckRFCmdRespStatus();
1206        /*STATUS INVALID PARAM 0x09*/
1207        if (status == 0x09) {
1208          phNxpNciHalRFConfigCmdRecSequence();
1209          retry_core_init_cnt++;
1210          goto retry_core_init;
1211        }
1212      } else
1213#endif
1214          if (status != NFCSTATUS_SUCCESS) {
1215        NXPLOG_NCIHAL_E("RF Settings BLK 1 failed");
1216        retry_core_init_cnt++;
1217        goto retry_core_init;
1218      }
1219    }
1220    retlen = 0;
1221
1222    NXPLOG_NCIHAL_D("Performing RF Settings BLK 2");
1223    isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_2, (char*)buffer,
1224                                   bufflen, &retlen);
1225    if (retlen > 0) {
1226      status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1227#if (NFC_NXP_CHIP_TYPE != PN547C2)
1228      if (status == NFCSTATUS_SUCCESS) {
1229        status = phNxpNciHal_CheckRFCmdRespStatus();
1230        /*STATUS INVALID PARAM 0x09*/
1231        if (status == 0x09) {
1232          phNxpNciHalRFConfigCmdRecSequence();
1233          retry_core_init_cnt++;
1234          goto retry_core_init;
1235        }
1236      } else
1237#endif
1238          if (status != NFCSTATUS_SUCCESS) {
1239        NXPLOG_NCIHAL_E("RF Settings BLK 2 failed");
1240        retry_core_init_cnt++;
1241        goto retry_core_init;
1242      }
1243    }
1244    retlen = 0;
1245
1246    NXPLOG_NCIHAL_D("Performing RF Settings BLK 3");
1247    isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_3, (char*)buffer,
1248                                   bufflen, &retlen);
1249    if (retlen > 0) {
1250      status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1251#if (NFC_NXP_CHIP_TYPE != PN547C2)
1252      if (status == NFCSTATUS_SUCCESS) {
1253        status = phNxpNciHal_CheckRFCmdRespStatus();
1254        /*STATUS INVALID PARAM 0x09*/
1255        if (status == 0x09) {
1256          phNxpNciHalRFConfigCmdRecSequence();
1257          retry_core_init_cnt++;
1258          goto retry_core_init;
1259        }
1260      } else
1261#endif
1262          if (status != NFCSTATUS_SUCCESS) {
1263        NXPLOG_NCIHAL_E("RF Settings BLK 3 failed");
1264        retry_core_init_cnt++;
1265        goto retry_core_init;
1266      }
1267    }
1268    retlen = 0;
1269
1270    NXPLOG_NCIHAL_D("Performing RF Settings BLK 4");
1271    isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_4, (char*)buffer,
1272                                   bufflen, &retlen);
1273    if (retlen > 0) {
1274      status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1275#if (NFC_NXP_CHIP_TYPE != PN547C2)
1276      if (status == NFCSTATUS_SUCCESS) {
1277        status = phNxpNciHal_CheckRFCmdRespStatus();
1278        /*STATUS INVALID PARAM 0x09*/
1279        if (status == 0x09) {
1280          phNxpNciHalRFConfigCmdRecSequence();
1281          retry_core_init_cnt++;
1282          goto retry_core_init;
1283        }
1284      } else
1285#endif
1286          if (status != NFCSTATUS_SUCCESS) {
1287        NXPLOG_NCIHAL_E("RF Settings BLK 4 failed");
1288        retry_core_init_cnt++;
1289        goto retry_core_init;
1290      }
1291    }
1292    retlen = 0;
1293
1294    NXPLOG_NCIHAL_D("Performing RF Settings BLK 5");
1295    isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_5, (char*)buffer,
1296                                   bufflen, &retlen);
1297    if (retlen > 0) {
1298      status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1299#if (NFC_NXP_CHIP_TYPE != PN547C2)
1300      if (status == NFCSTATUS_SUCCESS) {
1301        status = phNxpNciHal_CheckRFCmdRespStatus();
1302        /*STATUS INVALID PARAM 0x09*/
1303        if (status == 0x09) {
1304          phNxpNciHalRFConfigCmdRecSequence();
1305          retry_core_init_cnt++;
1306          goto retry_core_init;
1307        }
1308      } else
1309#endif
1310          if (status != NFCSTATUS_SUCCESS) {
1311        NXPLOG_NCIHAL_E("RF Settings BLK 5 failed");
1312        retry_core_init_cnt++;
1313        goto retry_core_init;
1314      }
1315    }
1316    retlen = 0;
1317
1318    NXPLOG_NCIHAL_D("Performing RF Settings BLK 6");
1319    isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_6, (char*)buffer,
1320                                   bufflen, &retlen);
1321    if (retlen > 0) {
1322      status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1323#if (NFC_NXP_CHIP_TYPE != PN547C2)
1324      if (status == NFCSTATUS_SUCCESS) {
1325        status = phNxpNciHal_CheckRFCmdRespStatus();
1326        /*STATUS INVALID PARAM 0x09*/
1327        if (status == 0x09) {
1328          phNxpNciHalRFConfigCmdRecSequence();
1329          retry_core_init_cnt++;
1330          goto retry_core_init;
1331        }
1332      } else
1333#endif
1334          if (status != NFCSTATUS_SUCCESS) {
1335        NXPLOG_NCIHAL_E("RF Settings BLK 6 failed");
1336        retry_core_init_cnt++;
1337        goto retry_core_init;
1338      }
1339    }
1340    retlen = 0;
1341#if (NFC_NXP_CHIP_TYPE != PN547C2)
1342    config_access = true;
1343#endif
1344    NXPLOG_NCIHAL_D("Performing NAME_NXP_CORE_CONF_EXTN Settings");
1345    isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF_EXTN, (char*)buffer,
1346                                   bufflen, &retlen);
1347    if (retlen > 0) {
1348      /* NXP ACT Proprietary Ext */
1349      status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1350      if (status != NFCSTATUS_SUCCESS) {
1351        NXPLOG_NCIHAL_E("NXP Core configuration failed");
1352        retry_core_init_cnt++;
1353        goto retry_core_init;
1354      }
1355    }
1356
1357    retlen = 0;
1358
1359    isfound = GetNxpByteArrayValue(NAME_NXP_CORE_MFCKEY_SETTING, (char*)buffer,
1360                                   bufflen, &retlen);
1361    if (retlen > 0) {
1362      /* NXP ACT Proprietary Ext */
1363      status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1364      if (status != NFCSTATUS_SUCCESS) {
1365        NXPLOG_NCIHAL_E("Setting mifare keys failed");
1366        retry_core_init_cnt++;
1367        goto retry_core_init;
1368      }
1369    }
1370
1371    retlen = 0;
1372#if (NFC_NXP_CHIP_TYPE != PN547C2)
1373    config_access = false;
1374#endif
1375    isfound = GetNxpByteArrayValue(NAME_NXP_CORE_RF_FIELD, (char*)buffer,
1376                                   bufflen, &retlen);
1377    if (retlen > 0) {
1378      /* NXP ACT Proprietary Ext */
1379      status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1380#if (NFC_NXP_CHIP_TYPE != PN547C2)
1381      if (status == NFCSTATUS_SUCCESS) {
1382        status = phNxpNciHal_CheckRFCmdRespStatus();
1383        /*STATUS INVALID PARAM 0x09*/
1384        if (status == 0x09) {
1385          phNxpNciHalRFConfigCmdRecSequence();
1386          retry_core_init_cnt++;
1387          goto retry_core_init;
1388        }
1389      } else
1390#endif
1391          if (status != NFCSTATUS_SUCCESS) {
1392        NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
1393        retry_core_init_cnt++;
1394        goto retry_core_init;
1395      }
1396    }
1397#if (NFC_NXP_CHIP_TYPE != PN547C2)
1398    config_access = true;
1399#endif
1400
1401    retlen = 0;
1402#if (NFC_NXP_CHIP_TYPE != PN547C2)
1403    /* NXP SWP switch timeout Setting*/
1404    if (GetNxpNumValue(NAME_NXP_SWP_SWITCH_TIMEOUT, (void*)&retlen,
1405                       sizeof(retlen))) {
1406      // Check the permissible range [0 - 60]
1407      if (0 <= retlen && retlen <= 60) {
1408        if (0 < retlen) {
1409          unsigned int timeout = retlen * 1000;
1410          unsigned int timeoutHx = 0x0000;
1411
1412          char tmpbuffer[10] = {0};
1413          snprintf((char*)tmpbuffer, 10, "%04x", timeout);
1414          sscanf((char*)tmpbuffer, "%x", &timeoutHx);
1415
1416          swp_switch_timeout_cmd[7] = (timeoutHx & 0xFF);
1417          swp_switch_timeout_cmd[8] = ((timeoutHx & 0xFF00) >> 8);
1418        }
1419
1420        status = phNxpNciHal_send_ext_cmd(sizeof(swp_switch_timeout_cmd),
1421                                          swp_switch_timeout_cmd);
1422        if (status != NFCSTATUS_SUCCESS) {
1423          NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed");
1424          retry_core_init_cnt++;
1425          goto retry_core_init;
1426        }
1427      } else {
1428        NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed - out of range!");
1429      }
1430    }
1431
1432    status = phNxpNciHal_china_tianjin_rf_setting();
1433    if (status != NFCSTATUS_SUCCESS) {
1434      NXPLOG_NCIHAL_E("phNxpNciHal_china_tianjin_rf_setting failed");
1435      return NFCSTATUS_FAILED;
1436    }
1437#endif
1438    // Update eeprom value
1439    status = phNxpNciHal_set_mw_eeprom();
1440    if (status != NFCSTATUS_SUCCESS) {
1441      NXPLOG_NCIHAL_E("NXP Update MW EEPROM Proprietary Ext failed");
1442    }
1443  }
1444
1445  retlen = 0;
1446
1447  isfound = GetNxpByteArrayValue(NAME_NXP_CORE_STANDBY, (char*)buffer, bufflen,
1448                                 &retlen);
1449  if (retlen > 0) {
1450    /* NXP ACT Proprietary Ext */
1451    status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1452    if (status != NFCSTATUS_SUCCESS) {
1453      NXPLOG_NCIHAL_E("Stand by mode enable failed");
1454      retry_core_init_cnt++;
1455      goto retry_core_init;
1456    }
1457  }
1458  retlen = 0;
1459
1460  isfound =
1461      GetNxpByteArrayValue(NAME_NXP_CORE_CONF, (char*)buffer, bufflen, &retlen);
1462  if (retlen > 0) {
1463    /* NXP ACT Proprietary Ext */
1464    status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1465    if (status != NFCSTATUS_SUCCESS) {
1466      NXPLOG_NCIHAL_E("Core Set Config failed");
1467      retry_core_init_cnt++;
1468      goto retry_core_init;
1469    }
1470  }
1471
1472  config_access = false;
1473  // if length of last command is 0 then only reset the P2P listen mode routing.
1474  if (p_core_init_rsp_params[35] == 0) {
1475    /* P2P listen mode routing */
1476    status = phNxpNciHal_send_ext_cmd(sizeof(p2p_listen_mode_routing_cmd),
1477                                      p2p_listen_mode_routing_cmd);
1478    if (status != NFCSTATUS_SUCCESS) {
1479      NXPLOG_NCIHAL_E("P2P listen mode routing failed");
1480      retry_core_init_cnt++;
1481      goto retry_core_init;
1482    }
1483  }
1484
1485  retlen = 0;
1486
1487  /* SWP FULL PWR MODE SETTING ON */
1488  if (GetNxpNumValue(NAME_NXP_SWP_FULL_PWR_ON, (void*)&retlen,
1489                     sizeof(retlen))) {
1490    if (1 == retlen) {
1491      status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd),
1492                                        swp_full_pwr_mode_on_cmd);
1493      if (status != NFCSTATUS_SUCCESS) {
1494        NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING ON CMD FAILED");
1495        retry_core_init_cnt++;
1496        goto retry_core_init;
1497      }
1498    } else {
1499      swp_full_pwr_mode_on_cmd[7] = 0x00;
1500      status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd),
1501                                        swp_full_pwr_mode_on_cmd);
1502      if (status != NFCSTATUS_SUCCESS) {
1503        NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING OFF CMD FAILED");
1504        retry_core_init_cnt++;
1505        goto retry_core_init;
1506      }
1507    }
1508  }
1509
1510  /* Android L AID Matching Platform Setting*/
1511  if (GetNxpNumValue(NAME_AID_MATCHING_PLATFORM, (void*)&retlen,
1512                     sizeof(retlen))) {
1513    if (1 == retlen) {
1514      status =
1515          phNxpNciHal_send_ext_cmd(sizeof(android_l_aid_matching_mode_on_cmd),
1516                                   android_l_aid_matching_mode_on_cmd);
1517      if (status != NFCSTATUS_SUCCESS) {
1518        NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
1519        retry_core_init_cnt++;
1520        goto retry_core_init;
1521      }
1522    } else if (2 == retlen) {
1523      android_l_aid_matching_mode_on_cmd[7] = 0x00;
1524      status =
1525          phNxpNciHal_send_ext_cmd(sizeof(android_l_aid_matching_mode_on_cmd),
1526                                   android_l_aid_matching_mode_on_cmd);
1527      if (status != NFCSTATUS_SUCCESS) {
1528        NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
1529        retry_core_init_cnt++;
1530        goto retry_core_init;
1531      }
1532    }
1533  }
1534
1535  if ((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)) {
1536    static phLibNfc_Message_t msg;
1537    uint16_t tmp_len = 0;
1538    uint8_t uicc_set_mode[] = {0x22, 0x01, 0x02, 0x02, 0x01};
1539    uint8_t set_screen_state[] = {0x2F, 0x15, 01, 00};  // SCREEN ON
1540    uint8_t nfcc_core_conn_create[] = {0x20, 0x04, 0x06, 0x03, 0x01,
1541                                       0x01, 0x02, 0x01, 0x01};
1542    uint8_t nfcc_mode_set_on[] = {0x22, 0x01, 0x02, 0x01, 0x01};
1543
1544    NXPLOG_NCIHAL_E(
1545        "Sending DH and NFCC core connection command as raw packet!!");
1546    status = phNxpNciHal_send_ext_cmd(sizeof(nfcc_core_conn_create),
1547                                      nfcc_core_conn_create);
1548
1549    if (status != NFCSTATUS_SUCCESS) {
1550      NXPLOG_NCIHAL_E(
1551          "Sending DH and NFCC core connection command as raw packet!! Failed");
1552      retry_core_init_cnt++;
1553      goto retry_core_init;
1554    }
1555
1556    NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!!");
1557    status =
1558        phNxpNciHal_send_ext_cmd(sizeof(nfcc_mode_set_on), nfcc_mode_set_on);
1559
1560    if (status != NFCSTATUS_SUCCESS) {
1561      NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!! Failed");
1562      retry_core_init_cnt++;
1563      goto retry_core_init;
1564    }
1565
1566    NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!!");
1567    status = phNxpNciHal_send_ext_cmd(sizeof(uicc_set_mode), uicc_set_mode);
1568    if (status != NFCSTATUS_SUCCESS) {
1569      NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!! Failed");
1570      retry_core_init_cnt++;
1571      goto retry_core_init;
1572    }
1573
1574    if (*(p_core_init_rsp_params + 1) == 1)  // RF state is Discovery!!
1575    {
1576      NXPLOG_NCIHAL_E("Sending Set Screen ON State Command as raw packet!!");
1577      status =
1578          phNxpNciHal_send_ext_cmd(sizeof(set_screen_state), set_screen_state);
1579      if (status != NFCSTATUS_SUCCESS) {
1580        NXPLOG_NCIHAL_E(
1581            "Sending Set Screen ON State Command as raw packet!! Failed");
1582        retry_core_init_cnt++;
1583        goto retry_core_init;
1584      }
1585
1586      NXPLOG_NCIHAL_E("Sending discovery as raw packet!!");
1587      status = phNxpNciHal_send_ext_cmd(p_core_init_rsp_params[2],
1588                                        (uint8_t*)&p_core_init_rsp_params[3]);
1589      if (status != NFCSTATUS_SUCCESS) {
1590        NXPLOG_NCIHAL_E("Sending discovery as raw packet Failed");
1591        retry_core_init_cnt++;
1592        goto retry_core_init;
1593      }
1594
1595    } else {
1596      NXPLOG_NCIHAL_E("Sending Set Screen OFF State Command as raw packet!!");
1597      set_screen_state[3] = 0x01;  // Screen OFF
1598      status =
1599          phNxpNciHal_send_ext_cmd(sizeof(set_screen_state), set_screen_state);
1600      if (status != NFCSTATUS_SUCCESS) {
1601        NXPLOG_NCIHAL_E(
1602            "Sending Set Screen OFF State Command as raw packet!! Failed");
1603        retry_core_init_cnt++;
1604        goto retry_core_init;
1605      }
1606    }
1607    NXPLOG_NCIHAL_E("Sending last command for Recovery ");
1608
1609    if (p_core_init_rsp_params[35] > 0) {  // if length of last command is 0
1610                                           // then it doesn't need to send last
1611                                           // command.
1612      if (!(((p_core_init_rsp_params[36] == 0x21) &&
1613             (p_core_init_rsp_params[37] == 0x03)) &&
1614            (*(p_core_init_rsp_params + 1) == 1)) &&
1615          !((p_core_init_rsp_params[36] == 0x21) &&
1616            (p_core_init_rsp_params[37] == 0x06) &&
1617            (p_core_init_rsp_params[39] == 0x00) &&
1618            (*(p_core_init_rsp_params + 1) == 0x00)))
1619      // if last command is discovery and RF status is also discovery state,
1620      // then it doesn't need to execute or similarly
1621      // if the last command is deactivate to idle and RF status is also idle ,
1622      // no need to execute the command .
1623      {
1624        tmp_len = p_core_init_rsp_params[35];
1625
1626        /* Check for NXP ext before sending write */
1627        status = phNxpNciHal_write_ext(
1628            &tmp_len, (uint8_t*)&p_core_init_rsp_params[36],
1629            &nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
1630        if (status != NFCSTATUS_SUCCESS) {
1631          if (buffer) {
1632            free(buffer);
1633            buffer = NULL;
1634          }
1635          /* Do not send packet to PN54X, send response directly */
1636          msg.eMsgType = NCI_HAL_RX_MSG;
1637          msg.pMsgData = NULL;
1638          msg.Size = 0;
1639
1640          phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1641                                (phLibNfc_Message_t*)&msg);
1642          return NFCSTATUS_SUCCESS;
1643        }
1644
1645        p_core_init_rsp_params[35] = (uint8_t)tmp_len;
1646
1647        status = phNxpNciHal_send_ext_cmd(
1648            p_core_init_rsp_params[35], (uint8_t*)&p_core_init_rsp_params[36]);
1649        if (status != NFCSTATUS_SUCCESS) {
1650          NXPLOG_NCIHAL_E("Sending last command for Recovery Failed");
1651          retry_core_init_cnt++;
1652          goto retry_core_init;
1653        }
1654      }
1655    }
1656  }
1657
1658  retry_core_init_cnt = 0;
1659
1660  if (buffer) {
1661    free(buffer);
1662    buffer = NULL;
1663  }
1664#if (NFC_NXP_CHIP_TYPE != PN547C2)
1665  // initialize dummy FW recovery variables
1666  gRecFWDwnld = 0;
1667  gRecFwRetryCount = 0;
1668#endif
1669  if (!((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)))
1670    phNxpNciHal_core_initialized_complete(status);
1671  else {
1672  invoke_callback:
1673    config_access = false;
1674    if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) {
1675      *p_core_init_rsp_params = 0;
1676      NXPLOG_NCIHAL_E("Invoking data callback!!");
1677      (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
1678                                               nxpncihal_ctrl.p_rx_data);
1679    }
1680  }
1681
1682#ifdef PN547C2_CLOCK_SETTING
1683  if (isNxpConfigModified()) {
1684    updateNxpConfigTimestamp();
1685  }
1686#endif
1687  return NFCSTATUS_SUCCESS;
1688}
1689#if (NFC_NXP_CHIP_TYPE != PN547C2)
1690/******************************************************************************
1691 * Function         phNxpNciHal_CheckRFCmdRespStatus
1692 *
1693 * Description      This function is called to check the resp status of
1694 *                  RF update commands.
1695 *
1696 * Returns          NFCSTATUS_SUCCESS           if successful,
1697 *                  NFCSTATUS_INVALID_PARAMETER if parameter is inavlid
1698 *                  NFCSTATUS_FAILED            if failed response
1699 *
1700 ******************************************************************************/
1701NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus() {
1702  NFCSTATUS status = NFCSTATUS_SUCCESS;
1703  static uint16_t INVALID_PARAM = 0x09;
1704  if ((nxpncihal_ctrl.rx_data_len > 0) && (nxpncihal_ctrl.p_rx_data[2] > 0)) {
1705    if (nxpncihal_ctrl.p_rx_data[3] == 0x09) {
1706      status = INVALID_PARAM;
1707    } else if (nxpncihal_ctrl.p_rx_data[3] != NFCSTATUS_SUCCESS) {
1708      status = NFCSTATUS_FAILED;
1709    }
1710  }
1711  return status;
1712}
1713/******************************************************************************
1714 * Function         phNxpNciHalRFConfigCmdRecSequence
1715 *
1716 * Description      This function is called to handle dummy FW recovery sequence
1717 *                  Whenever RF settings are failed to apply with invalid param
1718 *                  response, recovery mechanism includes dummy firmware
1719 *download
1720 *                  followed by firmware download and then config settings. The
1721 *dummy
1722 *                  firmware changes the major number of the firmware inside
1723 *NFCC.
1724 *                  Then actual firmware dowenload will be successful. This can
1725 *be
1726 *                  retried maximum three times.
1727 *
1728 * Returns          Always returns NFCSTATUS_SUCCESS
1729 *
1730 ******************************************************************************/
1731NFCSTATUS phNxpNciHalRFConfigCmdRecSequence() {
1732  NFCSTATUS status = NFCSTATUS_SUCCESS;
1733  uint16_t recFWState = 1;
1734  gRecFWDwnld = true;
1735  gRecFwRetryCount++;
1736  if (gRecFwRetryCount > 0x03) {
1737    NXPLOG_NCIHAL_D("Max retry count for RF config FW recovery exceeded ");
1738    gRecFWDwnld = false;
1739    return NFCSTATUS_FAILED;
1740  }
1741  do {
1742    status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1743    phDnldNfc_InitImgInfo();
1744    if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion()) {
1745      fw_download_success = 0;
1746      status = phNxpNciHal_fw_download();
1747      if (status == NFCSTATUS_SUCCESS) {
1748        fw_download_success = 1;
1749        status = phTmlNfc_Read(
1750            nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN,
1751            (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
1752        if (status != NFCSTATUS_PENDING) {
1753          NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
1754          phTmlNfc_Shutdown();
1755          status = NFCSTATUS_FAILED;
1756          break;
1757        }
1758      } else {
1759        status = NFCSTATUS_FAILED;
1760        break;
1761      }
1762    }
1763    gRecFWDwnld = false;
1764  } while (recFWState--);
1765  gRecFWDwnld = false;
1766  return status;
1767}
1768#endif
1769/******************************************************************************
1770 * Function         phNxpNciHal_core_initialized_complete
1771 *
1772 * Description      This function is called when phNxpNciHal_core_initialized
1773 *                  complete all proprietary command exchanges. This function
1774 *                  informs libnfc-nci about completion of core initialize
1775 *                  and result of that through callback.
1776 *
1777 * Returns          void.
1778 *
1779 ******************************************************************************/
1780static void phNxpNciHal_core_initialized_complete(NFCSTATUS status) {
1781  static phLibNfc_Message_t msg;
1782
1783  if (status == NFCSTATUS_SUCCESS) {
1784    msg.eMsgType = NCI_HAL_POST_INIT_CPLT_MSG;
1785  } else {
1786    msg.eMsgType = NCI_HAL_ERROR_MSG;
1787  }
1788  msg.pMsgData = NULL;
1789  msg.Size = 0;
1790
1791  phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1792                        (phLibNfc_Message_t*)&msg);
1793
1794  return;
1795}
1796
1797/******************************************************************************
1798 * Function         phNxpNciHal_pre_discover
1799 *
1800 * Description      This function is called by libnfc-nci to perform any
1801 *                  proprietary exchange before RF discovery. When proprietary
1802 *                  exchange is over completion is informed to libnfc-nci
1803 *                  through phNxpNciHal_pre_discover_complete function.
1804 *
1805 * Returns          It always returns NFCSTATUS_SUCCESS (0).
1806 *
1807 ******************************************************************************/
1808int phNxpNciHal_pre_discover(void) {
1809  /* Nothing to do here for initial version */
1810  return NFCSTATUS_SUCCESS;
1811}
1812
1813/******************************************************************************
1814 * Function         phNxpNciHal_pre_discover_complete
1815 *
1816 * Description      This function informs libnfc-nci about completion and
1817 *                  status of phNxpNciHal_pre_discover through callback.
1818 *
1819 * Returns          void.
1820 *
1821 ******************************************************************************/
1822static void phNxpNciHal_pre_discover_complete(NFCSTATUS status) {
1823  static phLibNfc_Message_t msg;
1824
1825  if (status == NFCSTATUS_SUCCESS) {
1826    msg.eMsgType = NCI_HAL_PRE_DISCOVER_CPLT_MSG;
1827  } else {
1828    msg.eMsgType = NCI_HAL_ERROR_MSG;
1829  }
1830  msg.pMsgData = NULL;
1831  msg.Size = 0;
1832
1833  phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
1834
1835  return;
1836}
1837
1838/******************************************************************************
1839 * Function         phNxpNciHal_close
1840 *
1841 * Description      This function close the NFCC interface and free all
1842 *                  resources.This is called by libnfc-nci on NFC service stop.
1843 *
1844 * Returns          Always return NFCSTATUS_SUCCESS (0).
1845 *
1846 ******************************************************************************/
1847int phNxpNciHal_close(void) {
1848  NFCSTATUS status;
1849  /*NCI_RESET_CMD*/
1850  static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
1851
1852  static uint8_t cmd_ce_disc_nci[] = {0x21, 0x03, 0x07, 0x03, 0x80,
1853                                      0x01, 0x81, 0x01, 0x82, 0x01};
1854
1855  if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
1856    NXPLOG_NCIHAL_E("phNxpNciHal_close is already closed, ignoring close");
1857    return NFCSTATUS_FAILED;
1858  }
1859  CONCURRENCY_LOCK();
1860  status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_disc_nci), cmd_ce_disc_nci);
1861  if (status != NFCSTATUS_SUCCESS) {
1862    NXPLOG_NCIHAL_E("CMD_CE_DISC_NCI: Failed");
1863  }
1864
1865  nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
1866
1867  status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
1868  if (status != NFCSTATUS_SUCCESS) {
1869    NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
1870  }
1871
1872  if (NULL != gpphTmlNfc_Context->pDevHandle) {
1873    phNxpNciHal_close_complete(NFCSTATUS_SUCCESS);
1874    /* Abort any pending read and write */
1875    status = phTmlNfc_ReadAbort();
1876    status = phTmlNfc_WriteAbort();
1877
1878    phOsalNfc_Timer_Cleanup();
1879
1880    status = phTmlNfc_Shutdown();
1881
1882    phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
1883
1884    memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
1885
1886    NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed");
1887  }
1888
1889  CONCURRENCY_UNLOCK();
1890
1891  phNxpNciHal_cleanup_monitor();
1892
1893  /* Return success always */
1894  return NFCSTATUS_SUCCESS;
1895}
1896
1897/******************************************************************************
1898 * Function         phNxpNciHal_close_complete
1899 *
1900 * Description      This function inform libnfc-nci about result of
1901 *                  phNxpNciHal_close.
1902 *
1903 * Returns          void.
1904 *
1905 ******************************************************************************/
1906void phNxpNciHal_close_complete(NFCSTATUS status) {
1907  static phLibNfc_Message_t msg;
1908
1909  if (status == NFCSTATUS_SUCCESS) {
1910    msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
1911  } else {
1912    msg.eMsgType = NCI_HAL_ERROR_MSG;
1913  }
1914  msg.pMsgData = NULL;
1915  msg.Size = 0;
1916
1917  phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
1918
1919  return;
1920}
1921/******************************************************************************
1922 * Function         phNxpNciHal_notify_i2c_fragmentation
1923 *
1924 * Description      This function can be used by HAL to inform
1925 *                 libnfc-nci that i2c fragmentation is enabled/disabled
1926 *
1927 * Returns          void.
1928 *
1929 ******************************************************************************/
1930void phNxpNciHal_notify_i2c_fragmentation(void) {
1931  if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
1932    /*inform libnfc-nci that i2c fragmentation is enabled/disabled */
1933    (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT,
1934                                        HAL_NFC_STATUS_OK);
1935  }
1936}
1937/******************************************************************************
1938 * Function         phNxpNciHal_control_granted
1939 *
1940 * Description      Called by libnfc-nci when NFCC control is granted to HAL.
1941 *
1942 * Returns          Always returns NFCSTATUS_SUCCESS (0).
1943 *
1944 ******************************************************************************/
1945int phNxpNciHal_control_granted(void) {
1946  /* Take the concurrency lock so no other calls from upper layer
1947   * will be allowed
1948   */
1949  CONCURRENCY_LOCK();
1950
1951  if (NULL != nxpncihal_ctrl.p_control_granted_cback) {
1952    (*nxpncihal_ctrl.p_control_granted_cback)();
1953  }
1954  /* At the end concurrency unlock so calls from upper layer will
1955   * be allowed
1956   */
1957  CONCURRENCY_UNLOCK();
1958  return NFCSTATUS_SUCCESS;
1959}
1960
1961/******************************************************************************
1962 * Function         phNxpNciHal_request_control
1963 *
1964 * Description      This function can be used by HAL to request control of
1965 *                  NFCC to libnfc-nci. When control is provided to HAL it is
1966 *                  notified through phNxpNciHal_control_granted.
1967 *
1968 * Returns          void.
1969 *
1970 ******************************************************************************/
1971void phNxpNciHal_request_control(void) {
1972  if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
1973    /* Request Control of NCI Controller from NCI NFC Stack */
1974    (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_REQUEST_CONTROL_EVT,
1975                                        HAL_NFC_STATUS_OK);
1976  }
1977
1978  return;
1979}
1980
1981/******************************************************************************
1982 * Function         phNxpNciHal_release_control
1983 *
1984 * Description      This function can be used by HAL to release the control of
1985 *                  NFCC back to libnfc-nci.
1986 *
1987 * Returns          void.
1988 *
1989 ******************************************************************************/
1990void phNxpNciHal_release_control(void) {
1991  if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
1992    /* Release Control of NCI Controller to NCI NFC Stack */
1993    (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_RELEASE_CONTROL_EVT,
1994                                        HAL_NFC_STATUS_OK);
1995  }
1996
1997  return;
1998}
1999
2000/******************************************************************************
2001 * Function         phNxpNciHal_power_cycle
2002 *
2003 * Description      This function is called by libnfc-nci when power cycling is
2004 *                  performed. When processing is complete it is notified to
2005 *                  libnfc-nci through phNxpNciHal_power_cycle_complete.
2006 *
2007 * Returns          Always return NFCSTATUS_SUCCESS (0).
2008 *
2009 ******************************************************************************/
2010int phNxpNciHal_power_cycle(void) {
2011  NXPLOG_NCIHAL_D("Power Cycle");
2012  NFCSTATUS status = NFCSTATUS_FAILED;
2013  if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
2014    NXPLOG_NCIHAL_D("Power Cycle failed due to hal status not open");
2015    return NFCSTATUS_FAILED;
2016  }
2017  status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
2018
2019  if (NFCSTATUS_SUCCESS == status) {
2020    NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
2021  } else {
2022    NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
2023  }
2024
2025  phNxpNciHal_power_cycle_complete(NFCSTATUS_SUCCESS);
2026  return NFCSTATUS_SUCCESS;
2027}
2028
2029/******************************************************************************
2030 * Function         phNxpNciHal_power_cycle_complete
2031 *
2032 * Description      This function is called to provide the status of
2033 *                  phNxpNciHal_power_cycle to libnfc-nci through callback.
2034 *
2035 * Returns          void.
2036 *
2037 ******************************************************************************/
2038static void phNxpNciHal_power_cycle_complete(NFCSTATUS status) {
2039  static phLibNfc_Message_t msg;
2040
2041  if (status == NFCSTATUS_SUCCESS) {
2042    msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
2043  } else {
2044    msg.eMsgType = NCI_HAL_ERROR_MSG;
2045  }
2046  msg.pMsgData = NULL;
2047  msg.Size = 0;
2048
2049  phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
2050
2051  return;
2052}
2053
2054/******************************************************************************
2055 * Function         phNxpNciHal_get_mw_eeprom
2056 *
2057 * Description      This function is called to retreive data in mw eeprom area
2058 *
2059 * Returns          NFCSTATUS.
2060 *
2061 ******************************************************************************/
2062static NFCSTATUS phNxpNciHal_get_mw_eeprom(void) {
2063  NFCSTATUS status = NFCSTATUS_SUCCESS;
2064  uint8_t retry_cnt = 0;
2065  static uint8_t get_mw_eeprom_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x0F};
2066  uint8_t bConfig;
2067
2068retry_send_ext:
2069  if (retry_cnt > 3) {
2070    return NFCSTATUS_FAILED;
2071  }
2072
2073  phNxpNciMwEepromArea.isGetEepromArea = true;
2074  status =
2075      phNxpNciHal_send_ext_cmd(sizeof(get_mw_eeprom_cmd), get_mw_eeprom_cmd);
2076  if (status != NFCSTATUS_SUCCESS) {
2077    NXPLOG_NCIHAL_E("unable to get the mw eeprom data");
2078    phNxpNciMwEepromArea.isGetEepromArea = false;
2079    retry_cnt++;
2080    goto retry_send_ext;
2081  }
2082  phNxpNciMwEepromArea.isGetEepromArea = false;
2083
2084  if (phNxpNciMwEepromArea.p_rx_data[12]) {
2085    fw_download_success = 1;
2086  }
2087  return status;
2088}
2089
2090/******************************************************************************
2091 * Function         phNxpNciHal_set_mw_eeprom
2092 *
2093 * Description      This function is called to update data in mw eeprom area
2094 *
2095 * Returns          void.
2096 *
2097 ******************************************************************************/
2098static NFCSTATUS phNxpNciHal_set_mw_eeprom(void) {
2099  NFCSTATUS status = NFCSTATUS_SUCCESS;
2100  uint8_t retry_cnt = 0;
2101  uint8_t set_mw_eeprom_cmd[39] = {0};
2102  uint8_t cmd_header[] = {0x20, 0x02, 0x24, 0x01, 0xA0, 0x0F, 0x20};
2103
2104  memcpy(set_mw_eeprom_cmd, cmd_header, sizeof(cmd_header));
2105  phNxpNciMwEepromArea.p_rx_data[12] = 0;
2106  memcpy(set_mw_eeprom_cmd + sizeof(cmd_header), phNxpNciMwEepromArea.p_rx_data,
2107         sizeof(phNxpNciMwEepromArea.p_rx_data));
2108
2109retry_send_ext:
2110  if (retry_cnt > 3) {
2111    return NFCSTATUS_FAILED;
2112  }
2113
2114  status =
2115      phNxpNciHal_send_ext_cmd(sizeof(set_mw_eeprom_cmd), set_mw_eeprom_cmd);
2116  if (status != NFCSTATUS_SUCCESS) {
2117    NXPLOG_NCIHAL_E("unable to update the mw eeprom data");
2118    retry_cnt++;
2119    goto retry_send_ext;
2120  }
2121  return status;
2122}
2123
2124/******************************************************************************
2125 * Function         phNxpNciHal_set_clock
2126 *
2127 * Description      This function is called after successfull download
2128 *                  to apply the clock setting provided in config file
2129 *
2130 * Returns          void.
2131 *
2132 ******************************************************************************/
2133static void phNxpNciHal_set_clock(void) {
2134  NFCSTATUS status = NFCSTATUS_FAILED;
2135  int retryCount = 0;
2136
2137retrySetclock:
2138  phNxpNciClock.isClockSet = true;
2139  if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) {
2140    static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x09, 0x02, 0xA0, 0x03,
2141                                      0x01, 0x11, 0xA0, 0x04, 0x01, 0x01};
2142    uint8_t param_clock_src = CLK_SRC_PLL;
2143    param_clock_src = param_clock_src << 3;
2144
2145    if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) {
2146      param_clock_src |= 0x00;
2147    } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) {
2148      param_clock_src |= 0x01;
2149    } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) {
2150      param_clock_src |= 0x02;
2151    } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) {
2152      param_clock_src |= 0x03;
2153    } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) {
2154      param_clock_src |= 0x04;
2155    } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) {
2156      param_clock_src |= 0x05;
2157    } else {
2158      NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
2159      param_clock_src = 0x11;
2160    }
2161
2162    set_clock_cmd[7] = param_clock_src;
2163    set_clock_cmd[11] = nxpprofile_ctrl.bTimeout;
2164    status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
2165    if (status != NFCSTATUS_SUCCESS) {
2166      NXPLOG_NCIHAL_E("PLL colck setting failed !!");
2167    }
2168  } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) {
2169    static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x05, 0x01,
2170                                      0xA0, 0x03, 0x01, 0x08};
2171    status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
2172    if (status != NFCSTATUS_SUCCESS) {
2173      NXPLOG_NCIHAL_E("XTAL colck setting failed !!");
2174    }
2175  } else {
2176    NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
2177  }
2178
2179  // Checking for SET CONFG SUCCESS, re-send the command  if not.
2180  phNxpNciClock.isClockSet = false;
2181  if (phNxpNciClock.p_rx_data[3] != NFCSTATUS_SUCCESS) {
2182    if (retryCount++ < 3) {
2183      NXPLOG_NCIHAL_E("Set-clk failed retry again ");
2184      goto retrySetclock;
2185    } else {
2186      NXPLOG_NCIHAL_D("Set clk  failed -  max count = 0x%x exceeded ",
2187                      retryCount);
2188      //            NXPLOG_NCIHAL_E("Set Config is failed for Clock Due to
2189      //            elctrical disturbances, aborting the NFC process");
2190      //            abort ();
2191    }
2192  }
2193}
2194
2195/******************************************************************************
2196 * Function         phNxpNciHal_check_clock_config
2197 *
2198 * Description      This function is called after successfull download
2199 *                  to check if clock settings in config file and chip
2200 *                  is same
2201 *
2202 * Returns          void.
2203 *
2204 ******************************************************************************/
2205NFCSTATUS phNxpNciHal_check_clock_config(void) {
2206  NFCSTATUS status = NFCSTATUS_SUCCESS;
2207  uint8_t param_clock_src;
2208  static uint8_t get_clock_cmd[] = {0x20, 0x03, 0x07, 0x03, 0xA0,
2209                                    0x02, 0xA0, 0x03, 0xA0, 0x04};
2210  phNxpNciClock.isClockSet = true;
2211  phNxpNciHal_get_clk_freq();
2212  status = phNxpNciHal_send_ext_cmd(sizeof(get_clock_cmd), get_clock_cmd);
2213
2214  if (status != NFCSTATUS_SUCCESS) {
2215    NXPLOG_NCIHAL_E("unable to retrieve get_clk_src_sel");
2216    return status;
2217  }
2218  param_clock_src = check_config_parameter();
2219  if (phNxpNciClock.p_rx_data[12] == param_clock_src &&
2220      phNxpNciClock.p_rx_data[16] == nxpprofile_ctrl.bTimeout) {
2221    phNxpNciClock.issetConfig = false;
2222  } else {
2223    phNxpNciClock.issetConfig = true;
2224  }
2225  phNxpNciClock.isClockSet = false;
2226
2227  return status;
2228}
2229
2230/******************************************************************************
2231 * Function         phNxpNciHal_china_tianjin_rf_setting
2232 *
2233 * Description      This function is called to check RF Setting
2234 *
2235 * Returns          Status.
2236 *
2237 ******************************************************************************/
2238NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void) {
2239  NFCSTATUS status = NFCSTATUS_SUCCESS;
2240  int isfound = 0;
2241  int rf_enable = false;
2242  int rf_val = 0;
2243  int send_flag;
2244  uint8_t retry_cnt = 0;
2245  int enable_bit = 0;
2246  static uint8_t get_rf_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x85};
2247
2248retry_send_ext:
2249  if (retry_cnt > 3) {
2250    return NFCSTATUS_FAILED;
2251  }
2252  send_flag = true;
2253  phNxpNciRfSet.isGetRfSetting = true;
2254  status = phNxpNciHal_send_ext_cmd(sizeof(get_rf_cmd), get_rf_cmd);
2255  if (status != NFCSTATUS_SUCCESS) {
2256    NXPLOG_NCIHAL_E("unable to get the RF setting");
2257    phNxpNciRfSet.isGetRfSetting = false;
2258    retry_cnt++;
2259    goto retry_send_ext;
2260  }
2261  phNxpNciRfSet.isGetRfSetting = false;
2262  if (phNxpNciRfSet.p_rx_data[3] != 0x00) {
2263    NXPLOG_NCIHAL_E("GET_CONFIG_RSP is FAILED for CHINA TIANJIN");
2264    return status;
2265  }
2266  rf_val = phNxpNciRfSet.p_rx_data[10];
2267  isfound = (GetNxpNumValue(NAME_NXP_CHINA_TIANJIN_RF_ENABLED,
2268                            (void*)&rf_enable, sizeof(rf_enable)));
2269  if (isfound > 0) {
2270    enable_bit = rf_val & 0x40;
2271    if ((enable_bit != 0x40) && (rf_enable == 1)) {
2272      phNxpNciRfSet.p_rx_data[10] |= 0x40;  // Enable if it is disabled
2273    } else if ((enable_bit == 0x40) && (rf_enable == 0)) {
2274      phNxpNciRfSet.p_rx_data[10] &= 0xBF;  // Disable if it is Enabled
2275    } else {
2276      send_flag = false;  // No need to change in RF setting
2277    }
2278
2279    if (send_flag == true) {
2280      static uint8_t set_rf_cmd[] = {0x20, 0x02, 0x08, 0x01, 0xA0, 0x85,
2281                                     0x04, 0x50, 0x08, 0x68, 0x00};
2282      memcpy(&set_rf_cmd[4], &phNxpNciRfSet.p_rx_data[5], 7);
2283      status = phNxpNciHal_send_ext_cmd(sizeof(set_rf_cmd), set_rf_cmd);
2284      if (status != NFCSTATUS_SUCCESS) {
2285        NXPLOG_NCIHAL_E("unable to set the RF setting");
2286        retry_cnt++;
2287        goto retry_send_ext;
2288      }
2289    }
2290  }
2291
2292  return status;
2293}
2294
2295int check_config_parameter() {
2296  NFCSTATUS status = NFCSTATUS_FAILED;
2297  uint8_t param_clock_src = CLK_SRC_PLL;
2298  if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) {
2299    param_clock_src = param_clock_src << 3;
2300
2301    if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) {
2302      param_clock_src |= 0x00;
2303    } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) {
2304      param_clock_src |= 0x01;
2305    } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) {
2306      param_clock_src |= 0x02;
2307    } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) {
2308      param_clock_src |= 0x03;
2309    } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) {
2310      param_clock_src |= 0x04;
2311    } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) {
2312      param_clock_src |= 0x05;
2313    } else {
2314      NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
2315      param_clock_src = 0x11;
2316    }
2317  } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) {
2318    param_clock_src = 0x08;
2319
2320  } else {
2321    NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
2322  }
2323  return param_clock_src;
2324}
2325/******************************************************************************
2326 * Function         phNxpNciHal_enable_i2c_fragmentation
2327 *
2328 * Description      This function is called to process the response status
2329 *                  and print the status byte.
2330 *
2331 * Returns          void.
2332 *
2333 ******************************************************************************/
2334void phNxpNciHal_enable_i2c_fragmentation() {
2335  NFCSTATUS status = NFCSTATUS_FAILED;
2336  static uint8_t fragmentation_enable_config_cmd[] = {0x20, 0x02, 0x05, 0x01,
2337                                                      0xA0, 0x05, 0x01, 0x10};
2338  int isfound = 0;
2339  long i2c_status = 0x00;
2340  long config_i2c_vlaue = 0xff;
2341  /*NCI_RESET_CMD*/
2342  static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
2343  /*NCI_INIT_CMD*/
2344  static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
2345  static uint8_t get_i2c_fragmentation_cmd[] = {0x20, 0x03, 0x03,
2346                                                0x01, 0xA0, 0x05};
2347  isfound = (GetNxpNumValue(NAME_NXP_I2C_FRAGMENTATION_ENABLED,
2348                            (void*)&i2c_status, sizeof(i2c_status)));
2349  status = phNxpNciHal_send_ext_cmd(sizeof(get_i2c_fragmentation_cmd),
2350                                    get_i2c_fragmentation_cmd);
2351  if (status != NFCSTATUS_SUCCESS) {
2352    NXPLOG_NCIHAL_E("unable to retrieve  get_i2c_fragmentation_cmd");
2353  } else {
2354    if (nxpncihal_ctrl.p_rx_data[8] == 0x10) {
2355      config_i2c_vlaue = 0x01;
2356      phNxpNciHal_notify_i2c_fragmentation();
2357      phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
2358    } else if (nxpncihal_ctrl.p_rx_data[8] == 0x00) {
2359      config_i2c_vlaue = 0x00;
2360    }
2361    if (config_i2c_vlaue == i2c_status) {
2362      NXPLOG_NCIHAL_E("i2c_fragmentation_status existing");
2363    } else {
2364      if (i2c_status == 0x01) {
2365        /* NXP I2C fragmenation enabled*/
2366        status =
2367            phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd),
2368                                     fragmentation_enable_config_cmd);
2369        if (status != NFCSTATUS_SUCCESS) {
2370          NXPLOG_NCIHAL_E("NXP fragmentation enable failed");
2371        }
2372      } else if (i2c_status == 0x00 || config_i2c_vlaue == 0xff) {
2373        fragmentation_enable_config_cmd[7] = 0x00;
2374        /* NXP I2C fragmentation disabled*/
2375        status =
2376            phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd),
2377                                     fragmentation_enable_config_cmd);
2378        if (status != NFCSTATUS_SUCCESS) {
2379          NXPLOG_NCIHAL_E("NXP fragmentation disable failed");
2380        }
2381      }
2382      status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
2383      if (status != NFCSTATUS_SUCCESS) {
2384        NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
2385      }
2386      status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
2387      if (status != NFCSTATUS_SUCCESS) {
2388        NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
2389      } else if (i2c_status == 0x01) {
2390        phNxpNciHal_notify_i2c_fragmentation();
2391        phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
2392      }
2393    }
2394  }
2395}
2396/******************************************************************************
2397 * Function         phNxpNciHal_check_factory_reset
2398 *
2399 * Description      This function is called at init time to check
2400 *                  the presence of ese related info. If file are not
2401 *                  present set the SWP_INT_SESSION_ID_CFG to FF to
2402 *                  force the NFCEE to re-run its initialization sequence.
2403 *
2404 * Returns          void.
2405 *
2406 ******************************************************************************/
2407static void phNxpNciHal_check_factory_reset(void) {
2408  struct stat st;
2409  int ret = 0;
2410  NFCSTATUS status = NFCSTATUS_FAILED;
2411  const char config_eseinfo_path[] = "/data/nfc/nfaStorage.bin1";
2412  static uint8_t reset_ese_session_identity_set[] = {
2413      0x20, 0x02, 0x17, 0x02, 0xA0, 0xEA, 0x08, 0xFF, 0xFF,
2414      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xEB, 0x08,
2415      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2416#ifdef PN547C2_FACTORY_RESET_DEBUG
2417  static uint8_t reset_ese_session_identity[] = {0x20, 0x03, 0x05, 0x02,
2418                                                 0xA0, 0xEA, 0xA0, 0xEB};
2419#endif
2420  if (stat(config_eseinfo_path, &st) == -1) {
2421    NXPLOG_NCIHAL_D("%s file not present = %s", __func__, config_eseinfo_path);
2422    ret = -1;
2423  } else {
2424    ret = 0;
2425  }
2426
2427  if (ret == -1) {
2428#ifdef PN547C2_FACTORY_RESET_DEBUG
2429    /* NXP ACT Proprietary Ext */
2430    status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity),
2431                                      reset_ese_session_identity);
2432    if (status != NFCSTATUS_SUCCESS) {
2433      NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed");
2434    }
2435#endif
2436    status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity_set),
2437                                      reset_ese_session_identity_set);
2438    if (status != NFCSTATUS_SUCCESS) {
2439      NXPLOG_NCIHAL_E("NXP reset_ese_session_identity_set command failed");
2440    }
2441#ifdef PN547C2_FACTORY_RESET_DEBUG
2442    /* NXP ACT Proprietary Ext */
2443    status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity),
2444                                      reset_ese_session_identity);
2445    if (status != NFCSTATUS_SUCCESS) {
2446      NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed");
2447    }
2448#endif
2449  }
2450}
2451
2452/******************************************************************************
2453 * Function         phNxpNciHal_print_res_status
2454 *
2455 * Description      This function is called to process the response status
2456 *                  and print the status byte.
2457 *
2458 * Returns          void.
2459 *
2460 ******************************************************************************/
2461static void phNxpNciHal_print_res_status(uint8_t* p_rx_data, uint16_t* p_len) {
2462  static uint8_t response_buf[][30] = {"STATUS_OK",
2463                                       "STATUS_REJECTED",
2464                                       "STATUS_RF_FRAME_CORRUPTED",
2465                                       "STATUS_FAILED",
2466                                       "STATUS_NOT_INITIALIZED",
2467                                       "STATUS_SYNTAX_ERROR",
2468                                       "STATUS_SEMANTIC_ERROR",
2469                                       "RFU",
2470                                       "RFU",
2471                                       "STATUS_INVALID_PARAM",
2472                                       "STATUS_MESSAGE_SIZE_EXCEEDED",
2473                                       "STATUS_UNDEFINED"};
2474  int status_byte;
2475  if (p_rx_data[0] == 0x40 && (p_rx_data[1] == 0x02 || p_rx_data[1] == 0x03)) {
2476    if (p_rx_data[2] && p_rx_data[3] <= 10) {
2477      status_byte = p_rx_data[CORE_RES_STATUS_BYTE];
2478      NXPLOG_NCIHAL_D("%s: response status =%s", __func__,
2479                      response_buf[status_byte]);
2480    } else {
2481      NXPLOG_NCIHAL_D("%s: response status =%s", __func__, response_buf[11]);
2482    }
2483    if (phNxpNciClock.isClockSet) {
2484      int i;
2485      for (i = 0; i < *p_len; i++) {
2486        phNxpNciClock.p_rx_data[i] = p_rx_data[i];
2487      }
2488    }
2489
2490    else if (phNxpNciRfSet.isGetRfSetting) {
2491      int i;
2492      for (i = 0; i < *p_len; i++) {
2493        phNxpNciRfSet.p_rx_data[i] = p_rx_data[i];
2494        // NXPLOG_NCIHAL_D("%s: response status =0x%x",__func__,p_rx_data[i]);
2495      }
2496    } else if (phNxpNciMwEepromArea.isGetEepromArea) {
2497      int i;
2498      for (i = 8; i < *p_len; i++) {
2499        phNxpNciMwEepromArea.p_rx_data[i - 8] = p_rx_data[i];
2500      }
2501    }
2502  }
2503
2504  if (p_rx_data[2] && (config_access == true)) {
2505    if (p_rx_data[3] != NFCSTATUS_SUCCESS) {
2506      NXPLOG_NCIHAL_W("Invalid Data from config file . Aborting..");
2507      phNxpNciHal_close();
2508    }
2509  }
2510}
2511
2512#if (NFC_NXP_CHIP_TYPE == PN548C2)
2513NFCSTATUS phNxpNciHal_core_reset_recovery() {
2514  NFCSTATUS status = NFCSTATUS_FAILED;
2515
2516  uint8_t buffer[260];
2517  long bufflen = 260;
2518
2519  /*NCI_INIT_CMD*/
2520  static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
2521  /*NCI_RESET_CMD*/
2522  static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01,
2523                                    0x00};  // keep configuration
2524
2525  /* reset config cache */
2526  uint8_t retry_core_init_cnt = 0;
2527
2528  if (discovery_cmd_len == 0) {
2529    goto FAILURE;
2530  }
2531  NXPLOG_NCIHAL_D("%s: recovery", __func__);
2532
2533retry_core_init:
2534  if (retry_core_init_cnt > 3) {
2535    goto FAILURE;
2536  }
2537
2538  status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
2539  if (status != NFCSTATUS_SUCCESS) {
2540    NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
2541    goto FAILURE;
2542  }
2543  status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
2544  if ((status != NFCSTATUS_SUCCESS) &&
2545      (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT)) {
2546    retry_core_init_cnt++;
2547    goto retry_core_init;
2548  } else if (status != NFCSTATUS_SUCCESS) {
2549    NXPLOG_NCIHAL_D("NCI_CORE_RESET: Failed");
2550    retry_core_init_cnt++;
2551    goto retry_core_init;
2552  }
2553  status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
2554  if (status != NFCSTATUS_SUCCESS) {
2555    NXPLOG_NCIHAL_D("NCI_CORE_INIT : Failed");
2556    retry_core_init_cnt++;
2557    goto retry_core_init;
2558  }
2559
2560  status = phNxpNciHal_send_ext_cmd(discovery_cmd_len, discovery_cmd);
2561  if (status != NFCSTATUS_SUCCESS) {
2562    NXPLOG_NCIHAL_D("RF_DISCOVERY : Failed");
2563    retry_core_init_cnt++;
2564    goto retry_core_init;
2565  }
2566
2567  return NFCSTATUS_SUCCESS;
2568FAILURE:
2569  abort();
2570}
2571
2572void phNxpNciHal_discovery_cmd_ext(uint8_t* p_cmd_data, uint16_t cmd_len) {
2573  NXPLOG_NCIHAL_D("phNxpNciHal_discovery_cmd_ext");
2574  if (cmd_len > 0 && cmd_len <= sizeof(discovery_cmd)) {
2575    memcpy(discovery_cmd, p_cmd_data, cmd_len);
2576    discovery_cmd_len = cmd_len;
2577  }
2578}
2579#endif
2580