• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012-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 #include <android-base/file.h>
18 #include <dlfcn.h>
19 #include <log/log.h>
20 #include <phDal4Nfc_messageQueueLib.h>
21 #include <phDnldNfc.h>
22 #include <phNxpConfig.h>
23 #include <phNxpLog.h>
24 #include <phNxpNciHal.h>
25 #include <phNxpNciHal_Adaptation.h>
26 #include <phNxpNciHal_Dnld.h>
27 #include <phNxpNciHal_NfcDepSWPrio.h>
28 #include <phNxpNciHal_ext.h>
29 #include <phTmlNfc.h>
30 #if (NXP_EXTNS == TRUE)
31 #include "phNxpNciHal_nciParser.h"
32 #endif
33 
34 #include <EseAdaptation.h>
35 #include <android-base/stringprintf.h>
36 #include <sys/stat.h>
37 
38 #include "NfccTransportFactory.h"
39 #include "NxpNfcThreadMutex.h"
40 #include "phNxpNciHal_IoctlOperations.h"
41 #include "phNxpNciHal_extOperations.h"
42 
43 using android::base::StringPrintf;
44 using namespace android::hardware::nfc::V1_1;
45 using namespace android::hardware::nfc::V1_2;
46 using android::base::WriteStringToFile;
47 using android::hardware::nfc::V1_1::NfcEvent;
48 
49 /*********************** Global Variables *************************************/
50 #define PN547C2_CLOCK_SETTING
51 #define CORE_RES_STATUS_BYTE 3
52 #define MAX_NXP_HAL_EXTN_BYTES 10
53 #define DEFAULT_MINIMAL_FW_VERSION 0x0110DE
54 
55 bool bEnableMfcExtns = false;
56 bool bEnableMfcReader = false;
57 bool bDisableLegacyMfcExtns = true;
58 
59 /* Processing of ISO 15693 EOF */
60 extern uint8_t icode_send_eof;
61 extern uint8_t icode_detected;
62 static uint8_t cmd_icode_eof[] = {0x00, 0x00, 0x00};
63 static const char* rf_block_num[] = {
64     "1",  "2",  "3",  "4",  "5",  "6",  "7",  "8",  "9",  "10", "11",
65     "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22",
66     "23", "24", "25", "26", "27", "28", "29", "30", NULL};
67 const char* rf_block_name = "NXP_RF_CONF_BLK_";
68 static uint8_t read_failed_disable_nfc = false;
69 /* FW download success flag */
70 static uint8_t fw_download_success = 0;
71 static uint8_t config_access = false;
72 static uint8_t config_success = true;
73 static NfcHalThreadMutex sHalFnLock;
74 
75 /* NCI HAL Control structure */
76 phNxpNciHal_Control_t nxpncihal_ctrl;
77 
78 /* NXP Poll Profile structure */
79 phNxpNciProfile_Control_t nxpprofile_ctrl;
80 
81 /* TML Context */
82 extern phTmlNfc_Context_t* gpphTmlNfc_Context;
83 extern spTransport gpTransportObj;
84 
85 extern void phTmlNfc_set_fragmentation_enabled(
86     phTmlNfc_i2cfragmentation_t result);
87 
88 extern NFCSTATUS phNxpNciHal_ext_send_sram_config_to_flash();
89 extern NFCSTATUS phNxpNciHal_enableDefaultUICC2SWPline(uint8_t uicc2_sel);
90 extern void phNxpNciHal_conf_nfc_forum_mode();
91 extern void phNxpNciHal_prop_conf_lpcd(bool enableLPCD);
92 extern void phNxpNciHal_prop_conf_rssi();
93 
94 nfc_stack_callback_t* p_nfc_stack_cback_backup;
95 phNxpNci_getCfg_info_t* mGetCfg_info = NULL;
96 bool_t gParserCreated = FALSE;
97 /* global variable to get FW version from NCI response or dl get version
98  * response*/
99 uint32_t wFwVerRsp;
100 EseAdaptation* gpEseAdapt = NULL;
101 #ifdef NXP_BOOTTIME_UPDATE
102 ese_update_state_t ese_update = ESE_UPDATE_COMPLETED;
103 #endif
104 /* External global variable to get FW version */
105 extern uint16_t wFwVer;
106 extern uint8_t gRecFWDwnld;
107 static uint8_t gRecFwRetryCount;  // variable to hold recovery FW retry count
108 static uint8_t write_unlocked_status = NFCSTATUS_SUCCESS;
109 uint8_t wFwUpdateReq = false;
110 uint8_t wRfUpdateReq = false;
111 uint32_t timeoutTimerId = 0;
112 #ifndef FW_DWNLD_FLAG
113 uint8_t fw_dwnld_flag = false;
114 #endif
115 bool nfc_debug_enabled = true;
116 
117 /*  Used to send Callback Transceive data during Mifare Write.
118  *  If this flag is enabled, no need to send response to Upper layer */
119 bool sendRspToUpperLayer = true;
120 
121 phNxpNciHal_Sem_t config_data;
122 
123 phNxpNciClock_t phNxpNciClock = {0, {0}, false};
124 
125 phNxpNciRfSetting_t phNxpNciRfSet = {false, {0}};
126 
127 phNxpNciMwEepromArea_t phNxpNciMwEepromArea = {false, {0}};
128 
129 volatile bool_t gsIsFirstHalMinOpen = true;
130 volatile bool_t gsIsFwRecoveryRequired = false;
131 
132 void* RfFwRegionDnld_handle = NULL;
133 fpVerInfoStoreInEeprom_t fpVerInfoStoreInEeprom = NULL;
134 fpRegRfFwDndl_t fpRegRfFwDndl = NULL;
135 fpPropConfCover_t fpPropConfCover = NULL;
136 void* phNxpNciHal_client_thread(void* arg);
137 /**************** local methods used in this file only ************************/
138 static void phNxpNciHal_open_complete(NFCSTATUS status);
139 static void phNxpNciHal_MinOpen_complete(NFCSTATUS status);
140 static void phNxpNciHal_write_complete(void* pContext,
141                                        phTmlNfc_TransactInfo_t* pInfo);
142 static void phNxpNciHal_read_complete(void* pContext,
143                                       phTmlNfc_TransactInfo_t* pInfo);
144 static void phNxpNciHal_close_complete(NFCSTATUS status);
145 static void phNxpNciHal_core_initialized_complete(NFCSTATUS status);
146 static void phNxpNciHal_power_cycle_complete(NFCSTATUS status);
147 static void phNxpNciHal_kill_client_thread(
148     phNxpNciHal_Control_t* p_nxpncihal_ctrl);
149 static void phNxpNciHal_nfccClockCfgRead(void);
150 static NFCSTATUS phNxpNciHal_nfccClockCfgApply(void);
151 static void phNxpNciHal_hci_network_reset(void);
152 static NFCSTATUS phNxpNciHal_do_swp_session_reset(void);
153 static void phNxpNciHal_print_res_status(uint8_t* p_rx_data, uint16_t* p_len);
154 static void phNxpNciHal_enable_i2c_fragmentation();
155 static NFCSTATUS phNxpNciHal_get_mw_eeprom(void);
156 static NFCSTATUS phNxpNciHal_set_mw_eeprom(void);
157 #if (NXP_EXTNS == TRUE)
158 static void phNxpNciHal_configNciParser(bool enable);
159 #endif
160 static void phNxpNciHal_gpio_restore(phNxpNciHal_GpioInfoState state);
161 static void phNxpNciHal_initialize_debug_enabled_flag();
162 static void phNxpNciHal_initialize_mifare_flag();
163 static NFCSTATUS phNxpNciHalRFConfigCmdRecSequence();
164 static NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus();
165 static void phNxpNciHal_UpdateFwStatus(HalNfcFwUpdateStatus fwStatus);
166 static NFCSTATUS phNxpNciHal_resetDefaultSettings(uint8_t fw_update_req,
167                                                   bool keep_config);
168 static NFCSTATUS phNxpNciHal_force_fw_download(uint8_t seq_handler_offset = 0);
169 static int phNxpNciHal_MinOpen_Clean(char* nfc_dev_node);
170 static void phNxpNciHal_CheckAndHandleFwTearDown(void);
171 static NFCSTATUS phNxpNciHal_getChipInfoInFwDnldMode(
172     bool bIsVenResetReqd = false);
173 static uint8_t phNxpNciHal_getSessionInfoInFwDnldMode();
174 static NFCSTATUS phNxpNciHal_dlResetInFwDnldMode();
175 static NFCSTATUS phNxpNciHal_enableTmlRead();
176 /******************************************************************************
177  * Function         phNxpNciHal_initialize_debug_enabled_flag
178  *
179  * Description      This function gets the value for nfc_debug_enabled
180  *
181  * Returns          void
182  *
183  ******************************************************************************/
phNxpNciHal_initialize_debug_enabled_flag()184 static void phNxpNciHal_initialize_debug_enabled_flag() {
185   unsigned long num = 0;
186   char valueStr[PROPERTY_VALUE_MAX] = {0};
187   if (GetNxpNumValue(NAME_NFC_DEBUG_ENABLED, &num, sizeof(num))) {
188     nfc_debug_enabled = (num == 0) ? false : true;
189   }
190 
191   int len = property_get("nfc.debug_enabled", valueStr, "");
192   if (len > 0) {
193     // let Android property override .conf variable
194     unsigned debug_enabled = 0;
195     sscanf(valueStr, "%u", &debug_enabled);
196     nfc_debug_enabled = (debug_enabled == 0) ? false : true;
197   }
198   NXPLOG_NCIHAL_D("nfc_debug_enabled : %d", nfc_debug_enabled);
199 }
200 
201 /******************************************************************************
202  * Function         phNxpNciHal_client_thread
203  *
204  * Description      This function is a thread handler which handles all TML and
205  *                  NCI messages.
206  *
207  * Returns          void
208  *
209  ******************************************************************************/
phNxpNciHal_client_thread(void * arg)210 void* phNxpNciHal_client_thread(void* arg) {
211   phNxpNciHal_Control_t* p_nxpncihal_ctrl = (phNxpNciHal_Control_t*)arg;
212   phLibNfc_Message_t msg;
213 
214   NXPLOG_NCIHAL_D("thread started");
215 
216   p_nxpncihal_ctrl->thread_running = 1;
217 
218   while (p_nxpncihal_ctrl->thread_running == 1) {
219     /* Fetch next message from the NFC stack message queue */
220     if (phDal4Nfc_msgrcv(p_nxpncihal_ctrl->gDrvCfg.nClientId, &msg, 0, 0) ==
221         -1) {
222       NXPLOG_NCIHAL_E("NFC client received bad message");
223       continue;
224     }
225 
226     if (p_nxpncihal_ctrl->thread_running == 0) {
227       break;
228     }
229 
230     switch (msg.eMsgType) {
231       case PH_LIBNFC_DEFERREDCALL_MSG: {
232         phLibNfc_DeferredCall_t* deferCall =
233             (phLibNfc_DeferredCall_t*)(msg.pMsgData);
234 
235         REENTRANCE_LOCK();
236         deferCall->pCallback(deferCall->pParameter);
237         REENTRANCE_UNLOCK();
238 
239         break;
240       }
241 
242       case NCI_HAL_OPEN_CPLT_MSG: {
243         REENTRANCE_LOCK();
244         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
245           /* Send the event */
246           (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT,
247                                               HAL_NFC_STATUS_OK);
248         }
249         REENTRANCE_UNLOCK();
250         break;
251       }
252 
253       case NCI_HAL_CLOSE_CPLT_MSG: {
254         REENTRANCE_LOCK();
255         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
256           /* Send the event */
257           (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_CLOSE_CPLT_EVT,
258                                               HAL_NFC_STATUS_OK);
259         }
260         phNxpNciHal_kill_client_thread(&nxpncihal_ctrl);
261         REENTRANCE_UNLOCK();
262         break;
263       }
264 
265       case NCI_HAL_POST_INIT_CPLT_MSG: {
266         REENTRANCE_LOCK();
267         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
268           /* Send the event */
269           (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_POST_INIT_CPLT_EVT,
270                                               HAL_NFC_STATUS_OK);
271         }
272         REENTRANCE_UNLOCK();
273         break;
274       }
275 
276       case NCI_HAL_PRE_DISCOVER_CPLT_MSG: {
277         REENTRANCE_LOCK();
278         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
279           /* Send the event */
280           (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_PRE_DISCOVER_CPLT_EVT,
281                                               HAL_NFC_STATUS_OK);
282         }
283         REENTRANCE_UNLOCK();
284         break;
285       }
286 
287       case NCI_HAL_HCI_NETWORK_RESET_MSG: {
288         REENTRANCE_LOCK();
289         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
290           /* Send the event */
291           (*nxpncihal_ctrl.p_nfc_stack_cback)(
292               (uint32_t)NfcEvent::HCI_NETWORK_RESET, HAL_NFC_STATUS_OK);
293         }
294         REENTRANCE_UNLOCK();
295         break;
296       }
297 
298       case NCI_HAL_ERROR_MSG: {
299         REENTRANCE_LOCK();
300         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
301           /* Send the event */
302           (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ERROR_EVT,
303                                               HAL_NFC_STATUS_FAILED);
304         }
305         REENTRANCE_UNLOCK();
306         break;
307       }
308 
309       case NCI_HAL_RX_MSG: {
310         REENTRANCE_LOCK();
311         if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) {
312           (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rsp_len,
313                                                    nxpncihal_ctrl.p_rsp_data);
314         }
315         REENTRANCE_UNLOCK();
316         break;
317       }
318       case HAL_NFC_FW_UPDATE_STATUS_EVT: {
319         REENTRANCE_LOCK();
320         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
321           /* Send the event */
322           (*nxpncihal_ctrl.p_nfc_stack_cback)(msg.eMsgType,
323                                               *((uint8_t*)msg.pMsgData));
324         }
325         REENTRANCE_UNLOCK();
326         break;
327       }
328     }
329   }
330 
331   NXPLOG_NCIHAL_D("NxpNciHal thread stopped");
332 
333   return NULL;
334 }
335 
336 /******************************************************************************
337  * Function         phNxpNciHal_kill_client_thread
338  *
339  * Description      This function safely kill the client thread and clean all
340  *                  resources.
341  *
342  * Returns          void.
343  *
344  ******************************************************************************/
phNxpNciHal_kill_client_thread(phNxpNciHal_Control_t * p_nxpncihal_ctrl)345 static void phNxpNciHal_kill_client_thread(
346     phNxpNciHal_Control_t* p_nxpncihal_ctrl) {
347   NXPLOG_NCIHAL_D("Terminating phNxpNciHal client thread...");
348 
349   p_nxpncihal_ctrl->p_nfc_stack_cback = NULL;
350   p_nxpncihal_ctrl->p_nfc_stack_data_cback = NULL;
351   p_nxpncihal_ctrl->thread_running = 0;
352 
353   return;
354 }
355 /******************************************************************************
356  * Function         phNxpNciHal_CheckIntegrityRecovery
357  *
358  * Description     This function to enter in recovery if FW download fails with
359  *                 check integrity.
360  *
361  * Returns         NFCSTATUS
362  *
363  ******************************************************************************/
phNxpNciHal_CheckIntegrityRecovery()364 static NFCSTATUS phNxpNciHal_CheckIntegrityRecovery() {
365   NFCSTATUS status = NFCSTATUS_FAILED;
366   if (phNxpNciHal_nfcc_core_reset_init(false) == NFCSTATUS_SUCCESS) {
367     status = phNxpNciHal_fw_download();
368   } else {
369     status = NFCSTATUS_FW_CHECK_INTEGRITY_FAILED;
370   }
371   return status;
372 }
373 /******************************************************************************
374  * Function         phNxpNciHal_force_fw_download
375  *
376  * Description     This function, based on the offset provided, will trigger
377  *                 Secure FW download sequence.
378  *                 It will retry the FW download in case the Check Integrity
379  *                 has been failed.
380  *
381  * Parameters      Offset by which the FW dnld Seq handler shall be triggered.
382  *                 e.g. if we want to send only the Check Integrity command,
383  *                 then the offset shall be 7.
384  *
385  * Returns         SUCCESS if FW download is successful else FAIL.
386  *
387  ******************************************************************************/
phNxpNciHal_force_fw_download(uint8_t seq_handler_offset)388 static NFCSTATUS phNxpNciHal_force_fw_download(uint8_t seq_handler_offset) {
389   NFCSTATUS wConfigStatus = NFCSTATUS_SUCCESS;
390   NFCSTATUS status = NFCSTATUS_SUCCESS;
391   /*Get FW version from device*/
392   for (int retry = 1; retry >= 0; retry--) {
393     if (phDnldNfc_InitImgInfo() == NFCSTATUS_SUCCESS) {
394       break;
395     } else {
396       phDnldNfc_ReSetHwDevHandle();
397       NXPLOG_NCIHAL_E("Image information extraction Failed!!");
398       if (!retry) return NFCSTATUS_FAILED;
399     }
400   }
401 
402   NXPLOG_NCIHAL_D("FW version for FW file = 0x%x", wFwVer);
403   NXPLOG_NCIHAL_D("FW version from device = 0x%x", wFwVerRsp);
404   bool bIsNfccDlState = false;
405   if (wFwVerRsp == 0) {
406     status = phNxpNciHal_getChipInfoInFwDnldMode(true);
407     if (status != NFCSTATUS_SUCCESS) {
408       NXPLOG_NCIHAL_E("phNxpNciHal_getChipInfoInFwDnldMode Failed");
409     }
410     bIsNfccDlState = true;
411   }
412   if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion()) {
413     NXPLOG_NCIHAL_D("FW update required");
414     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_UNKNOWN;
415     if (nfcFL.chipType < sn100u) phNxpNciHal_gpio_restore(GPIO_STORE);
416     fw_download_success = 0;
417     /*We are expecting NFC to be either in NFC or in the FW Download state*/
418     status = phNxpNciHal_fw_download(seq_handler_offset, bIsNfccDlState);
419     if (status == NFCSTATUS_FW_CHECK_INTEGRITY_FAILED) {
420       status = phNxpNciHal_CheckIntegrityRecovery();
421     }
422     property_set("nfc.fw.downloadmode_force", "0");
423     if (status == NFCSTATUS_SUCCESS) {
424       wConfigStatus = NFCSTATUS_SUCCESS;
425       fw_download_success = TRUE;
426     } else if (status == NFCSTATUS_FW_CHECK_INTEGRITY_FAILED ||
427                (phNxpNciHal_fw_mw_ver_check() != NFCSTATUS_SUCCESS)) {
428       phOsalNfc_Timer_Cleanup();
429       phTmlNfc_Shutdown_CleanUp();
430       return NFCSTATUS_CMD_ABORTED;
431     }
432 
433     status = phNxpNciHal_nfcc_core_reset_init();
434     if (status == NFCSTATUS_SUCCESS && nfcFL.chipType < sn100u) {
435       if (status == NFCSTATUS_SUCCESS) {
436         phNxpNciHal_gpio_restore(GPIO_RESTORE);
437       } else {
438         NXPLOG_NCIHAL_E("Failed to restore GPIO values!!!\n");
439       }
440     }
441   }
442   return wConfigStatus;
443 }
444 
445 /******************************************************************************
446  * Function         phNxpNciHal_fw_download
447  *
448  * Description      This function download the PN54X secure firmware to IC. If
449  *                  firmware version in Android filesystem and firmware in the
450  *                  IC is same then firmware download will return with success
451  *                  without downloading the firmware.
452  *
453  * Returns          NFCSTATUS_SUCCESS if firmware download successful
454  *                  NFCSTATUS_FAILED in case of failure
455  *
456  ******************************************************************************/
phNxpNciHal_fw_download(uint8_t seq_handler_offset,bool bIsNfccDlState)457 NFCSTATUS phNxpNciHal_fw_download(uint8_t seq_handler_offset,
458                                   bool bIsNfccDlState) {
459   NFCSTATUS status = NFCSTATUS_SUCCESS;
460   phNxpNciHal_UpdateFwStatus(HAL_NFC_FW_UPDATE_START);
461   phNxpNciHal_nfccClockCfgRead();
462 
463   if (!bIsNfccDlState) {
464     status = phNxpNciHal_write_fw_dw_status(TRUE);
465     if (status != NFCSTATUS_SUCCESS) {
466       NXPLOG_NCIHAL_E("%s: NXP Set FW DW Flag failed", __FUNCTION__);
467     }
468 
469     NXPLOG_NCIHAL_D("nfcFL.nfccFL._NFCC_DWNLD_MODE %x\n",
470                     nfcFL.nfccFL._NFCC_DWNLD_MODE);
471 
472     if (nfcFL.chipType >= sn100u) {
473       uint8_t ven_cfg_low_cmd[] = {0x20, 0x02, 0x05, 0x01,
474                                    0xA0, 0x07, 0x01, 0x00};
475       status =
476           phNxpNciHal_send_ext_cmd(sizeof(ven_cfg_low_cmd), ven_cfg_low_cmd);
477       if (status != NFCSTATUS_SUCCESS) {
478         NXPLOG_NCIHAL_E("Failed to set VEN_CFG to low \n");
479       }
480     }
481     /*Save UICC params */
482     status = phNxpNciHal_save_uicc_params();
483     if (status != NFCSTATUS_SUCCESS) {
484       NXPLOG_NCIHAL_E("Failed to save UICC params \n");
485     }
486 
487     status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
488     if (NFCSTATUS_SUCCESS != status) {
489       nxpncihal_ctrl.fwdnld_mode_reqd = FALSE;
490       phNxpNciHal_UpdateFwStatus(HAL_NFC_FW_UPDATE_FAILED);
491       return NFCSTATUS_FAILED;
492     }
493   }
494 
495   /* Make sure read thread is pending before updating fwdnld_mode_reqd to true*/
496   NFCSTATUS readStatus = phNxpNciHal_enableTmlRead();
497   if (readStatus != PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY)) {
498     NXPLOG_NCIHAL_E("Read Thread is not pending already. status = 0x%x \n",
499                     readStatus);
500   }
501 
502   nxpncihal_ctrl.fwdnld_mode_reqd = TRUE;
503   if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_NCI_CMD &&
504       (!bIsNfccDlState)) {
505     /*NCI_RESET_CMD*/
506     static uint8_t cmd_reset_nci_dwnld[] = {0x20, 0x00, 0x01, 0x80};
507     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci_dwnld),
508                                       cmd_reset_nci_dwnld);
509     if (status != NFCSTATUS_SUCCESS) {
510       NXPLOG_NCIHAL_E("Core reset FW download command failed \n");
511     }
512   }
513 
514   if (NFCSTATUS_SUCCESS == status) {
515     phTmlNfc_EnableFwDnldMode(true);
516     /* Set the obtained device handle to download module */
517 
518     phDnldNfc_SetHwDevHandle();
519 
520     if (nfcFL.chipType >= sn100u) {
521       phDnldNfc_SetI2CFragmentLength(NCI_CMDRESP_MAX_BUFF_SIZE_SNXXX);
522     } else {
523       phDnldNfc_SetI2CFragmentLength(NCI_CMDRESP_MAX_BUFF_SIZE_PN557);
524     }
525 
526     NXPLOG_NCIHAL_D("Calling Seq handler for FW Download \n");
527     status = phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal,
528                                          nxpprofile_ctrl.bClkFreqVal,
529                                          seq_handler_offset);
530 
531     if (phNxpNciHal_dlResetInFwDnldMode() != NFCSTATUS_SUCCESS) {
532       NXPLOG_NCIHAL_E("DL Reset failed in FW DN mode");
533     }
534 
535     /* FW download done.Therefore if previous I2C write failed then we can
536      * change the state to NFCSTATUS_SUCCESS*/
537     write_unlocked_status = NFCSTATUS_SUCCESS;
538   } else {
539     nxpncihal_ctrl.fwdnld_mode_reqd = FALSE;
540     status = NFCSTATUS_FAILED;
541   }
542   if (NFCSTATUS_SUCCESS == status) {
543     phNxpNciHal_UpdateFwStatus(HAL_NFC_FW_UPDATE_SCUCCESS);
544   } else {
545     phNxpNciHal_UpdateFwStatus(HAL_NFC_FW_UPDATE_FAILED);
546   }
547   return status;
548 }
549 
550 /******************************************************************************
551  * Function         phNxpNciHal_CheckValidFwVersion
552  *
553  * Description      This function checks the valid FW for Mobile device.
554  *                  If the FW doesn't belong the Mobile device it further
555  *                  checks nxp config file to override.
556  *
557  * Returns          NFCSTATUS_SUCCESS if valid fw version found
558  *                  NFCSTATUS_NOT_ALLOWED in case of FW not valid for mobile
559  *                  device
560  *
561  ******************************************************************************/
phNxpNciHal_CheckValidFwVersion(void)562 NFCSTATUS phNxpNciHal_CheckValidFwVersion(void) {
563   NFCSTATUS status = NFCSTATUS_NOT_ALLOWED;
564   const unsigned char sfw_infra_major_no = 0x02;
565   unsigned char ufw_current_major_no = 0x00;
566   uint8_t rom_version = 0xFF & (wFwVerRsp >> 16);
567   uint8_t fw_maj_ver = 0xFF & (wFwVerRsp >> 8);
568 
569   /* extract the firmware's major no */
570   ufw_current_major_no = ((0x00FF) & (wFwVer >> 8U));
571   NXPLOG_NCIHAL_D("%s current_major_no = 0x%x", __func__, ufw_current_major_no);
572   NXPLOG_NCIHAL_D("%s fw_maj_ver = 0x%x", __func__, fw_maj_ver);
573   if (nfcFL.chipType == pn557) {
574     if (ufw_current_major_no >= fw_maj_ver) {
575       /* if file major version is grater than the one from the
576          Nfc init command allow FW download
577       */
578       status = NFCSTATUS_SUCCESS;
579     }
580     return status;
581   }
582 
583   if (wFwVerRsp == 0) {
584     NXPLOG_NCIHAL_E(
585         "FW Version not received by NCI command >>> Force Firmware download");
586     status = NFCSTATUS_SUCCESS;
587   } else if ((ufw_current_major_no == nfcFL._FW_MOBILE_MAJOR_NUMBER) ||
588              ((ufw_current_major_no == FW_MOBILE_MAJOR_NUMBER_PN81A) &&
589               (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0))) {
590     NXPLOG_NCIHAL_E("FW Version 2");
591     status = NFCSTATUS_SUCCESS;
592   } else if (ufw_current_major_no == sfw_infra_major_no) {
593     if ((rom_version == FW_MOBILE_ROM_VERSION_PN553 ||
594          rom_version == FW_MOBILE_ROM_VERSION_PN557)) {
595       NXPLOG_NCIHAL_D(" PN557  allow Fw download with major number =  0x%x",
596                       ufw_current_major_no);
597       status = NFCSTATUS_SUCCESS;
598     } else {
599       status = NFCSTATUS_NOT_ALLOWED;
600     }
601   }
602 #ifdef NXP_DUMMY_FW_DNLD
603   else if (gRecFWDwnld == TRUE) {
604     NXPLOG_NCIHAL_E("FW Version 4");
605     status = NFCSTATUS_SUCCESS;
606   }
607 #endif
608   else {
609     NXPLOG_NCIHAL_E("Wrong FW Version >>> Firmware download not allowed");
610   }
611 
612   return status;
613 }
614 
615 /******************************************************************************
616  * Function         phNxpNciHal_MinOpen_Clean
617  *
618  * Description      This function shall be called from phNxpNciHal_MinOpen when
619  *                  any unrecoverable error has encountered which needs to mark
620  *                  min open as failed, HAL status as closed & deallocate any
621  *                  memory if allocated.
622  *
623  * Returns          This function always returns Failure
624  *
625  ******************************************************************************/
phNxpNciHal_MinOpen_Clean(char * nfc_dev_node)626 static int phNxpNciHal_MinOpen_Clean(char* nfc_dev_node) {
627   if (nfc_dev_node != NULL) {
628     free(nfc_dev_node);
629     nfc_dev_node = NULL;
630   }
631   if (mGetCfg_info != NULL) {
632     free(mGetCfg_info);
633     mGetCfg_info = NULL;
634   }
635   /* Report error status */
636   phNxpNciHal_cleanup_monitor();
637   nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
638   return NFCSTATUS_FAILED;
639 }
640 
641 /******************************************************************************
642  * Function         phNxpNciHal_MinOpen
643  *
644  * Description      This function initializes the least required resources to
645  *                  communicate to NFCC.This is mainly used to communicate to
646  *                  NFCC when NFC service is not available.
647  *
648  *
649  * Returns          This function return NFCSTATUS_SUCCESS (0) in case of
650  *success In case of failure returns other failure value.
651  *
652  ******************************************************************************/
phNxpNciHal_MinOpen()653 int phNxpNciHal_MinOpen() {
654   phOsalNfc_Config_t tOsalConfig;
655   phTmlNfc_Config_t tTmlConfig;
656   char* nfc_dev_node = NULL;
657   const uint16_t max_len = 260;
658   NFCSTATUS wConfigStatus = NFCSTATUS_SUCCESS;
659   NFCSTATUS status = NFCSTATUS_SUCCESS;
660   int dnld_retry_cnt = 0;
661   NXPLOG_NCIHAL_D("phNxpNci_MinOpen(): enter");
662 
663   NfcHalAutoThreadMutex a(sHalFnLock);
664   if (nxpncihal_ctrl.halStatus == HAL_STATUS_MIN_OPEN) {
665     NXPLOG_NCIHAL_D("phNxpNciHal_MinOpen(): already open");
666     return NFCSTATUS_SUCCESS;
667   }
668   phNxpNciHal_initializeRegRfFwDnld();
669 
670   int8_t ret_val = 0x00;
671 
672   phNxpNciHal_initialize_debug_enabled_flag();
673   /* initialize trace level */
674   phNxpLog_InitializeLogLevel();
675 
676   /* initialize Mifare flags*/
677   phNxpNciHal_initialize_mifare_flag();
678 
679   /*Create the timer for extns write response*/
680   timeoutTimerId = phOsalNfc_Timer_Create();
681 
682   if (phNxpNciHal_init_monitor() == NULL) {
683     NXPLOG_NCIHAL_E("Init monitor failed");
684     return NFCSTATUS_FAILED;
685   }
686 
687   CONCURRENCY_LOCK();
688   memset(&tOsalConfig, 0x00, sizeof(tOsalConfig));
689   memset(&tTmlConfig, 0x00, sizeof(tTmlConfig));
690   memset(&nxpprofile_ctrl, 0, sizeof(phNxpNciProfile_Control_t));
691 
692   /*Init binary semaphore for Spi Nfc synchronization*/
693   if (0 != sem_init(&nxpncihal_ctrl.syncSpiNfc, 0, 1)) {
694     NXPLOG_NCIHAL_E("sem_init() FAiled, errno = 0x%02X", errno);
695     CONCURRENCY_UNLOCK();
696     return phNxpNciHal_MinOpen_Clean(nfc_dev_node);
697   }
698 
699   /* By default HAL status is HAL_STATUS_OPEN */
700   nxpncihal_ctrl.halStatus = HAL_STATUS_OPEN;
701 
702   /*nci version NCI_VERSION_2_0 version by default for SN100 chip type*/
703   nxpncihal_ctrl.nci_info.nci_version = NCI_VERSION_2_0;
704   /* Read the nfc device node name */
705   nfc_dev_node = (char*)malloc(max_len * sizeof(char));
706   if (nfc_dev_node == NULL) {
707     NXPLOG_NCIHAL_D("malloc of nfc_dev_node failed ");
708     CONCURRENCY_UNLOCK();
709     return phNxpNciHal_MinOpen_Clean(nfc_dev_node);
710   } else if (!GetNxpStrValue(NAME_NXP_NFC_DEV_NODE, nfc_dev_node, max_len)) {
711     NXPLOG_NCIHAL_D(
712         "Invalid nfc device node name keeping the default device node "
713         "/dev/pn54x");
714     strlcpy(nfc_dev_node, "/dev/pn54x", (max_len * sizeof(char)));
715   }
716   /* Configure hardware link */
717   nxpncihal_ctrl.gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
718   nxpncihal_ctrl.gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C; /* For PN54X */
719   tTmlConfig.pDevName = (int8_t*)nfc_dev_node;
720   tOsalConfig.dwCallbackThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId;
721   tOsalConfig.pLogFile = NULL;
722   tTmlConfig.dwGetMsgThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId;
723   mGetCfg_info = NULL;
724   mGetCfg_info =
725       (phNxpNci_getCfg_info_t*)nxp_malloc(sizeof(phNxpNci_getCfg_info_t));
726   if (mGetCfg_info == NULL) {
727     CONCURRENCY_UNLOCK();
728     return phNxpNciHal_MinOpen_Clean(nfc_dev_node);
729   }
730   memset(mGetCfg_info, 0x00, sizeof(phNxpNci_getCfg_info_t));
731 
732   /* Set Default Fragment Length */
733   tTmlConfig.fragment_len = NCI_CMDRESP_MAX_BUFF_SIZE_PN557;
734 
735   /* Initialize TML layer */
736   wConfigStatus = phTmlNfc_Init(&tTmlConfig);
737   if (wConfigStatus != NFCSTATUS_SUCCESS) {
738     NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
739     CONCURRENCY_UNLOCK();
740     return phNxpNciHal_MinOpen_Clean(nfc_dev_node);
741   } else {
742     if (nfc_dev_node != NULL) {
743       free(nfc_dev_node);
744       nfc_dev_node = NULL;
745     }
746   }
747 
748   /* Create the client thread */
749   ret_val = pthread_create(&nxpncihal_ctrl.client_thread, NULL,
750                            phNxpNciHal_client_thread, &nxpncihal_ctrl);
751   if (ret_val != 0) {
752     NXPLOG_NCIHAL_E("pthread_create failed");
753     wConfigStatus = phTmlNfc_Shutdown_CleanUp();
754     CONCURRENCY_UNLOCK();
755     return phNxpNciHal_MinOpen_Clean(nfc_dev_node);
756   }
757 
758   CONCURRENCY_UNLOCK();
759   /* call read pending */
760   status = phTmlNfc_Read(
761       nxpncihal_ctrl.p_rsp_data, NCI_MAX_DATA_LEN,
762       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
763   if (status != NFCSTATUS_PENDING) {
764     NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
765     wConfigStatus = phTmlNfc_Shutdown_CleanUp();
766     wConfigStatus = NFCSTATUS_FAILED;
767     return phNxpNciHal_MinOpen_Clean(nfc_dev_node);
768   }
769 
770   if (gsIsFirstHalMinOpen) {
771     phNxpNciHal_CheckAndHandleFwTearDown();
772   }
773 
774   uint8_t seq_handler_offset = 0x00;
775   uint8_t fw_update_req = 1;
776   uint8_t rf_update_req;
777   phNxpNciHal_ext_init();
778 
779   phTmlNfc_IoCtl(phTmlNfc_e_EnableVen);
780 
781   /* reset version info new version info will be fetch */
782   wFwVerRsp = 0x00;
783   wFwVer = 0x00;
784   if (NFCSTATUS_SUCCESS == phNxpNciHal_nfcc_core_reset_init(true)) {
785     setNxpFwConfigPath();
786     if (nfcFL.chipType < sn100u) phNxpNciHal_enable_i2c_fragmentation();
787 
788     status = phNxpNciHal_CheckFwRegFlashRequired(&fw_update_req, &rf_update_req,
789                                                  false);
790     if (status != NFCSTATUS_OK) {
791       NXPLOG_NCIHAL_D(
792           "phNxpNciHal_CheckFwRegFlashRequired() failed:exit status = %x",
793           status);
794       fw_update_req = FALSE;
795       rf_update_req = FALSE;
796     }
797 
798     if (!wFwUpdateReq) {
799       uint8_t is_teared_down = 0x00;
800       status = phNxpNciHal_read_fw_dw_status(is_teared_down);
801       if (status != NFCSTATUS_SUCCESS) {
802         NXPLOG_NCIHAL_E("%s: NXP get FW DW Flag failed", __FUNCTION__);
803       }
804       if (is_teared_down) {
805         seq_handler_offset = PHLIBNFC_DNLD_CHECKINTEGRITY_OFFSET;
806         fw_update_req = TRUE;
807       } else {
808         NXPLOG_NCIHAL_D("FW update not required");
809         property_set("nfc.fw.downloadmode_force", "0");
810         phDnldNfc_ReSetHwDevHandle();
811       }
812     }
813   } else {
814     phNxpNciHal_getChipInfoInFwDnldMode(true);
815   }
816 
817   if (gsIsFirstHalMinOpen && gsIsFwRecoveryRequired) {
818     NXPLOG_NCIHAL_E("FW Recovery is required");
819     fw_update_req = true;
820   }
821 
822   do {
823     if (fw_update_req && !fw_download_success) {
824       gsIsFwRecoveryRequired = false;
825       status = phNxpNciHal_force_fw_download(seq_handler_offset);
826       if (status == NFCSTATUS_CMD_ABORTED) {
827         return phNxpNciHal_MinOpen_Clean(nfc_dev_node);
828       } else if (fw_download_success) {
829         wConfigStatus = NFCSTATUS_SUCCESS;
830       }
831     }
832     status = phNxpNciHal_resetDefaultSettings(
833         fw_update_req, fw_download_success ? false : true);
834 
835     if ((status != NFCSTATUS_SUCCESS && fw_download_success) ||
836         (gsIsFwRecoveryRequired && fw_update_req)) {
837       NXPLOG_NCIHAL_E(
838           "FW Recovery required, Perform Force FW Download "
839           "gsIsFwRecoveryRequired %d",
840           gsIsFwRecoveryRequired);
841       fw_update_req = 1;
842       dnld_retry_cnt++;
843     } else if (status != NFCSTATUS_SUCCESS) {
844       return phNxpNciHal_MinOpen_Clean(nfc_dev_node);
845     } else {
846       break;
847     }
848 
849     if (dnld_retry_cnt > 1) {
850       wConfigStatus = NFCSTATUS_FAILED;
851       break;
852     }
853 
854   } while (status != NFCSTATUS_SUCCESS || gsIsFwRecoveryRequired);
855   /* Call open complete */
856   phNxpNciHal_MinOpen_complete(wConfigStatus);
857   NXPLOG_NCIHAL_D("phNxpNciHal_MinOpen(): exit");
858   return wConfigStatus;
859 }
860 
861 /******************************************************************************
862  * Function         phNxpNciHal_open
863  *
864  * Description      This function is called by libnfc-nci during the
865  *                  initialization of the NFCC. It opens the physical connection
866  *                  with NFCC (PN54X) and creates required client thread for
867  *                  operation.
868  *                  After open is complete, status is informed to libnfc-nci
869  *                  through callback function.
870  *
871  * Returns          This function return NFCSTATUS_SUCCESS (0) in case of
872  *success In case of failure returns other failure value.
873  *
874  ******************************************************************************/
phNxpNciHal_open(nfc_stack_callback_t * p_cback,nfc_stack_data_callback_t * p_data_cback)875 int phNxpNciHal_open(nfc_stack_callback_t* p_cback,
876                      nfc_stack_data_callback_t* p_data_cback) {
877   NFCSTATUS wConfigStatus = NFCSTATUS_SUCCESS;
878   NFCSTATUS status = NFCSTATUS_SUCCESS;
879   NXPLOG_NCIHAL_E("phNxpNciHal_open NFC HAL OPEN");
880 #ifdef NXP_BOOTTIME_UPDATE
881   if (ese_update != ESE_UPDATE_COMPLETED) {
882     ALOGD("BLOCK NFC HAL OPEN");
883     if (p_cback != NULL) {
884       p_nfc_stack_cback_backup = p_cback;
885       (*p_cback)(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
886     }
887     return NFCSTATUS_FAILED;
888   }
889 #endif
890   if (nxpncihal_ctrl.halStatus == HAL_STATUS_OPEN) {
891     NXPLOG_NCIHAL_D("phNxpNciHal_open already open");
892     return NFCSTATUS_SUCCESS;
893   } else if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
894     memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
895     nxpncihal_ctrl.p_nfc_stack_cback = p_cback;
896     nxpncihal_ctrl.p_nfc_stack_data_cback = p_data_cback;
897     status = phNxpNciHal_MinOpen();
898     if (status != NFCSTATUS_SUCCESS) {
899       NXPLOG_NCIHAL_E("phNxpNciHal_MinOpen failed");
900       goto clean_and_return;
901     } /*else its already in MIN_OPEN state. continue with rest of
902          functionality*/
903   } else {
904     nxpncihal_ctrl.p_nfc_stack_cback = p_cback;
905     nxpncihal_ctrl.p_nfc_stack_data_cback = p_data_cback;
906   }
907   /* Call open complete */
908   phNxpNciHal_open_complete(wConfigStatus);
909 
910   return wConfigStatus;
911 
912 clean_and_return:
913   CONCURRENCY_UNLOCK();
914   /* Report error status */
915   if (p_cback != NULL) {
916     (*p_cback)(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
917   }
918 
919   nxpncihal_ctrl.p_nfc_stack_cback = NULL;
920   nxpncihal_ctrl.p_nfc_stack_data_cback = NULL;
921   phNxpNciHal_cleanup_monitor();
922   nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
923   return NFCSTATUS_FAILED;
924 }
925 
926 /******************************************************************************
927  * Function         phNxpNciHal_fw_mw_check
928  *
929  * Description      This function inform the status of phNxpNciHal_fw_mw_check
930  *                  function to libnfc-nci.
931  *
932  * Returns          int.
933  *
934  ******************************************************************************/
phNxpNciHal_fw_mw_ver_check()935 int phNxpNciHal_fw_mw_ver_check() {
936   NFCSTATUS status = NFCSTATUS_FAILED;
937   uint8_t rom_version = 0xFF & (wFwVerRsp >> 16);
938   uint8_t fw_maj_ver = 0xFF & (wFwVerRsp >> 8);
939 
940   if ((nfcFL.chipType == pn557) &&
941       (rom_version == FW_MOBILE_ROM_VERSION_PN557) && (fw_maj_ver == 0x01)) {
942     status = NFCSTATUS_SUCCESS;
943   } else if (((nfcFL.chipType == pn553) || (nfcFL.chipType == pn80T)) &&
944              (rom_version == 0x11) && (fw_maj_ver == 0x01)) {
945     status = NFCSTATUS_SUCCESS;
946   } else if (((nfcFL.chipType == pn551) || (nfcFL.chipType == pn67T)) &&
947              (rom_version == 0x10) && (fw_maj_ver == 0x05)) {
948     status = NFCSTATUS_SUCCESS;
949   } else if ((nfcFL.chipType == sn100u) && (rom_version == SN1XX_ROM_VERSION) &&
950              (fw_maj_ver == SN1XX_FW_MAJOR_VERSION)) {
951     status = NFCSTATUS_SUCCESS;
952   } else if ((nfcFL.chipType == sn220u) && (rom_version == SN2XX_ROM_VERSION) &&
953              (fw_maj_ver == SN2XX_FW_MAJOR_VERSION)) {
954     status = NFCSTATUS_SUCCESS;
955   }
956   if (NFCSTATUS_SUCCESS != status) {
957     NXPLOG_NCIHAL_D("Chip Version Middleware Version mismatch!!!!");
958   }
959   return status;
960 }
961 /******************************************************************************
962  * Function         phNxpNciHal_MinOpen_complete
963  *
964  * Description      This function updates the status of
965  *phNxpNciHal_MinOpen_complete to halstatus.
966  *
967  * Returns          void.
968  *
969  ******************************************************************************/
phNxpNciHal_MinOpen_complete(NFCSTATUS status)970 static void phNxpNciHal_MinOpen_complete(NFCSTATUS status) {
971   gsIsFirstHalMinOpen = false;
972   if (status == NFCSTATUS_SUCCESS) {
973     nxpncihal_ctrl.halStatus = HAL_STATUS_MIN_OPEN;
974   }
975 
976   return;
977 }
978 
979 /******************************************************************************
980  * Function         phNxpNciHal_open_complete
981  *
982  * Description      This function inform the status of phNxpNciHal_open
983  *                  function to libnfc-nci.
984  *
985  * Returns          void.
986  *
987  ******************************************************************************/
phNxpNciHal_open_complete(NFCSTATUS status)988 static void phNxpNciHal_open_complete(NFCSTATUS status) {
989   static phLibNfc_Message_t msg;
990 
991   if (status == NFCSTATUS_SUCCESS) {
992     msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
993     nxpncihal_ctrl.hal_open_status = true;
994     nxpncihal_ctrl.halStatus = HAL_STATUS_OPEN;
995   } else {
996     msg.eMsgType = NCI_HAL_ERROR_MSG;
997   }
998 
999   msg.pMsgData = NULL;
1000   msg.Size = 0;
1001 
1002   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1003                         (phLibNfc_Message_t*)&msg);
1004 
1005   return;
1006 }
1007 
1008 /******************************************************************************
1009  * Function         phNxpNciHal_write
1010  *
1011  * Description      This function write the data to NFCC through physical
1012  *                  interface (e.g. I2C) using the PN54X driver interface.
1013  *                  Before sending the data to NFCC, phNxpNciHal_write_ext
1014  *                  is called to check if there is any extension processing
1015  *                  is required for the NCI packet being sent out.
1016  *
1017  * Returns          It returns number of bytes successfully written to NFCC.
1018  *
1019  ******************************************************************************/
phNxpNciHal_write(uint16_t data_len,const uint8_t * p_data)1020 int phNxpNciHal_write(uint16_t data_len, const uint8_t* p_data) {
1021   if (bDisableLegacyMfcExtns && bEnableMfcExtns && p_data[0] == 0x00) {
1022     return NxpMfcReaderInstance.Write(data_len, p_data);
1023   }
1024   return phNxpNciHal_write_internal(data_len, p_data);
1025 }
1026 
1027 /******************************************************************************
1028  * Function         phNxpNciHal_write_internal
1029  *
1030  * Description      This function write the data to NFCC through physical
1031  *                  interface (e.g. I2C) using the PN54X driver interface.
1032  *                  Before sending the data to NFCC, phNxpNciHal_write_ext
1033  *                  is called to check if there is any extension processing
1034  *                  is required for the NCI packet being sent out.
1035  *
1036  * Returns          It returns number of bytes successfully written to NFCC.
1037  *
1038  ******************************************************************************/
phNxpNciHal_write_internal(uint16_t data_len,const uint8_t * p_data)1039 int phNxpNciHal_write_internal(uint16_t data_len, const uint8_t* p_data) {
1040   NFCSTATUS status = NFCSTATUS_FAILED;
1041   static phLibNfc_Message_t msg;
1042   if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
1043     return NFCSTATUS_FAILED;
1044   }
1045   /* Create local copy of cmd_data */
1046   memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
1047   nxpncihal_ctrl.cmd_len = data_len;
1048   if ((nxpncihal_ctrl.cmd_len + MAX_NXP_HAL_EXTN_BYTES) > NCI_MAX_DATA_LEN) {
1049     NXPLOG_NCIHAL_D("cmd_len exceeds limit NCI_MAX_DATA_LEN");
1050     goto clean_and_return;
1051   }
1052 #ifdef P2P_PRIO_LOGIC_HAL_IMP
1053   /* Specific logic to block RF disable when P2P priority logic is busy */
1054   if (p_data[0] == 0x21 && p_data[1] == 0x06 && p_data[2] == 0x01 &&
1055       EnableP2P_PrioLogic == true) {
1056     NXPLOG_NCIHAL_D("P2P priority logic busy: Disable it.");
1057     phNxpNciHal_clean_P2P_Prio();
1058   }
1059 #endif
1060 
1061   /* Check for NXP ext before sending write */
1062   status =
1063       phNxpNciHal_write_ext(&nxpncihal_ctrl.cmd_len, nxpncihal_ctrl.p_cmd_data,
1064                             &nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
1065   if (status != NFCSTATUS_SUCCESS) {
1066     /* Do not send packet to PN54X, send response directly */
1067     msg.eMsgType = NCI_HAL_RX_MSG;
1068     msg.pMsgData = NULL;
1069     msg.Size = 0;
1070 
1071     phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1072                           (phLibNfc_Message_t*)&msg);
1073     goto clean_and_return;
1074   }
1075 
1076   CONCURRENCY_LOCK();
1077   data_len = phNxpNciHal_write_unlocked(nxpncihal_ctrl.cmd_len,
1078                                         nxpncihal_ctrl.p_cmd_data, ORIG_LIBNFC);
1079   CONCURRENCY_UNLOCK();
1080 
1081   if (nfcFL.chipType < sn100u && nfcFL.chipType != pn557 &&
1082       icode_send_eof == 1) {
1083     usleep(10000);
1084     icode_send_eof = 2;
1085     status = phNxpNciHal_send_ext_cmd(3, cmd_icode_eof);
1086     if (status != NFCSTATUS_SUCCESS) {
1087       NXPLOG_NCIHAL_E("ICODE end of frame command failed");
1088     }
1089   }
1090 
1091 clean_and_return:
1092   /* No data written */
1093   return data_len;
1094 }
1095 
1096 /******************************************************************************
1097  * Function         phNxpNciHal_write_unlocked
1098  *
1099  * Description      This is the actual function which is being called by
1100  *                  phNxpNciHal_write. This function writes the data to NFCC.
1101  *                  It waits till write callback provide the result of write
1102  *                  process.
1103  *
1104  * Returns          It returns number of bytes successfully written to NFCC.
1105  *
1106  ******************************************************************************/
phNxpNciHal_write_unlocked(uint16_t data_len,const uint8_t * p_data,int origin)1107 int phNxpNciHal_write_unlocked(uint16_t data_len, const uint8_t* p_data,
1108                                int origin) {
1109   NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER;
1110   phNxpNciHal_Sem_t cb_data;
1111   nxpncihal_ctrl.retry_cnt = 0;
1112   int sem_val = 0;
1113   static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00,
1114                                 0xC7, 0xD4, 0x00, 0x00};
1115   /* Create the local semaphore */
1116   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
1117     NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked Create cb data failed");
1118     data_len = 0;
1119     goto clean_and_return;
1120   }
1121 
1122   /* Create local copy of cmd_data */
1123   memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
1124   nxpncihal_ctrl.cmd_len = data_len;
1125   write_unlocked_status = NFCSTATUS_FAILED;
1126   /* check for write synchronyztion */
1127   if (phNxpNciHal_check_ncicmd_write_window(nxpncihal_ctrl.cmd_len,
1128                                             nxpncihal_ctrl.p_cmd_data) !=
1129       NFCSTATUS_SUCCESS) {
1130     NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked  CMD window  check failed");
1131     data_len = 0;
1132     goto clean_and_return;
1133   }
1134 
1135   if (origin == ORIG_NXPHAL) HAL_ENABLE_EXT();
1136 
1137 retry:
1138 
1139   data_len = nxpncihal_ctrl.cmd_len;
1140 
1141   status = phTmlNfc_Write(
1142       (uint8_t*)nxpncihal_ctrl.p_cmd_data, (uint16_t)nxpncihal_ctrl.cmd_len,
1143       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_write_complete,
1144       (void*)&cb_data);
1145   if (status != NFCSTATUS_PENDING) {
1146     NXPLOG_NCIHAL_E("write_unlocked status error");
1147     data_len = 0;
1148     goto clean_and_return;
1149   }
1150 
1151   /* Wait for callback response */
1152   if (SEM_WAIT(cb_data)) {
1153     NXPLOG_NCIHAL_E("write_unlocked semaphore error");
1154     data_len = 0;
1155     goto clean_and_return;
1156   }
1157 
1158   if (cb_data.status != NFCSTATUS_SUCCESS) {
1159     data_len = 0;
1160     if (nxpncihal_ctrl.retry_cnt++ < MAX_RETRY_COUNT) {
1161       NXPLOG_NCIHAL_D(
1162           "write_unlocked failed - PN54X Maybe in Standby Mode - Retry");
1163       /* 10ms delay to give NFCC wake up delay */
1164       usleep(1000 * 10);
1165       goto retry;
1166     } else {
1167       NXPLOG_NCIHAL_E(
1168           "write_unlocked failed - PN54X Maybe in Standby Mode (max count = "
1169           "0x%x)",
1170           nxpncihal_ctrl.retry_cnt);
1171 
1172       status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1173 
1174       if (NFCSTATUS_SUCCESS == status) {
1175         NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
1176       } else {
1177         NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
1178       }
1179       if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL &&
1180           nxpncihal_ctrl.hal_open_status == true) {
1181         if (nxpncihal_ctrl.p_rx_data != NULL) {
1182           NXPLOG_NCIHAL_D(
1183               "Send the Core Reset NTF to upper layer, which will trigger the "
1184               "recovery\n");
1185           // Send the Core Reset NTF to upper layer, which will trigger the
1186           // recovery.
1187 #if (NXP_EXTNS == TRUE)
1188           abort();
1189 #endif
1190           nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf);
1191           memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf));
1192           (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
1193                                                    nxpncihal_ctrl.p_rx_data);
1194         } else {
1195           (*nxpncihal_ctrl.p_nfc_stack_data_cback)(0x00, NULL);
1196         }
1197         write_unlocked_status = NFCSTATUS_FAILED;
1198       }
1199     }
1200   } else {
1201     write_unlocked_status = NFCSTATUS_SUCCESS;
1202   }
1203 
1204 clean_and_return:
1205   if (write_unlocked_status == NFCSTATUS_FAILED) {
1206     sem_getvalue(&(nxpncihal_ctrl.syncSpiNfc), &sem_val);
1207     if (((nxpncihal_ctrl.p_cmd_data[0] & NCI_MT_MASK) == NCI_MT_CMD) &&
1208         sem_val == 0) {
1209       sem_post(&(nxpncihal_ctrl.syncSpiNfc));
1210       NXPLOG_NCIHAL_D("HAL write  failed CMD window check releasing \n");
1211     }
1212   }
1213   phNxpNciHal_cleanup_cb_data(&cb_data);
1214   return data_len;
1215 }
1216 
1217 /******************************************************************************
1218  * Function         phNxpNciHal_write_complete
1219  *
1220  * Description      This function handles write callback.
1221  *
1222  * Returns          void.
1223  *
1224  ******************************************************************************/
phNxpNciHal_write_complete(void * pContext,phTmlNfc_TransactInfo_t * pInfo)1225 static void phNxpNciHal_write_complete(void* pContext,
1226                                        phTmlNfc_TransactInfo_t* pInfo) {
1227   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
1228   if (pInfo->wStatus == NFCSTATUS_SUCCESS) {
1229     NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus);
1230   } else {
1231     NXPLOG_NCIHAL_D("write error status = 0x%x", pInfo->wStatus);
1232   }
1233 
1234   p_cb_data->status = pInfo->wStatus;
1235 
1236   SEM_POST(p_cb_data);
1237 
1238   return;
1239 }
1240 
1241 /******************************************************************************
1242  * Function         phNxpNciHal_read_complete
1243  *
1244  * Description      This function is called whenever there is an NCI packet
1245  *                  received from NFCC. It could be RSP or NTF packet. This
1246  *                  function provide the received NCI packet to libnfc-nci
1247  *                  using data callback of libnfc-nci.
1248  *                  There is a pending read called from each
1249  *                  phNxpNciHal_read_complete so each a packet received from
1250  *                  NFCC can be provide to libnfc-nci.
1251  *
1252  * Returns          void.
1253  *
1254  ******************************************************************************/
phNxpNciHal_read_complete(void * pContext,phTmlNfc_TransactInfo_t * pInfo)1255 static void phNxpNciHal_read_complete(void* pContext,
1256                                       phTmlNfc_TransactInfo_t* pInfo) {
1257   NFCSTATUS status = NFCSTATUS_FAILED;
1258   int sem_val;
1259   UNUSED_PROP(pContext);
1260   if (nxpncihal_ctrl.read_retry_cnt == 1) {
1261     nxpncihal_ctrl.read_retry_cnt = 0;
1262   }
1263   if (pInfo->wStatus == NFCSTATUS_SUCCESS) {
1264     NXPLOG_NCIHAL_D("read successful status = 0x%x", pInfo->wStatus);
1265 
1266     /*Check the Omapi command response and store in dedicated buffer to solve
1267      * sync issue*/
1268     if (nfcFL.chipType <= sn100u && pInfo->pBuff[0] == 0x4F &&
1269         pInfo->pBuff[1] == 0x01 && pInfo->pBuff[2] == 0x01) {
1270       nxpncihal_ctrl.p_rx_ese_data = pInfo->pBuff;
1271       nxpncihal_ctrl.rx_ese_data_len = pInfo->wLength;
1272       SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1273     } else {
1274       nxpncihal_ctrl.p_rx_data = pInfo->pBuff;
1275       nxpncihal_ctrl.rx_data_len = pInfo->wLength;
1276       status = phNxpNciHal_process_ext_rsp(nxpncihal_ctrl.p_rx_data,
1277                                            &nxpncihal_ctrl.rx_data_len);
1278       if (nxpncihal_ctrl.hal_ext_enabled && phTmlNfc_IsFwDnldModeEnabled()) {
1279         SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1280       }
1281     }
1282     phNxpNciHal_print_res_status(pInfo->pBuff, &pInfo->wLength);
1283 
1284     /* Check if response should go to hal module only */
1285     if (nxpncihal_ctrl.hal_ext_enabled == TRUE &&
1286         (nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_RSP) {
1287       if (status == NFCSTATUS_FAILED) {
1288         NXPLOG_NCIHAL_D("enter into NFCC init recovery");
1289         nxpncihal_ctrl.ext_cb_data.status = status;
1290       }
1291       /* Unlock semaphore only for responses*/
1292       if ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_RSP ||
1293           ((nfcFL.chipType < sn100u) && (icode_detected == true) &&
1294            (icode_send_eof == 3))) {
1295         /* Unlock semaphore */
1296         SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1297       }
1298     }  // Notification Checking
1299     else if ((nxpncihal_ctrl.hal_ext_enabled == TRUE) &&
1300              ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_NTF) &&
1301 #if (NXP_EXTNS == TRUE)
1302              ((nxpncihal_ctrl.p_cmd_data[0x00] & NCI_GID_MASK) ==
1303               (nxpncihal_ctrl.p_rx_data[0x00] & NCI_GID_MASK)) &&
1304              ((nxpncihal_ctrl.p_cmd_data[0x01] & NCI_OID_MASK) ==
1305               (nxpncihal_ctrl.p_rx_data[0x01] & NCI_OID_MASK)) &&
1306 #endif
1307              (nxpncihal_ctrl.nci_info.wait_for_ntf == TRUE)) {
1308       /* Unlock semaphore waiting for only  ntf*/
1309       nxpncihal_ctrl.nci_info.wait_for_ntf = FALSE;
1310       SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1311     } else if (bDisableLegacyMfcExtns && !sendRspToUpperLayer &&
1312                (nxpncihal_ctrl.p_rx_data[0x00] == 0x00)) {
1313       sendRspToUpperLayer = true;
1314       NFCSTATUS mfcRspStatus = NxpMfcReaderInstance.CheckMfcResponse(
1315           nxpncihal_ctrl.p_rx_data, nxpncihal_ctrl.rx_data_len);
1316       NXPLOG_NCIHAL_D("Mfc Response Status = 0x%x", mfcRspStatus);
1317       SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1318     }
1319     /* Read successful send the event to higher layer */
1320     else if ((nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) &&
1321              (status == NFCSTATUS_SUCCESS)) {
1322       NxpMfcReaderInstance.MfcNotifyOnAckReceived(nxpncihal_ctrl.p_rx_data);
1323       (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
1324                                                nxpncihal_ctrl.p_rx_data);
1325       // workaround for sync issue between SPI and NFC
1326       if ((nfcFL.chipType == pn557) && nxpncihal_ctrl.p_rx_data[0] == 0x62 &&
1327           nxpncihal_ctrl.p_rx_data[1] == 0x00 &&
1328           nxpncihal_ctrl.p_rx_data[3] == 0xC0 &&
1329           nxpncihal_ctrl.p_rx_data[4] == 0x00) {
1330         uint8_t nfcee_notifiations[3][9] = {
1331             {0x61, 0x0A, 0x06, 0x01, 0x00, 0x03, 0xC0, 0x80, 0x04},
1332             {0x61, 0x0A, 0x06, 0x01, 0x00, 0x03, 0xC0, 0x81, 0x04},
1333             {0x61, 0x0A, 0x06, 0x01, 0x00, 0x03, 0xC0, 0x82, 0x03},
1334         };
1335 
1336         for (int i = 0; i < 3; i++) {
1337           (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
1338               sizeof(nfcee_notifiations[i]), nfcee_notifiations[i]);
1339         }
1340       }
1341     }
1342     /* Unblock next Write Command Window */
1343     sem_getvalue(&(nxpncihal_ctrl.syncSpiNfc), &sem_val);
1344     if (((pInfo->pBuff[0] & NCI_MT_MASK) == NCI_MT_RSP) && sem_val == 0) {
1345       sem_post(&(nxpncihal_ctrl.syncSpiNfc));
1346     }
1347   } else {
1348     NXPLOG_NCIHAL_E("read error status = 0x%x", pInfo->wStatus);
1349   }
1350 
1351   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE &&
1352 #if (NXP_EXTNS == TRUE)
1353       (nxpncihal_ctrl.p_cmd_data[0x00] & NCI_GID_MASK) ==
1354           (nxpncihal_ctrl.p_rx_data[0x00] & NCI_GID_MASK) &&
1355       (nxpncihal_ctrl.p_cmd_data[0x01] & NCI_OID_MASK) ==
1356           (nxpncihal_ctrl.p_rx_data[0x01] & NCI_OID_MASK) &&
1357 #endif
1358       nxpncihal_ctrl.nci_info.wait_for_ntf == FALSE) {
1359     NXPLOG_NCIHAL_D(" Ignoring read , HAL close triggered");
1360     return;
1361   }
1362   /* Read again because read must be pending always except FWDNLD.*/
1363   if (TRUE != nxpncihal_ctrl.fwdnld_mode_reqd) {
1364     status = phTmlNfc_Read(
1365         nxpncihal_ctrl.p_rsp_data, NCI_MAX_DATA_LEN,
1366         (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
1367     if (status != NFCSTATUS_PENDING) {
1368       NXPLOG_NCIHAL_E("read status error status = %x", status);
1369       /* TODO: Not sure how to handle this ? */
1370     }
1371   }
1372   return;
1373 }
1374 
1375 /*******************************************************************************
1376  **
1377  ** Function:        phNxpNciHal_lastResetNtfReason()
1378  **
1379  ** Description:     Returns and clears last reset notification reason.
1380  **                      Intended to be called only once during recovery.
1381  **
1382  ** Returns:         reasonCode
1383  **
1384  ********************************************************************************/
phNxpNciHal_lastResetNtfReason(void)1385 uint8_t phNxpNciHal_lastResetNtfReason(void) {
1386   uint8_t reasonCode = nxpncihal_ctrl.nci_info.lastResetNtfReason;
1387 
1388   nxpncihal_ctrl.nci_info.lastResetNtfReason = 0;
1389 
1390   return reasonCode;
1391 }
1392 /******************************************************************************
1393  * Function         phNxpNciHal_enableTmlRead
1394  *
1395  * Description      Invokes TmlNfc Read to make sure always read thread is
1396  *                  pending
1397  *
1398  * Returns          Returns read status
1399  *
1400  ******************************************************************************/
phNxpNciHal_enableTmlRead()1401 NFCSTATUS phNxpNciHal_enableTmlRead() {
1402   /* Read again because read must be pending always.*/
1403   NFCSTATUS status = phTmlNfc_Read(
1404       nxpncihal_ctrl.p_rsp_data, NCI_MAX_DATA_LEN,
1405       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
1406   if (status != NFCSTATUS_PENDING) {
1407     NXPLOG_NCIHAL_E("read status error status = %x", status);
1408   }
1409   return status;
1410 }
1411 /******************************************************************************
1412  * Function         phNxpNciHal_core_initialized
1413  *
1414  * Description      This function is called by libnfc-nci after successful open
1415  *                  of NFCC. All proprietary setting for PN54X are done here.
1416  *                  After completion of proprietary settings notification is
1417  *                  provided to libnfc-nci through callback function.
1418  *
1419  * Returns          Always returns NFCSTATUS_SUCCESS (0).
1420  *
1421  ******************************************************************************/
phNxpNciHal_core_initialized(uint16_t core_init_rsp_params_len,uint8_t * p_core_init_rsp_params)1422 int phNxpNciHal_core_initialized(uint16_t core_init_rsp_params_len,
1423                                  uint8_t* p_core_init_rsp_params) {
1424   NFCSTATUS status = NFCSTATUS_SUCCESS;
1425   uint8_t* buffer = NULL;
1426   uint8_t isfound = 0;
1427   uint8_t fw_dwnld_flag = false;
1428   uint8_t setConfigAlways = false;
1429 
1430   uint8_t p2p_listen_mode_routing_cmd[] = {0x21, 0x01, 0x07, 0x00, 0x01,
1431                                            0x01, 0x03, 0x00, 0x01, 0x05};
1432 
1433   uint8_t swp_full_pwr_mode_on_cmd[] = {0x20, 0x02, 0x05, 0x01,
1434                                         0xA0, 0xF1, 0x01, 0x01};
1435   uint8_t enable_ce_in_phone_off = 0x01;
1436   uint8_t enable_ven_cfg = 0x01;
1437 
1438   uint8_t swp_switch_timeout_cmd[] = {0x20, 0x02, 0x06, 0x01, 0xA0,
1439                                       0xF3, 0x02, 0x00, 0x00};
1440 
1441   config_success = true;
1442   long bufflen = 260;
1443   long retlen = 0;
1444   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
1445 #if (NFC_NXP_HFO_SETTINGS == TRUE)
1446   /* Temp fix to re-apply the proper clock setting */
1447   int temp_fix = 1;
1448 #endif
1449   unsigned long num = 0;
1450   /*initialize recovery FW variables*/
1451   gRecFwRetryCount = 0;
1452   gRecFWDwnld = 0;
1453   // recovery --start
1454   /*NCI_INIT_CMD*/
1455   static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
1456   /*NCI_RESET_CMD*/
1457   static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01,
1458                                     0x00};  // keep configuration
1459   static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
1460   /* reset config cache */
1461   uint8_t retry_core_init_cnt = 0;
1462   if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
1463     return NFCSTATUS_FAILED;
1464   }
1465   if (core_init_rsp_params_len >= 1 && (*p_core_init_rsp_params > 0) &&
1466       (*p_core_init_rsp_params < 4))  // initializing for recovery.
1467   {
1468   retry_core_init:
1469     config_access = false;
1470     if (mGetCfg_info != NULL) {
1471       mGetCfg_info->isGetcfg = false;
1472     }
1473     if (buffer != NULL) {
1474       free(buffer);
1475       buffer = NULL;
1476     }
1477     if (retry_core_init_cnt > 3) {
1478       return NFCSTATUS_FAILED;
1479     }
1480     if (nfcFL.chipType < sn100u) {
1481       status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1482       if (NFCSTATUS_SUCCESS == status) {
1483         NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
1484       } else {
1485         NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
1486       }
1487     }
1488 
1489     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
1490     if ((status != NFCSTATUS_SUCCESS) &&
1491         (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT)) {
1492       NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
1493       retry_core_init_cnt++;
1494       goto retry_core_init;
1495     } else if (status != NFCSTATUS_SUCCESS) {
1496       NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
1497       retry_core_init_cnt++;
1498       goto retry_core_init;
1499     }
1500 
1501     if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
1502       status =
1503           phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
1504     } else {
1505       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
1506     }
1507     if (status != NFCSTATUS_SUCCESS) {
1508       NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
1509       retry_core_init_cnt++;
1510       goto retry_core_init;
1511     }
1512   }
1513   // recovery --end
1514 
1515   buffer = (uint8_t*)malloc(bufflen * sizeof(uint8_t));
1516   if (NULL == buffer) {
1517     return NFCSTATUS_FAILED;
1518   }
1519   config_access = true;
1520   retlen = 0;
1521   isfound = GetNxpByteArrayValue(NAME_NXP_ACT_PROP_EXTN, (char*)buffer, bufflen,
1522                                  &retlen);
1523   if (isfound > 0 && retlen > 0) {
1524     /* NXP ACT Proprietary Ext */
1525     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1526     if (status != NFCSTATUS_SUCCESS) {
1527       NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
1528       retry_core_init_cnt++;
1529       goto retry_core_init;
1530     }
1531   }
1532   if (nfcFL.chipType == sn100u) {
1533     uint8_t cmd_get_cfg_dbg_info[] = {0x20, 0x03, 0x0D, 0x06, 0xA0, 0x39,
1534                                       0xA0, 0x1A, 0xA0, 0x1B, 0xA0, 0x1C,
1535                                       0xA0, 0x27, 0xA1, 0x1F};
1536     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_get_cfg_dbg_info),
1537                                       cmd_get_cfg_dbg_info);
1538   } else if (nfcFL.chipType >= sn220u || nfcFL.chipType == pn557) {
1539     uint8_t cmd_get_cfg_dbg_info[] = {0x20, 0x03, 0x0B, 0x05, 0xA0, 0x39, 0xA0,
1540                                       0x1A, 0xA0, 0x1B, 0xA0, 0x1C, 0xA0, 0x27};
1541     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_get_cfg_dbg_info),
1542                                       cmd_get_cfg_dbg_info);
1543   }
1544   if (status != NFCSTATUS_SUCCESS) {
1545     NXPLOG_NCIHAL_E("Failed to retrieve NFCC debug info");
1546   }
1547 
1548   if (nfcFL.chipType >= sn220u) {
1549     uint8_t cmd_get_hard_fault_ctr_info[] = {0x20, 0x03, 0x03,
1550                                              0x01, 0xA1, 0x5A};
1551     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_get_hard_fault_ctr_info),
1552                                       cmd_get_hard_fault_ctr_info);
1553     if (status != NFCSTATUS_SUCCESS) {
1554       NXPLOG_NCIHAL_E("Failed to retrieve NFCC hard fault counter debug info");
1555     }
1556   }
1557 
1558   num = 0;
1559   if (GetNxpNumValue("NXP_I3C_MODE", &num, sizeof(num))) {
1560     if (num == 1) {
1561       uint8_t coreStandBy[] = {0x2F, 0x00, 0x01, 0x00};
1562       NXPLOG_NCIHAL_E("Disable NFCC standby");
1563       status = phNxpNciHal_send_ext_cmd(sizeof(coreStandBy), coreStandBy);
1564       if (status != NFCSTATUS_SUCCESS) {
1565         NXPLOG_NCIHAL_E("Failed to set NFCC Standby Disabled");
1566       }
1567     }
1568   }
1569 
1570   status = phNxpNciHal_setAutonomousMode();
1571   if (status != NFCSTATUS_SUCCESS) {
1572     NXPLOG_NCIHAL_E("Set Autonomous enable: Failed");
1573     retry_core_init_cnt++;
1574     goto retry_core_init;
1575   }
1576 
1577   if (nfcFL.chipType == pn557) enable_ven_cfg = PN557_VEN_CFG_DEFAULT;
1578 
1579   mEEPROM_info.buffer = &enable_ven_cfg;
1580   mEEPROM_info.bufflen = sizeof(uint8_t);
1581   mEEPROM_info.request_type = EEPROM_ENABLE_VEN_CFG;
1582   mEEPROM_info.request_mode = SET_EEPROM_DATA;
1583   request_EEPROM(&mEEPROM_info);
1584 
1585   if (nfcFL.chipType >= sn100u) {
1586     mEEPROM_info.buffer = &enable_ce_in_phone_off;
1587     mEEPROM_info.bufflen = sizeof(enable_ce_in_phone_off);
1588     mEEPROM_info.request_type = EEPROM_CE_PHONE_OFF_CFG;
1589     mEEPROM_info.request_mode = SET_EEPROM_DATA;
1590     request_EEPROM(&mEEPROM_info);
1591   }
1592 
1593   config_access = false;
1594   status = phNxpNciHal_read_fw_dw_status(fw_dwnld_flag);
1595   if (status != NFCSTATUS_SUCCESS) {
1596     NXPLOG_NCIHAL_E("%s: NXP get FW DW Flag failed", __FUNCTION__);
1597   }
1598   fw_dwnld_flag |= (bool)fw_download_success;
1599   if (fw_dwnld_flag == true) {
1600     phNxpNciHal_hci_network_reset();
1601   }
1602   if (nfcFL.chipType < sn100u) {
1603     // Check if firmware download success
1604     status = phNxpNciHal_get_mw_eeprom();
1605     if (status != NFCSTATUS_SUCCESS) {
1606       NXPLOG_NCIHAL_E("NXP GET MW EEPROM AREA Proprietary Ext failed");
1607       retry_core_init_cnt++;
1608       goto retry_core_init;
1609     }
1610   }
1611 
1612   config_access = true;
1613   setConfigAlways = false;
1614   isfound = GetNxpNumValue(NAME_NXP_SET_CONFIG_ALWAYS, &num, sizeof(num));
1615   if (isfound > 0) {
1616     setConfigAlways = num;
1617   }
1618   NXPLOG_NCIHAL_D("EEPROM_fw_dwnld_flag : 0x%02x SetConfigAlways flag : 0x%02x",
1619                   fw_dwnld_flag, setConfigAlways);
1620 
1621   if (isNxpConfigModified() || (fw_dwnld_flag == true)) {
1622     retlen = 0;
1623     fw_download_success = 0;
1624 
1625     /* EEPROM access variables */
1626     uint8_t auth_timeout_buffer[NXP_AUTH_TIMEOUT_BUF_LEN];
1627     mEEPROM_info.request_mode = GET_EEPROM_DATA;
1628     retlen = 0;
1629     memset(buffer, 0x00, bufflen);
1630     isfound = GetNxpByteArrayValue(NAME_NXP_AUTH_TIMEOUT_CFG, (char*)buffer,
1631                                    bufflen, &retlen);
1632 
1633     if ((isfound > 0) && (retlen == NXP_AUTH_TIMEOUT_BUF_LEN)) {
1634       memcpy(&auth_timeout_buffer, buffer, NXP_AUTH_TIMEOUT_BUF_LEN);
1635       mEEPROM_info.request_mode = SET_EEPROM_DATA;
1636 
1637       mEEPROM_info.buffer = auth_timeout_buffer;
1638       mEEPROM_info.bufflen = sizeof(auth_timeout_buffer);
1639       mEEPROM_info.request_type = EEPROM_AUTH_CMD_TIMEOUT;
1640       status = request_EEPROM(&mEEPROM_info);
1641       if (NFCSTATUS_SUCCESS == status) {
1642         memcpy(&mGetCfg_info->auth_cmd_timeout, mEEPROM_info.buffer,
1643                mEEPROM_info.bufflen);
1644         mGetCfg_info->auth_cmd_timeoutlen = mEEPROM_info.bufflen;
1645       }
1646     }
1647     NXPLOG_NCIHAL_D("Performing TVDD Settings");
1648     isfound = GetNxpNumValue(NAME_NXP_EXT_TVDD_CFG, &num, sizeof(num));
1649     if (isfound > 0) {
1650       if (num == 1) {
1651         isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_1, (char*)buffer,
1652                                        bufflen, &retlen);
1653         if (isfound && retlen > 0) {
1654           status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1655           if (status != NFCSTATUS_SUCCESS) {
1656             NXPLOG_NCIHAL_E("EXT TVDD CFG 1 Settings failed");
1657             retry_core_init_cnt++;
1658             goto retry_core_init;
1659           }
1660         }
1661       } else if (num == 2) {
1662         isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_2, (char*)buffer,
1663                                        bufflen, &retlen);
1664         if (isfound && retlen > 0) {
1665           status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1666           if (status != NFCSTATUS_SUCCESS) {
1667             NXPLOG_NCIHAL_E("EXT TVDD CFG 2 Settings failed");
1668             retry_core_init_cnt++;
1669             goto retry_core_init;
1670           }
1671         }
1672       } else if (num == 3) {
1673         isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_3, (char*)buffer,
1674                                        bufflen, &retlen);
1675         if (isfound && retlen > 0) {
1676           status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1677           if (status != NFCSTATUS_SUCCESS) {
1678             NXPLOG_NCIHAL_E("EXT TVDD CFG 3 Settings failed");
1679             retry_core_init_cnt++;
1680             goto retry_core_init;
1681           }
1682         }
1683       } else {
1684         NXPLOG_NCIHAL_E("Wrong Configuration Value %ld", num);
1685       }
1686     }
1687   }
1688   if ((true == fw_dwnld_flag) || (true == setConfigAlways) ||
1689       isNxpConfigModified()) {
1690     config_access = true;
1691 
1692     if (nfcFL.chipType != pn547C2) {
1693       config_access = true;
1694     }
1695 
1696     retlen = 0;
1697     /*Select UICC2/UICC3 SWP line from config param*/
1698     if (GetNxpNumValue(NAME_NXP_DEFAULT_UICC2_SELECT, (void*)&retlen,
1699                        sizeof(retlen))) {
1700       if (retlen > 0) phNxpNciHal_enableDefaultUICC2SWPline((uint8_t)retlen);
1701     }
1702     status = phNxpNciHal_setExtendedFieldMode();
1703     if (status != NFCSTATUS_SUCCESS &&
1704         status != NFCSTATUS_FEATURE_NOT_SUPPORTED) {
1705       NXPLOG_NCIHAL_E("phNxpNciHal_setExtendedFieldMode failed");
1706       retry_core_init_cnt++;
1707       goto retry_core_init;
1708     }
1709     status = phNxpNciHal_setGuardTimer();
1710     if (status != NFCSTATUS_SUCCESS &&
1711         status != NFCSTATUS_FEATURE_NOT_SUPPORTED) {
1712       NXPLOG_NCIHAL_E("phNxpNciHal_setGuardTimer failed");
1713       retry_core_init_cnt++;
1714       goto retry_core_init;
1715     }
1716 #if (NXP_EXTNS == TRUE && NXP_SRD == TRUE)
1717     status = phNxpNciHal_setSrdtimeout();
1718     if (status != NFCSTATUS_SUCCESS &&
1719         status != NFCSTATUS_FEATURE_NOT_SUPPORTED) {
1720       NXPLOG_NCIHAL_E("phNxpNciHal_setSrdtimeout failed");
1721       retry_core_init_cnt++;
1722       goto retry_core_init;
1723     }
1724 #endif
1725     config_access = true;
1726     retlen = 0;
1727     NXPLOG_NCIHAL_D("Performing ndef nfcee config settings");
1728     uint8_t cmd_t4t_nfcee_cfg;
1729 
1730     if (!GetNxpNumValue(NAME_NXP_T4T_NFCEE_ENABLE, (void*)&retlen,
1731                         sizeof(retlen))) {
1732       retlen = 0x00;
1733       NXPLOG_NCIHAL_D(
1734           "T4T_NFCEE_ENABLE not found. Taking default value : 0x%02lx", retlen);
1735     }
1736     cmd_t4t_nfcee_cfg = (uint8_t)retlen;
1737     mEEPROM_info.buffer = &cmd_t4t_nfcee_cfg;
1738     mEEPROM_info.bufflen = sizeof(cmd_t4t_nfcee_cfg);
1739     mEEPROM_info.request_type = EEPROM_T4T_NFCEE_ENABLE;
1740     mEEPROM_info.request_mode = SET_EEPROM_DATA;
1741     request_EEPROM(&mEEPROM_info);
1742     if (nfcFL.chipType >= sn100u) {
1743       if (phNxpNciHal_configure_merge_sak() != NFCSTATUS_SUCCESS) {
1744         NXPLOG_NCIHAL_E("Applying iso_dep sak merge settings failed");
1745       }
1746     }
1747   }
1748   if ((true == fw_dwnld_flag) || (true == setConfigAlways) ||
1749       isNxpConfigModified() || (wRfUpdateReq == true)) {
1750     retlen = 0;
1751     NXPLOG_NCIHAL_D("Performing NAME_NXP_CORE_CONF_EXTN Settings");
1752     isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF_EXTN, (char*)buffer,
1753                                    bufflen, &retlen);
1754     if (isfound > 0 && retlen > 0) {
1755       /* NXP ACT Proprietary Ext */
1756       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1757       if (status != NFCSTATUS_SUCCESS) {
1758         NXPLOG_NCIHAL_E("NXP Core configuration failed");
1759         retry_core_init_cnt++;
1760         goto retry_core_init;
1761       }
1762     }
1763 
1764     NXPLOG_NCIHAL_D("Performing SE Settings");
1765     phNxpNciHal_read_and_update_se_state();
1766 
1767     NXPLOG_NCIHAL_D("Performing NAME_NXP_CORE_CONF Settings");
1768     retlen = 0;
1769     isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF, (char*)buffer, bufflen,
1770                                    &retlen);
1771     if (isfound > 0 && retlen > 0) {
1772       /* NXP ACT Proprietary Ext */
1773       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1774       if (status != NFCSTATUS_SUCCESS) {
1775         NXPLOG_NCIHAL_E("Core Set Config failed");
1776         retry_core_init_cnt++;
1777         goto retry_core_init;
1778       }
1779     }
1780 
1781     if (fpVerInfoStoreInEeprom != NULL) {
1782       fpVerInfoStoreInEeprom();
1783     }
1784   }
1785   config_access = false;
1786   if ((true == fw_dwnld_flag) || (true == setConfigAlways) ||
1787       isNxpRFConfigModified()) {
1788     unsigned long loopcnt = 0;
1789 
1790     do {
1791       char rf_conf_block[22] = {'\0'};
1792       strlcpy(rf_conf_block, rf_block_name, sizeof(rf_conf_block));
1793       retlen = 0;
1794       strlcat(rf_conf_block, rf_block_num[loopcnt++], sizeof(rf_conf_block));
1795       isfound =
1796           GetNxpByteArrayValue(rf_conf_block, (char*)buffer, bufflen, &retlen);
1797       if (isfound > 0 && retlen > 0) {
1798         NXPLOG_NCIHAL_D(" Performing RF Settings BLK %ld", loopcnt);
1799         status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1800 
1801         if (status == NFCSTATUS_SUCCESS) {
1802           status = phNxpNciHal_CheckRFCmdRespStatus();
1803           /*STATUS INVALID PARAM 0x09*/
1804           if (status == 0x09) {
1805             phNxpNciHalRFConfigCmdRecSequence();
1806             retry_core_init_cnt++;
1807             goto retry_core_init;
1808           }
1809         } else if (status != NFCSTATUS_SUCCESS) {
1810           NXPLOG_NCIHAL_E("RF Settings BLK %ld failed", loopcnt);
1811           retry_core_init_cnt++;
1812           goto retry_core_init;
1813         }
1814       }
1815     } while (rf_block_num[loopcnt] != NULL);
1816     loopcnt = 0;
1817     if (phNxpNciHal_nfccClockCfgApply() != NFCSTATUS_SUCCESS) {
1818       NXPLOG_NCIHAL_E("phNxpNciHal_nfccClockCfgApply failed");
1819       retry_core_init_cnt++;
1820       goto retry_core_init;
1821     }
1822   }
1823 
1824   config_access = true;
1825 
1826   retlen = 0;
1827   if (nfcFL.chipType != pn547C2) {
1828     config_access = false;
1829   }
1830   isfound = GetNxpByteArrayValue(NAME_NXP_CORE_RF_FIELD, (char*)buffer, bufflen,
1831                                  &retlen);
1832   if (isfound > 0 && retlen > 0) {
1833     /* NXP ACT Proprietary Ext */
1834     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1835     if (status == NFCSTATUS_SUCCESS) {
1836       status = phNxpNciHal_CheckRFCmdRespStatus();
1837       /*STATUS INVALID PARAM 0x09*/
1838       if (status == 0x09) {
1839         phNxpNciHalRFConfigCmdRecSequence();
1840         retry_core_init_cnt++;
1841         goto retry_core_init;
1842       }
1843     } else if (status != NFCSTATUS_SUCCESS) {
1844       NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
1845       retry_core_init_cnt++;
1846       goto retry_core_init;
1847     }
1848   }
1849   config_access = true;
1850 
1851   retlen = 0;
1852   /* NXP SWP switch timeout Setting*/
1853   if (GetNxpNumValue(NAME_NXP_SWP_SWITCH_TIMEOUT, (void*)&retlen,
1854                      sizeof(retlen))) {
1855     // Check the permissible range [0 - 60]
1856     if (0 <= retlen && retlen <= 60) {
1857       if (0 < retlen) {
1858         unsigned int timeout = (uint32_t)retlen * 1000;
1859         unsigned int timeoutHx = 0x0000;
1860 
1861         char tmpbuffer[10] = {0};
1862         snprintf((char*)tmpbuffer, 10, "%04x", timeout);
1863         sscanf((char*)tmpbuffer, "%x", &timeoutHx);
1864 
1865         swp_switch_timeout_cmd[7] = (timeoutHx & 0xFF);
1866         swp_switch_timeout_cmd[8] = ((timeoutHx & 0xFF00) >> 8);
1867       }
1868 
1869       status = phNxpNciHal_send_ext_cmd(sizeof(swp_switch_timeout_cmd),
1870                                         swp_switch_timeout_cmd);
1871       if (status != NFCSTATUS_SUCCESS) {
1872         NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed");
1873         retry_core_init_cnt++;
1874         goto retry_core_init;
1875       }
1876     } else {
1877       NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed - out of range!");
1878     }
1879   }
1880 
1881   status = phNxpNciHal_china_tianjin_rf_setting();
1882   if (status != NFCSTATUS_SUCCESS) {
1883     NXPLOG_NCIHAL_E("phNxpNciHal_china_tianjin_rf_setting failed");
1884     retry_core_init_cnt++;
1885     goto retry_core_init;
1886   }
1887   if (nfcFL.chipType < sn100u) {
1888     // Update eeprom value
1889     status = phNxpNciHal_set_mw_eeprom();
1890     if (status != NFCSTATUS_SUCCESS) {
1891       NXPLOG_NCIHAL_E("NXP Update MW EEPROM Proprietary Ext failed");
1892     }
1893   }
1894 
1895   retlen = 0;
1896   config_access = false;
1897   // if recovery mode and length of last command is 0 then only reset the P2P
1898   // listen mode routing.
1899   if (core_init_rsp_params_len >= 36 && (*p_core_init_rsp_params > 0) &&
1900       (*p_core_init_rsp_params < 4) && p_core_init_rsp_params[35] == 0) {
1901     /* P2P listen mode routing */
1902     status = phNxpNciHal_send_ext_cmd(sizeof(p2p_listen_mode_routing_cmd),
1903                                       p2p_listen_mode_routing_cmd);
1904     if (status != NFCSTATUS_SUCCESS) {
1905       NXPLOG_NCIHAL_E("P2P listen mode routing failed");
1906       retry_core_init_cnt++;
1907       goto retry_core_init;
1908     }
1909   }
1910 
1911   retlen = 0;
1912 
1913   /* SWP FULL PWR MODE SETTING ON */
1914   if (GetNxpNumValue(NAME_NXP_SWP_FULL_PWR_ON, (void*)&retlen,
1915                      sizeof(retlen))) {
1916     if (1 == retlen) {
1917       status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd),
1918                                         swp_full_pwr_mode_on_cmd);
1919       if (status != NFCSTATUS_SUCCESS) {
1920         NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING ON CMD FAILED");
1921         retry_core_init_cnt++;
1922         goto retry_core_init;
1923       }
1924     } else {
1925       swp_full_pwr_mode_on_cmd[7] = 0x00;
1926       status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd),
1927                                         swp_full_pwr_mode_on_cmd);
1928       if (status != NFCSTATUS_SUCCESS) {
1929         NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING OFF CMD FAILED");
1930         retry_core_init_cnt++;
1931         goto retry_core_init;
1932       }
1933     }
1934   }
1935 
1936 #if (NXP_EXTNS == TRUE)
1937   isfound = GetNxpNumValue(NAME_NXP_NCI_PARSER_LIBRARY, &num, sizeof(num));
1938   if (isfound > 0 && num == 0x01) {
1939     phNxpNciHal_configNciParser(true);
1940     NXPLOG_NCIHAL_D("NCI Parser is enabled");
1941   } else if (isfound > 0 && num == 0x00) {
1942     NXPLOG_NCIHAL_D("Disabling NCI Parser...");
1943     phNxpNciHal_configNciParser(false);
1944   } else {
1945     NXPLOG_NCIHAL_D("NCI Parser is disabled");
1946   }
1947 
1948   if (nfcFL.chipType == pn557) {
1949     if (GetNxpNumValue(NAME_NXP_PROP_CE_ACTION_NTF, (void*)&retlen,
1950                        sizeof(retlen))) {
1951       uint8_t value = (uint8_t)retlen;
1952       NXPLOG_NCIHAL_D("Prop CE ACT NTF %x", value);
1953       mEEPROM_info.buffer = &value;
1954       mEEPROM_info.bufflen = sizeof(value);
1955       mEEPROM_info.request_type = EEPROM_CE_ACT_NTF;
1956       mEEPROM_info.request_mode = SET_EEPROM_DATA;
1957       request_EEPROM(&mEEPROM_info);
1958     }
1959   }
1960 
1961 #endif
1962 
1963   config_access = false;
1964   {
1965     if (isNxpRFConfigModified() || isNxpConfigModified() || fw_dwnld_flag ||
1966         setConfigAlways) {
1967       if (nfcFL.chipType >= sn100u) {
1968         status = phNxpNciHal_ext_send_sram_config_to_flash();
1969         if (status != NFCSTATUS_SUCCESS) {
1970           NXPLOG_NCIHAL_E("Updation of the SRAM contents failed");
1971         }
1972       }
1973       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
1974       if (status == NFCSTATUS_SUCCESS) {
1975         if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
1976           status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0),
1977                                             cmd_init_nci2_0);
1978         } else {
1979           status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
1980         }
1981       }
1982     }
1983     if (status == NFCSTATUS_SUCCESS) {
1984       status = phNxpNciHal_restore_uicc_params();
1985       if (status != NFCSTATUS_SUCCESS) {
1986         NXPLOG_NCIHAL_E("%s: Restore UICC params failed", __FUNCTION__);
1987       }
1988 
1989       phNxpNciHal_prop_conf_rssi();
1990 
1991       fw_dwnld_flag = false;
1992       status = phNxpNciHal_write_fw_dw_status(fw_dwnld_flag);
1993       if (status != NFCSTATUS_SUCCESS) {
1994         NXPLOG_NCIHAL_E("%s: NXP Set FW Download Flag failed", __FUNCTION__);
1995       }
1996       status = phNxpNciHal_send_get_cfgs();
1997       if (status == NFCSTATUS_SUCCESS) {
1998         NXPLOG_NCIHAL_E("Send get Configs SUCCESS");
1999       } else {
2000         NXPLOG_NCIHAL_E("Send get Configs FAILED");
2001       }
2002     }
2003   }
2004   retry_core_init_cnt = 0;
2005 
2006   if (buffer) {
2007     free(buffer);
2008     buffer = NULL;
2009   }
2010   // initialize recovery FW variables
2011   gRecFWDwnld = 0;
2012   gRecFwRetryCount = 0;
2013 
2014   phNxpNciHal_core_initialized_complete(status);
2015   if (isNxpConfigModified()) {
2016     updateNxpConfigTimestamp();
2017   }
2018   if (isNxpRFConfigModified()) {
2019     updateNxpRfConfigTimestamp();
2020   }
2021   return NFCSTATUS_SUCCESS;
2022 }
2023 /******************************************************************************
2024  * Function         phNxpNciHal_CheckRFCmdRespStatus
2025  *
2026  * Description      This function is called to check the resp status of
2027  *                  RF update commands.
2028  *
2029  * Returns          NFCSTATUS_SUCCESS           if successful,
2030  *                  NFCSTATUS_INVALID_PARAMETER if parameter is inavlid
2031  *                  NFCSTATUS_FAILED            if failed response
2032  *
2033  ******************************************************************************/
phNxpNciHal_CheckRFCmdRespStatus()2034 NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus() {
2035   NFCSTATUS status = NFCSTATUS_SUCCESS;
2036   static uint16_t INVALID_PARAM = 0x09;
2037   if ((nxpncihal_ctrl.rx_data_len > 0) && (nxpncihal_ctrl.p_rx_data[2] > 0)) {
2038     if (nxpncihal_ctrl.p_rx_data[3] == 0x09) {
2039       status = INVALID_PARAM;
2040     } else if (nxpncihal_ctrl.p_rx_data[3] != NFCSTATUS_SUCCESS) {
2041       status = NFCSTATUS_FAILED;
2042     }
2043   }
2044   return status;
2045 }
2046 /******************************************************************************
2047  * Function         phNxpNciHalRFConfigCmdRecSequence
2048  *
2049  * Description      This function is called to handle recovery FW sequence
2050  *                  Whenever RF settings are failed to apply with invalid param
2051  *                  response, recovery mechanism includes recovery firmware
2052  *                  download followed by firmware download and then config
2053  *                  settings. The recovery firmware changes the major number of
2054  *                  the firmware inside NFCC.Then actual firmware dowenload will
2055  *                  be successful. This can be retried maximum three times.
2056  *
2057  * Returns          Always returns NFCSTATUS_SUCCESS
2058  *
2059  ******************************************************************************/
phNxpNciHalRFConfigCmdRecSequence()2060 NFCSTATUS phNxpNciHalRFConfigCmdRecSequence() {
2061   NFCSTATUS status = NFCSTATUS_SUCCESS;
2062   uint16_t recFWState = 1;
2063   gRecFWDwnld = true;
2064   gRecFwRetryCount++;
2065   if (gRecFwRetryCount > 0x03) {
2066     NXPLOG_NCIHAL_D("Max retry count for RF config FW recovery exceeded ");
2067     gRecFWDwnld = false;
2068     return NFCSTATUS_FAILED;
2069   }
2070   do {
2071     status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
2072     phDnldNfc_InitImgInfo();
2073     if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion()) {
2074       status = phNxpNciHal_fw_download();
2075       if (status != NFCSTATUS_SUCCESS) {
2076         NXPLOG_NCIHAL_E("error in download = %x", status);
2077       }
2078       break;
2079     }
2080     gRecFWDwnld = false;
2081   } while (recFWState--);
2082   gRecFWDwnld = false;
2083   return status;
2084 }
2085 
2086 /******************************************************************************
2087  * Function         phNxpNciHal_core_initialized_complete
2088  *
2089  * Description      This function is called when phNxpNciHal_core_initialized
2090  *                  complete all proprietary command exchanges. This function
2091  *                  informs libnfc-nci about completion of core initialize
2092  *                  and result of that through callback.
2093  *
2094  * Returns          void.
2095  *
2096  ******************************************************************************/
phNxpNciHal_core_initialized_complete(NFCSTATUS status)2097 static void phNxpNciHal_core_initialized_complete(NFCSTATUS status) {
2098   static phLibNfc_Message_t msg;
2099 
2100   if (status == NFCSTATUS_SUCCESS) {
2101     msg.eMsgType = NCI_HAL_POST_INIT_CPLT_MSG;
2102   } else {
2103     msg.eMsgType = NCI_HAL_ERROR_MSG;
2104   }
2105   msg.pMsgData = NULL;
2106   msg.Size = 0;
2107 
2108   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
2109                         (phLibNfc_Message_t*)&msg);
2110   return;
2111 }
2112 
2113 /******************************************************************************
2114  * Function         phNxpNciHal_pre_discover
2115  *
2116  * Description      This function is called by libnfc-nci to perform any
2117  *                  proprietary exchange before RF discovery.
2118  *
2119  * Returns          It always returns NFCSTATUS_SUCCESS (0).
2120  *
2121  ******************************************************************************/
phNxpNciHal_pre_discover(void)2122 int phNxpNciHal_pre_discover(void) {
2123   /* Nothing to do here for initial version */
2124   return NFCSTATUS_SUCCESS;
2125 }
2126 
2127 /******************************************************************************
2128  * Function         phNxpNciHal_release_info
2129  *
2130  * Description      This function frees allocated memory for mGetCfg_info
2131  *
2132  * Returns          void.
2133  *
2134  ******************************************************************************/
phNxpNciHal_release_info(void)2135 static void phNxpNciHal_release_info(void) {
2136   NXPLOG_NCIHAL_D("phNxpNciHal_release_info mGetCfg_info");
2137   if (mGetCfg_info != NULL) {
2138     free(mGetCfg_info);
2139     mGetCfg_info = NULL;
2140   }
2141 }
2142 /******************************************************************************
2143  * Function         phNxpNciHal_close
2144  *
2145  * Description      This function close the NFCC interface and free all
2146  *                  resources.This is called by libnfc-nci on NFC service stop.
2147  *
2148  * Returns          Always return NFCSTATUS_SUCCESS (0).
2149  *
2150  ******************************************************************************/
phNxpNciHal_close(bool bShutdown)2151 int phNxpNciHal_close(bool bShutdown) {
2152   NFCSTATUS status = NFCSTATUS_FAILED;
2153   uint8_t cmd_ce_discovery_nci[10] = {
2154       0x21,
2155       0x03,
2156   };
2157   uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
2158   uint8_t cmd_ce_in_phone_off[] = {0x20, 0x02, 0x05, 0x01,
2159                                    0xA0, 0x8E, 0x01, 0x00};
2160   uint8_t cmd_ce_in_phone_off_pn557[] = {0x20, 0x02, 0x05, 0x01,
2161                                          0xA0, 0x07, 0x01, 0x02};
2162   uint8_t cmd_system_set_service_status[] = {0x2F, 0x01, 0x01, 0x00};
2163   uint8_t length = 0;
2164   uint8_t numPrms = 0;
2165   uint8_t ptr = 4;
2166   unsigned long uiccListenMask = 0x00;
2167   unsigned long eseListenMask = 0x00;
2168   uint8_t retry = 0;
2169 
2170   phNxpNciHal_deinitializeRegRfFwDnld();
2171   NfcHalAutoThreadMutex a(sHalFnLock);
2172   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
2173     NXPLOG_NCIHAL_D("phNxpNciHal_close is already closed, ignoring close");
2174     return NFCSTATUS_FAILED;
2175   }
2176 #if (NXP_EXTNS == TRUE)
2177   if (nfcFL.chipType < sn100u) {
2178 #endif
2179     if (!(GetNxpNumValue(NAME_NXP_UICC_LISTEN_TECH_MASK, &uiccListenMask,
2180                          sizeof(uiccListenMask)))) {
2181       uiccListenMask = 0x07;
2182       NXPLOG_NCIHAL_D("UICC_LISTEN_TECH_MASK = 0x%0lX", uiccListenMask);
2183     }
2184 
2185     if (!(GetNxpNumValue(NAME_NXP_ESE_LISTEN_TECH_MASK, &eseListenMask,
2186                          sizeof(eseListenMask)))) {
2187       eseListenMask = 0x07;
2188       NXPLOG_NCIHAL_D("NXP_ESE_LISTEN_TECH_MASK = 0x%0lX", eseListenMask);
2189     }
2190 #if (NXP_EXTNS == TRUE)
2191   }
2192 #endif
2193 
2194   CONCURRENCY_LOCK();
2195   int sem_val;
2196   sem_getvalue(&(nxpncihal_ctrl.syncSpiNfc), &sem_val);
2197   if (sem_val == 0) {
2198     sem_post(&(nxpncihal_ctrl.syncSpiNfc));
2199   }
2200   if (!bShutdown) {
2201     if (nfcFL.chipType >= sn100u) {
2202       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_in_phone_off),
2203                                         cmd_ce_in_phone_off);
2204       if (status != NFCSTATUS_SUCCESS) {
2205         NXPLOG_NCIHAL_E("CMD_CE_IN_PHONE_OFF: Failed");
2206       }
2207       config_ext.autonomous_mode = 0x00;
2208       status = phNxpNciHal_setAutonomousMode();
2209       if (status != NFCSTATUS_SUCCESS) {
2210         NXPLOG_NCIHAL_E("Autonomous mode Disable: Failed");
2211       }
2212     } else {
2213       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_in_phone_off_pn557),
2214                                         cmd_ce_in_phone_off_pn557);
2215       if (status != NFCSTATUS_SUCCESS) {
2216         NXPLOG_NCIHAL_E("CMD_CE_IN_PHONE_OFF: Failed");
2217       }
2218     }
2219   }
2220   if (nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT &&
2221       read_failed_disable_nfc) {
2222     read_failed_disable_nfc = false;
2223     goto close_and_return;
2224   }
2225 
2226   if (write_unlocked_status == NFCSTATUS_FAILED) {
2227     NXPLOG_NCIHAL_D("phNxpNciHal_close i2c write failed .Clean and Return");
2228     goto close_and_return;
2229   }
2230 
2231 #if (NXP_EXTNS == TRUE)
2232   if ((!bShutdown) && nfcFL.chipType < sn100u) {
2233 #endif
2234     if ((uiccListenMask & 0x1) == 0x01 || (eseListenMask & 0x1) == 0x01) {
2235       NXPLOG_NCIHAL_D("phNxpNciHal_close (): Adding A passive listen");
2236       numPrms++;
2237       cmd_ce_discovery_nci[ptr++] = 0x80;
2238       cmd_ce_discovery_nci[ptr++] = 0x01;
2239       length += 2;
2240     }
2241     if ((uiccListenMask & 0x2) == 0x02 || (eseListenMask & 0x4) == 0x04) {
2242       NXPLOG_NCIHAL_D("phNxpNciHal_close (): Adding B passive listen");
2243       numPrms++;
2244       cmd_ce_discovery_nci[ptr++] = 0x81;
2245       cmd_ce_discovery_nci[ptr++] = 0x01;
2246       length += 2;
2247     }
2248     if ((uiccListenMask & 0x4) == 0x04 || (eseListenMask & 0x4) == 0x04) {
2249       NXPLOG_NCIHAL_D("phNxpNciHal_close (): Adding F passive listen");
2250       numPrms++;
2251       cmd_ce_discovery_nci[ptr++] = 0x82;
2252       cmd_ce_discovery_nci[ptr++] = 0x01;
2253       length += 2;
2254     }
2255 
2256     if (length != 0) {
2257       cmd_ce_discovery_nci[2] = length + 1;
2258       cmd_ce_discovery_nci[3] = numPrms;
2259       status = phNxpNciHal_send_ext_cmd(length + 4, cmd_ce_discovery_nci);
2260       if (status != NFCSTATUS_SUCCESS) {
2261         NXPLOG_NCIHAL_E("CMD_CE_DISC_NCI: Failed");
2262       }
2263     } else {
2264       NXPLOG_NCIHAL_E(
2265           "No changes in the discovery command, sticking to last discovery "
2266           "command sent");
2267     }
2268 #if (NXP_EXTNS == TRUE)
2269   }
2270 #endif
2271 close_and_return:
2272   if ((nfcFL.chipType < sn220u) || bShutdown) {
2273     nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
2274   }
2275   do { /*This is NXP_EXTNS code for retry*/
2276     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
2277 
2278     if (status == NFCSTATUS_SUCCESS) {
2279       break;
2280     } else {
2281       NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed, perform retry after delay");
2282       usleep(1000 * 1000);
2283       retry++;
2284       if (retry > 3) {
2285         NXPLOG_NCIHAL_E(
2286             "Maximum retries performed, shall restart HAL to recover");
2287         abort();
2288       }
2289     }
2290   } while (retry < 3);
2291 
2292   if ((nfcFL.chipType >= sn220u) && !bShutdown) {
2293     nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
2294     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_system_set_service_status),
2295                                       cmd_system_set_service_status);
2296     if (status != NFCSTATUS_SUCCESS) {
2297       NXPLOG_NCIHAL_E("NCI SYSTEM SET SERVICE STATUS to OFF Failed");
2298     }
2299   }
2300 
2301   sem_destroy(&nxpncihal_ctrl.syncSpiNfc);
2302 
2303 #if (NXP_EXTNS == TRUE)
2304   if (gParserCreated) {
2305     phNxpNciHal_deinitParser();
2306     gParserCreated = FALSE;
2307   }
2308 #endif
2309   if (NULL != gpphTmlNfc_Context->pDevHandle) {
2310     phNxpNciHal_close_complete(NFCSTATUS_SUCCESS);
2311     /* Abort any pending read and write */
2312     status = phTmlNfc_ReadAbort();
2313     status = phTmlNfc_WriteAbort();
2314 
2315     phOsalNfc_Timer_Cleanup();
2316 
2317     status = phTmlNfc_Shutdown();
2318 
2319     if (0 != pthread_join(nxpncihal_ctrl.client_thread, (void**)NULL)) {
2320       NXPLOG_TML_E("Fail to kill client thread!");
2321     }
2322 
2323     phTmlNfc_CleanUp();
2324 
2325     phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
2326 
2327     memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
2328 
2329     NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed");
2330   }
2331 
2332   CONCURRENCY_UNLOCK();
2333 
2334   phNxpNciHal_cleanup_monitor();
2335   write_unlocked_status = NFCSTATUS_SUCCESS;
2336   phNxpNciHal_release_info();
2337   /* reset config cache */
2338   resetNxpConfig();
2339   /* Return success always */
2340   return NFCSTATUS_SUCCESS;
2341 }
2342 
2343 /******************************************************************************
2344  * Function         phNxpNciHal_close_complete
2345  *
2346  * Description      This function inform libnfc-nci about result of
2347  *                  phNxpNciHal_close.
2348  *
2349  * Returns          void.
2350  *
2351  ******************************************************************************/
phNxpNciHal_close_complete(NFCSTATUS status)2352 void phNxpNciHal_close_complete(NFCSTATUS status) {
2353   static phLibNfc_Message_t msg;
2354 
2355   if (status == NFCSTATUS_SUCCESS) {
2356     msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
2357   } else {
2358     msg.eMsgType = NCI_HAL_ERROR_MSG;
2359   }
2360   msg.pMsgData = NULL;
2361   msg.Size = 0;
2362   nxpncihal_ctrl.hal_open_status = false;
2363   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
2364 
2365   return;
2366 }
2367 
2368 /******************************************************************************
2369  * Function         phNxpNciHal_configDiscShutdown
2370  *
2371  * Description      Enable the CE and VEN config during shutdown.
2372  *
2373  * Returns          Always return NFCSTATUS_SUCCESS (0).
2374  *
2375  ******************************************************************************/
phNxpNciHal_configDiscShutdown(void)2376 int phNxpNciHal_configDiscShutdown(void) {
2377   NFCSTATUS status;
2378   /*NCI_RESET_CMD*/
2379 
2380   uint8_t cmd_disable_disc[] = {0x21, 0x06, 0x01, 0x00};
2381 
2382   uint8_t cmd_ce_disc_nci[] = {0x21, 0x03, 0x07, 0x03, 0x80,
2383                                0x01, 0x81, 0x01, 0x82, 0x01};
2384 
2385   uint8_t cmd_ven_pulld_enable_nci[] = {0x20, 0x02, 0x05, 0x01,
2386                                         0xA0, 0x07, 0x01, 0x03};
2387 
2388   /* Discover map - PROTOCOL_ISO_DEP, PROTOCOL_T3T and MIFARE Classic*/
2389   uint8_t cmd_disc_map[] = {0x21, 0x00, 0x0A, 0x03, 0x04, 0x03, 0x02,
2390                             0x03, 0x02, 0x01, 0x80, 0x01, 0x80};
2391   CONCURRENCY_LOCK();
2392 
2393   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_disable_disc), cmd_disable_disc);
2394   if (status != NFCSTATUS_SUCCESS) {
2395     NXPLOG_NCIHAL_E("CMD_DISABLE_DISCOVERY: Failed");
2396   }
2397 #if (NXP_EXTNS == TRUE)
2398   if (nfcFL.chipType < sn100u) {
2399 #endif
2400     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ven_pulld_enable_nci),
2401                                       cmd_ven_pulld_enable_nci);
2402     if (status != NFCSTATUS_SUCCESS) {
2403       NXPLOG_NCIHAL_E("CMD_VEN_PULLD_ENABLE_NCI: Failed");
2404     }
2405 #if (NXP_EXTNS == TRUE)
2406   }
2407 #endif
2408 
2409   if (nfcFL.chipType >= sn100u) {
2410     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_disc_map), cmd_disc_map);
2411     if (status != NFCSTATUS_SUCCESS) {
2412       NXPLOG_NCIHAL_E("Discovery Map command: Failed");
2413     }
2414     status = phNxpNciHal_ext_send_sram_config_to_flash();
2415     if (status != NFCSTATUS_SUCCESS) {
2416       NXPLOG_NCIHAL_E("Updation of the SRAM contents failed");
2417     }
2418   }
2419   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_disc_nci), cmd_ce_disc_nci);
2420   if (status != NFCSTATUS_SUCCESS) {
2421     NXPLOG_NCIHAL_E("CMD_CE_DISC_NCI: Failed");
2422   }
2423 
2424   CONCURRENCY_UNLOCK();
2425 
2426   status = phNxpNciHal_close(true);
2427   if (status != NFCSTATUS_SUCCESS) {
2428     NXPLOG_NCIHAL_E("NCI_HAL_CLOSE: Failed");
2429   }
2430 
2431   /* Return success always */
2432   return NFCSTATUS_SUCCESS;
2433 }
2434 
2435 /******************************************************************************
2436  * Function         phNxpNciHal_getVendorConfig
2437  *
2438  * Description      This function can be used by HAL to inform
2439  *                 to update vendor configuration parametres
2440  *
2441  * Returns          void.
2442  *
2443  ******************************************************************************/
2444 
phNxpNciHal_getVendorConfig(android::hardware::nfc::V1_1::NfcConfig & config)2445 void phNxpNciHal_getVendorConfig(
2446     android::hardware::nfc::V1_1::NfcConfig& config) {
2447   unsigned long num = 0;
2448   std::array<uint8_t, NXP_MAX_CONFIG_STRING_LEN> buffer;
2449   buffer.fill(0);
2450   long retlen = 0;
2451   memset(&config, 0x00, sizeof(android::hardware::nfc::V1_1::NfcConfig));
2452   memset(&config_ext, 0x00, sizeof(nxp_nfc_config_ext_t));
2453 
2454   if ((GetNxpNumValue(NAME_NXP_AUTONOMOUS_ENABLE, &num, sizeof(num)))) {
2455     config_ext.autonomous_mode = (uint8_t)num;
2456   }
2457   if ((GetNxpNumValue(NAME_NXP_GUARD_TIMER_VALUE, &num, sizeof(num)))) {
2458     config_ext.guard_timer_value = (uint8_t)num;
2459   }
2460   if (GetNxpNumValue(NAME_NFA_POLL_BAIL_OUT_MODE, &num, sizeof(num))) {
2461     config.nfaPollBailOutMode = (bool)num;
2462   }
2463   if (GetNxpNumValue(NAME_ISO_DEP_MAX_TRANSCEIVE, &num, sizeof(num))) {
2464     config.maxIsoDepTransceiveLength = (uint32_t)num;
2465   }
2466   if (GetNxpNumValue(NAME_DEFAULT_OFFHOST_ROUTE, &num, sizeof(num))) {
2467     config.defaultOffHostRoute = (uint8_t)num;
2468   }
2469   if (GetNxpNumValue(NAME_DEFAULT_NFCF_ROUTE, &num, sizeof(num))) {
2470     config.defaultOffHostRouteFelica = (uint8_t)num;
2471   }
2472   if (GetNxpNumValue(NAME_DEFAULT_SYS_CODE_ROUTE, &num, sizeof(num))) {
2473     config.defaultSystemCodeRoute = (uint8_t)num;
2474   }
2475   if (GetNxpNumValue(NAME_DEFAULT_SYS_CODE_PWR_STATE, &num, sizeof(num))) {
2476     config.defaultSystemCodePowerState =
2477         phNxpNciHal_updateAutonomousPwrState((uint8_t)num);
2478   }
2479   if (GetNxpNumValue(NAME_DEFAULT_ROUTE, &num, sizeof(num))) {
2480     config.defaultRoute = (uint8_t)num;
2481   }
2482   if (GetNxpByteArrayValue(NAME_DEVICE_HOST_WHITE_LIST, (char*)buffer.data(),
2483                            buffer.size(), &retlen)) {
2484     config.hostWhitelist.resize(retlen);
2485     for (long i = 0; i < retlen; i++) config.hostWhitelist[i] = buffer[i];
2486   }
2487   if (GetNxpNumValue(NAME_OFF_HOST_ESE_PIPE_ID, &num, sizeof(num))) {
2488     config.offHostESEPipeId = (uint8_t)num;
2489   }
2490   if (GetNxpNumValue(NAME_OFF_HOST_SIM_PIPE_ID, &num, sizeof(num))) {
2491     config.offHostSIMPipeId = (uint8_t)num;
2492   }
2493   if ((GetNxpByteArrayValue(NAME_NFA_PROPRIETARY_CFG, (char*)buffer.data(),
2494                             buffer.size(), &retlen)) &&
2495       (retlen == 9)) {
2496     config.nfaProprietaryCfg.protocol18092Active = (uint8_t)buffer[0];
2497     config.nfaProprietaryCfg.protocolBPrime = (uint8_t)buffer[1];
2498     config.nfaProprietaryCfg.protocolDual = (uint8_t)buffer[2];
2499     config.nfaProprietaryCfg.protocol15693 = (uint8_t)buffer[3];
2500     config.nfaProprietaryCfg.protocolKovio = (uint8_t)buffer[4];
2501     config.nfaProprietaryCfg.protocolMifare = (uint8_t)buffer[5];
2502     config.nfaProprietaryCfg.discoveryPollKovio = (uint8_t)buffer[6];
2503     config.nfaProprietaryCfg.discoveryPollBPrime = (uint8_t)buffer[7];
2504     config.nfaProprietaryCfg.discoveryListenBPrime = (uint8_t)buffer[8];
2505   } else {
2506     memset(&config.nfaProprietaryCfg, 0xFF, sizeof(ProtocolDiscoveryConfig));
2507   }
2508   if ((GetNxpNumValue(NAME_PRESENCE_CHECK_ALGORITHM, &num, sizeof(num))) &&
2509       (num <= 2)) {
2510     config.presenceCheckAlgorithm = (PresenceCheckAlgorithm)num;
2511   }
2512 }
2513 
2514 /******************************************************************************
2515  * Function         phNxpNciHal_getVendorConfig_1_2
2516  *
2517  * Description      This function can be used by HAL to inform
2518  *                 to update vendor configuration parametres
2519  *
2520  * Returns          void.
2521  *
2522  ******************************************************************************/
2523 
phNxpNciHal_getVendorConfig_1_2(android::hardware::nfc::V1_2::NfcConfig & config)2524 void phNxpNciHal_getVendorConfig_1_2(
2525     android::hardware::nfc::V1_2::NfcConfig& config) {
2526   unsigned long num = 0;
2527   std::array<uint8_t, NXP_MAX_CONFIG_STRING_LEN> buffer;
2528   buffer.fill(0);
2529   long retlen = 0;
2530   memset(&config, 0x00, sizeof(android::hardware::nfc::V1_2::NfcConfig));
2531   phNxpNciHal_getVendorConfig(config.v1_1);
2532 
2533   if (GetNxpByteArrayValue(NAME_OFFHOST_ROUTE_UICC, (char*)buffer.data(),
2534                            buffer.size(), &retlen)) {
2535     config.offHostRouteUicc.resize(retlen);
2536     for (long i = 0; i < retlen; i++) config.offHostRouteUicc[i] = buffer[i];
2537   }
2538 
2539   if (GetNxpByteArrayValue(NAME_OFFHOST_ROUTE_ESE, (char*)buffer.data(),
2540                            buffer.size(), &retlen)) {
2541     config.offHostRouteEse.resize(retlen);
2542     for (long i = 0; i < retlen; i++) config.offHostRouteEse[i] = buffer[i];
2543   }
2544 
2545   if (GetNxpNumValue(NAME_DEFAULT_ISODEP_ROUTE, &num, sizeof(num))) {
2546     config.defaultIsoDepRoute = num;
2547   }
2548 }
2549 
2550 /******************************************************************************
2551  * Function         phNxpNciHal_notify_i2c_fragmentation
2552  *
2553  * Description      This function can be used by HAL to inform
2554  *                 libnfc-nci that i2c fragmentation is enabled/disabled
2555  *
2556  * Returns          void.
2557  *
2558  ******************************************************************************/
phNxpNciHal_notify_i2c_fragmentation(void)2559 void phNxpNciHal_notify_i2c_fragmentation(void) {
2560   if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
2561     /*inform libnfc-nci that i2c fragmentation is enabled/disabled */
2562     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT,
2563                                         HAL_NFC_STATUS_OK);
2564   }
2565 }
2566 /******************************************************************************
2567  * Function         phNxpNciHal_control_granted
2568  *
2569  * Description      Called by libnfc-nci when NFCC control is granted to HAL.
2570  *
2571  * Returns          Always returns NFCSTATUS_SUCCESS (0).
2572  *
2573  ******************************************************************************/
phNxpNciHal_control_granted(void)2574 int phNxpNciHal_control_granted(void) {
2575   /* Take the concurrency lock so no other calls from upper layer
2576    * will be allowed
2577    */
2578   CONCURRENCY_LOCK();
2579 
2580   if (NULL != nxpncihal_ctrl.p_control_granted_cback) {
2581     (*nxpncihal_ctrl.p_control_granted_cback)();
2582   }
2583   /* At the end concurrency unlock so calls from upper layer will
2584    * be allowed
2585    */
2586   CONCURRENCY_UNLOCK();
2587   return NFCSTATUS_SUCCESS;
2588 }
2589 
2590 /******************************************************************************
2591  * Function         phNxpNciHal_request_control
2592  *
2593  * Description      This function can be used by HAL to request control of
2594  *                  NFCC to libnfc-nci. When control is provided to HAL it is
2595  *                  notified through phNxpNciHal_control_granted.
2596  *
2597  * Returns          void.
2598  *
2599  ******************************************************************************/
phNxpNciHal_request_control(void)2600 void phNxpNciHal_request_control(void) {
2601   if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
2602     /* Request Control of NCI Controller from NCI NFC Stack */
2603     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_REQUEST_CONTROL_EVT,
2604                                         HAL_NFC_STATUS_OK);
2605   }
2606 
2607   return;
2608 }
2609 
2610 /******************************************************************************
2611  * Function         phNxpNciHal_release_control
2612  *
2613  * Description      This function can be used by HAL to release the control of
2614  *                  NFCC back to libnfc-nci.
2615  *
2616  * Returns          void.
2617  *
2618  ******************************************************************************/
phNxpNciHal_release_control(void)2619 void phNxpNciHal_release_control(void) {
2620   if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
2621     /* Release Control of NCI Controller to NCI NFC Stack */
2622     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_RELEASE_CONTROL_EVT,
2623                                         HAL_NFC_STATUS_OK);
2624   }
2625 
2626   return;
2627 }
2628 
2629 /******************************************************************************
2630  * Function         phNxpNciHal_power_cycle
2631  *
2632  * Description      This function is called by libnfc-nci when power cycling is
2633  *                  performed. When processing is complete it is notified to
2634  *                  libnfc-nci through phNxpNciHal_power_cycle_complete.
2635  *
2636  * Returns          Always return NFCSTATUS_SUCCESS (0).
2637  *
2638  ******************************************************************************/
phNxpNciHal_power_cycle(void)2639 int phNxpNciHal_power_cycle(void) {
2640   NXPLOG_NCIHAL_D("Power Cycle");
2641   NFCSTATUS status = NFCSTATUS_FAILED;
2642   if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
2643     NXPLOG_NCIHAL_D("Power Cycle failed due to hal status not open");
2644     return NFCSTATUS_FAILED;
2645   }
2646   status = phTmlNfc_IoCtl(phTmlNfc_e_PowerReset);
2647 
2648   if (NFCSTATUS_SUCCESS == status) {
2649     NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
2650   } else {
2651     NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
2652   }
2653 
2654   phNxpNciHal_power_cycle_complete(NFCSTATUS_SUCCESS);
2655   return NFCSTATUS_SUCCESS;
2656 }
2657 
2658 /******************************************************************************
2659  * Function         phNxpNciHal_power_cycle_complete
2660  *
2661  * Description      This function is called to provide the status of
2662  *                  phNxpNciHal_power_cycle to libnfc-nci through callback.
2663  *
2664  * Returns          void.
2665  *
2666  ******************************************************************************/
phNxpNciHal_power_cycle_complete(NFCSTATUS status)2667 static void phNxpNciHal_power_cycle_complete(NFCSTATUS status) {
2668   static phLibNfc_Message_t msg;
2669 
2670   if (status == NFCSTATUS_SUCCESS) {
2671     msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
2672   } else {
2673     msg.eMsgType = NCI_HAL_ERROR_MSG;
2674   }
2675   msg.pMsgData = NULL;
2676   msg.Size = 0;
2677 
2678   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
2679 
2680   return;
2681 }
2682 /******************************************************************************
2683  * Function         phNxpNciHal_check_ncicmd_write_window
2684  *
2685  * Description      This function is called to check the write synchroniztion
2686  *                  status if write already acquired then wait for corresponding
2687                     read to complete.
2688  *
2689  * Returns          return 0 on success and -1 on fail.
2690  *
2691  ******************************************************************************/
2692 
phNxpNciHal_check_ncicmd_write_window(uint16_t cmd_len,uint8_t * p_cmd)2693 int phNxpNciHal_check_ncicmd_write_window(uint16_t cmd_len, uint8_t* p_cmd) {
2694   UNUSED_PROP(cmd_len);
2695   NFCSTATUS status = NFCSTATUS_FAILED;
2696   int sem_timedout = 2, s;
2697   struct timespec ts;
2698 
2699   if (cmd_len < 1) {
2700     android_errorWriteLog(0x534e4554, "153880357");
2701     return NFCSTATUS_FAILED;
2702   }
2703 
2704   if ((p_cmd[0] & 0xF0) == 0x20) {
2705     clock_gettime(CLOCK_MONOTONIC, &ts);
2706     ts.tv_sec += sem_timedout;
2707     while ((s = sem_timedwait_monotonic_np(&nxpncihal_ctrl.syncSpiNfc, &ts)) == -1 &&
2708            errno == EINTR) {
2709       continue; /* Restart if interrupted by handler */
2710     }
2711     if (s != -1) {
2712       status = NFCSTATUS_SUCCESS;
2713     }
2714   } else {
2715     /* cmd window check not required for writing data packet */
2716     status = NFCSTATUS_SUCCESS;
2717   }
2718   return status;
2719 }
2720 
2721 /******************************************************************************
2722  * Function         phNxpNciHal_ioctl
2723  *
2724  * Description      This function is called by jni when wired mode is
2725  *                  performed.First Pn54x driver will give the access
2726  *                  permission whether wired mode is allowed or not
2727  *                  arg (0):
2728  * Returns          return 0 on success and -1 on fail, On success
2729  *                  update the acutual state of operation in arg pointer
2730  *
2731  ******************************************************************************/
phNxpNciHal_ioctl(long arg,void * p_data)2732 int phNxpNciHal_ioctl(long arg, void* p_data) {
2733   return phNxpNciHal_ioctlIf(arg, p_data);
2734 }
2735 
2736 /******************************************************************************
2737  * Function         phNxpNciHal_nfccClockCfgRead
2738  *
2739  * Description      This function is called for loading a data strcuture from
2740  *                  the config file with clock source and clock frequency values
2741  *
2742  * Returns          void.
2743  *
2744  ******************************************************************************/
phNxpNciHal_nfccClockCfgRead(void)2745 static void phNxpNciHal_nfccClockCfgRead(void) {
2746   unsigned long num = 0;
2747   int isfound = 0;
2748 
2749   nxpprofile_ctrl.bClkSrcVal = 0;
2750   nxpprofile_ctrl.bClkFreqVal = 0;
2751   nxpprofile_ctrl.bTimeout = 0;
2752 
2753   isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &num, sizeof(num));
2754   if (isfound > 0) {
2755     nxpprofile_ctrl.bClkSrcVal = num;
2756   }
2757 
2758   num = 0;
2759   isfound = 0;
2760   isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &num, sizeof(num));
2761   if (isfound > 0) {
2762     nxpprofile_ctrl.bClkFreqVal = num;
2763   }
2764 
2765   num = 0;
2766   isfound = 0;
2767   isfound = GetNxpNumValue(NAME_NXP_SYS_CLOCK_TO_CFG, &num, sizeof(num));
2768   if (isfound > 0) {
2769     nxpprofile_ctrl.bTimeout = num;
2770   }
2771 
2772   NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkSrcVal = 0x%x",
2773                   nxpprofile_ctrl.bClkSrcVal);
2774   NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x",
2775                   nxpprofile_ctrl.bClkFreqVal);
2776   NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x",
2777                   nxpprofile_ctrl.bTimeout);
2778 
2779   if ((nxpprofile_ctrl.bClkSrcVal < CLK_SRC_XTAL) ||
2780       (nxpprofile_ctrl.bClkSrcVal > CLK_SRC_PLL)) {
2781     NXPLOG_FWDNLD_E(
2782         "Clock source value is wrong in config file, setting it as default");
2783     nxpprofile_ctrl.bClkSrcVal = NXP_SYS_CLK_SRC_SEL;
2784   }
2785   if ((nxpprofile_ctrl.bClkFreqVal < CLK_FREQ_13MHZ) ||
2786       (nxpprofile_ctrl.bClkFreqVal > CLK_FREQ_52MHZ)) {
2787     NXPLOG_FWDNLD_E(
2788         "Clock frequency value is wrong in config file, setting it as default");
2789     nxpprofile_ctrl.bClkFreqVal = NXP_SYS_CLK_FREQ_SEL;
2790   }
2791   if ((nxpprofile_ctrl.bTimeout < CLK_TO_CFG_DEF) ||
2792       (nxpprofile_ctrl.bTimeout > CLK_TO_CFG_MAX)) {
2793     NXPLOG_FWDNLD_E(
2794         "Clock timeout value is wrong in config file, setting it as default");
2795     nxpprofile_ctrl.bTimeout = CLK_TO_CFG_DEF;
2796   }
2797 }
2798 
2799 /******************************************************************************
2800  * Function         phNxpNciHal_determineConfiguredClockSrc
2801  *
2802  * Description      This function determines and encodes clock source based on
2803  *                  clock frequency
2804  *
2805  * Returns          encoded form of clock source
2806  *
2807  *****************************************************************************/
phNxpNciHal_determineConfiguredClockSrc()2808 int phNxpNciHal_determineConfiguredClockSrc() {
2809   uint8_t param_clock_src = CLK_SRC_PLL;
2810   if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) {
2811     if (nfcFL.chipType == pn553) {
2812       param_clock_src = param_clock_src << 3;
2813     } else if (nfcFL.chipType >= sn100u) {
2814       param_clock_src = 0;
2815     }
2816 
2817     if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) {
2818       param_clock_src |= 0x00;
2819     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) {
2820       param_clock_src |= 0x01;
2821     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) {
2822       param_clock_src |= 0x02;
2823     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) {
2824       param_clock_src |= 0x03;
2825     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) {
2826       param_clock_src |= 0x04;
2827     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) {
2828       param_clock_src |= 0x05;
2829     } else {
2830       NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
2831       if (nfcFL.chipType < sn100u)
2832         param_clock_src = 0x11;
2833       else
2834         param_clock_src = 0x01;
2835     }
2836   } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) {
2837     param_clock_src = 0x08;
2838 
2839   } else {
2840     NXPLOG_NCIHAL_E("Wrong clock source. Don't apply any modification");
2841   }
2842   return param_clock_src;
2843 }
2844 
2845 /******************************************************************************
2846  * Function         phNxpNciHal_determineConfiguredClockSrc
2847  *
2848  * Description      This function determines and encodes clock source based on
2849  *                  clock frequency
2850  *
2851  * Returns          encoded form of clock source
2852  *
2853  *****************************************************************************/
phNxpNciHal_determineClockDelayRequest(uint8_t nfcc_cfg_clock_src)2854 int phNxpNciHal_determineClockDelayRequest(uint8_t nfcc_cfg_clock_src) {
2855   unsigned long num = 0;
2856   int isfound = 0;
2857   uint8_t nfcc_clock_delay_req = 0;
2858   uint8_t nfcc_clock_set_needed = false;
2859 
2860   isfound = GetNxpNumValue(NAME_NXP_CLOCK_REQ_DELAY, &num, sizeof(num));
2861   if (isfound > 0) {
2862     nxpprofile_ctrl.clkReqDelay = num;
2863   }
2864   if ((nxpprofile_ctrl.clkReqDelay < CLK_REQ_DELAY_MIN) ||
2865       (nxpprofile_ctrl.clkReqDelay > CLK_REQ_DELAY_MAX)) {
2866     NXPLOG_FWDNLD_E(
2867         "default delay to start clock value is wrong in config "
2868         "file, setting it as default");
2869     nxpprofile_ctrl.clkReqDelay = CLK_REQ_DELAY_DEF;
2870     return nfcc_clock_set_needed;
2871   }
2872   nfcc_clock_delay_req = nxpprofile_ctrl.clkReqDelay;
2873 
2874   /*Check if the clock source is XTAL as per config*/
2875   if (nfcc_cfg_clock_src == CLK_CFG_XTAL) {
2876     if (nfcc_clock_delay_req !=
2877         (phNxpNciClock.p_rx_data[CLK_REQ_DELAY_XTAL_OFFSET] &
2878          CLK_REQ_DELAY_MASK)) {
2879       nfcc_clock_set_needed = true;
2880       phNxpNciClock.p_rx_data[CLK_REQ_DELAY_XTAL_OFFSET] &=
2881           ~(CLK_REQ_DELAY_MASK);
2882       phNxpNciClock.p_rx_data[CLK_REQ_DELAY_XTAL_OFFSET] |=
2883           (nfcc_clock_delay_req & CLK_REQ_DELAY_MASK);
2884     }
2885   }
2886   /*Check if the clock source is PLL as per config*/
2887   else if (nfcc_cfg_clock_src < 6) {
2888     if (nfcc_clock_delay_req !=
2889         (phNxpNciClock.p_rx_data[CLK_REQ_DELAY_PLL_OFFSET] &
2890          CLK_REQ_DELAY_MASK)) {
2891       nfcc_clock_set_needed = true;
2892       phNxpNciClock.p_rx_data[CLK_REQ_DELAY_PLL_OFFSET] &=
2893           ~(CLK_REQ_DELAY_MASK);
2894       phNxpNciClock.p_rx_data[CLK_REQ_DELAY_PLL_OFFSET] |=
2895           (nfcc_clock_delay_req & CLK_REQ_DELAY_MASK);
2896     }
2897   }
2898   return nfcc_clock_set_needed;
2899 }
2900 
2901 /******************************************************************************
2902  * Function         phNxpNciHal_nfccClockCfgApply
2903  *
2904  * Description      This function is called after successful download
2905  *                  to check if clock settings in config file and chip
2906  *                  is same
2907  *
2908  * Returns          void.
2909  *
2910  ******************************************************************************/
phNxpNciHal_nfccClockCfgApply(void)2911 NFCSTATUS phNxpNciHal_nfccClockCfgApply(void) {
2912   NFCSTATUS status = NFCSTATUS_SUCCESS;
2913   uint8_t nfcc_cfg_clock_src, nfcc_cur_clock_src;
2914   uint8_t nfcc_clock_set_needed;
2915   uint8_t nfcc_clock_delay_req;
2916   static uint8_t* get_clock_cmd;
2917   uint8_t get_clck_cmd[] = {0x20, 0x03, 0x07, 0x03, 0xA0,
2918                             0x02, 0xA0, 0x03, 0xA0, 0x04};
2919   uint8_t get_clck_cmd_sn100[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x11};
2920   uint8_t set_clck_cmd[] = {0x20, 0x02, 0x0B, 0x01, 0xA0, 0x11, 0x07,
2921                             0x01, 0x0A, 0x32, 0x02, 0x01, 0xF6, 0xF6};
2922   uint8_t get_clk_size = 0;
2923 
2924   if (nfcFL.chipType < sn100u) {
2925     get_clock_cmd = get_clck_cmd;
2926     get_clk_size = sizeof(get_clck_cmd);
2927   } else {
2928     get_clock_cmd = get_clck_cmd_sn100;
2929     get_clk_size = sizeof(get_clck_cmd_sn100);
2930   }
2931   phNxpNciHal_nfccClockCfgRead();
2932   phNxpNciClock.isClockSet = true;
2933   status = phNxpNciHal_send_ext_cmd(get_clk_size, get_clock_cmd);
2934   phNxpNciClock.isClockSet = false;
2935 
2936   if (status != NFCSTATUS_SUCCESS) {
2937     NXPLOG_NCIHAL_E("unable to retrieve get_clk_src_sel");
2938     return status;
2939   }
2940 
2941   nfcc_cfg_clock_src = phNxpNciHal_determineConfiguredClockSrc();
2942   if (nfcFL.chipType < sn100u) {
2943     nfcc_cur_clock_src = phNxpNciClock.p_rx_data[12];
2944   } else {
2945     nfcc_cur_clock_src = phNxpNciClock.p_rx_data[8];
2946   }
2947 
2948   if (nfcFL.chipType < sn100u) {
2949     nfcc_clock_set_needed =
2950         (nfcc_cfg_clock_src != nfcc_cur_clock_src ||
2951          phNxpNciClock.p_rx_data[16] == nxpprofile_ctrl.bTimeout)
2952             ? true
2953             : false;
2954   } else {
2955     nfcc_clock_delay_req =
2956         phNxpNciHal_determineClockDelayRequest(nfcc_cfg_clock_src);
2957     /**Determine clock src is as expected*/
2958     nfcc_clock_set_needed =
2959         ((nfcc_cfg_clock_src != nfcc_cur_clock_src || nfcc_clock_delay_req)
2960              ? true
2961              : false);
2962   }
2963 
2964   if (nfcc_clock_set_needed) {
2965     NXPLOG_NCIHAL_D("Setting Clock Source and Frequency");
2966     if (nfcFL.chipType < sn100u) {
2967       phNxpNciHal_txNfccClockSetCmd();
2968     } else {
2969       /*Read the preset value from FW*/
2970       memcpy(&set_clck_cmd[7], &phNxpNciClock.p_rx_data[8],
2971              phNxpNciClock.p_rx_data[7]);
2972       /*Update clock source and frequency as per DH configuration*/
2973       set_clck_cmd[7] = nfcc_cfg_clock_src;
2974       status = phNxpNciHal_send_ext_cmd(sizeof(set_clck_cmd), set_clck_cmd);
2975     }
2976   }
2977 
2978   return status;
2979 }
2980 
2981 /******************************************************************************
2982  * Function         phNxpNciHal_get_mw_eeprom
2983  *
2984  * Description      This function is called to retrieve data in mw eeprom area
2985  *
2986  * Returns          NFCSTATUS.
2987  *
2988  ******************************************************************************/
phNxpNciHal_get_mw_eeprom(void)2989 static NFCSTATUS phNxpNciHal_get_mw_eeprom(void) {
2990   NFCSTATUS status = NFCSTATUS_SUCCESS;
2991   uint8_t retry_cnt = 0;
2992   static uint8_t get_mw_eeprom_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x0F};
2993 
2994 retry_send_ext:
2995   if (retry_cnt > 3) {
2996     return NFCSTATUS_FAILED;
2997   }
2998 
2999   phNxpNciMwEepromArea.isGetEepromArea = true;
3000   status =
3001       phNxpNciHal_send_ext_cmd(sizeof(get_mw_eeprom_cmd), get_mw_eeprom_cmd);
3002   if (status != NFCSTATUS_SUCCESS) {
3003     NXPLOG_NCIHAL_D("unable to get the mw eeprom data");
3004     phNxpNciMwEepromArea.isGetEepromArea = false;
3005     retry_cnt++;
3006     goto retry_send_ext;
3007   }
3008   phNxpNciMwEepromArea.isGetEepromArea = false;
3009 
3010   if (phNxpNciMwEepromArea.p_rx_data[12]) {
3011     fw_download_success = 1;
3012   }
3013   return status;
3014 }
3015 
3016 /******************************************************************************
3017  * Function         phNxpNciHal_set_mw_eeprom
3018  *
3019  * Description      This function is called to update data in mw eeprom area
3020  *
3021  * Returns          void.
3022  *
3023  ******************************************************************************/
phNxpNciHal_set_mw_eeprom(void)3024 static NFCSTATUS phNxpNciHal_set_mw_eeprom(void) {
3025   NFCSTATUS status = NFCSTATUS_SUCCESS;
3026   uint8_t retry_cnt = 0;
3027   uint8_t set_mw_eeprom_cmd[39] = {0};
3028   uint8_t cmd_header[] = {0x20, 0x02, 0x24, 0x01, 0xA0, 0x0F, 0x20};
3029 
3030   memcpy(set_mw_eeprom_cmd, cmd_header, sizeof(cmd_header));
3031   phNxpNciMwEepromArea.p_rx_data[12] = 0;
3032   memcpy(set_mw_eeprom_cmd + sizeof(cmd_header), phNxpNciMwEepromArea.p_rx_data,
3033          sizeof(phNxpNciMwEepromArea.p_rx_data));
3034 
3035 retry_send_ext:
3036   if (retry_cnt > 3) {
3037     return NFCSTATUS_FAILED;
3038   }
3039 
3040   status =
3041       phNxpNciHal_send_ext_cmd(sizeof(set_mw_eeprom_cmd), set_mw_eeprom_cmd);
3042   if (status != NFCSTATUS_SUCCESS) {
3043     NXPLOG_NCIHAL_D("unable to update the mw eeprom data");
3044     retry_cnt++;
3045     goto retry_send_ext;
3046   }
3047   return status;
3048 }
3049 
3050 /******************************************************************************
3051  * Function         phNxpNciHal_china_tianjin_rf_setting
3052  *
3053  * Description      This function is called to check RF Setting
3054  *
3055  * Returns          Status.
3056  *
3057  ******************************************************************************/
phNxpNciHal_china_tianjin_rf_setting(void)3058 NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void) {
3059   NFCSTATUS status = NFCSTATUS_SUCCESS;
3060   int isfound = 0;
3061   unsigned long config_value = 0;
3062   int rf_val = 0;
3063   int flag_send_tianjin_config = true;
3064   int flag_send_transit_config = true;
3065   int flag_send_cmabypass_config = true;
3066   int flag_send_mfc_rf_setting_config = true;
3067   uint8_t retry_cnt = 0;
3068   int enable_bit = 0;
3069 
3070   static uint8_t get_rf_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x85};
3071   NXPLOG_NCIHAL_D("phNxpNciHal_china_tianjin_rf_setting - Enter");
3072 
3073 retry_send_ext:
3074   if (retry_cnt > 3) {
3075     return NFCSTATUS_FAILED;
3076   }
3077 
3078   phNxpNciRfSet.isGetRfSetting = true;
3079   status = phNxpNciHal_send_ext_cmd(sizeof(get_rf_cmd), get_rf_cmd);
3080   if (status != NFCSTATUS_SUCCESS) {
3081     NXPLOG_NCIHAL_E("unable to get the RF setting");
3082     phNxpNciRfSet.isGetRfSetting = false;
3083     retry_cnt++;
3084     goto retry_send_ext;
3085   }
3086   phNxpNciRfSet.isGetRfSetting = false;
3087   if (phNxpNciRfSet.p_rx_data[3] != 0x00) {
3088     NXPLOG_NCIHAL_E("GET_CONFIG_RSP is FAILED for CHINA TIANJIN");
3089     return status;
3090   }
3091 
3092   /* check if tianjin_rf_setting is required */
3093   rf_val = phNxpNciRfSet.p_rx_data[10];
3094   isfound = (GetNxpNumValue(NAME_NXP_CHINA_TIANJIN_RF_ENABLED,
3095                             (void*)&config_value, sizeof(config_value)));
3096   if (isfound > 0) {
3097     enable_bit = rf_val & 0x40;
3098     if (nfcFL.nfccFL._NFCC_MIFARE_TIANJIN) {
3099       if ((enable_bit != 0x40) && (config_value == 1)) {
3100         phNxpNciRfSet.p_rx_data[10] |= 0x40;  // Enable if it is disabled
3101       } else if ((enable_bit == 0x40) && (config_value == 0)) {
3102         phNxpNciRfSet.p_rx_data[10] &= 0xBF;  // Disable if it is Enabled
3103       } else {
3104         flag_send_tianjin_config = false;  // No need to change in RF setting
3105       }
3106     } else {
3107       enable_bit = phNxpNciRfSet.p_rx_data[11] & 0x10;
3108       if ((config_value == 1) && (enable_bit != 0x10)) {
3109         NXPLOG_NCIHAL_E("Setting Non-Mifare reader for china tianjin");
3110         phNxpNciRfSet.p_rx_data[11] |= 0x10;
3111       } else if ((config_value == 0) && (enable_bit == 0x10)) {
3112         NXPLOG_NCIHAL_E("Setting Non-Mifare reader for china tianjin");
3113         phNxpNciRfSet.p_rx_data[11] &= 0xEF;
3114       } else {
3115         flag_send_tianjin_config = false;
3116       }
3117     }
3118   } else {
3119     flag_send_tianjin_config = false;
3120   }
3121 
3122   config_value = 0;
3123   /*check MFC NACK settings*/
3124   rf_val = phNxpNciRfSet.p_rx_data[9];
3125   isfound = (GetNxpNumValue(NAME_NXP_MIFARE_NACK_TO_RATS_ENABLE,
3126                             (void*)&config_value, sizeof(config_value)));
3127   if (isfound > 0) {
3128     enable_bit = rf_val & 0x20;
3129     if ((enable_bit != 0x20) && (config_value == 1)) {
3130       phNxpNciRfSet.p_rx_data[9] |= 0x20;  // Enable if it is disabled
3131     } else if ((enable_bit == 0x20) && (config_value == 0)) {
3132       phNxpNciRfSet.p_rx_data[9] &= ~0x20;  // Disable if it is Enabled
3133     } else {
3134       flag_send_mfc_rf_setting_config =
3135           false;  // No need to change in RF setting
3136     }
3137   } else {
3138     flag_send_mfc_rf_setting_config = FALSE;  // No need to change in RF setting
3139   }
3140 
3141   config_value = 0;
3142   /*check if china block number check is required*/
3143   rf_val = phNxpNciRfSet.p_rx_data[8];
3144   isfound = (GetNxpNumValue(NAME_NXP_CHINA_BLK_NUM_CHK_ENABLE,
3145                             (void*)&config_value, sizeof(config_value)));
3146   if (isfound > 0) {
3147     enable_bit = rf_val & 0x40;
3148     if ((enable_bit != 0x40) && (config_value == 1)) {
3149       phNxpNciRfSet.p_rx_data[8] |= 0x40;  // Enable if it is disabled
3150     } else if ((enable_bit == 0x40) && (config_value == 0)) {
3151       phNxpNciRfSet.p_rx_data[8] &= ~0x40;  // Disable if it is Enabled
3152     } else {
3153       flag_send_transit_config = false;  // No need to change in RF setting
3154     }
3155   } else {
3156     flag_send_transit_config = FALSE;  // No need to change in RF setting
3157   }
3158 
3159   config_value = 0;
3160   isfound = (GetNxpNumValue(NAME_NXP_CN_TRANSIT_CMA_BYPASSMODE_ENABLE,
3161                             (void*)&config_value, sizeof(config_value)));
3162   if (isfound > 0) {
3163     if (config_value == 0 && ((phNxpNciRfSet.p_rx_data[10] & 0x80) == 0x80)) {
3164       NXPLOG_NCIHAL_D("Disable CMA_BYPASSMODE Supports EMVCo PICC Complaincy");
3165       phNxpNciRfSet.p_rx_data[10] &=
3166           ~0x80;  // set 24th bit of RF MISC SETTING to 0 for EMVCo PICC
3167                   // Complaincy support
3168     } else if (config_value == 1 &&
3169                ((phNxpNciRfSet.p_rx_data[10] & 0x80) == 0)) {
3170       NXPLOG_NCIHAL_D(
3171           "Enable CMA_BYPASSMODE bypass the ISO14443-3A state machine from "
3172           "READY to ACTIVE and backward compatibility with MIfrae Reader ");
3173       phNxpNciRfSet.p_rx_data[10] |=
3174           0x80;  // set 24th bit of RF MISC SETTING to 1 for backward
3175                  // compatibility with MIfrae Reader
3176     } else {
3177       flag_send_cmabypass_config = FALSE;  // No need to change in RF setting
3178     }
3179   } else {
3180     flag_send_cmabypass_config = FALSE;
3181   }
3182 
3183   if (flag_send_tianjin_config || flag_send_transit_config ||
3184       flag_send_cmabypass_config || flag_send_mfc_rf_setting_config) {
3185     static uint8_t set_rf_cmd[] = {0x20, 0x02, 0x08, 0x01, 0xA0, 0x85,
3186                                    0x04, 0x50, 0x08, 0x68, 0x00};
3187     memcpy(&set_rf_cmd[4], &phNxpNciRfSet.p_rx_data[5], 7);
3188     status = phNxpNciHal_send_ext_cmd(sizeof(set_rf_cmd), set_rf_cmd);
3189     if (status != NFCSTATUS_SUCCESS) {
3190       NXPLOG_NCIHAL_E("unable to set the RF setting");
3191       retry_cnt++;
3192       goto retry_send_ext;
3193     }
3194   }
3195 
3196   return status;
3197 }
3198 
3199 /******************************************************************************
3200  * Function         phNxpNciHal_CheckAndHandleFwTearDown
3201  *
3202  * Description      Check Whether chip is in FW download mode, If chip is in
3203  *                  Download mode and previous session is not complete, then
3204  *                  Do force FW update.
3205  *
3206  * Returns          Status
3207  *
3208  ******************************************************************************/
phNxpNciHal_CheckAndHandleFwTearDown()3209 void phNxpNciHal_CheckAndHandleFwTearDown() {
3210   NFCSTATUS status = NFCSTATUS_FAILED;
3211   uint8_t session_state = -1;
3212   unsigned long minimal_fw_version = DEFAULT_MINIMAL_FW_VERSION;
3213   status = phNxpNciHal_getChipInfoInFwDnldMode();
3214   if (status != NFCSTATUS_SUCCESS) {
3215     NXPLOG_NCIHAL_E("Get Chip Info Failed");
3216     usleep(150 * 1000);
3217     return;
3218   }
3219   if (!GetNxpNumValue(NAME_NXP_MINIMAL_FW_VERSION, &minimal_fw_version,
3220                       sizeof(minimal_fw_version))) {
3221     /* If config file doesn't contain the info use default */
3222     minimal_fw_version = DEFAULT_MINIMAL_FW_VERSION;
3223   }
3224   if (wFwVerRsp != minimal_fw_version) {
3225     session_state = phNxpNciHal_getSessionInfoInFwDnldMode();
3226     if (session_state == 0) {
3227       NXPLOG_NCIHAL_E("NFC not in the teared state, boot NFCC in NCI mode");
3228       return;
3229     }
3230   }
3231   phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
3232   if (wFwVerRsp == minimal_fw_version) {
3233     /* since minimal fw required dlreset
3234      * to boot in Download mode */
3235     status = phNxpNciHal_dlResetInFwDnldMode();
3236     if (status != NFCSTATUS_SUCCESS) {
3237       NXPLOG_NCIHAL_E("DL Reset failed for minimal fw");
3238     }
3239   }
3240   phTmlNfc_EnableFwDnldMode(true);
3241   nxpncihal_ctrl.fwdnld_mode_reqd = TRUE;
3242 
3243   /* Set the obtained device handle to download module */
3244   phDnldNfc_SetHwDevHandle();
3245   NXPLOG_NCIHAL_D("Calling Seq handler for FW Download \n");
3246   status = phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal,
3247                                        nxpprofile_ctrl.bClkFreqVal);
3248   if (status != NFCSTATUS_SUCCESS) {
3249     NXPLOG_NCIHAL_E("FW Download Sequence Handler Failed.");
3250   } else {
3251     property_set("nfc.fw.force_download", "0");
3252     fw_download_success = 1;
3253   }
3254 
3255   status = phNxpNciHal_dlResetInFwDnldMode();
3256   if (status != NFCSTATUS_SUCCESS) {
3257     NXPLOG_NCIHAL_E("DL Reset failed in FW DN mode");
3258   }
3259 }
3260 
3261 /******************************************************************************
3262  * Function         phNxpNciHal_getChipInfoInFwDnldMode
3263  *
3264  * Description      Helper function to get the chip info in download mode
3265  *
3266  * Returns          Status
3267  *
3268  ******************************************************************************/
phNxpNciHal_getChipInfoInFwDnldMode(bool bIsVenResetReqd)3269 NFCSTATUS phNxpNciHal_getChipInfoInFwDnldMode(bool bIsVenResetReqd) {
3270   uint8_t get_chip_info_cmd[] = {0x00, 0x04, 0xF1, 0x00,
3271                                  0x00, 0x00, 0x6E, 0xEF};
3272   NFCSTATUS status = NFCSTATUS_FAILED;
3273   int retry_cnt = 0;
3274   if (bIsVenResetReqd) {
3275     status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadModeWithVenRst);
3276     if (status != NFCSTATUS_SUCCESS) {
3277       NXPLOG_NCIHAL_E("Enable Download mode failed");
3278       return status;
3279     }
3280   }
3281   phTmlNfc_EnableFwDnldMode(true);
3282   nxpncihal_ctrl.fwdnld_mode_reqd = TRUE;
3283   do {
3284     status =
3285         phNxpNciHal_send_ext_cmd(sizeof(get_chip_info_cmd), get_chip_info_cmd);
3286     if (status != NFCSTATUS_SUCCESS) {
3287       /* break the loop if HAL write failed or response Timeout */
3288       break;
3289     } else {
3290       /* Check FW getResponse command response status byte */
3291       if (nxpncihal_ctrl.p_rx_data[0] == 0x00) {
3292         if (nxpncihal_ctrl.p_rx_data[2] != 0x00) {
3293           status = NFCSTATUS_FAILED;
3294           if (retry_cnt < MAX_RETRY_COUNT) {
3295             retry_cnt++;
3296             /*reset NFCC state to avoid any failures
3297              *such as DL_PROTOCOL_ERROR
3298              */
3299             status = phNxpNciHal_dlResetInFwDnldMode();
3300             if (status != NFCSTATUS_SUCCESS) {
3301               NXPLOG_NCIHAL_E("DL Reset failed in FW DN mode");
3302             }
3303           }
3304         }
3305       } else {
3306         status = NFCSTATUS_FAILED;
3307         break;
3308       }
3309     }
3310   } while ((status != NFCSTATUS_SUCCESS) && (retry_cnt < MAX_RETRY_COUNT));
3311 
3312   nxpncihal_ctrl.fwdnld_mode_reqd = FALSE;
3313   phTmlNfc_EnableFwDnldMode(false);
3314   if (phNxpNciHal_enableTmlRead() != NFCSTATUS_PENDING) {
3315     NXPLOG_NCIHAL_E("%s read status error status", __FUNCTION__);
3316   }
3317   if (status == NFCSTATUS_SUCCESS) {
3318     phNxpNciHal_configFeatureList(nxpncihal_ctrl.p_rx_data,
3319                                   nxpncihal_ctrl.rx_data_len);
3320     setNxpFwConfigPath();
3321   }
3322   return status;
3323 }
3324 
3325 /******************************************************************************
3326  * Function         phNxpNciHal_getSessionInfoInFwDnldMode
3327  *
3328  * Description      Helper function to get the session info in download mode
3329  *
3330  * Returns          0 means session closed
3331  *
3332  ******************************************************************************/
phNxpNciHal_getSessionInfoInFwDnldMode()3333 uint8_t phNxpNciHal_getSessionInfoInFwDnldMode() {
3334   uint8_t session_status = -1;
3335   uint8_t get_session_info_cmd[] = {0x00, 0x04, 0xF2, 0x00,
3336                                     0x00, 0x00, 0xF5, 0x33};
3337   phTmlNfc_EnableFwDnldMode(true);
3338   nxpncihal_ctrl.fwdnld_mode_reqd = TRUE;
3339   NFCSTATUS status = phNxpNciHal_send_ext_cmd(sizeof(get_session_info_cmd),
3340                                               get_session_info_cmd);
3341   if (status == NFCSTATUS_SUCCESS) {
3342     /* Check FW getResponse command response status byte */
3343     if (nxpncihal_ctrl.p_rx_data[2] == 0x00 &&
3344         nxpncihal_ctrl.p_rx_data[0] == 0x00) {
3345       if (nxpncihal_ctrl.p_rx_data[3] == 0x00) {
3346         session_status = 0;
3347       }
3348     } else {
3349       NXPLOG_NCIHAL_D("get session info Failed !!!");
3350       usleep(150 * 1000);
3351     }
3352   }
3353   status = phNxpNciHal_dlResetInFwDnldMode();
3354   if (status != NFCSTATUS_SUCCESS) {
3355     NXPLOG_NCIHAL_E("DL Reset failed in FW DN mode");
3356   }
3357   return session_status;
3358 }
3359 
3360 /******************************************************************************
3361  * Function         phNxpNciHal_dlResetInFwDnldMode
3362  *
3363  * Description      Helper function to change the mode from FW to NCI
3364  *
3365  * Returns          Status
3366  *
3367  ******************************************************************************/
phNxpNciHal_dlResetInFwDnldMode()3368 NFCSTATUS phNxpNciHal_dlResetInFwDnldMode() {
3369   NFCSTATUS status = NFCSTATUS_FAILED;
3370   phTmlNfc_EnableFwDnldMode(true);
3371   nxpncihal_ctrl.fwdnld_mode_reqd = TRUE;
3372   NXPLOG_NCIHAL_D("Sending DL Reset for NFCC soft reboot");
3373   phDnldNfc_SetHwDevHandle();
3374 
3375   if (nfcFL.chipType >= sn100u) {
3376     phDnldNfc_SetI2CFragmentLength(NCI_CMDRESP_MAX_BUFF_SIZE_SNXXX);
3377   } else {
3378     phDnldNfc_SetI2CFragmentLength(NCI_CMDRESP_MAX_BUFF_SIZE_PN557);
3379   }
3380 
3381   status = phNxpNciHal_fw_dnld_switch_normal_mode();
3382 
3383   nxpncihal_ctrl.fwdnld_mode_reqd = FALSE;
3384   phTmlNfc_EnableFwDnldMode(false);
3385   phDnldNfc_ReSetHwDevHandle();
3386   if (phNxpNciHal_enableTmlRead() != NFCSTATUS_PENDING) {
3387     NXPLOG_NCIHAL_E("%s read status error status", __FUNCTION__);
3388     status = NFCSTATUS_FAILED;
3389   }
3390   return status;
3391 }
3392 
3393 /******************************************************************************
3394  * Function         phNxpNciHal_gpio_restore
3395  *
3396  * Description      This function restores the gpio values into eeprom
3397  *
3398  * Returns          void
3399  *
3400  ******************************************************************************/
phNxpNciHal_gpio_restore(phNxpNciHal_GpioInfoState state)3401 static void phNxpNciHal_gpio_restore(phNxpNciHal_GpioInfoState state) {
3402   NFCSTATUS status = NFCSTATUS_SUCCESS;
3403   uint8_t get_gpio_values_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x00};
3404   uint8_t set_gpio_values_cmd[] = {
3405       0x20, 0x02, 0x00, 0x01, 0xA0, 0x00, 0x20, 0x00, 0x00, 0x00,
3406       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3407       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3408       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3409 
3410   if (state == GPIO_STORE) {
3411     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_STORE;
3412     get_gpio_values_cmd[5] = 0x08;
3413     status = phNxpNciHal_send_ext_cmd(sizeof(get_gpio_values_cmd),
3414                                       get_gpio_values_cmd);
3415     if (status != NFCSTATUS_SUCCESS) {
3416       NXPLOG_NCIHAL_E("Failed to get GPIO values!!!\n");
3417       return;
3418     }
3419 
3420     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_STORE_DONE;
3421     set_gpio_values_cmd[2] = 0x24;
3422     set_gpio_values_cmd[5] = 0x14;
3423     set_gpio_values_cmd[7] = nxpncihal_ctrl.phNxpNciGpioInfo.values[0];
3424     set_gpio_values_cmd[8] = nxpncihal_ctrl.phNxpNciGpioInfo.values[1];
3425     status = phNxpNciHal_send_ext_cmd(sizeof(set_gpio_values_cmd),
3426                                       set_gpio_values_cmd);
3427     if (status != NFCSTATUS_SUCCESS) {
3428       NXPLOG_NCIHAL_E("Failed to set GPIO values!!!\n");
3429       return;
3430     }
3431   } else if (state == GPIO_RESTORE) {
3432     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_RESTORE;
3433     get_gpio_values_cmd[5] = 0x14;
3434     status = phNxpNciHal_send_ext_cmd(sizeof(get_gpio_values_cmd),
3435                                       get_gpio_values_cmd);
3436     if (status != NFCSTATUS_SUCCESS) {
3437       NXPLOG_NCIHAL_E("Failed to get GPIO values!!!\n");
3438       return;
3439     }
3440 
3441     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_RESTORE_DONE;
3442     set_gpio_values_cmd[2] = 0x06;
3443     set_gpio_values_cmd[5] = 0x08;  // update TAG
3444     set_gpio_values_cmd[6] = 0x02;  // update length
3445     set_gpio_values_cmd[7] = nxpncihal_ctrl.phNxpNciGpioInfo.values[0];
3446     set_gpio_values_cmd[8] = nxpncihal_ctrl.phNxpNciGpioInfo.values[1];
3447     status = phNxpNciHal_send_ext_cmd(9, set_gpio_values_cmd);
3448     if (status != NFCSTATUS_SUCCESS) {
3449       NXPLOG_NCIHAL_E("Failed to set GPIO values!!!\n");
3450       return;
3451     }
3452   } else {
3453     NXPLOG_NCIHAL_E("GPIO Restore Invalid Option!!!\n");
3454   }
3455 }
3456 
3457 /******************************************************************************
3458  * Function         phNxpNciHal_nfcc_core_reset_init
3459  *
3460  * Description      Helper function to do nfcc core reset & core init
3461  *
3462  * Returns          Status
3463  *
3464  ******************************************************************************/
phNxpNciHal_nfcc_core_reset_init(bool keep_config)3465 NFCSTATUS phNxpNciHal_nfcc_core_reset_init(bool keep_config) {
3466   NFCSTATUS status = NFCSTATUS_FAILED;
3467   uint8_t retry_cnt = 0;
3468   uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x01};
3469 
3470   if (keep_config) {
3471     cmd_reset_nci[3] = 0x00;
3472   }
3473 retry_core_reset:
3474   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
3475   if ((status != NFCSTATUS_SUCCESS) && (retry_cnt < 3)) {
3476     NXPLOG_NCIHAL_D("Retry: NCI_CORE_RESET");
3477     retry_cnt++;
3478     goto retry_core_reset;
3479   } else if (status != NFCSTATUS_SUCCESS) {
3480     NXPLOG_NCIHAL_E("NCI_CORE_RESET failed!!!\n");
3481     return status;
3482   }
3483 
3484   retry_cnt = 0;
3485   uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
3486   uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
3487 retry_core_init:
3488   if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
3489     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
3490   } else {
3491     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
3492   }
3493 
3494   if ((status != NFCSTATUS_SUCCESS) && (retry_cnt < 3)) {
3495     NXPLOG_NCIHAL_D("Retry: NCI_CORE_INIT\n");
3496     retry_cnt++;
3497     goto retry_core_init;
3498   } else if (status != NFCSTATUS_SUCCESS) {
3499     NXPLOG_NCIHAL_E("NCI_CORE_INIT failed!!!\n");
3500     return status;
3501   }
3502 
3503   return status;
3504 }
3505 
3506 /******************************************************************************
3507  * Function         phNxpNciHal_resetDefaultSettings
3508  *
3509  * Description      Helper function to do nfcc core reset, core init
3510  *                  (if previously firmware update was triggered) and
3511  *                  apply default NFC settings
3512  *
3513  * Returns          Status
3514  *
3515  ******************************************************************************/
phNxpNciHal_resetDefaultSettings(uint8_t fw_update_req,bool keep_config)3516 NFCSTATUS phNxpNciHal_resetDefaultSettings(uint8_t fw_update_req,
3517                                            bool keep_config) {
3518   NFCSTATUS status = NFCSTATUS_SUCCESS;
3519   if (fw_update_req) {
3520     status = phNxpNciHal_nfcc_core_reset_init(keep_config);
3521   }
3522   if (status == NFCSTATUS_SUCCESS) {
3523     unsigned long num = 0;
3524     int ret = 0;
3525     phNxpNciHal_conf_nfc_forum_mode();
3526     if (nfcFL.chipType >= sn100u) {
3527       ret = GetNxpNumValue(NAME_NXP_RDR_DISABLE_ENABLE_LPCD, &num, sizeof(num));
3528       if (!ret || num == 1 || num == 2) {
3529         phNxpNciHal_prop_conf_lpcd(true);
3530       } else if (ret && num == 0) {
3531         phNxpNciHal_prop_conf_lpcd(false);
3532       }
3533     }
3534   }
3535   return status;
3536 }
3537 
phNxpNciHal_check_config_parameter()3538 int phNxpNciHal_check_config_parameter() {
3539   uint8_t param_clock_src = CLK_SRC_PLL;
3540   if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) {
3541     if ((nfcFL.chipType != pn553) && (nfcFL.chipType != pn557)) {
3542       param_clock_src = param_clock_src << 3;
3543     }
3544     if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) {
3545       param_clock_src |= 0x00;
3546     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) {
3547       param_clock_src |= 0x01;
3548     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) {
3549       param_clock_src |= 0x02;
3550     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) {
3551       param_clock_src |= 0x03;
3552     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) {
3553       param_clock_src |= 0x04;
3554     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) {
3555       param_clock_src |= 0x05;
3556     } else {
3557       NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
3558       param_clock_src = 0x11;
3559     }
3560   } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) {
3561     param_clock_src = 0x08;
3562 
3563   } else {
3564     NXPLOG_NCIHAL_E("Wrong clock source. Don't apply any modification");
3565   }
3566   return param_clock_src;
3567 }
3568 /******************************************************************************
3569  * Function         phNxpNciHal_enable_i2c_fragmentation
3570  *
3571  * Description      This function is called to process the response status
3572  *                  and print the status byte.
3573  *
3574  * Returns          void.
3575  *
3576  ******************************************************************************/
phNxpNciHal_enable_i2c_fragmentation()3577 void phNxpNciHal_enable_i2c_fragmentation() {
3578   NFCSTATUS status = NFCSTATUS_FAILED;
3579   static uint8_t fragmentation_enable_config_cmd[] = {0x20, 0x02, 0x05, 0x01,
3580                                                       0xA0, 0x05, 0x01, 0x10};
3581   long i2c_status = 0x00;
3582   long config_i2c_vlaue = 0xff;
3583   /*NCI_RESET_CMD*/
3584   static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
3585   /*NCI_INIT_CMD*/
3586   static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
3587   static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
3588   static uint8_t get_i2c_fragmentation_cmd[] = {0x20, 0x03, 0x03,
3589                                                 0x01, 0xA0, 0x05};
3590   if (GetNxpNumValue(NAME_NXP_I2C_FRAGMENTATION_ENABLED, (void*)&i2c_status,
3591                      sizeof(i2c_status)) == true) {
3592     NXPLOG_FWDNLD_D("I2C status : %ld", i2c_status);
3593   } else {
3594     NXPLOG_FWDNLD_E("I2C status read not succeeded. Default value : %ld",
3595                     i2c_status);
3596   }
3597   status = phNxpNciHal_send_ext_cmd(sizeof(get_i2c_fragmentation_cmd),
3598                                     get_i2c_fragmentation_cmd);
3599   if (status != NFCSTATUS_SUCCESS) {
3600     NXPLOG_NCIHAL_E("unable to retrieve  get_i2c_fragmentation_cmd");
3601   } else {
3602     if (nxpncihal_ctrl.p_rx_data[8] == 0x10) {
3603       config_i2c_vlaue = 0x01;
3604       phNxpNciHal_notify_i2c_fragmentation();
3605       phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
3606     } else if (nxpncihal_ctrl.p_rx_data[8] == 0x00) {
3607       config_i2c_vlaue = 0x00;
3608     }
3609     // if the value already matches, nothing to be done
3610     if (config_i2c_vlaue != i2c_status) {
3611       if (i2c_status == 0x01) {
3612         /* NXP I2C fragmenation enabled*/
3613         status =
3614             phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd),
3615                                      fragmentation_enable_config_cmd);
3616         if (status != NFCSTATUS_SUCCESS) {
3617           NXPLOG_NCIHAL_E("NXP fragmentation enable failed");
3618         }
3619       } else if (i2c_status == 0x00 || config_i2c_vlaue == 0xff) {
3620         fragmentation_enable_config_cmd[7] = 0x00;
3621         /* NXP I2C fragmentation disabled*/
3622         status =
3623             phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd),
3624                                      fragmentation_enable_config_cmd);
3625         if (status != NFCSTATUS_SUCCESS) {
3626           NXPLOG_NCIHAL_E("NXP fragmentation disable failed");
3627         }
3628       }
3629       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
3630       if (status != NFCSTATUS_SUCCESS) {
3631         NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
3632       }
3633       if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
3634         status =
3635             phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
3636       } else {
3637         status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
3638       }
3639       if (status != NFCSTATUS_SUCCESS) {
3640         NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
3641       } else if (i2c_status == 0x01) {
3642         phNxpNciHal_notify_i2c_fragmentation();
3643         phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
3644       }
3645     }
3646   }
3647 }
3648 /******************************************************************************
3649  * Function         phNxpNciHal_do_se_session_reset
3650  *
3651  * Description      This function is called to set the session id to default
3652  *                  value.
3653  *
3654  * Returns          NFCSTATUS.
3655  *
3656  ******************************************************************************/
phNxpNciHal_do_swp_session_reset(void)3657 static NFCSTATUS phNxpNciHal_do_swp_session_reset(void) {
3658   NFCSTATUS status = NFCSTATUS_FAILED;
3659   static uint8_t reset_swp_session_identity_set[] = {
3660       0x20, 0x02, 0x17, 0x02, 0xA0, 0xEA, 0x08, 0xFF, 0xFF,
3661       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x1E, 0x08,
3662       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
3663   status = phNxpNciHal_send_ext_cmd(sizeof(reset_swp_session_identity_set),
3664                                     reset_swp_session_identity_set);
3665   if (status != NFCSTATUS_SUCCESS) {
3666     NXPLOG_NCIHAL_E("NXP reset_ese_session_identity_set command failed");
3667   }
3668   return status;
3669 }
3670 /******************************************************************************
3671  * Function         phNxpNciHal_do_factory_reset
3672  *
3673  * Description      This function is called during factory reset to clear/reset
3674  *                  nfc sub-system persistent data.
3675  *
3676  * Returns          void.
3677  *
3678  ******************************************************************************/
phNxpNciHal_do_factory_reset(void)3679 void phNxpNciHal_do_factory_reset(void) {
3680   NFCSTATUS status = NFCSTATUS_FAILED;
3681   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
3682     status = phNxpNciHal_MinOpen();
3683     if (status != NFCSTATUS_SUCCESS) {
3684       NXPLOG_NCIHAL_E("%s: NXP Nfc Open failed", __func__);
3685       return;
3686     }
3687     phNxpNciHal_deinitializeRegRfFwDnld();
3688   }
3689   status = phNxpNciHal_do_swp_session_reset();
3690   if (status != NFCSTATUS_SUCCESS) {
3691     NXPLOG_NCIHAL_E("%s failed. status = %x ", __func__, status);
3692   }
3693 }
3694 /******************************************************************************
3695  * Function         phNxpNciHal_hci_network_reset
3696  *
3697  * Description      This function resets the session id's of all the se's
3698  *                  in the HCI network and notify to HCI_NETWORK_RESET event to
3699  *                  NFC HAL Client.
3700  *
3701  * Returns          void.
3702  *
3703  ******************************************************************************/
phNxpNciHal_hci_network_reset(void)3704 static void phNxpNciHal_hci_network_reset(void) {
3705   static phLibNfc_Message_t msg;
3706   msg.pMsgData = NULL;
3707   msg.Size = 0;
3708 
3709   NFCSTATUS status = phNxpNciHal_do_swp_session_reset();
3710 
3711   if (status != NFCSTATUS_SUCCESS) {
3712     msg.eMsgType = NCI_HAL_ERROR_MSG;
3713   } else {
3714     msg.eMsgType = NCI_HAL_HCI_NETWORK_RESET_MSG;
3715   }
3716   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
3717 }
3718 /******************************************************************************
3719  * Function         phNxpNciHal_print_res_status
3720  *
3721  * Description      This function is called to process the response status
3722  *                  and print the status byte.
3723  *
3724  * Returns          void.
3725  *
3726  ******************************************************************************/
phNxpNciHal_print_res_status(uint8_t * p_rx_data,uint16_t * p_len)3727 static void phNxpNciHal_print_res_status(uint8_t* p_rx_data, uint16_t* p_len) {
3728   static uint8_t response_buf[][30] = {"STATUS_OK",
3729                                        "STATUS_REJECTED",
3730                                        "STATUS_RF_FRAME_CORRUPTED",
3731                                        "STATUS_FAILED",
3732                                        "STATUS_NOT_INITIALIZED",
3733                                        "STATUS_SYNTAX_ERROR",
3734                                        "STATUS_SEMANTIC_ERROR",
3735                                        "RFU",
3736                                        "RFU",
3737                                        "STATUS_INVALID_PARAM",
3738                                        "STATUS_MESSAGE_SIZE_EXCEEDED",
3739                                        "STATUS_UNDEFINED"};
3740   int status_byte;
3741   if (p_rx_data[0] == 0x40 && (p_rx_data[1] == 0x02 || p_rx_data[1] == 0x03)) {
3742     if (p_rx_data[2] && p_rx_data[3] <= 10) {
3743       status_byte = p_rx_data[CORE_RES_STATUS_BYTE];
3744       NXPLOG_NCIHAL_D("%s: response status =%s", __func__,
3745                       response_buf[status_byte]);
3746     } else {
3747       NXPLOG_NCIHAL_D("%s: response status =%s", __func__, response_buf[11]);
3748     }
3749     if (phNxpNciClock.isClockSet) {
3750       int i, len = sizeof(phNxpNciClock.p_rx_data);
3751       if (*p_len > len) {
3752         android_errorWriteLog(0x534e4554, "169257710");
3753       } else {
3754         len = *p_len;
3755       }
3756       for (i = 0; i < len; i++) {
3757         phNxpNciClock.p_rx_data[i] = p_rx_data[i];
3758       }
3759     }
3760 
3761     else if (phNxpNciRfSet.isGetRfSetting) {
3762       int i, len = sizeof(phNxpNciRfSet.p_rx_data);
3763       if (*p_len > len) {
3764         android_errorWriteLog(0x534e4554, "169258733");
3765       } else {
3766         len = *p_len;
3767       }
3768       for (i = 0; i < len; i++) {
3769         phNxpNciRfSet.p_rx_data[i] = p_rx_data[i];
3770         // NXPLOG_NCIHAL_D("%s: response status =0x%x",__func__,p_rx_data[i]);
3771       }
3772     } else if (phNxpNciMwEepromArea.isGetEepromArea) {
3773       int i, len = sizeof(phNxpNciMwEepromArea.p_rx_data) + 8;
3774       if (*p_len > len) {
3775         android_errorWriteLog(0x534e4554, "169258884");
3776       } else {
3777         len = *p_len;
3778       }
3779       for (i = 8; i < len; i++) {
3780         phNxpNciMwEepromArea.p_rx_data[i - 8] = p_rx_data[i];
3781       }
3782     } else if (nxpncihal_ctrl.phNxpNciGpioInfo.state == GPIO_STORE) {
3783       NXPLOG_NCIHAL_D("%s: Storing GPIO Values...", __func__);
3784       nxpncihal_ctrl.phNxpNciGpioInfo.values[0] = p_rx_data[9];
3785       nxpncihal_ctrl.phNxpNciGpioInfo.values[1] = p_rx_data[8];
3786     } else if (nxpncihal_ctrl.phNxpNciGpioInfo.state == GPIO_RESTORE) {
3787       NXPLOG_NCIHAL_D("%s: Restoring GPIO Values...", __func__);
3788       nxpncihal_ctrl.phNxpNciGpioInfo.values[0] = p_rx_data[9];
3789       nxpncihal_ctrl.phNxpNciGpioInfo.values[1] = p_rx_data[8];
3790     }
3791   }
3792 
3793   if (p_rx_data[2] && (config_access == true)) {
3794     if (p_rx_data[3] != NFCSTATUS_SUCCESS) {
3795       NXPLOG_NCIHAL_W("Invalid Data from config file.");
3796       config_success = false;
3797     }
3798   }
3799 }
3800 /******************************************************************************
3801  * Function         phNxpNciHal_initialize_mifare_flag
3802  *
3803  * Description      This function gets the value for Mfc flags.
3804  *
3805  * Returns          void
3806  *
3807  ******************************************************************************/
phNxpNciHal_initialize_mifare_flag()3808 static void phNxpNciHal_initialize_mifare_flag() {
3809   unsigned long num = 0;
3810   bEnableMfcReader = false;
3811   bDisableLegacyMfcExtns = true;
3812   // 1: Enable Mifare Classic protocol in RF Discovery.
3813   // 0: Remove Mifare Classic protocol in RF Discovery.
3814   if (GetNxpNumValue(NAME_MIFARE_READER_ENABLE, &num, sizeof(num))) {
3815     bEnableMfcReader = (num == 0) ? false : true;
3816   }
3817   // 1: Use legacy JNI MFC extns.
3818   // 0: Disable legacy JNI MFC extns, use hal MFC Extns instead.
3819   if (GetNxpNumValue(NAME_LEGACY_MIFARE_READER, &num, sizeof(num))) {
3820     bDisableLegacyMfcExtns = (num == 0) ? true : false;
3821   }
3822 }
3823 
3824 /*****************************************************************************
3825  * Function         phNxpNciHal_send_get_cfgs
3826  *
3827  * Description      This function is called to  send get configs
3828  *                  for all the types in get_cfg_arr.
3829  *                  Response of getConfigs(EEPROM stored) will be
3830  *                  compared with request coming from MW during discovery.
3831  *                  If same, then current setConfigs will be dropped
3832  *
3833  * Returns          Returns NFCSTATUS_SUCCESS if sending cmd is successful and
3834  *                  response is received.
3835  *
3836  *****************************************************************************/
phNxpNciHal_send_get_cfgs()3837 NFCSTATUS phNxpNciHal_send_get_cfgs() {
3838   NXPLOG_NCIHAL_D("%s Enter", __func__);
3839   NFCSTATUS status = NFCSTATUS_FAILED;
3840   uint8_t num_cfgs = sizeof(get_cfg_arr) / sizeof(uint8_t);
3841   uint8_t cfg_count = 0, retry_cnt = 0;
3842   if (mGetCfg_info != NULL) {
3843     mGetCfg_info->isGetcfg = true;
3844   }
3845   uint8_t cmd_get_cfg[] = {0x20, 0x03, 0x02, 0x01, 0x00};
3846 
3847   while (cfg_count < num_cfgs) {
3848     cmd_get_cfg[sizeof(cmd_get_cfg) - 1] = get_cfg_arr[cfg_count];
3849 
3850   retry_get_cfg:
3851     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_get_cfg), cmd_get_cfg);
3852     if (status != NFCSTATUS_SUCCESS && retry_cnt < 3) {
3853       NXPLOG_NCIHAL_E("cmd_get_cfg failed");
3854       retry_cnt++;
3855       goto retry_get_cfg;
3856     }
3857     if (retry_cnt == 3) {
3858       break;
3859     }
3860     cfg_count++;
3861     retry_cnt = 0;
3862   }
3863   mGetCfg_info->isGetcfg = false;
3864   return status;
3865 }
3866 
3867 /*******************************************************************************
3868 **
3869 ** Function         phNxpNciHal_configFeatureList
3870 **
3871 ** Description      Configures the featureList based on chip type &
3872 **                  Configure fragmentation length based on chip type.
3873 **                  HW Version information number will provide chipType.
3874 **                  HW Version can be obtained from CORE_INIT_RESPONSE(NCI 1.0)
3875 **                  or CORE_RST_NTF(NCI 2.0)
3876 **
3877 ** Parameters       CORE_INIT_RESPONSE/CORE_RST_NTF, len
3878 **
3879 ** Returns          none
3880 *******************************************************************************/
phNxpNciHal_configFeatureList(uint8_t * init_rsp,uint16_t rsp_len)3881 void phNxpNciHal_configFeatureList(uint8_t* init_rsp, uint16_t rsp_len) {
3882   nxpncihal_ctrl.chipType = pConfigFL->processChipType(init_rsp, rsp_len);
3883   tNFC_chipType chipType = nxpncihal_ctrl.chipType;
3884   NXPLOG_NCIHAL_D("phNxpNciHal_configFeatureList ()chipType = %d", chipType);
3885   CONFIGURE_FEATURELIST(chipType);
3886   /* update fragment len based on the chip type.*/
3887   phTmlNfc_IoCtl(phTmlNfc_e_setFragmentSize);
3888 }
3889 
3890 /*******************************************************************************
3891 **
3892 ** Function         phNxpNciHal_UpdateFwStatus
3893 **
3894 ** Description      It shall be called to update the FW download status to the
3895 **                  libnfc-nci.
3896 **
3897 ** Parameters       fwStatus: FW update status
3898 **
3899 ** Returns          void
3900 *******************************************************************************/
phNxpNciHal_UpdateFwStatus(HalNfcFwUpdateStatus fwStatus)3901 static void phNxpNciHal_UpdateFwStatus(HalNfcFwUpdateStatus fwStatus) {
3902   static phLibNfc_Message_t msg;
3903   static uint8_t status;
3904   NXPLOG_NCIHAL_D("phNxpNciHal_UpdateFwStatus Enter");
3905 
3906   status = (uint8_t)fwStatus;
3907   msg.eMsgType = HAL_NFC_FW_UPDATE_STATUS_EVT;
3908   msg.pMsgData = &status;
3909   msg.Size = sizeof(status);
3910   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
3911                         (phLibNfc_Message_t*)&msg);
3912   return;
3913 }
3914 
3915 #if (NXP_EXTNS == TRUE)
3916 /*******************************************************************************
3917 **
3918 ** Function         phNxpNciHal_configNciParser(bool enable)
3919 **
3920 ** Description      Helper function to configure LxDebug modes
3921 **
3922 ** Parameters       none
3923 **
3924 ** Returns          void
3925 *******************************************************************************/
phNxpNciHal_configNciParser(bool enable)3926 void phNxpNciHal_configNciParser(bool enable) {
3927   NFCSTATUS status = NFCSTATUS_SUCCESS;
3928   unsigned long lx_debug_cfg = 0;
3929   uint8_t isfound = 0;
3930   static uint8_t cmd_lxdebug[] = {0x20, 0x02, 0x06, 0x01, 0xA0,
3931                                   0x1D, 0x02, 0x00, 0x00};
3932 
3933   isfound = GetNxpNumValue(NAME_NXP_CORE_PROP_SYSTEM_DEBUG, &lx_debug_cfg,
3934                            sizeof(lx_debug_cfg));
3935 
3936   if (isfound > 0 && enable == true) {
3937     if (lx_debug_cfg & LX_DEBUG_CFG_MASK_RFU) {
3938       NXPLOG_NCIHAL_E(
3939           "One or more RFU bits are enabled.\nMasking the RFU bits");
3940       lx_debug_cfg = lx_debug_cfg & ~LX_DEBUG_CFG_MASK_RFU;
3941     }
3942     if (lx_debug_cfg == LX_DEBUG_CFG_DISABLE) {
3943       NXPLOG_NCIHAL_D("Disable LxDebug");
3944     }
3945     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_L1_EVENT) {
3946       NXPLOG_NCIHAL_D("Enable L1 RF NTF debugs");
3947     }
3948     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_L2_EVENT) {
3949       NXPLOG_NCIHAL_D("Enable L2 RF NTF debugs (CE)");
3950     }
3951     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_FELICA_RF) {
3952       NXPLOG_NCIHAL_D("Enable all Felica CM events");
3953     }
3954     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_FELICA_SYSCODE) {
3955       NXPLOG_NCIHAL_D("Enable Felica System Code");
3956     }
3957     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_L2_EVENT_READER) {
3958       NXPLOG_NCIHAL_D("Enable L2 RF NTF debugs (Reader)");
3959     }
3960     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_MOD_DETECTED_EVENT) {
3961       NXPLOG_NCIHAL_D("Enable Modulation detected event");
3962     }
3963 
3964     cmd_lxdebug[7] = (uint8_t)lx_debug_cfg & LX_DEBUG_CFG_MASK;
3965   }
3966   status = phNxpNciHal_send_ext_cmd(
3967       sizeof(cmd_lxdebug) / sizeof(cmd_lxdebug[0]), cmd_lxdebug);
3968   if (status != NFCSTATUS_SUCCESS) {
3969     NXPLOG_NCIHAL_E("Set lxDebug config failed");
3970   }
3971   if (enable ==
3972       false) { /*We are here to disable the LX_DEBUG_CFG and parser library*/
3973     return;
3974   }
3975   /* try initializing parser library*/
3976   NXPLOG_NCIHAL_D("Try Init Parser gParserCreated:%d", gParserCreated);
3977 
3978   if (!gParserCreated) {
3979     gParserCreated = phNxpNciHal_initParser();
3980   } else {
3981     NXPLOG_NCIHAL_D("Parser Already Initialized");
3982   }
3983 
3984   if (gParserCreated) {
3985     NXPLOG_NCIHAL_D("Parser Initialized Successfully");
3986     if (isfound) {
3987       NXPLOG_NCIHAL_D("Setting lxdebug levels in library");
3988       phNxpNciHal_parsePacket(cmd_lxdebug,
3989                               sizeof(cmd_lxdebug) / sizeof(cmd_lxdebug[0]));
3990     }
3991   } else {
3992     NXPLOG_NCIHAL_E("Parser Library Not Available");
3993   }
3994 }
3995 
3996 /*******************************************************************************
3997 **
3998 ** Function         phNxpNciHal_initializeRegRfFwDnld(void)
3999 **
4000 ** Description      Loads the module & initializes function pointers for Region
4001 **                  based RF & FW update module
4002 **
4003 ** Parameters       none
4004 **
4005 ** Returns          void
4006 *******************************************************************************/
phNxpNciHal_initializeRegRfFwDnld()4007 void phNxpNciHal_initializeRegRfFwDnld() {
4008   // Getting pointer to RF & RF Region Code Download module
4009   RfFwRegionDnld_handle =
4010       dlopen("/system/vendor/lib64/libonebinary.so", RTLD_NOW);
4011   if (RfFwRegionDnld_handle == NULL) {
4012     NXPLOG_NCIHAL_D(
4013         "Error : opening (/system/vendor/lib64/libonebinary.so) !!");
4014     return;
4015   }
4016   if ((fpVerInfoStoreInEeprom = (fpVerInfoStoreInEeprom_t)dlsym(
4017            RfFwRegionDnld_handle, "read_version_info_and_store_in_eeprom")) ==
4018       NULL) {
4019     NXPLOG_NCIHAL_D(
4020         "Error while linking (read_version_info_and_store_in_eeprom) !!");
4021     return;
4022   }
4023   if ((fpRegRfFwDndl = (fpRegRfFwDndl_t)dlsym(RfFwRegionDnld_handle,
4024                                               "RegRfFwDndl")) == NULL) {
4025     NXPLOG_NCIHAL_D("Error while linking (RegRfFwDndl) !!");
4026     return;
4027   }
4028   if ((fpPropConfCover = (fpPropConfCover_t)dlsym(RfFwRegionDnld_handle,
4029                                                   "prop_conf_cover")) == NULL) {
4030     NXPLOG_NCIHAL_D("Error while linking (prop_conf_cover) !!");
4031     return;
4032   }
4033 }
4034 
4035 /*******************************************************************************
4036 **
4037 ** Function         phNxpNciHal_deinitializeRegRfFwDnld(void)
4038 **
4039 ** Description      Resets the module handle & all the function pointers for
4040 **                  Region based RF & FW update module
4041 **
4042 ** Parameters       none
4043 **
4044 ** Returns          void
4045 *******************************************************************************/
phNxpNciHal_deinitializeRegRfFwDnld()4046 void phNxpNciHal_deinitializeRegRfFwDnld() {
4047   if (RfFwRegionDnld_handle != NULL) {
4048     NXPLOG_NCIHAL_D("closing libonebinary.so");
4049     fpVerInfoStoreInEeprom = NULL;
4050     fpRegRfFwDndl = NULL;
4051     fpPropConfCover = NULL;
4052     dlclose(RfFwRegionDnld_handle);
4053     RfFwRegionDnld_handle = NULL;
4054   }
4055 }
4056 
4057 #endif
4058