• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 NXP
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 #if (NXP_NFC_RECOVERY == TRUE)
18 
19 #include "phNxpNciHal_Recovery.h"
20 
21 #include <phDnldNfc.h>
22 #include <phNfcStatus.h>
23 #include <phNfcTypes.h>
24 #include <phNxpLog.h>
25 #include <phNxpNciHal.h>
26 #include <phNxpNciHal_Dnld.h>
27 #include <phNxpNciHal_ext.h>
28 #include <phOsalNfc_Timer.h>
29 #include <phTmlNfc.h>
30 #undef property_set
31 #undef PROPERTY_VALUE_MAX
32 #undef property_get
33 #include <cutils/properties.h>
34 #define MAX_CORE_RESET 3
35 
36 extern phNxpNciProfile_Control_t nxpprofile_ctrl;
37 extern phNxpNciHal_Control_t nxpncihal_ctrl;
38 extern phTmlNfc_Context_t* gpphTmlNfc_Context;
39 extern void* phNxpNciHal_client_thread(void* arg);
40 
41 static void phnxpNciHal_partialClose();
42 static NFCSTATUS phnxpNciHal_partialOpen();
43 
44 // property name for storing boot time init status
45 const char* halInitProperty = "vendor.nfc.min_firmware";
46 
47 /******************************************************************************
48  * Function         getHalInitStatus
49  *
50  * Description      Get property whether it is boot init/not
51  *
52  * Parameters       Parameter to return the hal status is boot init/not.
53  *
54  * Returns          None
55  *
56  ******************************************************************************/
getHalInitStatus(char * halInitStatus)57 static void getHalInitStatus(char* halInitStatus) {
58   NXPLOG_NCIHAL_D("Enter : %s", __func__);
59   if (property_get(halInitProperty, halInitStatus, "Boot-time") != 0) {
60     NXPLOG_NCIHAL_E("Error in property_get : %s", __func__);
61   }
62 }
63 
64 /******************************************************************************
65  * Function         setHalInitStatus
66  *
67  * Description      To set property as per input whether it is boot init/not
68  *
69  * Parameters       status to be updated in property
70  *
71  * Returns          void
72  *
73  ******************************************************************************/
setHalInitStatus(const char * status)74 static void setHalInitStatus(const char* status) {
75   NXPLOG_NCIHAL_E("Enter : %s", __func__);
76   if (property_set(halInitProperty, status) != 0) {
77     NXPLOG_NCIHAL_E("Error in property_set : %s", __func__);
78   }
79 }
80 
81 /******************************************************************************
82  * Function         phNxpNciHal_read_callback
83  *
84  * Description      Callback function for read request to tml reader thread
85  *
86  * Parameters       pContext - context value passed while callback register
87  *                  pInfo    - Information which contains status and response
88  *                             buffers.
89  *
90  * Returns          void
91  *
92  ******************************************************************************/
phNxpNciHal_read_callback(void * pContext,phTmlNfc_TransactInfo_t * pInfo)93 static void phNxpNciHal_read_callback(void* pContext,
94                                       phTmlNfc_TransactInfo_t* pInfo) {
95   UNUSED_PROP(pContext);
96   if (pInfo != NULL) {
97     NXPLOG_NCIHAL_E("%s Status %d", __func__, pInfo->wStatus);
98     if (pInfo->wStatus == NFCSTATUS_SUCCESS) {
99       nxpncihal_ctrl.p_rx_data = pInfo->pBuff;
100       nxpncihal_ctrl.rx_data_len = pInfo->wLength;
101     }
102     nxpncihal_ctrl.ext_cb_data.status = pInfo->wStatus;
103   } else {
104     nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_FAILED;
105   }
106   SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
107 }
108 
109 /******************************************************************************
110  * Function         phNxpNciHal_write_callback
111  *
112  * Description      Callback function for write request to tml writer thread
113  *
114  * Parameters       pContext - context value passed while callback register
115  *                  pInfo    - Information which contains status and response
116  *                             buffers.
117  *
118  * Returns          void
119  *
120  ******************************************************************************/
phNxpNciHal_write_callback(void * pContext,phTmlNfc_TransactInfo_t * pInfo)121 static void phNxpNciHal_write_callback(void* pContext,
122                                        phTmlNfc_TransactInfo_t* pInfo) {
123   UNUSED_PROP(pContext);
124   if (pInfo != NULL) {
125     if (pInfo->wStatus != NFCSTATUS_SUCCESS) {
126       NXPLOG_NCIHAL_E("write error status = 0x%x", pInfo->wStatus);
127     }
128     nxpncihal_ctrl.ext_cb_data.status = pInfo->wStatus;
129   } else {
130     nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_FAILED;
131   }
132   SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
133 }
134 
135 /******************************************************************************
136  * Function         phNxpNciHal_semWaitTimeout
137  *
138  * Description      Helper function for global sem wait with timeout value
139  *
140  * Parameters       timeout - wait timeout in nanoseconds
141  *
142  * Returns          NFCSTATUS
143  *
144  ******************************************************************************/
phNxpNciHal_semWaitTimeout(long timeout)145 static NFCSTATUS phNxpNciHal_semWaitTimeout(long timeout) {
146   NFCSTATUS status = NFCSTATUS_FAILED;
147   int retVal = 0;
148   struct timespec ts;
149   clock_gettime(CLOCK_MONOTONIC, &ts);
150   ts.tv_nsec += timeout;
151   ts.tv_sec += ts.tv_nsec / 1000000000;
152   ts.tv_nsec %= 1000000000;
153   while ((retVal = sem_timedwait_monotonic_np(&nxpncihal_ctrl.ext_cb_data.sem, &ts)) == -1 &&
154          errno == EINTR) {
155     continue; /* Restart if interrupted by handler */
156   }
157   if (retVal == -1 && errno != ETIMEDOUT) {
158     NXPLOG_NCIHAL_E("%s : sem_timedwait failed : errno = 0x%x", __func__,
159                     errno);
160   }
161   if (retVal != -1) {
162     status = nxpncihal_ctrl.ext_cb_data.status;
163   } else if (errno == ETIMEDOUT && retVal == -1) {
164     NXPLOG_NCIHAL_E("%s :timed out errno = 0x%x", __func__, errno);
165   }
166   return status;
167 }
168 
169 /******************************************************************************
170  * Function         phNxpNciHal_writeCmd
171  *
172  * Description      Helper function to write command to NFCC
173  *
174  * Parameters       timeout - wait timeout in nanoseconds
175  *
176  * Returns          NFCSTATUS
177  *
178  ******************************************************************************/
phNxpNciHal_writeCmd(uint16_t data_len,const uint8_t * p_data,long timeout)179 static NFCSTATUS phNxpNciHal_writeCmd(uint16_t data_len, const uint8_t* p_data,
180                                       long timeout) {
181   NFCSTATUS status = NFCSTATUS_FAILED;
182   const char context[] = "RecoveryWrite";
183 
184   if (p_data == NULL) {
185     NXPLOG_NCIHAL_E("Invalid Command Buffer");
186     return NFCSTATUS_INVALID_PARAMETER;
187   }
188   /* Create local copy of cmd_data */
189   memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
190   nxpncihal_ctrl.cmd_len = data_len;
191   status = phTmlNfc_Write(
192       (uint8_t*)nxpncihal_ctrl.p_cmd_data, (uint16_t)nxpncihal_ctrl.cmd_len,
193       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_write_callback,
194       (void*)context);
195   if (status == NFCSTATUS_PENDING) {
196     return phNxpNciHal_semWaitTimeout(timeout);
197   }
198   NXPLOG_NCIHAL_E("tml write request failed");
199   return status;
200 }
201 
202 /******************************************************************************
203  * Function         phNxpNciHal_ReadResponse
204  *
205  * Description      Helper function to read response from NFCC
206  *
207  * Parameters       len - response buffer len
208  *                  rsp_buffer - Ptr to the response buffer
209  *                  timeout - wait timeout in nanoseconds
210  *
211  * Returns          NFCSTATUS
212  *
213  ******************************************************************************/
phNxpNciHal_ReadResponse(uint16_t * len,uint8_t ** rsp_buffer,long timeout)214 static NFCSTATUS phNxpNciHal_ReadResponse(uint16_t* len, uint8_t** rsp_buffer,
215                                           long timeout) {
216   NFCSTATUS status = NFCSTATUS_FAILED;
217   const char context[] = "RecoveryRead";
218 
219   if (len == NULL) {
220     NXPLOG_NCIHAL_E("%s Invalid Parameters", __func__);
221     return NFCSTATUS_INVALID_PARAMETER;
222   }
223   status = phTmlNfc_Read(
224       nxpncihal_ctrl.p_rsp_data, NCI_MAX_DATA_LEN,
225       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_callback,
226       (void*)context);
227   if (phNxpNciHal_semWaitTimeout(timeout) == NFCSTATUS_SUCCESS) {
228     if (nxpncihal_ctrl.p_rx_data != NULL && nxpncihal_ctrl.rx_data_len > 0) {
229       *rsp_buffer = nxpncihal_ctrl.p_rx_data;
230       *len = nxpncihal_ctrl.rx_data_len;
231       status = NFCSTATUS_SUCCESS;
232     } else
233       status = NFCSTATUS_FAILED;
234   }
235   return status;
236 }
237 
238 /******************************************************************************
239  * Function         phNxpNciHal_readNFCCClockCfgValues
240  *
241  * Description      Helper function to read clock configuration from
242  *                  nfcc configuration file and stores value in global strcture
243  *
244  * Returns          void
245  *
246  ******************************************************************************/
phNxpNciHal_readNFCCClockCfgValues(void)247 static void phNxpNciHal_readNFCCClockCfgValues(void) {
248   unsigned long num = 0;
249   int isfound = 0;
250 
251   isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &num, sizeof(num));
252   if (isfound > 0) nxpprofile_ctrl.bClkSrcVal = num;
253   num = 0;
254   isfound = 0;
255   isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &num, sizeof(num));
256   if (isfound > 0) nxpprofile_ctrl.bClkFreqVal = num;
257 }
258 
259 /******************************************************************************
260  * Function         phNxpNciHal_determineChipType
261  *
262  * Description      Helper function to determine the chip info in nci mode
263  *                  from NCI command and stores value in global strcture
264  *
265  * Returns          bool
266  *
267  ******************************************************************************/
phNxpNciHal_determineChipType(void)268 static bool phNxpNciHal_determineChipType(void) {
269   const uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
270   uint8_t* rsp_buffer = NULL;
271   uint16_t rsp_len = 0;
272   uint8_t retry = 0;
273   bool status = false;
274 
275   do {
276     if ((phNxpNciHal_writeCmd(sizeof(cmd_reset_nci), cmd_reset_nci,
277                               WRITE_TIMEOUT_NS) != NFCSTATUS_SUCCESS)) {
278       NXPLOG_NCIHAL_E("NCI_CORE_RESET Write Failure ");
279       break;
280     }
281     // 10ms delay  for first core reset response to avoid nfcc standby
282     usleep(NCI_RESET_RESP_READ_DELAY_US);
283     if ((phNxpNciHal_ReadResponse(&rsp_len, &rsp_buffer,
284                                   RESPONSE_READ_TIMEOUT_NS) !=
285          NFCSTATUS_SUCCESS) ||
286         (rsp_buffer == NULL)) {
287       NXPLOG_NCIHAL_E("NCI_CORE_RESET read response failed");
288       break;
289     }
290     if (rsp_buffer[NCI_RSP_IDX] == NCI_MSG_RSP) {
291       if ((phNxpNciHal_ReadResponse(&rsp_len, &rsp_buffer,
292                                     RESPONSE_READ_TIMEOUT_NS) !=
293            NFCSTATUS_SUCCESS) ||
294           (rsp_buffer == NULL)) {
295         NXPLOG_NCIHAL_E("NCI_CORE_RESET NTF read failed");
296         break;
297       }
298       if (rsp_buffer[NCI_RSP_IDX] == NCI_MSG_NTF) {
299         phNxpNciHal_configFeatureList(rsp_buffer, rsp_len);
300         status = true;
301         break;
302       }
303     } else {
304       NXPLOG_NCIHAL_E("NCI_CORE_RESPONSE Wrong Status");
305     }
306   } while (retry++ < MAX_CORE_RESET);
307   return status;
308 }
309 
310 /******************************************************************************
311  * Function         phNxpNciHal_isSessionClosed
312  *
313  * Description      Helper function to determine download session state
314  *
315  * Returns          true means session closed
316  *
317  ******************************************************************************/
phNxpNciHal_isSessionClosed(void)318 bool phNxpNciHal_isSessionClosed(void) {
319   const uint8_t get_session_cmd[] = {0x00, 0x04, 0xF2, 0x00,
320                                      0x00, 0x00, 0xF5, 0x33};
321   uint8_t* rsp_buffer = NULL;
322   uint16_t rsp_len = 0;
323 
324   if ((phNxpNciHal_writeCmd(sizeof(get_session_cmd), get_session_cmd,
325                             WRITE_TIMEOUT_NS) == NFCSTATUS_SUCCESS)) {
326     if ((phNxpNciHal_ReadResponse(&rsp_len, &rsp_buffer,
327                                   RESPONSE_READ_TIMEOUT_NS) !=
328          NFCSTATUS_SUCCESS) ||
329         (rsp_buffer == NULL)) {
330       NXPLOG_NCIHAL_E("Get Session read response failed");
331     } else if (rsp_buffer[DL_RSP_STAT_IDX] == DL_MSG_STAT_RSP &&
332                rsp_buffer[DL_RSP_IDX] == DL_MSG_RSP) {
333       if (rsp_buffer[DL_RSP_SESS_IDX] == DL_SESSION_CLOSE_TAG) {
334         return true;
335       }
336     }
337   }
338   return false;
339 }
340 
341 /******************************************************************************
342  * Function         phNxpNciHal_determineChipTypeDlMode
343  *
344  * Description      Helper function to determine the chip info in download mode
345  *                  from get version command and stores value in global strcture
346  *
347  * Returns          bool
348  *
349  ******************************************************************************/
phNxpNciHal_determineChipTypeDlMode(void)350 static bool phNxpNciHal_determineChipTypeDlMode(void) {
351   const uint8_t get_version_cmd[] = {0x00, 0x04, 0xF1, 0x00,
352                                      0x00, 0x00, 0x6E, 0xEF};
353   uint8_t* rsp_buffer = NULL;
354   uint16_t rsp_len = 0;
355 
356   if ((phNxpNciHal_writeCmd(sizeof(get_version_cmd), get_version_cmd,
357                             WRITE_TIMEOUT_NS) == NFCSTATUS_SUCCESS)) {
358     if ((phNxpNciHal_ReadResponse(&rsp_len, &rsp_buffer,
359                                   RESPONSE_READ_TIMEOUT_NS) !=
360          NFCSTATUS_SUCCESS) ||
361         (rsp_buffer == NULL)) {
362       NXPLOG_NCIHAL_E("Get Version read response failed");
363     } else if (rsp_buffer[DL_RSP_STAT_IDX] == DL_MSG_STAT_RSP &&
364                rsp_buffer[DL_RSP_IDX] == DL_MSG_RSP) {
365       phNxpNciHal_configFeatureList(rsp_buffer, rsp_len);
366       return true;
367     }
368   }
369   return false;
370 }
371 
372 /******************************************************************************
373  * Function        phNxpNciHal_RecoverFWTearDown
374  *
375  * Description     Function to determine the NFCC state and recovery using
376  *                 minimal fw download.
377  *
378  * Parameters      None
379  *
380  * Returns         SUCCESS if recovery is successful else FAIL.
381  *
382  ******************************************************************************/
phNxpNciHal_RecoverFWTearDown(void)383 void phNxpNciHal_RecoverFWTearDown(void) {
384   uint8_t nfcc_recovery_support = 0x00;
385   // status post boot completed
386   const char* status = "Boot-completed";
387   char halInitStatus[PROPERTY_VALUE_MAX] = {0};
388 
389   NXPLOG_NCIHAL_D("phNxpNciHal_RecoverFWTearDown(): enter \n");
390   if (!GetNxpNumValue(NAME_NXP_NFCC_RECOVERY_SUPPORT, &nfcc_recovery_support,
391                       sizeof(nfcc_recovery_support))) {
392     NXPLOG_NCIHAL_E("Failed to read NXP_NFC_RECOVERY_SUPPORT config :");
393   }
394   if (nfcc_recovery_support == 0x00) {
395     NXPLOG_NCIHAL_D("NFCC Recovery not supported");
396     return;
397   }
398 
399   // If this is not boot time invocation return
400   getHalInitStatus(halInitStatus);
401   if (strncmp(halInitStatus, status, PROPERTY_VALUE_MAX) == 0) {
402     NXPLOG_NCIHAL_D("Not boot time, skip minimal FW download");
403     return;
404   } else {
405     NXPLOG_NCIHAL_D("boot time, check minimal FW download required");
406   }
407 
408   if (phnxpNciHal_partialOpen() != NFCSTATUS_SUCCESS) {
409     NXPLOG_NCIHAL_E("Failed to Initialize Partial HAL for NFCC recovery \n");
410     return;
411   }
412   if (phTmlNfc_IoCtl(phTmlNfc_e_PowerReset) != NFCSTATUS_SUCCESS) {
413     NXPLOG_NCIHAL_E("Failed to Perform VEN RESET \n");
414     phnxpNciHal_partialClose();
415     return;
416   }
417   if (phNxpNciHal_determineChipType()) {
418     NXPLOG_NCIHAL_D("Recovery not required \n");
419     phnxpNciHal_partialClose();
420     setHalInitStatus(status);
421     return;
422   }
423   if (phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadModeWithVenRst) !=
424       NFCSTATUS_SUCCESS) {
425     NXPLOG_NCIHAL_E("Enable Download mode failed");
426     phnxpNciHal_partialClose();
427     setHalInitStatus(status);
428     return;
429   }
430 
431   phTmlNfc_EnableFwDnldMode(true);
432   nxpncihal_ctrl.fwdnld_mode_reqd = TRUE;
433   bool bEnableNormalMode = true;
434   if (!phNxpNciHal_determineChipTypeDlMode()) {
435     NXPLOG_NCIHAL_E("Not able to determine chiptype");
436   } else if (nfcFL.chipType != sn100u) {
437     NXPLOG_NCIHAL_E("Recovery not supported for chiptype (%d)", nfcFL.chipType);
438   } else if (phNxpNciHal_isSessionClosed()) {
439     NXPLOG_NCIHAL_D("FW Dnld session is closed");
440   } else if (phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal,
441                                          nxpprofile_ctrl.bClkFreqVal, 0,
442                                          true) != NFCSTATUS_SUCCESS) {
443     NXPLOG_NCIHAL_E("Minimal FW Update failed \n");
444   } else {
445     /* In the success case, the phNxpNciHal_fw_download_seq() will enable normal
446      * mode */
447     bEnableNormalMode = false;
448   }
449   if (bEnableNormalMode) {
450     phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
451   }
452   phTmlNfc_IoCtl(phTmlNfc_e_PowerReset);
453   phnxpNciHal_partialClose();
454   // Minimal FW not required in this boot session
455   setHalInitStatus(status);
456 }
457 
458 /*******************************************************************************
459  *
460  * Function         phnxpNciHal_partialOpenCleanUp
461  *
462  * Description      Helper function to cleanUp the Memory and flags from
463  *                  phnxpNciHal_partialOpen
464  *
465  * Parameters       nfc_dev_node - dev node to be freed
466  *
467  * Returns          NFCSTATUS
468  *******************************************************************************/
phnxpNciHal_partialOpenCleanUp(char * nfc_dev_node)469 static int phnxpNciHal_partialOpenCleanUp(char* nfc_dev_node) {
470   if (nfc_dev_node != NULL) {
471     free(nfc_dev_node);
472     nfc_dev_node = NULL;
473   }
474   /* Report error status */
475   phNxpNciHal_cleanup_monitor();
476   nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
477   return NFCSTATUS_FAILED;
478 }
479 
480 /*******************************************************************************
481  *
482  * Function         phnxpNciHal_partialOpen
483  *
484  * Description      Initialize the Minimal HAL
485  *
486  * Parameters       none
487  *
488  * Returns          NFCSTATUS
489  *******************************************************************************/
phnxpNciHal_partialOpen(void)490 static NFCSTATUS phnxpNciHal_partialOpen(void) {
491   phOsalNfc_Config_t tOsalConfig;
492   phTmlNfc_Config_t tTmlConfig;
493   char* nfc_dev_node = NULL;
494 
495   NXPLOG_NCIHAL_D("phnxpNciHal_partialOpen(): enter");
496   if (nxpncihal_ctrl.halStatus == HAL_STATUS_MIN_OPEN) {
497     NXPLOG_NCIHAL_D("phNxpNciHal: already open");
498     return NFCSTATUS_SUCCESS;
499   }
500   /* initialize trace level */
501   phNxpLog_InitializeLogLevel();
502   if (phNxpNciHal_init_monitor() == NULL) {
503     NXPLOG_NCIHAL_E("Init monitor failed");
504     return NFCSTATUS_FAILED;
505   }
506   /* Create the local semaphore */
507   if (phNxpNciHal_init_cb_data(&nxpncihal_ctrl.ext_cb_data, NULL) !=
508       NFCSTATUS_SUCCESS) {
509     NXPLOG_NCIHAL_D("Create ext_cb_data failed");
510     return NFCSTATUS_FAILED;
511   }
512   CONCURRENCY_LOCK();
513   memset(&tOsalConfig, 0x00, sizeof(tOsalConfig));
514   memset(&tTmlConfig, 0x00, sizeof(tTmlConfig));
515   memset(&nxpprofile_ctrl, 0, sizeof(phNxpNciProfile_Control_t));
516 
517   /* By default HAL status is HAL_STATUS_OPEN */
518   nxpncihal_ctrl.halStatus = HAL_STATUS_OPEN;
519 
520   /*nci version NCI_VERSION_2_0 version by default for SN100 chip type*/
521   nxpncihal_ctrl.nci_info.nci_version = NCI_VERSION_2_0;
522   /* Read the nfc device node name */
523   nfc_dev_node = (char*)malloc(NXP_MAX_CONFIG_STRING_LEN * sizeof(char));
524   if (nfc_dev_node == NULL) {
525     NXPLOG_NCIHAL_D("malloc of nfc_dev_node failed ");
526     CONCURRENCY_UNLOCK();
527     return phnxpNciHal_partialOpenCleanUp(nfc_dev_node);
528   } else if (!GetNxpStrValue(NAME_NXP_NFC_DEV_NODE, nfc_dev_node,
529                              NXP_MAX_CONFIG_STRING_LEN)) {
530     NXPLOG_NCIHAL_D(
531         "Invalid nfc device node name keeping the default device node "
532         "/dev/pn54x");
533     strlcpy(nfc_dev_node, "/dev/pn54x",
534             (NXP_MAX_CONFIG_STRING_LEN * sizeof(char)));
535   }
536   /* Configure hardware link */
537   nxpncihal_ctrl.gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
538   nxpncihal_ctrl.gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C; /* For PN54X */
539   tTmlConfig.pDevName = (int8_t*)nfc_dev_node;
540   tOsalConfig.dwCallbackThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId;
541   tOsalConfig.pLogFile = NULL;
542   tTmlConfig.dwGetMsgThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId;
543 
544   /* Set Default Fragment Length */
545   tTmlConfig.fragment_len = NCI_CMDRESP_MAX_BUFF_SIZE_PN557;
546 
547   /* Initialize TML layer */
548   if (phTmlNfc_Init(&tTmlConfig) != NFCSTATUS_SUCCESS) {
549     NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
550     CONCURRENCY_UNLOCK();
551     return phnxpNciHal_partialOpenCleanUp(nfc_dev_node);
552   } else {
553     if (nfc_dev_node != NULL) {
554       free(nfc_dev_node);
555       nfc_dev_node = NULL;
556     }
557   }
558   /* Create the client thread */
559   if (pthread_create(&nxpncihal_ctrl.client_thread, NULL,
560                      phNxpNciHal_client_thread, &nxpncihal_ctrl) != 0) {
561     NXPLOG_NCIHAL_E("pthread_create failed");
562     if (phTmlNfc_Shutdown_CleanUp() != NFCSTATUS_SUCCESS) {
563       NXPLOG_NCIHAL_E("phTmlNfc_Shutdown_CleanUp: Failed");
564     }
565     CONCURRENCY_UNLOCK();
566     return phnxpNciHal_partialOpenCleanUp(nfc_dev_node);
567   }
568   phNxpNciHal_readNFCCClockCfgValues();
569   CONCURRENCY_UNLOCK();
570   return NFCSTATUS_SUCCESS;
571 }
572 
573 /*******************************************************************************
574  *
575  * Function         phnxpNciHal_partialClose
576  *
577  * Description      close the Minimal HAL
578  *
579  * Parameters       none
580  *
581  * Returns          void
582  *******************************************************************************/
phnxpNciHal_partialClose(void)583 static void phnxpNciHal_partialClose(void) {
584   NFCSTATUS status = NFCSTATUS_SUCCESS;
585   phLibNfc_Message_t msg;
586   nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
587 
588   if (NULL != gpphTmlNfc_Context->pDevHandle) {
589     msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
590     msg.pMsgData = NULL;
591     msg.Size = 0;
592     phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
593     /* Abort any pending read and write */
594     status = phTmlNfc_ReadAbort();
595     status = phTmlNfc_WriteAbort();
596     status = phTmlNfc_Shutdown();
597     if (0 != pthread_join(nxpncihal_ctrl.client_thread, (void**)NULL)) {
598       NXPLOG_TML_E("Fail to kill client thread!");
599     }
600     phTmlNfc_CleanUp();
601     phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
602     phNxpNciHal_cleanup_cb_data(&nxpncihal_ctrl.ext_cb_data);
603     memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
604     NXPLOG_NCIHAL_D("phnxpNciHal_partialClose - phOsalNfc_DeInit completed");
605   }
606   CONCURRENCY_UNLOCK();
607   phNxpNciHal_cleanup_monitor();
608 }
609 
610 #endif
611