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