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