1 /*
2 * Copyright 2021-2023 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 bool bEnableNormalMode = true;
433 if (!phNxpNciHal_determineChipTypeDlMode()) {
434 NXPLOG_NCIHAL_E("Not able to determine chiptype");
435 } else if (IS_CHIP_TYPE_NE(sn100u)) {
436 NXPLOG_NCIHAL_E("Recovery not supported for chiptype (%d)", nfcFL.chipType);
437 } else if (phNxpNciHal_isSessionClosed()) {
438 NXPLOG_NCIHAL_D("FW Dnld session is closed");
439 } else if (phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal,
440 nxpprofile_ctrl.bClkFreqVal, 0,
441 true) != NFCSTATUS_SUCCESS) {
442 NXPLOG_NCIHAL_E("Minimal FW Update failed \n");
443 } else {
444 /* In the success case, the phNxpNciHal_fw_download_seq() will enable normal
445 * mode */
446 bEnableNormalMode = false;
447 }
448 if (bEnableNormalMode) {
449 phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
450 }
451 phTmlNfc_IoCtl(phTmlNfc_e_PowerReset);
452 phnxpNciHal_partialClose();
453 // Minimal FW not required in this boot session
454 setHalInitStatus(status);
455 }
456
457 /*******************************************************************************
458 *
459 * Function phnxpNciHal_partialOpenCleanUp
460 *
461 * Description Helper function to cleanUp the Memory and flags from
462 * phnxpNciHal_partialOpen
463 *
464 * Parameters nfc_dev_node - dev node to be freed
465 *
466 * Returns NFCSTATUS
467 *******************************************************************************/
phnxpNciHal_partialOpenCleanUp(char * nfc_dev_node)468 static int phnxpNciHal_partialOpenCleanUp(char* nfc_dev_node) {
469 if (nfc_dev_node != NULL) {
470 free(nfc_dev_node);
471 nfc_dev_node = NULL;
472 }
473 /* Report error status */
474 phNxpNciHal_cleanup_monitor();
475 nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
476 return NFCSTATUS_FAILED;
477 }
478
479 /*******************************************************************************
480 *
481 * Function phnxpNciHal_partialOpen
482 *
483 * Description Initialize the Minimal HAL
484 *
485 * Parameters none
486 *
487 * Returns NFCSTATUS
488 *******************************************************************************/
phnxpNciHal_partialOpen(void)489 static NFCSTATUS phnxpNciHal_partialOpen(void) {
490 phOsalNfc_Config_t tOsalConfig;
491 phTmlNfc_Config_t tTmlConfig;
492 char* nfc_dev_node = NULL;
493
494 NXPLOG_NCIHAL_D("phnxpNciHal_partialOpen(): enter");
495 if (nxpncihal_ctrl.halStatus == HAL_STATUS_MIN_OPEN) {
496 NXPLOG_NCIHAL_D("phNxpNciHal: already open");
497 return NFCSTATUS_SUCCESS;
498 }
499 /* initialize trace level */
500 phNxpLog_InitializeLogLevel();
501 if (phNxpNciHal_init_monitor() == NULL) {
502 NXPLOG_NCIHAL_E("Init monitor failed");
503 return NFCSTATUS_FAILED;
504 }
505 /* Create the local semaphore */
506 if (phNxpNciHal_init_cb_data(&nxpncihal_ctrl.ext_cb_data, NULL) !=
507 NFCSTATUS_SUCCESS) {
508 NXPLOG_NCIHAL_D("Create ext_cb_data failed");
509 return NFCSTATUS_FAILED;
510 }
511 CONCURRENCY_LOCK();
512 memset(&tOsalConfig, 0x00, sizeof(tOsalConfig));
513 memset(&tTmlConfig, 0x00, sizeof(tTmlConfig));
514 memset(&nxpprofile_ctrl, 0, sizeof(phNxpNciProfile_Control_t));
515
516 /* By default HAL status is HAL_STATUS_OPEN */
517 nxpncihal_ctrl.halStatus = HAL_STATUS_OPEN;
518
519 /*nci version NCI_VERSION_2_0 version by default for SN100 chip type*/
520 nxpncihal_ctrl.nci_info.nci_version = NCI_VERSION_2_0;
521 /* Read the nfc device node name */
522 nfc_dev_node = (char*)malloc(NXP_MAX_CONFIG_STRING_LEN * sizeof(char));
523 if (nfc_dev_node == NULL) {
524 NXPLOG_NCIHAL_D("malloc of nfc_dev_node failed ");
525 CONCURRENCY_UNLOCK();
526 return phnxpNciHal_partialOpenCleanUp(nfc_dev_node);
527 } else if (!GetNxpStrValue(NAME_NXP_NFC_DEV_NODE, nfc_dev_node,
528 NXP_MAX_CONFIG_STRING_LEN)) {
529 NXPLOG_NCIHAL_D(
530 "Invalid nfc device node name keeping the default device node "
531 "/dev/pn54x");
532 strlcpy(nfc_dev_node, "/dev/pn54x",
533 (NXP_MAX_CONFIG_STRING_LEN * sizeof(char)));
534 }
535 /* Configure hardware link */
536 nxpncihal_ctrl.gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
537 nxpncihal_ctrl.gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C; /* For PN54X */
538 tTmlConfig.pDevName = (int8_t*)nfc_dev_node;
539 tOsalConfig.dwCallbackThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId;
540 tOsalConfig.pLogFile = NULL;
541 tTmlConfig.dwGetMsgThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId;
542
543 /* Initialize TML layer */
544 if (phTmlNfc_Init(&tTmlConfig) != NFCSTATUS_SUCCESS) {
545 NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
546 CONCURRENCY_UNLOCK();
547 return phnxpNciHal_partialOpenCleanUp(nfc_dev_node);
548 } else {
549 if (nfc_dev_node != NULL) {
550 free(nfc_dev_node);
551 nfc_dev_node = NULL;
552 }
553 }
554 /* Create the client thread */
555 if (pthread_create(&nxpncihal_ctrl.client_thread, NULL,
556 phNxpNciHal_client_thread, &nxpncihal_ctrl) != 0) {
557 NXPLOG_NCIHAL_E("pthread_create failed");
558 if (phTmlNfc_Shutdown_CleanUp() != NFCSTATUS_SUCCESS) {
559 NXPLOG_NCIHAL_E("phTmlNfc_Shutdown_CleanUp: Failed");
560 }
561 CONCURRENCY_UNLOCK();
562 return phnxpNciHal_partialOpenCleanUp(nfc_dev_node);
563 }
564 phNxpNciHal_readNFCCClockCfgValues();
565 CONCURRENCY_UNLOCK();
566 return NFCSTATUS_SUCCESS;
567 }
568
569 /*******************************************************************************
570 *
571 * Function phnxpNciHal_partialClose
572 *
573 * Description close the Minimal HAL
574 *
575 * Parameters none
576 *
577 * Returns void
578 *******************************************************************************/
phnxpNciHal_partialClose(void)579 static void phnxpNciHal_partialClose(void) {
580 phLibNfc_Message_t msg;
581 nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
582
583 if (NULL != gpphTmlNfc_Context->pDevHandle) {
584 msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
585 msg.pMsgData = NULL;
586 msg.Size = 0;
587 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
588 /* Abort any pending read and write */
589 phTmlNfc_ReadAbort();
590 phTmlNfc_WriteAbort();
591 phTmlNfc_Shutdown();
592 if (0 != pthread_join(nxpncihal_ctrl.client_thread, (void**)NULL)) {
593 NXPLOG_TML_E("Fail to kill client thread!");
594 }
595 phTmlNfc_CleanUp();
596 phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
597 phNxpNciHal_cleanup_cb_data(&nxpncihal_ctrl.ext_cb_data);
598 memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
599 NXPLOG_NCIHAL_D("phnxpNciHal_partialClose - phOsalNfc_DeInit completed");
600 }
601 CONCURRENCY_UNLOCK();
602 phNxpNciHal_cleanup_monitor();
603 }
604
605 #endif
606