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