• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012-2025 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 (p_data[NCI_GID_INDEX] == NCI_RF_DISC_COMMD_GID &&
1154              p_data[NCI_OID_INDEX] == NCI_RF_DISC_COMMAND_OID) {
1155     NciDiscoveryCommandBuilderInstance.setDiscoveryCommand(data_len, p_data);
1156     if (isObserveModeEnabled()) {
1157       vector<uint8_t> v_data =
1158           NciDiscoveryCommandBuilderInstance.reConfigRFDiscCmd();
1159       return phNxpNciHal_write_internal(v_data.size(), v_data.data());
1160     } else {
1161       return phNxpNciHal_write_internal(data_len, p_data);
1162     }
1163   } else if (IS_HCI_PACKET(p_data)) {
1164     // Inform WiredSe service that HCI Pkt is sending from libnfc layer
1165     phNxpNciHal_WiredSeDispatchEvent(&gWiredSeHandle, SENDING_HCI_PKT);
1166   } else if (IS_NFCEE_DISABLE(p_data)) {
1167     // NFCEE_MODE_SET(DISABLE) is called. Dispatch event to WiredSe so
1168     // that it can close if session is ongoing on same NFCEE
1169     phNxpNciHal_WiredSeDispatchEvent(
1170         &gWiredSeHandle, DISABLING_NFCEE,
1171         (WiredSeEvtData)NfcPkt((uint8_t*)p_data, data_len));
1172   }
1173   long value = 0;
1174   /* NXP Removal Detection timeout Config */
1175   if (GetNxpNumValue(NAME_NXP_REMOVAL_DETECTION_TIMEOUT, (void*)&value,
1176                      sizeof(value))) {
1177     // Change the timeout value as per config file
1178     uint8_t* wait_time = (uint8_t*)&p_data[3];
1179     if ((data_len == 0x04) && (p_data[0] == 0x21 && p_data[1] == 0x12)) {
1180       *wait_time = value;
1181     }
1182   }
1183   return phNxpNciHal_write_internal(data_len, p_data);
1184 }
1185 
1186 /******************************************************************************
1187  * Function         phNxpNciHal_write_internal
1188  *
1189  * Description      This function write the data to NFCC through physical
1190  *                  interface (e.g. I2C) using the NFCC driver interface.
1191  *                  Before sending the data to NFCC, phNxpNciHal_write_ext
1192  *                  is called to check if there is any extension processing
1193  *                  is required for the NCI packet being sent out.
1194  *
1195  * Returns          It returns number of bytes successfully written to NFCC.
1196  *
1197  ******************************************************************************/
phNxpNciHal_write_internal(uint16_t data_len,const uint8_t * p_data)1198 int phNxpNciHal_write_internal(uint16_t data_len, const uint8_t* p_data) {
1199   NFCSTATUS status = NFCSTATUS_FAILED;
1200   static phLibNfc_Message_t msg;
1201   if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
1202     return NFCSTATUS_FAILED;
1203   }
1204   if ((data_len + MAX_NXP_HAL_EXTN_BYTES) > NCI_MAX_DATA_LEN) {
1205     NXPLOG_NCIHAL_D("cmd_len exceeds limit NCI_MAX_DATA_LEN");
1206     android_errorWriteLog(0x534e4554, "121267042");
1207     goto clean_and_return;
1208   }
1209 
1210   CONCURRENCY_LOCK();
1211   /* Create local copy of cmd_data */
1212   memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
1213   nxpncihal_ctrl.cmd_len = data_len;
1214 
1215   /* Check for NXP ext before sending write */
1216   status =
1217       phNxpNciHal_write_ext(&nxpncihal_ctrl.cmd_len, nxpncihal_ctrl.p_cmd_data,
1218                             &nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
1219   if (status != NFCSTATUS_SUCCESS) {
1220     /* Do not send packet to NFCC, send response directly */
1221     msg.eMsgType = NCI_HAL_RX_MSG;
1222     msg.pMsgData = NULL;
1223     msg.Size = 0;
1224 
1225     phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1226                           (phLibNfc_Message_t*)&msg);
1227     goto clean_and_return;
1228   }
1229 
1230   data_len = phNxpNciHal_write_unlocked(nxpncihal_ctrl.cmd_len,
1231                                         nxpncihal_ctrl.p_cmd_data, ORIG_LIBNFC);
1232 
1233   if (IS_CHIP_TYPE_L(sn100u) && IS_CHIP_TYPE_NE(pn557) && icode_send_eof == 1) {
1234     usleep(10000);
1235     icode_send_eof = 2;
1236     status = phNxpNciHal_send_ext_cmd(3, cmd_icode_eof);
1237     if (status != NFCSTATUS_SUCCESS) {
1238       NXPLOG_NCIHAL_E("ICODE end of frame command failed");
1239     }
1240   }
1241 
1242 clean_and_return:
1243   /* No data written */
1244   CONCURRENCY_UNLOCK();
1245   return data_len;
1246 }
1247 
1248 /******************************************************************************
1249  * Function         phNxpNciHal_write_unlocked
1250  *
1251  * Description      This is the actual function which is being called by
1252  *                  phNxpNciHal_write. This function writes the data to NFCC.
1253  *                  It waits till write callback provide the result of write
1254  *                  process.
1255  *
1256  * Returns          It returns number of bytes successfully written to NFCC.
1257  *
1258  ******************************************************************************/
phNxpNciHal_write_unlocked(uint16_t data_len,const uint8_t * p_data,int origin)1259 int phNxpNciHal_write_unlocked(uint16_t data_len, const uint8_t* p_data,
1260                                int origin) {
1261   NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER;
1262   phNxpNciHal_Sem_t cb_data;
1263   nxpncihal_ctrl.retry_cnt = 0;
1264   int sem_val = 0;
1265   static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00,
1266                                 0xC7, 0xD4, 0x00, 0x00};
1267   /* Create the local semaphore */
1268   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
1269     NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked Create cb data failed");
1270     data_len = 0;
1271     goto clean_and_return;
1272   }
1273 
1274   /* Create local copy of cmd_data */
1275   memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
1276   nxpncihal_ctrl.cmd_len = data_len;
1277   write_unlocked_status = NFCSTATUS_FAILED;
1278   /* check for write synchronyztion */
1279   if (phNxpNciHal_check_ncicmd_write_window(nxpncihal_ctrl.cmd_len,
1280                                             nxpncihal_ctrl.p_cmd_data) !=
1281       NFCSTATUS_SUCCESS) {
1282     NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked  CMD window  check failed");
1283     data_len = 0;
1284     goto clean_and_return;
1285   }
1286 
1287   if (origin == ORIG_NXPHAL) HAL_ENABLE_EXT();
1288 
1289 retry:
1290 
1291   data_len = nxpncihal_ctrl.cmd_len;
1292   if (!phNxpTempMgr::GetInstance().IsICTempOk())
1293     phNxpTempMgr::GetInstance().Wait();
1294 
1295   status = phTmlNfc_Write(
1296       (uint8_t*)nxpncihal_ctrl.p_cmd_data, (uint16_t)nxpncihal_ctrl.cmd_len,
1297       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_write_complete,
1298       (void*)&cb_data);
1299   if (status != NFCSTATUS_PENDING) {
1300     NXPLOG_NCIHAL_E("write_unlocked status error");
1301     data_len = 0;
1302     goto clean_and_return;
1303   }
1304 
1305   /* Wait for callback response */
1306   if (SEM_WAIT(cb_data)) {
1307     NXPLOG_NCIHAL_E("write_unlocked semaphore error");
1308     data_len = 0;
1309     goto clean_and_return;
1310   }
1311 
1312   if (cb_data.status != NFCSTATUS_SUCCESS) {
1313     data_len = 0;
1314     if (nxpncihal_ctrl.retry_cnt++ < MAX_RETRY_COUNT) {
1315       NXPLOG_NCIHAL_D(
1316           "write_unlocked failed - NFCC Maybe in Standby Mode - Retry");
1317       goto retry;
1318     } else {
1319       NXPLOG_NCIHAL_E(
1320           "write_unlocked failed - NFCC Maybe in Standby Mode (max count = "
1321           "0x%x)",
1322           nxpncihal_ctrl.retry_cnt);
1323 
1324       status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1325 
1326       if (NFCSTATUS_SUCCESS == status) {
1327         NXPLOG_NCIHAL_D("NFCC Reset - SUCCESS\n");
1328       } else {
1329         NXPLOG_NCIHAL_D("NFCC Reset - FAILED\n");
1330       }
1331       if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL &&
1332           nxpncihal_ctrl.hal_open_status != HAL_CLOSED) {
1333         if (nxpncihal_ctrl.p_rx_data != NULL) {
1334           NXPLOG_NCIHAL_D(
1335               "Send the Core Reset NTF to upper layer, which will trigger the "
1336               "recovery\n");
1337           // Send the Core Reset NTF to upper layer, which will trigger the
1338           // recovery.
1339           abort();
1340           nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf);
1341           memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf));
1342           (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
1343                                                    nxpncihal_ctrl.p_rx_data);
1344         } else {
1345           (*nxpncihal_ctrl.p_nfc_stack_data_cback)(0x00, NULL);
1346         }
1347         write_unlocked_status = NFCSTATUS_FAILED;
1348       }
1349     }
1350   } else {
1351     write_unlocked_status = NFCSTATUS_SUCCESS;
1352   }
1353 
1354 clean_and_return:
1355   if (write_unlocked_status == NFCSTATUS_FAILED) {
1356     sem_getvalue(&(nxpncihal_ctrl.syncSpiNfc), &sem_val);
1357     if (((nxpncihal_ctrl.p_cmd_data[0] & NCI_MT_MASK) == NCI_MT_CMD) &&
1358         sem_val == 0) {
1359       sem_post(&(nxpncihal_ctrl.syncSpiNfc));
1360       NXPLOG_NCIHAL_D("HAL write  failed CMD window check releasing \n");
1361     }
1362   }
1363   phNxpNciHal_cleanup_cb_data(&cb_data);
1364   return data_len;
1365 }
1366 
1367 /******************************************************************************
1368  * Function         phNxpNciHal_write_complete
1369  *
1370  * Description      This function handles write callback.
1371  *
1372  * Returns          void.
1373  *
1374  ******************************************************************************/
phNxpNciHal_write_complete(void * pContext,phTmlNfc_TransactInfo_t * pInfo)1375 static void phNxpNciHal_write_complete(void* pContext,
1376                                        phTmlNfc_TransactInfo_t* pInfo) {
1377   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
1378   if (pInfo->wStatus == NFCSTATUS_SUCCESS) {
1379     NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus);
1380   } else {
1381     NXPLOG_NCIHAL_D("write error status = 0x%x", pInfo->wStatus);
1382   }
1383 
1384   p_cb_data->status = pInfo->wStatus;
1385 
1386   SEM_POST(p_cb_data);
1387 
1388   return;
1389 }
1390 
1391 /******************************************************************************
1392  * Function         phNxpNciHal_read_complete
1393  *
1394  * Description      This function is called whenever there is an NCI packet
1395  *                  received from NFCC. It could be RSP or NTF packet. This
1396  *                  function provide the received NCI packet to libnfc-nci
1397  *                  using data callback of libnfc-nci.
1398  *                  There is a pending read called from each
1399  *                  phNxpNciHal_read_complete so each a packet received from
1400  *                  NFCC can be provide to libnfc-nci.
1401  *
1402  * Returns          void.
1403  *
1404  ******************************************************************************/
phNxpNciHal_read_complete(void * pContext,phTmlNfc_TransactInfo_t * pInfo)1405 static void phNxpNciHal_read_complete(void* pContext,
1406                                       phTmlNfc_TransactInfo_t* pInfo) {
1407   NFCSTATUS status = NFCSTATUS_FAILED;
1408   int sem_val;
1409   UNUSED_PROP(pContext);
1410   if (nxpncihal_ctrl.read_retry_cnt == 1) {
1411     nxpncihal_ctrl.read_retry_cnt = 0;
1412   }
1413   if (pInfo->wStatus == NFCSTATUS_SUCCESS) {
1414     NXPLOG_NCIHAL_D("read successful status = 0x%x", pInfo->wStatus);
1415 
1416     /*Check the Omapi command response and store in dedicated buffer to solve
1417      * sync issue*/
1418     if (IS_CHIP_TYPE_LE(sn100u) && pInfo->wLength > 2 &&
1419         pInfo->pBuff[0] == 0x4F && pInfo->pBuff[1] == 0x01 &&
1420         pInfo->pBuff[2] == 0x01) {
1421       nxpncihal_ctrl.p_rx_ese_data = pInfo->pBuff;
1422       nxpncihal_ctrl.rx_ese_data_len = pInfo->wLength;
1423       SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1424     } else {
1425       nxpncihal_ctrl.p_rx_data = pInfo->pBuff;
1426       nxpncihal_ctrl.rx_data_len = pInfo->wLength;
1427       status = phNxpNciHal_process_ext_rsp(nxpncihal_ctrl.p_rx_data,
1428                                            &nxpncihal_ctrl.rx_data_len);
1429       if (nxpncihal_ctrl.hal_ext_enabled && phTmlNfc_IsFwDnldModeEnabled()) {
1430         SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1431       }
1432     }
1433     phNxpNciHal_print_res_status(pInfo->pBuff, &pInfo->wLength);
1434     if (nxpncihal_ctrl.power_reset_triggered == true) {
1435       nxpncihal_ctrl.power_reset_triggered = false;
1436     }
1437 
1438     /* Check if response should go to hal module only */
1439     if (nxpncihal_ctrl.hal_ext_enabled == TRUE &&
1440         (nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_RSP) {
1441       if (status == NFCSTATUS_FAILED) {
1442         NXPLOG_NCIHAL_D("enter into NFCC init recovery");
1443         nxpncihal_ctrl.ext_cb_data.status = status;
1444       }
1445       /* Unlock semaphore only for responses*/
1446       if ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_RSP ||
1447           (IS_CHIP_TYPE_L(sn100u) && (icode_detected == true) &&
1448            (icode_send_eof == 3))) {
1449         /* Unlock semaphore */
1450         SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1451       }
1452     }  // Notification Checking
1453     else if ((nxpncihal_ctrl.hal_ext_enabled == TRUE) &&
1454              ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_NTF) &&
1455              ((nxpncihal_ctrl.p_cmd_data[0x00] & NCI_GID_MASK) ==
1456               (nxpncihal_ctrl.p_rx_data[0x00] & NCI_GID_MASK)) &&
1457              ((nxpncihal_ctrl.p_cmd_data[0x01] & NCI_OID_MASK) ==
1458               (nxpncihal_ctrl.p_rx_data[0x01] & NCI_OID_MASK)) &&
1459              (nxpncihal_ctrl.nci_info.wait_for_ntf == TRUE)) {
1460       /* Unlock semaphore waiting for only  ntf*/
1461       nxpncihal_ctrl.nci_info.wait_for_ntf = FALSE;
1462       SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1463     } else if (!sendRspToUpperLayer &&
1464                (nxpncihal_ctrl.p_rx_data[0x00] == 0x00)) {
1465       sendRspToUpperLayer = true;
1466       NFCSTATUS mfcRspStatus = NxpMfcReaderInstance.CheckMfcResponse(
1467           nxpncihal_ctrl.p_rx_data, nxpncihal_ctrl.rx_data_len);
1468       NXPLOG_NCIHAL_D("Mfc Response Status = 0x%x", mfcRspStatus);
1469       SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1470     } else if (phNxpNciHal_WiredSeDispatchEvent(
1471                    &gWiredSeHandle, NFC_PKT_RECEIVED,
1472                    (WiredSeEvtData)NfcPkt(nxpncihal_ctrl.p_rx_data,
1473                                           nxpncihal_ctrl.rx_data_len)) ==
1474                NFCSTATUS_SUCCESS) {
1475       NXPLOG_NCIHAL_D("%s => %d, Processed WiredSe Packet", __func__, __LINE__);
1476     }
1477     /* Read successful send the event to higher layer */
1478     else if (status == NFCSTATUS_SUCCESS) {
1479       phNxpNciHal_client_data_callback();
1480     }
1481     /* Unblock next Write Command Window */
1482     sem_getvalue(&(nxpncihal_ctrl.syncSpiNfc), &sem_val);
1483     if (((pInfo->pBuff[0] & NCI_MT_MASK) == NCI_MT_RSP) && sem_val == 0) {
1484       sem_post(&(nxpncihal_ctrl.syncSpiNfc));
1485     }
1486   } else {
1487     NXPLOG_NCIHAL_E("read error status = 0x%x", pInfo->wStatus);
1488   }
1489 
1490   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE &&
1491       (nxpncihal_ctrl.p_cmd_data[0x00] & NCI_GID_MASK) ==
1492           (nxpncihal_ctrl.p_rx_data[0x00] & NCI_GID_MASK) &&
1493       (nxpncihal_ctrl.p_cmd_data[0x01] & NCI_OID_MASK) ==
1494           (nxpncihal_ctrl.p_rx_data[0x01] & NCI_OID_MASK) &&
1495       nxpncihal_ctrl.nci_info.wait_for_ntf == FALSE) {
1496     NXPLOG_NCIHAL_D(" Ignoring read , HAL close triggered");
1497     return;
1498   }
1499   /* Read again because read must be pending always except FWDNLD.*/
1500   if (!phTmlNfc_IsFwDnldModeEnabled()) {
1501     status = phTmlNfc_Read(
1502         nxpncihal_ctrl.p_rsp_data, NCI_MAX_DATA_LEN,
1503         (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
1504     if (status != NFCSTATUS_PENDING) {
1505       NXPLOG_NCIHAL_E("read status error status = %x", status);
1506       /* TODO: Not sure how to handle this ? */
1507     }
1508   }
1509   return;
1510 }
1511 
1512 /******************************************************************************
1513  * Function         phNxpNciHal_notifyPollingFrame
1514  *
1515  * Description      Send polling info notification to send to upper layer
1516  *
1517  * Parameters       p_data - Polling loop info notification
1518  *
1519  * Returns          void
1520  *
1521  ******************************************************************************/
phNxpNciHal_notifyPollingFrame(uint16_t data_len,uint8_t * p_data)1522 void phNxpNciHal_notifyPollingFrame(uint16_t data_len, uint8_t* p_data) {
1523   phNxpNciHal_print_packet("RECV", p_data, data_len,
1524                            RfFwRegionDnld_handle == NULL);
1525   if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) {
1526     (*nxpncihal_ctrl.p_nfc_stack_data_cback)(data_len, p_data);
1527   }
1528 }
1529 
1530 /******************************************************************************
1531  * Function         phNxpNciHal_client_data_callback
1532  *
1533  * Description      This will process the data and sends message to lib-nfc
1534  *                  client via callback
1535  *
1536  * Returns          void
1537  *
1538  ******************************************************************************/
phNxpNciHal_client_data_callback()1539 void phNxpNciHal_client_data_callback() {
1540   if (nxpncihal_ctrl.p_nfc_stack_data_cback == NULL) {
1541     NXPLOG_NCIHAL_E("callback is NULL");
1542     return;
1543   }
1544   NxpMfcReaderInstance.MfcNotifyOnAckReceived(nxpncihal_ctrl.p_rx_data);
1545 
1546   if (isObserveModeEnabled() &&
1547       nxpncihal_ctrl.p_rx_data[NCI_GID_INDEX] == NCI_PROP_NTF_GID &&
1548       nxpncihal_ctrl.p_rx_data[NCI_OID_INDEX] == NCI_PROP_LX_NTF_OID) {
1549     unsigned long notificationType = 0;
1550     ReaderPollConfigParser readerPollConfigParser;
1551     int isFound = GetNxpNumValue(NAME_NXP_OBSERVE_MODE_REQ_NOTIFICATION_TYPE,
1552                                  &notificationType, sizeof(notificationType));
1553     if (isFound == 0) {
1554       notificationType = 0;
1555     }
1556     readerPollConfigParser.setNotificationType(notificationType);
1557     readerPollConfigParser.setReaderPollCallBack(
1558         phNxpNciHal_notifyPollingFrame);
1559     readerPollConfigParser.parseAndSendReaderPollInfo(
1560         nxpncihal_ctrl.p_rx_data, nxpncihal_ctrl.rx_data_len);
1561   } else {
1562     (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
1563                                              nxpncihal_ctrl.p_rx_data);
1564   }
1565   // workaround for sync issue between SPI and NFC
1566   if (IS_CHIP_TYPE_EQ(pn557) && nxpncihal_ctrl.p_rx_data[0] == 0x62 &&
1567       nxpncihal_ctrl.p_rx_data[1] == 0x00 &&
1568       nxpncihal_ctrl.p_rx_data[3] == 0xC0 &&
1569       nxpncihal_ctrl.p_rx_data[4] == 0x00) {
1570     uint8_t nfcee_notifiations[3][9] = {
1571         {0x61, 0x0A, 0x06, 0x01, 0x00, 0x03, 0xC0, 0x80, 0x04},
1572         {0x61, 0x0A, 0x06, 0x01, 0x00, 0x03, 0xC0, 0x81, 0x04},
1573         {0x61, 0x0A, 0x06, 0x01, 0x00, 0x03, 0xC0, 0x82, 0x03},
1574     };
1575 
1576     for (int i = 0; i < 3; i++) {
1577       (*nxpncihal_ctrl.p_nfc_stack_data_cback)(sizeof(nfcee_notifiations[i]),
1578                                                nfcee_notifiations[i]);
1579     }
1580   }
1581 }
1582 
1583 /******************************************************************************
1584  * Function         phNxpNciHal_enableTmlRead
1585  *
1586  * Description      Invokes TmlNfc Read to make sure always read thread is
1587  *                  pending
1588  *
1589  * Returns          Returns read status
1590  *
1591  ******************************************************************************/
phNxpNciHal_enableTmlRead()1592 NFCSTATUS phNxpNciHal_enableTmlRead() {
1593   /* Read again because read must be pending always.*/
1594   NFCSTATUS status = phTmlNfc_Read(
1595       nxpncihal_ctrl.p_rsp_data, NCI_MAX_DATA_LEN,
1596       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
1597   if (status != NFCSTATUS_PENDING) {
1598     NXPLOG_NCIHAL_E("read status error status = %x", status);
1599   }
1600   return status;
1601 }
1602 /******************************************************************************
1603  * Function         phNxpNciHal_core_initialized
1604  *
1605  * Description      This function is called by libnfc-nci after successful open
1606  *                  of NFCC. All proprietary setting for NFCC are done here.
1607  *                  After completion of proprietary settings notification is
1608  *                  provided to libnfc-nci through callback function.
1609  *
1610  * Returns          Always returns NFCSTATUS_SUCCESS (0).
1611  *
1612  ******************************************************************************/
phNxpNciHal_core_initialized(uint16_t core_init_rsp_params_len,uint8_t * p_core_init_rsp_params)1613 int phNxpNciHal_core_initialized(uint16_t core_init_rsp_params_len,
1614                                  uint8_t* p_core_init_rsp_params) {
1615   NFCSTATUS status = NFCSTATUS_SUCCESS;
1616   uint8_t* buffer = NULL;
1617   uint8_t isfound = 0;
1618   uint8_t fw_dwnld_flag = false;
1619   uint8_t setConfigAlways = false;
1620 
1621   uint8_t swp_full_pwr_mode_on_cmd[] = {0x20, 0x02, 0x05, 0x01,
1622                                         0xA0, 0xF1, 0x01, 0x01};
1623   uint8_t enable_ce_in_phone_off = 0x01;
1624   uint8_t enable_ven_cfg = 0x01;
1625 
1626   uint8_t swp_switch_timeout_cmd[] = {0x20, 0x02, 0x06, 0x01, 0xA0,
1627                                       0xF3, 0x02, 0x00, 0x00};
1628 
1629   config_success = true;
1630   long bufflen = 260;
1631   long retlen = 0;
1632   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
1633 #if (NFC_NXP_HFO_SETTINGS == TRUE)
1634   /* Temp fix to re-apply the proper clock setting */
1635   int temp_fix = 1;
1636 #endif
1637   unsigned long num = 0;
1638   /*initialize recovery FW variables*/
1639   gRecFwRetryCount = 0;
1640   gRecFWDwnld = 0;
1641   // recovery --start
1642   /*NCI_INIT_CMD*/
1643   static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
1644   /*NCI_RESET_CMD*/
1645   static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01,
1646                                     0x00};  // keep configuration
1647   static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
1648   /* reset config cache */
1649   uint8_t retry_core_init_cnt = 0;
1650   if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
1651     return NFCSTATUS_FAILED;
1652   }
1653   nxpncihal_ctrl.hal_open_status = HAL_OPEN_CORE_INITIALIZING;
1654   if (core_init_rsp_params_len >= 1 && (*p_core_init_rsp_params > 0) &&
1655       (*p_core_init_rsp_params < 4))  // initializing for recovery.
1656   {
1657   retry_core_init:
1658     config_access = false;
1659     if (mGetCfg_info != NULL) {
1660       mGetCfg_info->isGetcfg = false;
1661     }
1662     if (buffer != NULL) {
1663       free(buffer);
1664       buffer = NULL;
1665     }
1666     if (retry_core_init_cnt > 3) {
1667       nxpncihal_ctrl.hal_open_status = HAL_OPENED;
1668       return NFCSTATUS_FAILED;
1669     }
1670     if (IS_CHIP_TYPE_L(sn100u)) {
1671       status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1672       if (NFCSTATUS_SUCCESS == status) {
1673         NXPLOG_NCIHAL_D("NFCC Reset - SUCCESS\n");
1674       } else {
1675         NXPLOG_NCIHAL_D("NFCC Reset - FAILED\n");
1676       }
1677     }
1678 
1679     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
1680     if ((status != NFCSTATUS_SUCCESS) &&
1681         (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT)) {
1682       NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
1683       retry_core_init_cnt++;
1684       goto retry_core_init;
1685     } else if (status != NFCSTATUS_SUCCESS) {
1686       NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
1687       retry_core_init_cnt++;
1688       goto retry_core_init;
1689     }
1690 
1691     if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
1692       status =
1693           phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
1694     } else {
1695       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
1696     }
1697     if (status != NFCSTATUS_SUCCESS) {
1698       NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
1699       retry_core_init_cnt++;
1700       goto retry_core_init;
1701     }
1702   }
1703   // recovery --end
1704 
1705   buffer = (uint8_t*)malloc(bufflen * sizeof(uint8_t));
1706   if (NULL == buffer) {
1707     nxpncihal_ctrl.hal_open_status = HAL_OPENED;
1708     return NFCSTATUS_FAILED;
1709   }
1710   config_access = true;
1711   retlen = 0;
1712   isfound = GetNxpByteArrayValue(NAME_NXP_ACT_PROP_EXTN, (char*)buffer, bufflen,
1713                                  &retlen);
1714   if (isfound > 0 && retlen > 0) {
1715     /* NXP ACT Proprietary Ext */
1716     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1717     if (status != NFCSTATUS_SUCCESS) {
1718       NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
1719       retry_core_init_cnt++;
1720       goto retry_core_init;
1721     }
1722   }
1723   if (IS_CHIP_TYPE_EQ(sn100u)) {
1724     uint8_t cmd_get_cfg_dbg_info[] = {0x20, 0x03, 0x0D, 0x06, 0xA0, 0x39,
1725                                       0xA0, 0x1A, 0xA0, 0x1B, 0xA0, 0x1C,
1726                                       0xA0, 0x27, 0xA1, 0x1F};
1727     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_get_cfg_dbg_info),
1728                                       cmd_get_cfg_dbg_info);
1729   } else if (IS_CHIP_TYPE_GE(sn220u) || IS_CHIP_TYPE_EQ(pn557)) {
1730     uint8_t cmd_get_cfg_dbg_info[] = {0x20, 0x03, 0x0B, 0x05, 0xA0, 0x39, 0xA0,
1731                                       0x1A, 0xA0, 0x1B, 0xA0, 0x1C, 0xA0, 0x27};
1732     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_get_cfg_dbg_info),
1733                                       cmd_get_cfg_dbg_info);
1734   }
1735   if (status != NFCSTATUS_SUCCESS) {
1736     NXPLOG_NCIHAL_E("Failed to retrieve NFCC debug info");
1737   }
1738 
1739   if (IS_CHIP_TYPE_GE(sn220u)) {
1740     uint8_t cmd_get_hard_fault_ctr_info[] = {0x20, 0x03, 0x03,
1741                                              0x01, 0xA1, 0x5A};
1742     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_get_hard_fault_ctr_info),
1743                                       cmd_get_hard_fault_ctr_info);
1744     if (status != NFCSTATUS_SUCCESS) {
1745       NXPLOG_NCIHAL_E("Failed to retrieve NFCC hard fault counter debug info");
1746     }
1747   }
1748 
1749   num = 0;
1750   if (GetNxpNumValue("NXP_I3C_MODE", &num, sizeof(num))) {
1751     if (num == 1) {
1752       uint8_t coreStandBy[] = {0x2F, 0x00, 0x01, 0x00};
1753       NXPLOG_NCIHAL_E("Disable NFCC standby");
1754       status = phNxpNciHal_send_ext_cmd(sizeof(coreStandBy), coreStandBy);
1755       if (status != NFCSTATUS_SUCCESS) {
1756         NXPLOG_NCIHAL_E("Failed to set NFCC Standby Disabled");
1757       }
1758     }
1759   }
1760 
1761   status = phNxpNciHal_setAutonomousMode();
1762   if (status != NFCSTATUS_SUCCESS) {
1763     NXPLOG_NCIHAL_E("Set Autonomous enable: Failed");
1764     retry_core_init_cnt++;
1765     goto retry_core_init;
1766   }
1767 
1768   if (IS_CHIP_TYPE_EQ(pn557)) enable_ven_cfg = PN557_VEN_CFG_DEFAULT;
1769   if (IS_CHIP_TYPE_GE(sn220u) && phNxpNciHal_isULPDetSupported()) {
1770     enable_ven_cfg = 0x00;
1771   }
1772 
1773   mEEPROM_info.buffer = &enable_ven_cfg;
1774   mEEPROM_info.bufflen = sizeof(uint8_t);
1775   mEEPROM_info.request_type = EEPROM_ENABLE_VEN_CFG;
1776   mEEPROM_info.request_mode = SET_EEPROM_DATA;
1777   request_EEPROM(&mEEPROM_info);
1778 
1779   if (IS_CHIP_TYPE_GE(sn100u)) {
1780     unsigned long num = 0;
1781     if ((GetNxpNumValue(NAME_NXP_CE_SUPPORT_IN_NFC_OFF_PHONE_OFF, &num,
1782                         sizeof(num))) &&
1783         (IS_CHIP_TYPE_EQ(sn300u))) {
1784       if (num == ENABLE_T4T_CE) enable_ce_in_phone_off = num;
1785     }
1786     mEEPROM_info.buffer = &enable_ce_in_phone_off;
1787     mEEPROM_info.bufflen = sizeof(enable_ce_in_phone_off);
1788     mEEPROM_info.request_type = EEPROM_CE_PHONE_OFF_CFG;
1789     mEEPROM_info.request_mode = SET_EEPROM_DATA;
1790     request_EEPROM(&mEEPROM_info);
1791   }
1792 
1793   phNxpNciHal_propConfULPDetMode(false);
1794 
1795   if (gPowerTrackerHandle.start != NULL) {
1796     gPowerTrackerHandle.start(gPowerTrackerHandle.pollDuration);
1797   }
1798   config_access = false;
1799   status = phNxpNciHal_read_fw_dw_status(fw_dwnld_flag);
1800   if (status != NFCSTATUS_SUCCESS) {
1801     NXPLOG_NCIHAL_E("%s: NXP get FW DW Flag failed", __FUNCTION__);
1802   }
1803   fw_dwnld_flag |= (bool)fw_download_success;
1804   if (fw_dwnld_flag == true) {
1805     phNxpNciHal_hci_network_reset();
1806   }
1807   if (IS_CHIP_TYPE_L(sn100u)) {
1808     // Check if firmware download success
1809     status = phNxpNciHal_get_mw_eeprom();
1810     if (status != NFCSTATUS_SUCCESS) {
1811       NXPLOG_NCIHAL_E("NXP GET MW EEPROM AREA Proprietary Ext failed");
1812       retry_core_init_cnt++;
1813       goto retry_core_init;
1814     }
1815   }
1816 
1817   config_access = true;
1818   setConfigAlways = false;
1819   isfound = GetNxpNumValue(NAME_NXP_SET_CONFIG_ALWAYS, &num, sizeof(num));
1820   if (isfound > 0) {
1821     setConfigAlways = num;
1822   }
1823   NXPLOG_NCIHAL_D("EEPROM_fw_dwnld_flag : 0x%02x SetConfigAlways flag : 0x%02x",
1824                   fw_dwnld_flag, setConfigAlways);
1825 
1826   if (isNxpConfigModified() || (fw_dwnld_flag == true)) {
1827     retlen = 0;
1828     fw_download_success = 0;
1829 
1830     /* EEPROM access variables */
1831     mEEPROM_info.request_mode = GET_EEPROM_DATA;
1832     retlen = 0;
1833     memset(buffer, 0x00, bufflen);
1834     isfound = GetNxpByteArrayValue(NAME_NXP_AUTH_TIMEOUT_CFG, (char*)buffer,
1835                                    bufflen, &retlen);
1836 
1837     if ((isfound > 0) && (retlen > 0)) {
1838       uint64_t auth_timeout_buffer_length;
1839       if (IS_CHIP_TYPE_GE(sn100u)) {
1840         auth_timeout_buffer_length = SNXXX_NXP_AUTH_TIMEOUT_BUF_LEN;
1841       } else {
1842         auth_timeout_buffer_length = PN557_NXP_AUTH_TIMEOUT_BUF_LEN;
1843       }
1844       uint8_t auth_timeout_buffer[auth_timeout_buffer_length];
1845       memcpy(&auth_timeout_buffer, buffer, auth_timeout_buffer_length);
1846       mEEPROM_info.request_mode = SET_EEPROM_DATA;
1847       mEEPROM_info.buffer = auth_timeout_buffer;
1848       mEEPROM_info.bufflen = auth_timeout_buffer_length;
1849       mEEPROM_info.request_type = EEPROM_AUTH_CMD_TIMEOUT;
1850       status = request_EEPROM(&mEEPROM_info);
1851       if (NFCSTATUS_SUCCESS == status) {
1852         memcpy(&mGetCfg_info->auth_cmd_timeout, mEEPROM_info.buffer,
1853                mEEPROM_info.bufflen);
1854         mGetCfg_info->auth_cmd_timeoutlen = mEEPROM_info.bufflen;
1855       }
1856     }
1857     NXPLOG_NCIHAL_D("Performing TVDD Settings");
1858     isfound = GetNxpNumValue(NAME_NXP_EXT_TVDD_CFG, &num, sizeof(num));
1859     if (isfound > 0) {
1860       if (num == 1) {
1861         isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_1, (char*)buffer,
1862                                        bufflen, &retlen);
1863         if (isfound && retlen > 0) {
1864           status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1865           if (status != NFCSTATUS_SUCCESS) {
1866             NXPLOG_NCIHAL_E("EXT TVDD CFG 1 Settings failed");
1867             retry_core_init_cnt++;
1868             goto retry_core_init;
1869           }
1870         }
1871       } else if (num == 2) {
1872         isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_2, (char*)buffer,
1873                                        bufflen, &retlen);
1874         if (isfound && retlen > 0) {
1875           status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1876           if (status != NFCSTATUS_SUCCESS) {
1877             NXPLOG_NCIHAL_E("EXT TVDD CFG 2 Settings failed");
1878             retry_core_init_cnt++;
1879             goto retry_core_init;
1880           }
1881         }
1882       } else if (num == 3) {
1883         isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_3, (char*)buffer,
1884                                        bufflen, &retlen);
1885         if (isfound && retlen > 0) {
1886           status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1887           if (status != NFCSTATUS_SUCCESS) {
1888             NXPLOG_NCIHAL_E("EXT TVDD CFG 3 Settings failed");
1889             retry_core_init_cnt++;
1890             goto retry_core_init;
1891           }
1892         }
1893       } else {
1894         NXPLOG_NCIHAL_E("Wrong Configuration Value %ld", num);
1895       }
1896     }
1897   }
1898   if ((true == fw_dwnld_flag) || (true == setConfigAlways) ||
1899       isNxpConfigModified()) {
1900     config_access = true;
1901 
1902     if (IS_CHIP_TYPE_NE(pn547C2)) {
1903       config_access = true;
1904     }
1905 
1906     retlen = 0;
1907     /*Select UICC2/UICC3 SWP line from config param*/
1908     if (GetNxpNumValue(NAME_NXP_DEFAULT_UICC2_SELECT, (void*)&retlen,
1909                        sizeof(retlen))) {
1910       if (retlen > 0) phNxpNciHal_enableDefaultUICC2SWPline((uint8_t)retlen);
1911     }
1912     status = phNxpNciHal_setExtendedFieldMode();
1913     if (status != NFCSTATUS_SUCCESS &&
1914         status != NFCSTATUS_FEATURE_NOT_SUPPORTED) {
1915       NXPLOG_NCIHAL_E("phNxpNciHal_setExtendedFieldMode failed");
1916       retry_core_init_cnt++;
1917       goto retry_core_init;
1918     }
1919     status = phNxpNciHal_setGuardTimer();
1920     if (status != NFCSTATUS_SUCCESS &&
1921         status != NFCSTATUS_FEATURE_NOT_SUPPORTED) {
1922       NXPLOG_NCIHAL_E("phNxpNciHal_setGuardTimer failed");
1923       retry_core_init_cnt++;
1924       goto retry_core_init;
1925     }
1926 #if (NXP_SRD == TRUE)
1927     status = phNxpNciHal_setSrdtimeout();
1928     if (status != NFCSTATUS_SUCCESS &&
1929         status != NFCSTATUS_FEATURE_NOT_SUPPORTED) {
1930       NXPLOG_NCIHAL_E("phNxpNciHal_setSrdtimeout failed");
1931       retry_core_init_cnt++;
1932       goto retry_core_init;
1933     }
1934 #endif
1935     config_access = true;
1936     retlen = 0;
1937     NXPLOG_NCIHAL_D("Performing ndef nfcee config settings");
1938     uint8_t cmd_t4t_nfcee_cfg;
1939 
1940     if (!GetNxpNumValue(NAME_NXP_T4T_NFCEE_ENABLE, (void*)&retlen,
1941                         sizeof(retlen))) {
1942       retlen = 0x00;
1943       NXPLOG_NCIHAL_D(
1944           "T4T_NFCEE_ENABLE not found. Taking default value : 0x%02lx", retlen);
1945     }
1946     cmd_t4t_nfcee_cfg = (uint8_t)retlen;
1947     mEEPROM_info.buffer = &cmd_t4t_nfcee_cfg;
1948     mEEPROM_info.bufflen = sizeof(cmd_t4t_nfcee_cfg);
1949     mEEPROM_info.request_type = EEPROM_T4T_NFCEE_ENABLE;
1950     mEEPROM_info.request_mode = SET_EEPROM_DATA;
1951     request_EEPROM(&mEEPROM_info);
1952     if (IS_CHIP_TYPE_GE(sn100u)) {
1953       if (phNxpNciHal_configure_merge_sak() != NFCSTATUS_SUCCESS) {
1954         NXPLOG_NCIHAL_E("Applying iso_dep sak merge settings failed");
1955       }
1956     }
1957   }
1958   if ((true == fw_dwnld_flag) || (true == setConfigAlways) ||
1959       isNxpConfigModified() || (wRfUpdateReq == true)) {
1960     retlen = 0;
1961     NXPLOG_NCIHAL_D("Performing NAME_NXP_CORE_CONF_EXTN Settings");
1962     isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF_EXTN, (char*)buffer,
1963                                    bufflen, &retlen);
1964     if (isfound > 0 && retlen > 0) {
1965       /* NXP ACT Proprietary Ext */
1966       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1967       if (status != NFCSTATUS_SUCCESS) {
1968         NXPLOG_NCIHAL_E("NXP Core configuration failed");
1969         retry_core_init_cnt++;
1970         goto retry_core_init;
1971       }
1972     }
1973 
1974     NXPLOG_NCIHAL_D("Performing SE Settings");
1975     phNxpNciHal_read_and_update_se_state();
1976 
1977     NXPLOG_NCIHAL_D("Performing NAME_NXP_CORE_CONF Settings");
1978     retlen = 0;
1979     isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF, (char*)buffer, bufflen,
1980                                    &retlen);
1981     if (isfound > 0 && retlen > 0) {
1982       /* NXP ACT Proprietary Ext */
1983       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1984       if (status != NFCSTATUS_SUCCESS) {
1985         NXPLOG_NCIHAL_E("Core Set Config failed");
1986         retry_core_init_cnt++;
1987         goto retry_core_init;
1988       }
1989     }
1990 
1991     phNxpNciHal_setDCDCConfig();
1992 
1993     if (fpVerInfoStoreInEeprom != NULL) {
1994       fpVerInfoStoreInEeprom();
1995     }
1996   }
1997   config_access = false;
1998   if ((true == fw_dwnld_flag) || (true == setConfigAlways) ||
1999       isNxpRFConfigModified()) {
2000     unsigned long loopcnt = 0;
2001 
2002     do {
2003       char rf_conf_block[22] = {'\0'};
2004       strlcpy(rf_conf_block, rf_block_name, sizeof(rf_conf_block));
2005       retlen = 0;
2006       strlcat(rf_conf_block, rf_block_num[loopcnt++], sizeof(rf_conf_block));
2007       isfound =
2008           GetNxpByteArrayValue(rf_conf_block, (char*)buffer, bufflen, &retlen);
2009       if (isfound > 0 && retlen > 0) {
2010         NXPLOG_NCIHAL_D(" Performing RF Settings BLK %ld", loopcnt);
2011         status = phNxpNciHal_send_ext_cmd(retlen, buffer);
2012 
2013         if (status == NFCSTATUS_SUCCESS) {
2014           status = phNxpNciHal_CheckRFCmdRespStatus();
2015           /*STATUS INVALID PARAM 0x09*/
2016           if (status == INVALID_PARAM) {
2017             phNxpNciHalRFConfigCmdRecSequence();
2018             retry_core_init_cnt++;
2019             goto retry_core_init;
2020           }
2021         } else if (status != NFCSTATUS_SUCCESS) {
2022           NXPLOG_NCIHAL_E("RF Settings BLK %ld failed", loopcnt);
2023           /*STATUS INVALID PARAM 0x09*/
2024           if (status == INVALID_PARAM) {
2025             phNxpNciHalRFConfigCmdRecSequence();
2026           }
2027           retry_core_init_cnt++;
2028           goto retry_core_init;
2029         }
2030       }
2031     } while (rf_block_num[loopcnt] != NULL);
2032     loopcnt = 0;
2033     if (phNxpNciHal_nfccClockCfgApply() != NFCSTATUS_SUCCESS) {
2034       NXPLOG_NCIHAL_E("phNxpNciHal_nfccClockCfgApply failed");
2035       retry_core_init_cnt++;
2036       goto retry_core_init;
2037     }
2038   }
2039   if (fpDoAntennaActivity != NULL) {
2040     fpDoAntennaActivity(ANTENNA_SET_VDDPA);
2041   }
2042   config_access = true;
2043 
2044   retlen = 0;
2045   if (IS_CHIP_TYPE_NE(pn547C2)) {
2046     config_access = false;
2047   }
2048   isfound = GetNxpByteArrayValue(NAME_NXP_CORE_RF_FIELD, (char*)buffer, bufflen,
2049                                  &retlen);
2050   if (isfound > 0 && retlen > 0) {
2051     /* NXP ACT Proprietary Ext */
2052     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
2053     if (status == NFCSTATUS_SUCCESS) {
2054       status = phNxpNciHal_CheckRFCmdRespStatus();
2055       /*STATUS INVALID PARAM 0x09*/
2056       if (status == INVALID_PARAM) {
2057         phNxpNciHalRFConfigCmdRecSequence();
2058         retry_core_init_cnt++;
2059         goto retry_core_init;
2060       }
2061     } else if (status != NFCSTATUS_SUCCESS) {
2062       NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
2063       if (status == INVALID_PARAM) {
2064         phNxpNciHalRFConfigCmdRecSequence();
2065       }
2066       retry_core_init_cnt++;
2067       goto retry_core_init;
2068     }
2069   }
2070   config_access = true;
2071 
2072   retlen = 0;
2073   /* NXP SWP switch timeout Setting*/
2074   if (GetNxpNumValue(NAME_NXP_SWP_SWITCH_TIMEOUT, (void*)&retlen,
2075                      sizeof(retlen))) {
2076     // Check the permissible range [0 - 60]
2077     if (0 <= retlen && retlen <= 60) {
2078       if (0 < retlen) {
2079         unsigned int timeout = (uint32_t)retlen * 1000;
2080         unsigned int timeoutHx = 0x0000;
2081 
2082         char tmpbuffer[10] = {0};
2083         snprintf((char*)tmpbuffer, 10, "%04x", timeout);
2084         int ret = sscanf((char*)tmpbuffer, "%x", &timeoutHx);
2085         if (!ret) timeoutHx = 0x0000;
2086 
2087         swp_switch_timeout_cmd[7] = (timeoutHx & 0xFF);
2088         swp_switch_timeout_cmd[8] = ((timeoutHx & 0xFF00) >> 8);
2089       }
2090 
2091       status = phNxpNciHal_send_ext_cmd(sizeof(swp_switch_timeout_cmd),
2092                                         swp_switch_timeout_cmd);
2093       if (status != NFCSTATUS_SUCCESS) {
2094         NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed");
2095         retry_core_init_cnt++;
2096         goto retry_core_init;
2097       }
2098     } else {
2099       NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed - out of range!");
2100     }
2101   }
2102 
2103   status = phNxpNciHal_china_tianjin_rf_setting();
2104   if (status != NFCSTATUS_SUCCESS) {
2105     NXPLOG_NCIHAL_E("phNxpNciHal_china_tianjin_rf_setting failed");
2106     retry_core_init_cnt++;
2107     goto retry_core_init;
2108   }
2109   if (IS_CHIP_TYPE_L(sn100u)) {
2110     // Update eeprom value
2111     status = phNxpNciHal_set_mw_eeprom();
2112     if (status != NFCSTATUS_SUCCESS) {
2113       NXPLOG_NCIHAL_E("NXP Update MW EEPROM Proprietary Ext failed");
2114     }
2115   }
2116 
2117   retlen = 0;
2118   config_access = false;
2119 
2120   retlen = 0;
2121 
2122   /* SWP FULL PWR MODE SETTING ON */
2123   if (GetNxpNumValue(NAME_NXP_SWP_FULL_PWR_ON, (void*)&retlen,
2124                      sizeof(retlen))) {
2125     if (1 == retlen) {
2126       status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd),
2127                                         swp_full_pwr_mode_on_cmd);
2128       if (status != NFCSTATUS_SUCCESS) {
2129         NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING ON CMD FAILED");
2130         retry_core_init_cnt++;
2131         goto retry_core_init;
2132       }
2133     } else {
2134       swp_full_pwr_mode_on_cmd[7] = 0x00;
2135       status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd),
2136                                         swp_full_pwr_mode_on_cmd);
2137       if (status != NFCSTATUS_SUCCESS) {
2138         NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING OFF CMD FAILED");
2139         retry_core_init_cnt++;
2140         goto retry_core_init;
2141       }
2142     }
2143   }
2144 
2145   uint8_t gpioCtrl[3] = {0x00, 0x00, 0x00};
2146   long gpioCtrlLen = 0;
2147   isfound = GetNxpByteArrayValue(NAME_CONF_GPIO_CONTROL, (char*)gpioCtrl,
2148                                  sizeof(gpioCtrl), &gpioCtrlLen);
2149   if (isfound > 0 && gpioCtrlLen != 0) {
2150     phNxpNciHal_configGPIOControl(gpioCtrl, gpioCtrlLen);
2151   }
2152   phNxpNciHal_configureLxDebugMode();
2153 
2154   if (IS_CHIP_TYPE_EQ(pn557)) {
2155     if (GetNxpNumValue(NAME_NXP_PROP_CE_ACTION_NTF, (void*)&retlen,
2156                        sizeof(retlen))) {
2157       uint8_t value = (uint8_t)retlen;
2158       NXPLOG_NCIHAL_D("Prop CE ACT NTF %x", value);
2159       mEEPROM_info.buffer = &value;
2160       mEEPROM_info.bufflen = sizeof(value);
2161       mEEPROM_info.request_type = EEPROM_CE_ACT_NTF;
2162       mEEPROM_info.request_mode = SET_EEPROM_DATA;
2163       request_EEPROM(&mEEPROM_info);
2164     }
2165   }
2166 
2167   config_access = false;
2168   {
2169     if (isNxpRFConfigModified() || isNxpConfigModified() || fw_dwnld_flag ||
2170         setConfigAlways) {
2171       if (IS_CHIP_TYPE_GE(sn100u)) {
2172         status = phNxpNciHal_ext_send_sram_config_to_flash();
2173         if (status != NFCSTATUS_SUCCESS) {
2174           NXPLOG_NCIHAL_E("Updation of the SRAM contents failed");
2175         }
2176       }
2177       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
2178       if (status == NFCSTATUS_SUCCESS) {
2179         if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
2180           status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0),
2181                                             cmd_init_nci2_0);
2182         } else {
2183           status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
2184         }
2185       }
2186     }
2187     if (status == NFCSTATUS_SUCCESS) {
2188       status = phNxpNciHal_restore_uicc_params();
2189       if (status != NFCSTATUS_SUCCESS) {
2190         NXPLOG_NCIHAL_E("%s: Restore UICC params failed", __FUNCTION__);
2191       }
2192 
2193       phNxpNciHal_prop_conf_rssi();
2194 
2195       fw_dwnld_flag = false;
2196       status = phNxpNciHal_write_fw_dw_status(fw_dwnld_flag);
2197       if (status != NFCSTATUS_SUCCESS) {
2198         NXPLOG_NCIHAL_E("%s: NXP Set FW Download Flag failed", __FUNCTION__);
2199       }
2200       status = phNxpNciHal_send_get_cfgs();
2201       if (status == NFCSTATUS_SUCCESS) {
2202         NXPLOG_NCIHAL_E("Send get Configs SUCCESS");
2203       } else {
2204         NXPLOG_NCIHAL_E("Send get Configs FAILED");
2205       }
2206     }
2207   }
2208   retry_core_init_cnt = 0;
2209 
2210   if (buffer) {
2211     free(buffer);
2212     buffer = NULL;
2213   }
2214   // initialize recovery FW variables
2215   gRecFWDwnld = 0;
2216   gRecFwRetryCount = 0;
2217 
2218   // Callback not needed for config applying in error recovery
2219   if (!sIsHalOpenErrorRecovery) {
2220     phNxpNciHal_core_initialized_complete(status);
2221   }
2222   if (isNxpConfigModified()) {
2223     updateNxpConfigTimestamp();
2224   }
2225   if (isNxpRFConfigModified()) {
2226     updateNxpRfConfigTimestamp();
2227   }
2228   return NFCSTATUS_SUCCESS;
2229 }
2230 /******************************************************************************
2231  * Function         phNxpNciHal_CheckRFCmdRespStatus
2232  *
2233  * Description      This function is called to check the resp status of
2234  *                  RF update commands.
2235  *
2236  * Returns          NFCSTATUS_SUCCESS           if successful,
2237  *                  NFCSTATUS_INVALID_PARAMETER if parameter is inavlid
2238  *                  NFCSTATUS_FAILED            if failed response
2239  *
2240  ******************************************************************************/
phNxpNciHal_CheckRFCmdRespStatus()2241 NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus() {
2242   NFCSTATUS status = NFCSTATUS_SUCCESS;
2243   if ((nxpncihal_ctrl.rx_data_len > 0) && (nxpncihal_ctrl.p_rx_data[2] > 0)) {
2244     if (nxpncihal_ctrl.p_rx_data[3] == 0x09) {
2245       status = INVALID_PARAM;
2246     } else if (nxpncihal_ctrl.p_rx_data[3] != NFCSTATUS_SUCCESS) {
2247       status = NFCSTATUS_FAILED;
2248     }
2249   }
2250   return status;
2251 }
2252 /******************************************************************************
2253  * Function         phNxpNciHalRFConfigCmdRecSequence
2254  *
2255  * Description      This function is called to handle recovery FW sequence
2256  *                  Whenever RF settings are failed to apply with invalid param
2257  *                  response, recovery mechanism includes recovery firmware
2258  *                  download followed by firmware download and then config
2259  *                  settings. The recovery firmware changes the major number of
2260  *                  the firmware inside NFCC.Then actual firmware dowenload will
2261  *                  be successful. This can be retried maximum three times.
2262  *
2263  * Returns          Always returns NFCSTATUS_SUCCESS
2264  *
2265  ******************************************************************************/
phNxpNciHalRFConfigCmdRecSequence()2266 NFCSTATUS phNxpNciHalRFConfigCmdRecSequence() {
2267   NFCSTATUS status = NFCSTATUS_SUCCESS;
2268   uint16_t recFWState = 1;
2269   gRecFWDwnld = true;
2270   gRecFwRetryCount++;
2271   if (gRecFwRetryCount > 0x03) {
2272     NXPLOG_NCIHAL_D("Max retry count for RF config FW recovery exceeded ");
2273     gRecFWDwnld = false;
2274     return NFCSTATUS_FAILED;
2275   }
2276   do {
2277     status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
2278     phDnldNfc_InitImgInfo();
2279     if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion()) {
2280       status = phNxpNciHal_fw_download();
2281       if (status != NFCSTATUS_SUCCESS) {
2282         NXPLOG_NCIHAL_E("error in download = %x", status);
2283       }
2284       break;
2285     }
2286     gRecFWDwnld = false;
2287   } while (recFWState--);
2288   gRecFWDwnld = false;
2289   return status;
2290 }
2291 
2292 /******************************************************************************
2293  * Function         phNxpNciHal_core_initialized_complete
2294  *
2295  * Description      This function is called when phNxpNciHal_core_initialized
2296  *                  complete all proprietary command exchanges. This function
2297  *                  informs libnfc-nci about completion of core initialize
2298  *                  and result of that through callback.
2299  *
2300  * Returns          void.
2301  *
2302  ******************************************************************************/
phNxpNciHal_core_initialized_complete(NFCSTATUS status)2303 static void phNxpNciHal_core_initialized_complete(NFCSTATUS status) {
2304   static phLibNfc_Message_t msg;
2305 
2306   nxpncihal_ctrl.hal_open_status = HAL_OPENED;
2307   if (status == NFCSTATUS_SUCCESS) {
2308     msg.eMsgType = NCI_HAL_POST_INIT_CPLT_MSG;
2309   } else {
2310     msg.eMsgType = NCI_HAL_ERROR_MSG;
2311   }
2312   msg.pMsgData = NULL;
2313   msg.Size = 0;
2314 
2315   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
2316                         (phLibNfc_Message_t*)&msg);
2317   return;
2318 }
2319 
2320 /******************************************************************************
2321  * Function         phNxpNciHal_pre_discover
2322  *
2323  * Description      This function is called by libnfc-nci to perform any
2324  *                  proprietary exchange before RF discovery.
2325  *
2326  * Returns          It always returns NFCSTATUS_SUCCESS (0).
2327  *
2328  ******************************************************************************/
phNxpNciHal_pre_discover(void)2329 int phNxpNciHal_pre_discover(void) {
2330   if (nxpncihal_ctrl.halStatus != HAL_STATUS_CLOSE) {
2331     // Flush SRAM content to flash
2332     CONCURRENCY_LOCK();
2333     if (phNxpNciHal_ext_send_sram_config_to_flash() != NFCSTATUS_SUCCESS) {
2334       NXPLOG_NCIHAL_E("phNxpNciHal_ext_send_sram_config_to_flash: Failed");
2335     }
2336     CONCURRENCY_UNLOCK();
2337     // Inform WireSe Service that NFC is ON
2338     phNxpNciHal_WiredSeDispatchEvent(&gWiredSeHandle, NFC_STATE_CHANGE,
2339                                      (WiredSeEvtData)NfcState::NFC_ON);
2340   }
2341   /* Nothing to do here for initial version */
2342   // This is set to return Failed as no vendor specific pre-discovery action is
2343   // needed in case of HalPrediscover
2344   return NFCSTATUS_FAILED;
2345 }
2346 
2347 /******************************************************************************
2348  * Function         phNxpNciHal_release_info
2349  *
2350  * Description      This function frees allocated memory for mGetCfg_info
2351  *
2352  * Returns          void.
2353  *
2354  ******************************************************************************/
phNxpNciHal_release_info(void)2355 static void phNxpNciHal_release_info(void) {
2356   NXPLOG_NCIHAL_D("phNxpNciHal_release_info mGetCfg_info");
2357   if (mGetCfg_info != NULL) {
2358     free(mGetCfg_info);
2359     mGetCfg_info = NULL;
2360   }
2361 }
2362 /******************************************************************************
2363  * Function         phNxpNciHal_close
2364  *
2365  * Description      This function close the NFCC interface and free all
2366  *                  resources.This is called by libnfc-nci on NFC service stop.
2367  *
2368  * Returns          Always return NFCSTATUS_SUCCESS (0).
2369  *
2370  ******************************************************************************/
phNxpNciHal_close(bool bShutdown)2371 int phNxpNciHal_close(bool bShutdown) {
2372   NFCSTATUS status = NFCSTATUS_FAILED;
2373   uint8_t cmd_ce_discovery_nci[10] = {
2374       0x21,
2375       0x03,
2376   };
2377   uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
2378   uint8_t cmd_system_ese_power_cycle[] = {0x2F, 0x1E, 0x00};
2379   uint8_t cmd_ce_in_phone_off[] = {0x20, 0x02, 0x05, 0x01,
2380                                    0xA0, 0x8E, 0x01, 0x00};
2381   uint8_t cmd_ce_in_phone_off_pn557[] = {0x20, 0x02, 0x05, 0x01,
2382                                          0xA0, 0x07, 0x01, 0x02};
2383   uint8_t cmd_system_set_service_status[] = {0x2F, 0x01, 0x01, 0x00};
2384   uint8_t length = 0;
2385   uint8_t numPrms = 0;
2386   uint8_t ptr = 4;
2387   unsigned long uiccListenMask = 0x00;
2388   unsigned long eseListenMask = 0x00;
2389   uint8_t retry = 0;
2390   uint8_t num = 0x00;
2391 
2392   phNxpNciHal_deinitializeRegRfFwDnld();
2393   NfcHalAutoThreadMutex a(sHalFnLock);
2394   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
2395     NXPLOG_NCIHAL_D("phNxpNciHal_close is already closed, ignoring close");
2396     return NFCSTATUS_FAILED;
2397   }
2398   if (gPowerTrackerHandle.stop != NULL) {
2399     gPowerTrackerHandle.stop();
2400   }
2401   phNxpNciHal_WiredSeDispatchEvent(&gWiredSeHandle, NFC_STATE_CHANGE,
2402                                    (WiredSeEvtData)NfcState::NFC_OFF);
2403   if (IS_CHIP_TYPE_L(sn100u)) {
2404     if (!(GetNxpNumValue(NAME_NXP_UICC_LISTEN_TECH_MASK, &uiccListenMask,
2405                          sizeof(uiccListenMask)))) {
2406       uiccListenMask = 0x07;
2407       NXPLOG_NCIHAL_D("UICC_LISTEN_TECH_MASK = 0x%0lX", uiccListenMask);
2408     }
2409 
2410     if (!(GetNxpNumValue(NAME_NXP_ESE_LISTEN_TECH_MASK, &eseListenMask,
2411                          sizeof(eseListenMask)))) {
2412       eseListenMask = 0x07;
2413       NXPLOG_NCIHAL_D("NXP_ESE_LISTEN_TECH_MASK = 0x%0lX", eseListenMask);
2414     }
2415   }
2416 
2417   CONCURRENCY_LOCK();
2418   int sem_val;
2419   sem_getvalue(&(nxpncihal_ctrl.syncSpiNfc), &sem_val);
2420   if (sem_val == 0) {
2421     sem_post(&(nxpncihal_ctrl.syncSpiNfc));
2422   }
2423 
2424   /**
2425    * @brief In Case of chipset greater than or equal to SN110,
2426    * If Chipset is SN300 &
2427    *    - NAME_NXP_CE_SUPPORT_IN_NFC_OFF_PHONE_OFF is 0x00,
2428    *      then CE support in Phone off NFC off is not supported &
2429    *      Autonomous mode is disabled.
2430    *    - NAME_NXP_CE_SUPPORT_IN_NFC_OFF_PHONE_OFF is 0x03,
2431    *      then CE support for T4T in Phone off NFC off is supported &
2432    *      Autonomous mode is disabled.
2433    * otherwise, CE support in Phone off NFC off is not supported &
2434    * Autonomous mode is disabled.
2435    */
2436   if (!bShutdown && phNxpNciHal_getULPDetFlag() == false) {
2437     if ((IS_CHIP_TYPE_GE(sn100u) && IS_CHIP_TYPE_L(sn300u)) ||
2438         ((IS_CHIP_TYPE_EQ(sn300u)) &&
2439          (GetNxpNumValue(NAME_NXP_CE_SUPPORT_IN_NFC_OFF_PHONE_OFF, &num,
2440                          sizeof(num))) &&
2441          ((num == NXP_PHONE_OFF_NFC_OFF_CE_NOT_SUPPORTED) ||
2442           (num == NXP_PHONE_OFF_NFC_OFF_T4T_CE_SUPPORTED)))) {
2443       if (num == NXP_PHONE_OFF_NFC_OFF_CE_NOT_SUPPORTED) {
2444         status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_in_phone_off),
2445                                           cmd_ce_in_phone_off);
2446         if (status != NFCSTATUS_SUCCESS) {
2447           NXPLOG_NCIHAL_E("CMD_CE_IN_PHONE_OFF: Failed");
2448         }
2449       }
2450       config_ext.autonomous_mode = 0x00;
2451       status = phNxpNciHal_setAutonomousMode();
2452       if (status != NFCSTATUS_SUCCESS) {
2453         NXPLOG_NCIHAL_E("Autonomous mode Disable: Failed");
2454       }
2455     } else if (IS_CHIP_TYPE_EQ(pn557)) {
2456       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_in_phone_off_pn557),
2457                                         cmd_ce_in_phone_off_pn557);
2458       if (status != NFCSTATUS_SUCCESS) {
2459         NXPLOG_NCIHAL_E("CMD_CE_IN_PHONE_OFF: Failed");
2460       }
2461     }
2462   }
2463   if (nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT &&
2464       read_failed_disable_nfc) {
2465     read_failed_disable_nfc = false;
2466     goto close_and_return;
2467   }
2468 
2469   if (write_unlocked_status == NFCSTATUS_FAILED) {
2470     NXPLOG_NCIHAL_D("phNxpNciHal_close i2c write failed .Clean and Return");
2471     goto close_and_return;
2472   }
2473 
2474   if ((!bShutdown) && IS_CHIP_TYPE_L(sn100u)) {
2475     if ((uiccListenMask & 0x1) == 0x01 || (eseListenMask & 0x1) == 0x01) {
2476       NXPLOG_NCIHAL_D("phNxpNciHal_close (): Adding A passive listen");
2477       numPrms++;
2478       cmd_ce_discovery_nci[ptr++] = 0x80;
2479       cmd_ce_discovery_nci[ptr++] = 0x01;
2480       length += 2;
2481     }
2482     if ((uiccListenMask & 0x2) == 0x02 || (eseListenMask & 0x4) == 0x04) {
2483       NXPLOG_NCIHAL_D("phNxpNciHal_close (): Adding B passive listen");
2484       numPrms++;
2485       cmd_ce_discovery_nci[ptr++] = 0x81;
2486       cmd_ce_discovery_nci[ptr++] = 0x01;
2487       length += 2;
2488     }
2489     if ((uiccListenMask & 0x4) == 0x04 || (eseListenMask & 0x4) == 0x04) {
2490       NXPLOG_NCIHAL_D("phNxpNciHal_close (): Adding F passive listen");
2491       numPrms++;
2492       cmd_ce_discovery_nci[ptr++] = 0x82;
2493       cmd_ce_discovery_nci[ptr++] = 0x01;
2494       length += 2;
2495     }
2496 
2497     if (length != 0) {
2498       cmd_ce_discovery_nci[2] = length + 1;
2499       cmd_ce_discovery_nci[3] = numPrms;
2500       status = phNxpNciHal_send_ext_cmd(length + 4, cmd_ce_discovery_nci);
2501       if (status != NFCSTATUS_SUCCESS) {
2502         NXPLOG_NCIHAL_E("CMD_CE_DISC_NCI: Failed");
2503       }
2504     } else {
2505       NXPLOG_NCIHAL_E(
2506           "No changes in the discovery command, sticking to last discovery "
2507           "command sent");
2508     }
2509   } else if ((!bShutdown) && IS_CHIP_TYPE_GE(sn220u)) {
2510     if (phNxpNciHal_getULPDetFlag() == true) {
2511       phNxpNciHal_propConfULPDetMode(true);
2512     }
2513   }
2514 close_and_return:
2515   if (IS_CHIP_TYPE_EQ(sn100u) && bShutdown) {
2516     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_system_ese_power_cycle),
2517                                       cmd_system_ese_power_cycle);
2518     if (status != NFCSTATUS_SUCCESS) {
2519       NXPLOG_NCIHAL_E("ese power cycle failed");
2520     }
2521   }
2522   if (IS_CHIP_TYPE_L(sn220u) || bShutdown) {
2523     nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
2524   }
2525   if (phNxpNciHal_getULPDetFlag() == false) {
2526     do {
2527       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
2528 
2529       if (status == NFCSTATUS_SUCCESS) {
2530         break;
2531       } else {
2532         retry++;
2533         NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed %x, perform retry after delay", retry);
2534         usleep(1000 * 1000);
2535         if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
2536           // make sure read is pending
2537           NFCSTATUS readStatus = phNxpNciHal_enableTmlRead();
2538           NXPLOG_NCIHAL_D("read status = %x", readStatus);
2539         }
2540         if (retry > 3) {
2541           NXPLOG_NCIHAL_E(
2542               "Maximum retries performed, shall restart HAL to recover");
2543           abort();
2544         }
2545       }
2546     } while (1);
2547 
2548     if (IS_CHIP_TYPE_GE(sn220u) && !bShutdown) {
2549       nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
2550       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_system_set_service_status),
2551                                         cmd_system_set_service_status);
2552       if (status != NFCSTATUS_SUCCESS) {
2553         NXPLOG_NCIHAL_E("NCI SYSTEM SET SERVICE STATUS to OFF Failed");
2554       }
2555     }
2556   }
2557   sem_destroy(&sem_reset_ntf_received);
2558   sem_destroy(&nxpncihal_ctrl.syncSpiNfc);
2559 
2560   if (NULL != gpphTmlNfc_Context->pDevHandle) {
2561     phNxpNciHal_close_complete(NFCSTATUS_SUCCESS);
2562     /* Abort any pending read and write */
2563     status = phTmlNfc_ReadAbort();
2564     status = phTmlNfc_WriteAbort();
2565 
2566     phOsalNfc_Timer_Cleanup();
2567 
2568     status = phTmlNfc_Shutdown();
2569 
2570     if (0 != pthread_join(nxpncihal_ctrl.client_thread, (void**)NULL)) {
2571       NXPLOG_TML_E("Fail to kill client thread!");
2572     }
2573     PhNxpEventLogger::GetInstance().Finalize();
2574     phNxpTempMgr::GetInstance().Reset();
2575     phTmlNfc_CleanUp();
2576 
2577     phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
2578 
2579     memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
2580 
2581     NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed");
2582   }
2583 
2584   CONCURRENCY_UNLOCK();
2585 
2586   phNxpNciHal_cleanup_monitor();
2587   write_unlocked_status = NFCSTATUS_SUCCESS;
2588   phNxpNciHal_release_info();
2589   /* reset config cache */
2590   resetNxpConfig();
2591   /* Return success always */
2592   return NFCSTATUS_SUCCESS;
2593 }
2594 
2595 /******************************************************************************
2596  * Function         phNxpNciHal_close_complete
2597  *
2598  * Description      This function inform libnfc-nci about result of
2599  *                  phNxpNciHal_close.
2600  *
2601  * Returns          void.
2602  *
2603  ******************************************************************************/
phNxpNciHal_close_complete(NFCSTATUS status)2604 void phNxpNciHal_close_complete(NFCSTATUS status) {
2605   static phLibNfc_Message_t msg;
2606 
2607   if (status == NFCSTATUS_SUCCESS) {
2608     msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
2609   } else {
2610     msg.eMsgType = NCI_HAL_ERROR_MSG;
2611   }
2612   msg.pMsgData = NULL;
2613   msg.Size = 0;
2614   nxpncihal_ctrl.hal_open_status = HAL_CLOSED;
2615   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
2616 
2617   return;
2618 }
2619 
2620 /******************************************************************************
2621  * Function         phNxpNciHal_clean_resources
2622  *
2623  * Description      This function clean the resources.
2624  *
2625  * Returns          void.
2626  *
2627  ******************************************************************************/
phNxpNciHal_clean_resources()2628 void phNxpNciHal_clean_resources() {
2629   phNxpNciHal_deinitializeRegRfFwDnld();
2630 
2631   if (gPowerTrackerHandle.stop != NULL) {
2632     gPowerTrackerHandle.stop();
2633   }
2634   phNxpNciHal_WiredSeDispatchEvent(&gWiredSeHandle, NFC_STATE_CHANGE,
2635                                    (WiredSeEvtData)NfcState::NFC_OFF);
2636 
2637   sem_destroy(&sem_reset_ntf_received);
2638   sem_destroy(&nxpncihal_ctrl.syncSpiNfc);
2639 
2640   if (NULL != gpphTmlNfc_Context->pDevHandle) {
2641     phNxpNciHal_close_complete(NFCSTATUS_SUCCESS);
2642     /* Abort any pending read and write */
2643     NFCSTATUS status = phTmlNfc_ReadAbort();
2644     if (status != NFCSTATUS_SUCCESS) {
2645       NXPLOG_TML_E("phTmlNfc_ReadAbort Failed");
2646     }
2647     phOsalNfc_Timer_Cleanup();
2648 
2649     status = phTmlNfc_Shutdown();
2650     if (status != NFCSTATUS_SUCCESS) {
2651       NXPLOG_TML_E("phTmlNfc_Shutdown Failed");
2652     }
2653 
2654     PhNxpEventLogger::GetInstance().Finalize();
2655     phNxpTempMgr::GetInstance().Reset();
2656     phTmlNfc_CleanUp();
2657 
2658     phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
2659 
2660     memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
2661   }
2662 
2663   phNxpNciHal_cleanup_monitor();
2664   write_unlocked_status = NFCSTATUS_SUCCESS;
2665   phNxpNciHal_release_info();
2666   /* reset config cache */
2667   resetNxpConfig();
2668 }
2669 
2670 /******************************************************************************
2671  * Function         phNxpNciHal_configDiscShutdown
2672  *
2673  * Description      Enable the CE and VEN config during shutdown.
2674  *
2675  * Returns          Always return NFCSTATUS_SUCCESS (0).
2676  *
2677  ******************************************************************************/
phNxpNciHal_configDiscShutdown(void)2678 int phNxpNciHal_configDiscShutdown(void) {
2679   NFCSTATUS status;
2680   /*NCI_RESET_CMD*/
2681 
2682   uint8_t cmd_disable_disc[] = {0x21, 0x06, 0x01, 0x00};
2683 
2684   uint8_t cmd_ce_disc_nci[] = {0x21, 0x03, 0x07, 0x03, 0x80,
2685                                0x01, 0x81, 0x01, 0x82, 0x01};
2686 
2687   uint8_t cmd_ven_pulld_enable_nci[] = {0x20, 0x02, 0x05, 0x01,
2688                                         0xA0, 0x07, 0x01, 0x03};
2689 
2690   /* Discover map - PROTOCOL_ISO_DEP, PROTOCOL_T3T and MIFARE Classic*/
2691   uint8_t cmd_disc_map[] = {0x21, 0x00, 0x0A, 0x03, 0x04, 0x03, 0x02,
2692                             0x03, 0x02, 0x01, 0x80, 0x01, 0x80};
2693   CONCURRENCY_LOCK();
2694 
2695   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_disable_disc), cmd_disable_disc);
2696   if (status != NFCSTATUS_SUCCESS) {
2697     NXPLOG_NCIHAL_E("CMD_DISABLE_DISCOVERY: Failed");
2698   }
2699   if (IS_CHIP_TYPE_L(sn100u)) {
2700     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ven_pulld_enable_nci),
2701                                       cmd_ven_pulld_enable_nci);
2702     if (status != NFCSTATUS_SUCCESS) {
2703       NXPLOG_NCIHAL_E("CMD_VEN_PULLD_ENABLE_NCI: Failed");
2704     }
2705   }
2706 
2707   if (IS_CHIP_TYPE_GE(sn100u)) {
2708     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_disc_map), cmd_disc_map);
2709     if (status != NFCSTATUS_SUCCESS) {
2710       NXPLOG_NCIHAL_E("Discovery Map command: Failed");
2711     }
2712     status = phNxpNciHal_ext_send_sram_config_to_flash();
2713     if (status != NFCSTATUS_SUCCESS) {
2714       NXPLOG_NCIHAL_E("Updation of the SRAM contents failed");
2715     }
2716   }
2717   if (IS_CHIP_TYPE_GE(sn220u)) {
2718     if (phNxpNciHal_isULPDetSupported() &&
2719         phNxpNciHal_getULPDetFlag() == false) {
2720       if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
2721         NXPLOG_NCIHAL_D("phNxpNciHal_close is already closed, ignoring close");
2722         CONCURRENCY_UNLOCK();
2723         return NFCSTATUS_FAILED;
2724       }
2725       NXPLOG_NCIHAL_D("Ulpdet supported");
2726       status = phNxpNciHal_propConfULPDetMode(true);
2727       CONCURRENCY_UNLOCK();
2728       phNxpNciHal_clean_resources();
2729       return status;
2730     }
2731   }
2732   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_disc_nci), cmd_ce_disc_nci);
2733   if (status != NFCSTATUS_SUCCESS) {
2734     NXPLOG_NCIHAL_E("CMD_CE_DISC_NCI: Failed");
2735   }
2736 
2737   CONCURRENCY_UNLOCK();
2738 
2739   status = phNxpNciHal_close(true);
2740   if (status != NFCSTATUS_SUCCESS) {
2741     NXPLOG_NCIHAL_E("NCI_HAL_CLOSE: Failed");
2742   }
2743 
2744   /* Return success always */
2745   return NFCSTATUS_SUCCESS;
2746 }
2747 
2748 /******************************************************************************
2749  * Function         phNxpNciHal_notify_i2c_fragmentation
2750  *
2751  * Description      This function can be used by HAL to inform
2752  *                 libnfc-nci that i2c fragmentation is enabled/disabled
2753  *
2754  * Returns          void.
2755  *
2756  ******************************************************************************/
phNxpNciHal_notify_i2c_fragmentation(void)2757 void phNxpNciHal_notify_i2c_fragmentation(void) {
2758   if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
2759     /*inform libnfc-nci that i2c fragmentation is enabled/disabled */
2760     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT,
2761                                         HAL_NFC_STATUS_OK);
2762   }
2763 }
2764 /******************************************************************************
2765  * Function         phNxpNciHal_control_granted
2766  *
2767  * Description      Called by libnfc-nci when NFCC control is granted to HAL.
2768  *
2769  * Returns          Always returns NFCSTATUS_SUCCESS (0).
2770  *
2771  ******************************************************************************/
phNxpNciHal_control_granted(void)2772 int phNxpNciHal_control_granted(void) {
2773   /* Take the concurrency lock so no other calls from upper layer
2774    * will be allowed
2775    */
2776   CONCURRENCY_LOCK();
2777 
2778   if (NULL != nxpncihal_ctrl.p_control_granted_cback) {
2779     (*nxpncihal_ctrl.p_control_granted_cback)();
2780   }
2781   /* At the end concurrency unlock so calls from upper layer will
2782    * be allowed
2783    */
2784   CONCURRENCY_UNLOCK();
2785   return NFCSTATUS_SUCCESS;
2786 }
2787 
2788 /******************************************************************************
2789  * Function         phNxpNciHal_request_control
2790  *
2791  * Description      This function can be used by HAL to request control of
2792  *                  NFCC to libnfc-nci. When control is provided to HAL it is
2793  *                  notified through phNxpNciHal_control_granted.
2794  *
2795  * Returns          void.
2796  *
2797  ******************************************************************************/
phNxpNciHal_request_control(void)2798 void phNxpNciHal_request_control(void) {
2799   if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
2800     /* Request Control of NCI Controller from NCI NFC Stack */
2801     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_REQUEST_CONTROL_EVT,
2802                                         HAL_NFC_STATUS_OK);
2803   }
2804 
2805   return;
2806 }
2807 
2808 /******************************************************************************
2809  * Function         phNxpNciHal_release_control
2810  *
2811  * Description      This function can be used by HAL to release the control of
2812  *                  NFCC back to libnfc-nci.
2813  *
2814  * Returns          void.
2815  *
2816  ******************************************************************************/
phNxpNciHal_release_control(void)2817 void phNxpNciHal_release_control(void) {
2818   if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
2819     /* Release Control of NCI Controller to NCI NFC Stack */
2820     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_RELEASE_CONTROL_EVT,
2821                                         HAL_NFC_STATUS_OK);
2822   }
2823 
2824   return;
2825 }
2826 
2827 /******************************************************************************
2828  * Function         phNxpNciHal_power_cycle
2829  *
2830  * Description      This function is called by libnfc-nci when power cycling is
2831  *                  performed. When processing is complete it is notified to
2832  *                  libnfc-nci through phNxpNciHal_power_cycle_complete.
2833  *
2834  * Returns          Always return NFCSTATUS_SUCCESS (0).
2835  *
2836  ******************************************************************************/
phNxpNciHal_power_cycle(void)2837 int phNxpNciHal_power_cycle(void) {
2838   NXPLOG_NCIHAL_D("Power Cycle");
2839   NFCSTATUS status = NFCSTATUS_FAILED;
2840   if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
2841     NXPLOG_NCIHAL_D("Power Cycle failed due to hal status not open");
2842     return NFCSTATUS_FAILED;
2843   }
2844   nxpncihal_ctrl.power_reset_triggered = true;
2845   status = phTmlNfc_IoCtl(phTmlNfc_e_PowerReset);
2846 
2847   if (NFCSTATUS_SUCCESS == status) {
2848     NXPLOG_NCIHAL_D("NFCC Reset - SUCCESS\n");
2849   } else {
2850     NXPLOG_NCIHAL_D("NFCC Reset - FAILED\n");
2851   }
2852 
2853   phNxpNciHal_power_cycle_complete(NFCSTATUS_SUCCESS);
2854   return NFCSTATUS_SUCCESS;
2855 }
2856 
2857 /******************************************************************************
2858  * Function         phNxpNciHal_power_cycle_complete
2859  *
2860  * Description      This function is called to provide the status of
2861  *                  phNxpNciHal_power_cycle to libnfc-nci through callback.
2862  *
2863  * Returns          void.
2864  *
2865  ******************************************************************************/
phNxpNciHal_power_cycle_complete(NFCSTATUS status)2866 static void phNxpNciHal_power_cycle_complete(NFCSTATUS status) {
2867   static phLibNfc_Message_t msg;
2868 
2869   if (status == NFCSTATUS_SUCCESS) {
2870     msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
2871   } else {
2872     msg.eMsgType = NCI_HAL_ERROR_MSG;
2873   }
2874   msg.pMsgData = NULL;
2875   msg.Size = 0;
2876 
2877   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
2878 
2879   return;
2880 }
2881 /******************************************************************************
2882  * Function         phNxpNciHal_check_ncicmd_write_window
2883  *
2884  * Description      This function is called to check the write synchroniztion
2885  *                  status if write already acquired then wait for corresponding
2886                     read to complete.
2887  *
2888  * Returns          return 0 on success and -1 on fail.
2889  *
2890  ******************************************************************************/
2891 
phNxpNciHal_check_ncicmd_write_window(uint16_t cmd_len,uint8_t * p_cmd)2892 int phNxpNciHal_check_ncicmd_write_window(uint16_t cmd_len, uint8_t* p_cmd) {
2893   NFCSTATUS status = NFCSTATUS_FAILED;
2894   int sem_timedout = 2, s;
2895   struct timespec ts;
2896 
2897   if (cmd_len < 1) {
2898     android_errorWriteLog(0x534e4554, "153880357");
2899     return NFCSTATUS_FAILED;
2900   }
2901 
2902   if ((p_cmd[0] & 0xF0) == 0x20) {
2903     clock_gettime(CLOCK_MONOTONIC, &ts);
2904     ts.tv_sec += sem_timedout;
2905     while ((s = sem_timedwait_monotonic_np(&nxpncihal_ctrl.syncSpiNfc, &ts)) == -1 &&
2906            errno == EINTR) {
2907       continue; /* Restart if interrupted by handler */
2908     }
2909     if (s != -1) {
2910       status = NFCSTATUS_SUCCESS;
2911     }
2912   } else {
2913     /* cmd window check not required for writing data packet */
2914     status = NFCSTATUS_SUCCESS;
2915   }
2916   return status;
2917 }
2918 
2919 /******************************************************************************
2920  * Function         phNxpNciHal_ioctl
2921  *
2922  * Description      This function is called by jni when wired mode is
2923  *                  performed.First NFCC driver will give the access
2924  *                  permission whether wired mode is allowed or not
2925  *                  arg (0):
2926  * Returns          return 0 on success and -1 on fail, On success
2927  *                  update the acutual state of operation in arg pointer
2928  *
2929  ******************************************************************************/
phNxpNciHal_ioctl(long arg,void * p_data)2930 int phNxpNciHal_ioctl(long arg, void* p_data) {
2931   return phNxpNciHal_ioctlIf(arg, p_data);
2932 }
2933 
2934 /******************************************************************************
2935  * Function         phNxpNciHal_nfccClockCfgRead
2936  *
2937  * Description      This function is called for loading a data strcuture from
2938  *                  the config file with clock source and clock frequency values
2939  *
2940  * Returns          void.
2941  *
2942  ******************************************************************************/
phNxpNciHal_nfccClockCfgRead(void)2943 static void phNxpNciHal_nfccClockCfgRead(void) {
2944   unsigned long num = 0;
2945   int isfound = 0;
2946 
2947   nxpprofile_ctrl.bClkSrcVal = 0;
2948   nxpprofile_ctrl.bClkFreqVal = 0;
2949   nxpprofile_ctrl.bTimeout = 0;
2950 
2951   isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &num, sizeof(num));
2952   if (isfound > 0) {
2953     nxpprofile_ctrl.bClkSrcVal = num;
2954   }
2955 
2956   num = 0;
2957   isfound = 0;
2958   isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &num, sizeof(num));
2959   if (isfound > 0) {
2960     nxpprofile_ctrl.bClkFreqVal = num;
2961   }
2962 
2963   num = 0;
2964   isfound = 0;
2965   isfound = GetNxpNumValue(NAME_NXP_SYS_CLOCK_TO_CFG, &num, sizeof(num));
2966   if (isfound > 0) {
2967     nxpprofile_ctrl.bTimeout = num;
2968   }
2969 
2970   NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkSrcVal = 0x%x",
2971                   nxpprofile_ctrl.bClkSrcVal);
2972   NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x",
2973                   nxpprofile_ctrl.bClkFreqVal);
2974   NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x",
2975                   nxpprofile_ctrl.bTimeout);
2976 
2977   if ((nxpprofile_ctrl.bClkSrcVal < CLK_SRC_XTAL) ||
2978       (nxpprofile_ctrl.bClkSrcVal > CLK_SRC_PLL)) {
2979     NXPLOG_FWDNLD_E(
2980         "Clock source value is wrong in config file, setting it as default");
2981     nxpprofile_ctrl.bClkSrcVal = NXP_SYS_CLK_SRC_SEL;
2982   }
2983   if ((nxpprofile_ctrl.bClkFreqVal < CLK_FREQ_13MHZ) ||
2984       (nxpprofile_ctrl.bClkFreqVal > CLK_FREQ_76_8MHZ)) {
2985     NXPLOG_FWDNLD_E(
2986         "Clock frequency value is wrong in config file, setting it as default");
2987     nxpprofile_ctrl.bClkFreqVal = NXP_SYS_CLK_FREQ_SEL;
2988   }
2989   if ((nxpprofile_ctrl.bTimeout < CLK_TO_CFG_DEF) ||
2990       (nxpprofile_ctrl.bTimeout > CLK_TO_CFG_MAX)) {
2991     NXPLOG_FWDNLD_E(
2992         "Clock timeout value is wrong in config file, setting it as default");
2993     nxpprofile_ctrl.bTimeout = CLK_TO_CFG_DEF;
2994   }
2995 }
2996 
2997 /******************************************************************************
2998  * Function         phNxpNciHal_determineConfiguredClockSrc
2999  *
3000  * Description      This function determines and encodes clock source based on
3001  *                  clock frequency
3002  *
3003  * Returns          encoded form of clock source
3004  *
3005  *****************************************************************************/
phNxpNciHal_determineConfiguredClockSrc()3006 int phNxpNciHal_determineConfiguredClockSrc() {
3007   uint8_t param_clock_src = CLK_SRC_PLL;
3008   if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) {
3009     if (IS_CHIP_TYPE_EQ(pn553)) {
3010       param_clock_src = param_clock_src << 3;
3011     } else if (IS_CHIP_TYPE_GE(sn100u)) {
3012       param_clock_src = 0;
3013     }
3014 
3015     if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) {
3016       param_clock_src |= 0x00;
3017     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) {
3018       param_clock_src |= 0x01;
3019     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) {
3020       param_clock_src |= 0x02;
3021     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) {
3022       param_clock_src |= 0x03;
3023     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) {
3024       param_clock_src |= 0x04;
3025     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) {
3026       param_clock_src |= 0x05;
3027     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_32MHZ) {
3028       param_clock_src |= 0x06;
3029     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_48MHZ) {
3030       param_clock_src |= 0x0A;
3031     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_76_8MHZ) {
3032       param_clock_src |= 0x0B;
3033     } else {
3034       NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
3035       if (IS_CHIP_TYPE_L(sn100u))
3036         param_clock_src = 0x11;
3037       else
3038         param_clock_src = 0x01;
3039     }
3040   } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) {
3041     param_clock_src = 0x08;
3042 
3043   } else {
3044     NXPLOG_NCIHAL_E("Wrong clock source. Don't apply any modification");
3045   }
3046   return param_clock_src;
3047 }
3048 
3049 /******************************************************************************
3050  * Function         phNxpNciHal_determineConfiguredClockSrc
3051  *
3052  * Description      This function determines and encodes clock source based on
3053  *                  clock frequency
3054  *
3055  * Returns          encoded form of clock source
3056  *
3057  *****************************************************************************/
phNxpNciHal_determineClockDelayRequest(uint8_t nfcc_cfg_clock_src)3058 int phNxpNciHal_determineClockDelayRequest(uint8_t nfcc_cfg_clock_src) {
3059   unsigned long num = 0;
3060   int isfound = 0;
3061   uint8_t nfcc_clock_delay_req = 0;
3062   uint8_t nfcc_clock_set_needed = false;
3063 
3064   isfound = GetNxpNumValue(NAME_NXP_CLOCK_REQ_DELAY, &num, sizeof(num));
3065   if (isfound > 0) {
3066     nxpprofile_ctrl.clkReqDelay = num;
3067   }
3068   if ((nxpprofile_ctrl.clkReqDelay < CLK_REQ_DELAY_MIN) ||
3069       (nxpprofile_ctrl.clkReqDelay > CLK_REQ_DELAY_MAX)) {
3070     NXPLOG_FWDNLD_E(
3071         "default delay to start clock value is wrong in config "
3072         "file, setting it as default");
3073     nxpprofile_ctrl.clkReqDelay = CLK_REQ_DELAY_DEF;
3074     return nfcc_clock_set_needed;
3075   }
3076   nfcc_clock_delay_req = nxpprofile_ctrl.clkReqDelay;
3077 
3078   /*Check if the clock source is XTAL as per config*/
3079   if (nfcc_cfg_clock_src == CLK_CFG_XTAL) {
3080     if (nfcc_clock_delay_req !=
3081         (phNxpNciClock.p_rx_data[CLK_REQ_DELAY_XTAL_OFFSET] &
3082          CLK_REQ_DELAY_MASK)) {
3083       nfcc_clock_set_needed = true;
3084       phNxpNciClock.p_rx_data[CLK_REQ_DELAY_XTAL_OFFSET] &=
3085           ~(CLK_REQ_DELAY_MASK);
3086       phNxpNciClock.p_rx_data[CLK_REQ_DELAY_XTAL_OFFSET] |=
3087           (nfcc_clock_delay_req & CLK_REQ_DELAY_MASK);
3088     }
3089   }
3090   /*Check if the clock source is PLL as per config*/
3091   else if (nfcc_cfg_clock_src < 6) {
3092     if (nfcc_clock_delay_req !=
3093         (phNxpNciClock.p_rx_data[CLK_REQ_DELAY_PLL_OFFSET] &
3094          CLK_REQ_DELAY_MASK)) {
3095       nfcc_clock_set_needed = true;
3096       phNxpNciClock.p_rx_data[CLK_REQ_DELAY_PLL_OFFSET] &=
3097           ~(CLK_REQ_DELAY_MASK);
3098       phNxpNciClock.p_rx_data[CLK_REQ_DELAY_PLL_OFFSET] |=
3099           (nfcc_clock_delay_req & CLK_REQ_DELAY_MASK);
3100     }
3101   }
3102   return nfcc_clock_set_needed;
3103 }
3104 
3105 /******************************************************************************
3106  * Function         phNxpNciHal_nfccClockCfgApply
3107  *
3108  * Description      This function is called after successful download
3109  *                  to check if clock settings in config file and chip
3110  *                  is same
3111  *
3112  * Returns          void.
3113  *
3114  ******************************************************************************/
phNxpNciHal_nfccClockCfgApply(void)3115 NFCSTATUS phNxpNciHal_nfccClockCfgApply(void) {
3116   NFCSTATUS status = NFCSTATUS_SUCCESS;
3117   uint8_t nfcc_cfg_clock_src, nfcc_cur_clock_src;
3118   uint8_t nfcc_clock_set_needed;
3119   uint8_t nfcc_clock_delay_req;
3120   static uint8_t* get_clock_cmd;
3121   uint8_t get_clck_cmd[] = {0x20, 0x03, 0x07, 0x03, 0xA0,
3122                             0x02, 0xA0, 0x03, 0xA0, 0x04};
3123   uint8_t get_clck_cmd_sn100[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x11};
3124   uint8_t set_clck_cmd[] = {0x20, 0x02, 0x0B, 0x01, 0xA0, 0x11, 0x07,
3125                             0x01, 0x0A, 0x32, 0x02, 0x01, 0xF6, 0xF6};
3126   uint8_t get_clk_size = 0;
3127 
3128   if (IS_CHIP_TYPE_L(sn100u)) {
3129     get_clock_cmd = get_clck_cmd;
3130     get_clk_size = sizeof(get_clck_cmd);
3131   } else {
3132     get_clock_cmd = get_clck_cmd_sn100;
3133     get_clk_size = sizeof(get_clck_cmd_sn100);
3134   }
3135   phNxpNciHal_nfccClockCfgRead();
3136   phNxpNciClock.isClockSet = true;
3137   status = phNxpNciHal_send_ext_cmd(get_clk_size, get_clock_cmd);
3138   phNxpNciClock.isClockSet = false;
3139 
3140   if (status != NFCSTATUS_SUCCESS) {
3141     NXPLOG_NCIHAL_E("unable to retrieve get_clk_src_sel");
3142     return status;
3143   }
3144 
3145   nfcc_cfg_clock_src = phNxpNciHal_determineConfiguredClockSrc();
3146   if (IS_CHIP_TYPE_L(sn100u)) {
3147     nfcc_cur_clock_src = phNxpNciClock.p_rx_data[12];
3148   } else {
3149     nfcc_cur_clock_src = phNxpNciClock.p_rx_data[8];
3150   }
3151 
3152   if (IS_CHIP_TYPE_L(sn100u)) {
3153     nfcc_clock_set_needed =
3154         (nfcc_cfg_clock_src != nfcc_cur_clock_src ||
3155          phNxpNciClock.p_rx_data[16] == nxpprofile_ctrl.bTimeout)
3156             ? true
3157             : false;
3158   } else {
3159     nfcc_clock_delay_req =
3160         phNxpNciHal_determineClockDelayRequest(nfcc_cfg_clock_src);
3161     /**Determine clock src is as expected*/
3162     nfcc_clock_set_needed =
3163         ((nfcc_cfg_clock_src != nfcc_cur_clock_src || nfcc_clock_delay_req)
3164              ? true
3165              : false);
3166   }
3167 
3168   if (nfcc_clock_set_needed) {
3169     NXPLOG_NCIHAL_D("Setting Clock Source and Frequency");
3170     if (IS_CHIP_TYPE_L(sn100u)) {
3171       phNxpNciHal_txNfccClockSetCmd();
3172     } else {
3173       /*Read the preset value from FW*/
3174       memcpy(&set_clck_cmd[7], &phNxpNciClock.p_rx_data[8],
3175              phNxpNciClock.p_rx_data[7]);
3176       /*Update clock source and frequency as per DH configuration*/
3177       set_clck_cmd[7] = nfcc_cfg_clock_src;
3178       status = phNxpNciHal_send_ext_cmd(sizeof(set_clck_cmd), set_clck_cmd);
3179     }
3180   }
3181 
3182   return status;
3183 }
3184 
3185 /******************************************************************************
3186  * Function         phNxpNciHal_get_mw_eeprom
3187  *
3188  * Description      This function is called to retrieve data in mw eeprom area
3189  *
3190  * Returns          NFCSTATUS.
3191  *
3192  ******************************************************************************/
phNxpNciHal_get_mw_eeprom(void)3193 static NFCSTATUS phNxpNciHal_get_mw_eeprom(void) {
3194   NFCSTATUS status = NFCSTATUS_SUCCESS;
3195   uint8_t retry_cnt = 0;
3196   static uint8_t get_mw_eeprom_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x0F};
3197 
3198 retry_send_ext:
3199   if (retry_cnt > 3) {
3200     return NFCSTATUS_FAILED;
3201   }
3202 
3203   phNxpNciMwEepromArea.isGetEepromArea = true;
3204   status =
3205       phNxpNciHal_send_ext_cmd(sizeof(get_mw_eeprom_cmd), get_mw_eeprom_cmd);
3206   if (status != NFCSTATUS_SUCCESS) {
3207     NXPLOG_NCIHAL_D("unable to get the mw eeprom data");
3208     phNxpNciMwEepromArea.isGetEepromArea = false;
3209     retry_cnt++;
3210     goto retry_send_ext;
3211   }
3212   phNxpNciMwEepromArea.isGetEepromArea = false;
3213 
3214   if (phNxpNciMwEepromArea.p_rx_data[12]) {
3215     fw_download_success = 1;
3216   }
3217   return status;
3218 }
3219 
3220 /******************************************************************************
3221  * Function         phNxpNciHal_set_mw_eeprom
3222  *
3223  * Description      This function is called to update data in mw eeprom area
3224  *
3225  * Returns          void.
3226  *
3227  ******************************************************************************/
phNxpNciHal_set_mw_eeprom(void)3228 static NFCSTATUS phNxpNciHal_set_mw_eeprom(void) {
3229   NFCSTATUS status = NFCSTATUS_SUCCESS;
3230   uint8_t retry_cnt = 0;
3231   uint8_t set_mw_eeprom_cmd[39] = {0};
3232   uint8_t cmd_header[] = {0x20, 0x02, 0x24, 0x01, 0xA0, 0x0F, 0x20};
3233 
3234   memcpy(set_mw_eeprom_cmd, cmd_header, sizeof(cmd_header));
3235   phNxpNciMwEepromArea.p_rx_data[12] = 0;
3236   memcpy(set_mw_eeprom_cmd + sizeof(cmd_header), phNxpNciMwEepromArea.p_rx_data,
3237          sizeof(phNxpNciMwEepromArea.p_rx_data));
3238 
3239 retry_send_ext:
3240   if (retry_cnt > 3) {
3241     return NFCSTATUS_FAILED;
3242   }
3243 
3244   status =
3245       phNxpNciHal_send_ext_cmd(sizeof(set_mw_eeprom_cmd), set_mw_eeprom_cmd);
3246   if (status != NFCSTATUS_SUCCESS) {
3247     NXPLOG_NCIHAL_D("unable to update the mw eeprom data");
3248     retry_cnt++;
3249     goto retry_send_ext;
3250   }
3251   return status;
3252 }
3253 
3254 /******************************************************************************
3255  * Function         phNxpNciHal_china_tianjin_rf_setting
3256  *
3257  * Description      This function is called to check RF Setting
3258  *
3259  * Returns          Status.
3260  *
3261  ******************************************************************************/
phNxpNciHal_china_tianjin_rf_setting(void)3262 NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void) {
3263   NFCSTATUS status = NFCSTATUS_SUCCESS;
3264   const int GET_CONFIG_STATUS_INDEX = 3;
3265   const int GET_CONFIG_RF_MISC_TAG_START_INDEX = 5;
3266   const int GET_CONFIG_RF_MISC_TAG_NUM_OF_BYTES = 7;
3267 
3268   uint8_t retry_cnt = 0;
3269 
3270   static uint8_t get_rf_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x85};
3271   NXPLOG_NCIHAL_D("phNxpNciHal_china_tianjin_rf_setting - Enter");
3272 
3273 retry_send_ext:
3274   if (retry_cnt > 3) {
3275     return NFCSTATUS_FAILED;
3276   }
3277 
3278   phNxpNciRfSet.isGetRfSetting = true;
3279   status = phNxpNciHal_send_ext_cmd(sizeof(get_rf_cmd), get_rf_cmd);
3280   if (status != NFCSTATUS_SUCCESS) {
3281     NXPLOG_NCIHAL_E("unable to get the RF setting");
3282     phNxpNciRfSet.isGetRfSetting = false;
3283     retry_cnt++;
3284     goto retry_send_ext;
3285   }
3286   phNxpNciRfSet.isGetRfSetting = false;
3287   if ((int)phNxpNciRfSet.p_rx_data.size() <= GET_CONFIG_STATUS_INDEX ||
3288       ((int)phNxpNciRfSet.p_rx_data.size() > GET_CONFIG_STATUS_INDEX &&
3289        phNxpNciRfSet.p_rx_data[GET_CONFIG_STATUS_INDEX] != 0x00)) {
3290     NXPLOG_NCIHAL_E("GET_CONFIG_RSP is FAILED for CHINA TIANJIN");
3291     return status;
3292   }
3293 
3294   bool isUpdateRequired = phNxpNciHal_UpdateRfMiscSettings();
3295 
3296   if (isUpdateRequired) {
3297     vector<uint8_t> set_rf_cmd = {0x20, 0x02, 0x08, 0x01};
3298     if ((int)phNxpNciRfSet.p_rx_data.size() >=
3299         (GET_CONFIG_RF_MISC_TAG_START_INDEX +
3300          GET_CONFIG_RF_MISC_TAG_NUM_OF_BYTES)) {
3301       set_rf_cmd.insert(
3302           set_rf_cmd.end(),
3303           phNxpNciRfSet.p_rx_data.begin() + GET_CONFIG_RF_MISC_TAG_START_INDEX,
3304           phNxpNciRfSet.p_rx_data.begin() + GET_CONFIG_RF_MISC_TAG_START_INDEX +
3305               GET_CONFIG_RF_MISC_TAG_NUM_OF_BYTES);
3306       status = phNxpNciHal_send_ext_cmd(set_rf_cmd.size(), set_rf_cmd.data());
3307     } else {
3308       status = NFCSTATUS_FAILED;
3309     }
3310     if (status != NFCSTATUS_SUCCESS) {
3311       NXPLOG_NCIHAL_E("unable to set the RF setting");
3312       retry_cnt++;
3313       goto retry_send_ext;
3314     }
3315   }
3316 
3317   return status;
3318 }
3319 
3320 /******************************************************************************
3321  * Function         phNxpNciHal_UpdateRfMiscSettings
3322  *
3323  * Description      This will look the configuration properties and
3324  *                  update the RF misc settings
3325  *
3326  * Returns          bool - true if the RF Misc settings update required
3327  *                      otherwise false
3328  *
3329  ******************************************************************************/
phNxpNciHal_UpdateRfMiscSettings()3330 bool phNxpNciHal_UpdateRfMiscSettings() {
3331   vector<phRfMiscSettings> settings;
3332 
3333   const int MISC_CHINA_BLK_INDEX = 8;
3334   const int MISC_MIFARE_CONFIG_RATS_INDEX = 9;
3335   const int MISC_TIANJIN_RF_INDEX = 11;
3336   const int MISC_CN_TRANSIT_CMA_INDEX = 10;
3337   const int MISC_TIANJIN_RF_INDEX_PN557 = 10;
3338   const uint8_t MISC_TIANJIN_RF_BITMASK = 0x10;
3339   const uint8_t MISC_TIANJIN_RF_BITMASK_PN557 = 0x40;
3340   const uint8_t MISC_MIFARE_NACK_TO_RATS_BITMASK = 0x20;
3341   const uint8_t MISC_MIFARE_MUTE_TO_RATS_BITMASK = 0x02;
3342   const uint8_t MISC_CHINA_BLK_NUM_CHK_BITMASK = 0x40;
3343   const uint8_t MISC_CN_TRANSIT_CMA_BYPASSMODE_BITMASK = 0x80;
3344 
3345   bool isUpdaterequired = false;
3346   if (nfcFL.nfccFL._NFCC_MIFARE_TIANJIN) {
3347     settings.push_back({NAME_NXP_CHINA_TIANJIN_RF_ENABLED,
3348                         MISC_TIANJIN_RF_INDEX_PN557,
3349                         MISC_TIANJIN_RF_BITMASK_PN557});
3350   } else {
3351     settings.push_back({NAME_NXP_CHINA_TIANJIN_RF_ENABLED,
3352                         MISC_TIANJIN_RF_INDEX, MISC_TIANJIN_RF_BITMASK});
3353   }
3354   settings.push_back({NAME_NXP_MIFARE_NACK_TO_RATS_ENABLE,
3355                       MISC_MIFARE_CONFIG_RATS_INDEX,
3356                       MISC_MIFARE_NACK_TO_RATS_BITMASK});
3357   settings.push_back({NAME_NXP_MIFARE_MUTE_TO_RATS_ENABLE,
3358                       MISC_MIFARE_CONFIG_RATS_INDEX,
3359                       MISC_MIFARE_MUTE_TO_RATS_BITMASK});
3360   settings.push_back({NAME_NXP_CHINA_BLK_NUM_CHK_ENABLE, MISC_CHINA_BLK_INDEX,
3361                       MISC_CHINA_BLK_NUM_CHK_BITMASK});
3362   settings.push_back({NAME_NXP_CN_TRANSIT_CMA_BYPASSMODE_ENABLE,
3363                       MISC_CN_TRANSIT_CMA_INDEX,
3364                       MISC_CN_TRANSIT_CMA_BYPASSMODE_BITMASK});
3365 
3366   vector<phRfMiscSettings>::iterator it;
3367   for (it = settings.begin(); it != settings.end(); it++) {
3368     unsigned long config_value = 0;
3369     int position = it->configPosition;
3370     if ((int)phNxpNciRfSet.p_rx_data.size() <= position) {
3371       NXPLOG_NCIHAL_E(
3372           "Can't update the value due to the length issue, hence ignoring %s",
3373           it->configName);
3374       continue;
3375     }
3376     int rf_val = phNxpNciRfSet.p_rx_data[position];
3377     int isfound = (GetNxpNumValue(it->configName, (void*)&config_value,
3378                                   sizeof(config_value)));
3379     if (isfound > 0) {
3380       uint8_t configBitMask = it->configBitMask;
3381       int enable_bit = rf_val & configBitMask;
3382       if ((enable_bit != configBitMask) && (config_value == 1)) {
3383         phNxpNciRfSet.p_rx_data[position] |=
3384             configBitMask;  // Enable if it is disabled
3385         isUpdaterequired = true;
3386       } else if ((enable_bit == configBitMask) && (config_value == 0)) {
3387         phNxpNciRfSet.p_rx_data[position] &=
3388             ~configBitMask;  // Disable if it is Enabled
3389         isUpdaterequired = true;
3390       } else {
3391         NXPLOG_NCIHAL_E("No change in value, hence ignoring %s",
3392                         it->configName);
3393       }
3394     }
3395   }
3396 
3397   return isUpdaterequired;
3398 }
3399 
3400 /******************************************************************************
3401  * Function         phNxpNciHal_DownloadFw
3402  *
3403  * Description      It is used to trigger the FW download as part of FW tearing
3404  *                  scenario handling. It downloads either degraded or Normal
3405  *                  FW, based on the session state of the NFCC.
3406  *
3407  * Returns          void
3408  *
3409  ******************************************************************************/
phNxpNciHal_DownloadFw(bool isMinFwVer,bool degradedFwDnld)3410 static void phNxpNciHal_DownloadFw(bool isMinFwVer, bool degradedFwDnld) {
3411   NFCSTATUS status = NFCSTATUS_FAILED;
3412   phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
3413   if (isMinFwVer) {
3414     /* since minimal fw required dlreset to boot in Download mode */
3415     status = phNxpNciHal_dlResetInFwDnldMode();
3416     if (status != NFCSTATUS_SUCCESS) {
3417       NXPLOG_NCIHAL_E("DL Reset failed for minimal fw");
3418     }
3419   }
3420   phTmlNfc_EnableFwDnldMode(true);
3421 
3422   /* Set the obtained device handle to download module */
3423   phDnldNfc_SetHwDevHandle();
3424   NXPLOG_NCIHAL_D("Calling Seq handler for FW Download \n");
3425   status = phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal,
3426                                        nxpprofile_ctrl.bClkFreqVal, 0, false,
3427                                        degradedFwDnld);
3428   if (status != NFCSTATUS_SUCCESS) {
3429     NXPLOG_NCIHAL_E("FW Download Sequence Handler Failed.");
3430   } else {
3431     property_set("nfc.fw.force_download", "0");
3432     fw_download_success = 1;
3433   }
3434 
3435   status = phNxpNciHal_dlResetInFwDnldMode();
3436   if (status != NFCSTATUS_SUCCESS) {
3437     NXPLOG_NCIHAL_E("DL Reset failed in FW DN mode");
3438   }
3439 }
3440 
3441 /******************************************************************************
3442  * Function         phNxpNciHal_CheckAndHandleFwTearDown
3443  *
3444  * Description      Check Whether chip is in FW download mode, If chip is in
3445  *                  Download mode and previous session is not complete, then
3446  *                  Do force FW update.
3447  *
3448  * Returns          void
3449  *
3450  ******************************************************************************/
phNxpNciHal_CheckAndHandleFwTearDown()3451 void phNxpNciHal_CheckAndHandleFwTearDown() {
3452   NFCSTATUS status = NFCSTATUS_FAILED;
3453   uint8_t session_state = -1;
3454   unsigned long minimal_fw_version = DEFAULT_MINIMAL_FW_VERSION;
3455   bool isMinFwVer = false;
3456   status = phNxpNciHal_getChipInfoInFwDnldMode();
3457   if (status != NFCSTATUS_SUCCESS) {
3458     NXPLOG_NCIHAL_E("Get Chip Info Failed");
3459     usleep(150 * 1000);
3460     return;
3461   }
3462   if (!GetNxpNumValue(NAME_NXP_MINIMAL_FW_VERSION, &minimal_fw_version,
3463                       sizeof(minimal_fw_version))) {
3464     /* If config file doesn't contain the info use default */
3465     minimal_fw_version = DEFAULT_MINIMAL_FW_VERSION;
3466   }
3467   if (wFwVerRsp != minimal_fw_version) {
3468     session_state = phNxpNciHal_getSessionInfoInFwDnldMode();
3469     if (session_state == 0) {
3470       NXPLOG_NCIHAL_E("NFC not in the teared state, boot NFCC in NCI mode");
3471       return;
3472     }
3473   } else {
3474     isMinFwVer = true;
3475   }
3476   if (session_state == EOS_FW_SESSION_STATE_LOCKED) {
3477     phNxpNciHal_DownloadFw(isMinFwVer, true);
3478   }
3479   phNxpNciHal_DownloadFw(isMinFwVer);
3480 }
3481 
3482 /******************************************************************************
3483  * Function         phNxpNciHal_getChipInfoInFwDnldMode
3484  *
3485  * Description      Helper function to get the chip info in download mode
3486  *
3487  * Returns          Status
3488  *
3489  ******************************************************************************/
phNxpNciHal_getChipInfoInFwDnldMode(bool bIsVenResetReqd)3490 NFCSTATUS phNxpNciHal_getChipInfoInFwDnldMode(bool bIsVenResetReqd) {
3491   uint8_t get_chip_info_cmd[] = {0x00, 0x04, 0xF1, 0x00,
3492                                  0x00, 0x00, 0x6E, 0xEF};
3493   NFCSTATUS status = NFCSTATUS_FAILED;
3494   int retry_cnt = 0;
3495   if (bIsVenResetReqd) {
3496     status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadModeWithVenRst);
3497     if (status != NFCSTATUS_SUCCESS) {
3498       NXPLOG_NCIHAL_E("Enable Download mode failed");
3499       return status;
3500     }
3501   }
3502   phTmlNfc_EnableFwDnldMode(true);
3503   do {
3504     status =
3505         phNxpNciHal_send_ext_cmd(sizeof(get_chip_info_cmd), get_chip_info_cmd);
3506     if (status != NFCSTATUS_SUCCESS) {
3507       /* break the loop if HAL write failed or response Timeout */
3508       break;
3509     } else {
3510       /* Check FW getResponse command response status byte */
3511       if (nxpncihal_ctrl.p_rx_data[0] == 0x00) {
3512         if (nxpncihal_ctrl.p_rx_data[2] != 0x00) {
3513           status = NFCSTATUS_FAILED;
3514           /* Resend DL_GET_VERSION_CMD to recover from error
3515            * such as DL_PROTOCOL_ERROR.
3516            */
3517           if (retry_cnt < MAX_RETRY_COUNT) {
3518             retry_cnt++;
3519             /* No default read pending in FW dowbload mode.
3520              * Thus, keep read pending before every cmd retry
3521              */
3522             if (phNxpNciHal_enableTmlRead() != NFCSTATUS_PENDING) {
3523               NXPLOG_NCIHAL_E("%s read error", __func__);
3524             }
3525           }
3526         }
3527       } else {
3528         status = NFCSTATUS_FAILED;
3529         break;
3530       }
3531     }
3532   } while ((status != NFCSTATUS_SUCCESS) && (retry_cnt < MAX_RETRY_COUNT));
3533 
3534   phTmlNfc_EnableFwDnldMode(false);
3535   if (phNxpNciHal_enableTmlRead() != NFCSTATUS_PENDING) {
3536     NXPLOG_NCIHAL_E("%s read status error status", __FUNCTION__);
3537   }
3538   if (status == NFCSTATUS_SUCCESS) {
3539     phNxpNciHal_configFeatureList(nxpncihal_ctrl.p_rx_data,
3540                                   nxpncihal_ctrl.rx_data_len);
3541     wFwVerRsp = pConfigFL->getFWVersionInfo(nxpncihal_ctrl.p_rx_data,
3542                                             nxpncihal_ctrl.rx_data_len);
3543     setNxpFwConfigPath();
3544   }
3545   return status;
3546 }
3547 
3548 /******************************************************************************
3549  * Function         phNxpNciHal_getSessionInfoInFwDnldMode
3550  *
3551  * Description      Helper function to get the session info in download mode
3552  *
3553  * Returns          0 means session closed
3554  *
3555  ******************************************************************************/
phNxpNciHal_getSessionInfoInFwDnldMode()3556 uint8_t phNxpNciHal_getSessionInfoInFwDnldMode() {
3557   uint8_t session_status = -1;
3558   uint8_t get_session_info_cmd[] = {0x00, 0x04, 0xF2, 0x00,
3559                                     0x00, 0x00, 0xF5, 0x33};
3560   phTmlNfc_EnableFwDnldMode(true);
3561   NFCSTATUS status = phNxpNciHal_send_ext_cmd(sizeof(get_session_info_cmd),
3562                                               get_session_info_cmd);
3563   if (status == NFCSTATUS_SUCCESS) {
3564     /* Check FW getResponse command response status byte */
3565     if (nxpncihal_ctrl.p_rx_data[2] == 0x00 &&
3566         nxpncihal_ctrl.p_rx_data[0] == 0x00) {
3567       session_status = nxpncihal_ctrl.p_rx_data[3];
3568     } else {
3569       NXPLOG_NCIHAL_D("get session info Failed !!!");
3570       usleep(150 * 1000);
3571     }
3572   }
3573   status = phNxpNciHal_dlResetInFwDnldMode();
3574   if (status != NFCSTATUS_SUCCESS) {
3575     NXPLOG_NCIHAL_E("DL Reset failed in FW DN mode");
3576   }
3577   return session_status;
3578 }
3579 
3580 /******************************************************************************
3581  * Function         phNxpNciHal_dlResetInFwDnldMode
3582  *
3583  * Description      Helper function to change the mode from FW to NCI
3584  *
3585  * Returns          Status
3586  *
3587  ******************************************************************************/
phNxpNciHal_dlResetInFwDnldMode()3588 NFCSTATUS phNxpNciHal_dlResetInFwDnldMode() {
3589   NFCSTATUS status = NFCSTATUS_FAILED;
3590   phTmlNfc_EnableFwDnldMode(true);
3591   NXPLOG_NCIHAL_D("Sending DL Reset for NFCC soft reboot");
3592   phDnldNfc_SetHwDevHandle();
3593 
3594   status = phNxpNciHal_fw_dnld_switch_normal_mode();
3595 
3596   phTmlNfc_EnableFwDnldMode(false);
3597   phTmlNfc_ReadAbort();
3598   phDnldNfc_ReSetHwDevHandle();
3599   if (phNxpNciHal_enableTmlRead() != NFCSTATUS_PENDING) {
3600     NXPLOG_NCIHAL_E("%s read status error status", __FUNCTION__);
3601     status = NFCSTATUS_FAILED;
3602   }
3603   return status;
3604 }
3605 
3606 /******************************************************************************
3607  * Function         phNxpNciHal_gpio_restore
3608  *
3609  * Description      This function restores the gpio values into eeprom
3610  *
3611  * Returns          void
3612  *
3613  ******************************************************************************/
phNxpNciHal_gpio_restore(phNxpNciHal_GpioInfoState state)3614 static void phNxpNciHal_gpio_restore(phNxpNciHal_GpioInfoState state) {
3615   NFCSTATUS status = NFCSTATUS_SUCCESS;
3616   uint8_t get_gpio_values_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x00};
3617   uint8_t set_gpio_values_cmd[] = {
3618       0x20, 0x02, 0x00, 0x01, 0xA0, 0x00, 0x20, 0x00, 0x00, 0x00,
3619       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3620       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3621       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3622 
3623   if (state == GPIO_STORE) {
3624     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_STORE;
3625     get_gpio_values_cmd[5] = 0x08;
3626     status = phNxpNciHal_send_ext_cmd(sizeof(get_gpio_values_cmd),
3627                                       get_gpio_values_cmd);
3628     if (status != NFCSTATUS_SUCCESS) {
3629       NXPLOG_NCIHAL_E("Failed to get GPIO values!!!\n");
3630       return;
3631     }
3632 
3633     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_STORE_DONE;
3634     set_gpio_values_cmd[2] = 0x24;
3635     set_gpio_values_cmd[5] = 0x14;
3636     set_gpio_values_cmd[7] = nxpncihal_ctrl.phNxpNciGpioInfo.values[0];
3637     set_gpio_values_cmd[8] = nxpncihal_ctrl.phNxpNciGpioInfo.values[1];
3638     status = phNxpNciHal_send_ext_cmd(sizeof(set_gpio_values_cmd),
3639                                       set_gpio_values_cmd);
3640     if (status != NFCSTATUS_SUCCESS) {
3641       NXPLOG_NCIHAL_E("Failed to set GPIO values!!!\n");
3642       return;
3643     }
3644   } else if (state == GPIO_RESTORE) {
3645     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_RESTORE;
3646     get_gpio_values_cmd[5] = 0x14;
3647     status = phNxpNciHal_send_ext_cmd(sizeof(get_gpio_values_cmd),
3648                                       get_gpio_values_cmd);
3649     if (status != NFCSTATUS_SUCCESS) {
3650       NXPLOG_NCIHAL_E("Failed to get GPIO values!!!\n");
3651       return;
3652     }
3653 
3654     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_RESTORE_DONE;
3655     set_gpio_values_cmd[2] = 0x06;
3656     set_gpio_values_cmd[5] = 0x08;  // update TAG
3657     set_gpio_values_cmd[6] = 0x02;  // update length
3658     set_gpio_values_cmd[7] = nxpncihal_ctrl.phNxpNciGpioInfo.values[0];
3659     set_gpio_values_cmd[8] = nxpncihal_ctrl.phNxpNciGpioInfo.values[1];
3660     status = phNxpNciHal_send_ext_cmd(9, set_gpio_values_cmd);
3661     if (status != NFCSTATUS_SUCCESS) {
3662       NXPLOG_NCIHAL_E("Failed to set GPIO values!!!\n");
3663       return;
3664     }
3665   } else {
3666     NXPLOG_NCIHAL_E("GPIO Restore Invalid Option!!!\n");
3667   }
3668 }
3669 
3670 /******************************************************************************
3671  * Function         phNxpNciHal_nfcc_core_reset_init
3672  *
3673  * Description      Helper function to do nfcc core reset & core init
3674  *
3675  * Returns          Status
3676  *
3677  ******************************************************************************/
phNxpNciHal_nfcc_core_reset_init(bool keep_config)3678 NFCSTATUS phNxpNciHal_nfcc_core_reset_init(bool keep_config) {
3679   NFCSTATUS status = NFCSTATUS_FAILED;
3680   uint8_t retry_cnt = 0;
3681   uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x01};
3682 
3683   if (keep_config) {
3684     cmd_reset_nci[3] = 0x00;
3685   }
3686 retry_core_reset:
3687   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
3688   if ((status != NFCSTATUS_SUCCESS) && (retry_cnt < 3)) {
3689     NXPLOG_NCIHAL_D("Retry: NCI_CORE_RESET");
3690     retry_cnt++;
3691     goto retry_core_reset;
3692   } else if (status != NFCSTATUS_SUCCESS) {
3693     NXPLOG_NCIHAL_E("NCI_CORE_RESET failed!!!\n");
3694     return status;
3695   }
3696 
3697   retry_cnt = 0;
3698   uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
3699   uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
3700 retry_core_init:
3701   if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
3702     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
3703   } else {
3704     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
3705   }
3706 
3707   if ((status != NFCSTATUS_SUCCESS) && (retry_cnt < 3)) {
3708     NXPLOG_NCIHAL_D("Retry: NCI_CORE_INIT\n");
3709     retry_cnt++;
3710     goto retry_core_init;
3711   } else if (status != NFCSTATUS_SUCCESS) {
3712     NXPLOG_NCIHAL_E("NCI_CORE_INIT failed!!!\n");
3713     return status;
3714   }
3715 
3716   return status;
3717 }
3718 
3719 /******************************************************************************
3720  * Function         phNxpNciHal_resetDefaultSettings
3721  *
3722  * Description      Helper function to do nfcc core reset, core init
3723  *                  (if previously firmware update was triggered) and
3724  *                  apply default NFC settings
3725  *
3726  * Returns          Status
3727  *
3728  ******************************************************************************/
phNxpNciHal_resetDefaultSettings(uint8_t fw_update_req,bool keep_config)3729 NFCSTATUS phNxpNciHal_resetDefaultSettings(uint8_t fw_update_req,
3730                                            bool keep_config) {
3731   NFCSTATUS status = NFCSTATUS_SUCCESS;
3732   if (fw_update_req) {
3733     status = phNxpNciHal_nfcc_core_reset_init(keep_config);
3734   }
3735   if (status == NFCSTATUS_SUCCESS) {
3736     unsigned long num = 0;
3737     int ret = 0;
3738     phNxpNciHal_conf_nfc_forum_mode();
3739     if (IS_CHIP_TYPE_GE(sn100u)) {
3740       ret = GetNxpNumValue(NAME_NXP_RDR_DISABLE_ENABLE_LPCD, &num, sizeof(num));
3741       if (!ret || num == 1 || num == 2) {
3742         phNxpNciHal_prop_conf_lpcd(true);
3743       } else if (ret && num == 0) {
3744         phNxpNciHal_prop_conf_lpcd(false);
3745       }
3746     }
3747   }
3748   return status;
3749 }
3750 
3751 /******************************************************************************
3752  * Function         phNxpNciHal_enable_i2c_fragmentation
3753  *
3754  * Description      This function is called to process the response status
3755  *                  and print the status byte.
3756  *
3757  * Returns          void.
3758  *
3759  ******************************************************************************/
phNxpNciHal_enable_i2c_fragmentation()3760 void phNxpNciHal_enable_i2c_fragmentation() {
3761   NFCSTATUS status = NFCSTATUS_FAILED;
3762   static uint8_t fragmentation_enable_config_cmd[] = {0x20, 0x02, 0x05, 0x01,
3763                                                       0xA0, 0x05, 0x01, 0x10};
3764   long i2c_status = 0x00;
3765   long config_i2c_vlaue = 0xff;
3766   /*NCI_RESET_CMD*/
3767   static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
3768   /*NCI_INIT_CMD*/
3769   static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
3770   static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
3771   static uint8_t get_i2c_fragmentation_cmd[] = {0x20, 0x03, 0x03,
3772                                                 0x01, 0xA0, 0x05};
3773   if (GetNxpNumValue(NAME_NXP_I2C_FRAGMENTATION_ENABLED, (void*)&i2c_status,
3774                      sizeof(i2c_status)) == true) {
3775     NXPLOG_FWDNLD_D("I2C status : %ld", i2c_status);
3776   } else {
3777     NXPLOG_FWDNLD_E("I2C status read not succeeded. Default value : %ld",
3778                     i2c_status);
3779   }
3780   status = phNxpNciHal_send_ext_cmd(sizeof(get_i2c_fragmentation_cmd),
3781                                     get_i2c_fragmentation_cmd);
3782   if (status != NFCSTATUS_SUCCESS) {
3783     NXPLOG_NCIHAL_E("unable to retrieve  get_i2c_fragmentation_cmd");
3784   } else {
3785     if (nxpncihal_ctrl.p_rx_data[8] == 0x10) {
3786       config_i2c_vlaue = 0x01;
3787       phNxpNciHal_notify_i2c_fragmentation();
3788       phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
3789     } else if (nxpncihal_ctrl.p_rx_data[8] == 0x00) {
3790       config_i2c_vlaue = 0x00;
3791     }
3792     // if the value already matches, nothing to be done
3793     if (config_i2c_vlaue != i2c_status) {
3794       if (i2c_status == 0x01) {
3795         /* NXP I2C fragmenation enabled*/
3796         status =
3797             phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd),
3798                                      fragmentation_enable_config_cmd);
3799         if (status != NFCSTATUS_SUCCESS) {
3800           NXPLOG_NCIHAL_E("NXP fragmentation enable failed");
3801         }
3802       } else if (i2c_status == 0x00 || config_i2c_vlaue == 0xff) {
3803         fragmentation_enable_config_cmd[7] = 0x00;
3804         /* NXP I2C fragmentation disabled*/
3805         status =
3806             phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd),
3807                                      fragmentation_enable_config_cmd);
3808         if (status != NFCSTATUS_SUCCESS) {
3809           NXPLOG_NCIHAL_E("NXP fragmentation disable failed");
3810         }
3811       }
3812       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
3813       if (status != NFCSTATUS_SUCCESS) {
3814         NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
3815       }
3816       if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
3817         status =
3818             phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
3819       } else {
3820         status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
3821       }
3822       if (status != NFCSTATUS_SUCCESS) {
3823         NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
3824       } else if (i2c_status == 0x01) {
3825         phNxpNciHal_notify_i2c_fragmentation();
3826         phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
3827       }
3828     }
3829   }
3830 }
3831 /******************************************************************************
3832  * Function         phNxpNciHal_do_se_session_reset
3833  *
3834  * Description      This function is called to set the session id to default
3835  *                  value.
3836  *
3837  * Returns          NFCSTATUS.
3838  *
3839  ******************************************************************************/
phNxpNciHal_do_swp_session_reset(void)3840 static NFCSTATUS phNxpNciHal_do_swp_session_reset(void) {
3841   NFCSTATUS status = NFCSTATUS_FAILED;
3842   static uint8_t reset_swp_session_identity_set[] = {
3843       0x20, 0x02, 0x17, 0x02, 0xA0, 0xEA, 0x08, 0xFF, 0xFF,
3844       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x1E, 0x08,
3845       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
3846   status = phNxpNciHal_send_ext_cmd(sizeof(reset_swp_session_identity_set),
3847                                     reset_swp_session_identity_set);
3848   if (status != NFCSTATUS_SUCCESS) {
3849     NXPLOG_NCIHAL_E("NXP reset_ese_session_identity_set command failed");
3850   }
3851   return status;
3852 }
3853 /******************************************************************************
3854  * Function         phNxpNciHal_do_factory_reset
3855  *
3856  * Description      This function is called during factory reset to clear/reset
3857  *                  nfc sub-system persistent data.
3858  *
3859  * Returns          void.
3860  *
3861  ******************************************************************************/
phNxpNciHal_do_factory_reset(void)3862 void phNxpNciHal_do_factory_reset(void) {
3863   NFCSTATUS status = NFCSTATUS_FAILED;
3864   bool isHalOpenRequested = false;
3865   // After factory reset phone will turnoff so mutex not required here.
3866   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
3867     isHalOpenRequested = true;
3868     status = phNxpNciHal_MinOpen();
3869     if (status != NFCSTATUS_SUCCESS) {
3870       NXPLOG_NCIHAL_E("%s: NXP Nfc Open failed", __func__);
3871       return;
3872     }
3873   }
3874   status = phNxpNciHal_do_swp_session_reset();
3875   if (status != NFCSTATUS_SUCCESS) {
3876     NXPLOG_NCIHAL_E("%s failed. status = %x ", __func__, status);
3877   }
3878   if (nxpncihal_ctrl.halStatus == HAL_STATUS_MIN_OPEN && isHalOpenRequested) {
3879     phNxpNciHal_close(false);
3880   }
3881 }
3882 /******************************************************************************
3883  * Function         phNxpNciHal_hci_network_reset
3884  *
3885  * Description      This function resets the session id's of all the se's
3886  *                  in the HCI network and notify to HCI_NETWORK_RESET event to
3887  *                  NFC HAL Client.
3888  *
3889  * Returns          void.
3890  *
3891  ******************************************************************************/
phNxpNciHal_hci_network_reset(void)3892 static void phNxpNciHal_hci_network_reset(void) {
3893   static phLibNfc_Message_t msg;
3894   msg.pMsgData = NULL;
3895   msg.Size = 0;
3896 
3897   NFCSTATUS status = phNxpNciHal_do_swp_session_reset();
3898 
3899   if (status != NFCSTATUS_SUCCESS) {
3900     msg.eMsgType = NCI_HAL_ERROR_MSG;
3901   } else {
3902     msg.eMsgType = NCI_HAL_HCI_NETWORK_RESET_MSG;
3903   }
3904   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
3905 }
3906 /******************************************************************************
3907  * Function         phNxpNciHal_print_res_status
3908  *
3909  * Description      This function is called to process the response status
3910  *                  and print the status byte.
3911  *
3912  * Returns          void.
3913  *
3914  ******************************************************************************/
phNxpNciHal_print_res_status(uint8_t * p_rx_data,uint16_t * p_len)3915 static void phNxpNciHal_print_res_status(uint8_t* p_rx_data, uint16_t* p_len) {
3916   static uint8_t response_buf[][30] = {"STATUS_OK",
3917                                        "STATUS_REJECTED",
3918                                        "STATUS_RF_FRAME_CORRUPTED",
3919                                        "STATUS_FAILED",
3920                                        "STATUS_NOT_INITIALIZED",
3921                                        "STATUS_SYNTAX_ERROR",
3922                                        "STATUS_SEMANTIC_ERROR",
3923                                        "RFU",
3924                                        "RFU",
3925                                        "STATUS_INVALID_PARAM",
3926                                        "STATUS_MESSAGE_SIZE_EXCEEDED",
3927                                        "STATUS_UNDEFINED"};
3928   int status_byte;
3929   if (p_rx_data[0] == 0x40 && (p_rx_data[1] == 0x02 || p_rx_data[1] == 0x03)) {
3930     if (p_rx_data[2] && p_rx_data[3] <= 10) {
3931       status_byte = p_rx_data[CORE_RES_STATUS_BYTE];
3932       NXPLOG_NCIHAL_D("%s: response status =%s", __func__,
3933                       response_buf[status_byte]);
3934     } else {
3935       NXPLOG_NCIHAL_D("%s: response status =%s", __func__, response_buf[11]);
3936     }
3937     if (phNxpNciClock.isClockSet) {
3938       int i, len = sizeof(phNxpNciClock.p_rx_data);
3939       if (*p_len > len) {
3940         android_errorWriteLog(0x534e4554, "169257710");
3941       } else {
3942         len = *p_len;
3943       }
3944       for (i = 0; i < len; i++) {
3945         phNxpNciClock.p_rx_data[i] = p_rx_data[i];
3946       }
3947     }
3948 
3949     else if (phNxpNciRfSet.isGetRfSetting) {
3950       phNxpNciRfSet.p_rx_data = vector<uint8_t>(p_rx_data, p_rx_data + *p_len);
3951     } else if (phNxpNciMwEepromArea.isGetEepromArea) {
3952       int i, len = sizeof(phNxpNciMwEepromArea.p_rx_data) + 8;
3953       if (*p_len > len) {
3954         android_errorWriteLog(0x534e4554, "169258884");
3955       } else {
3956         len = *p_len;
3957       }
3958       for (i = 8; i < len; i++) {
3959         phNxpNciMwEepromArea.p_rx_data[i - 8] = p_rx_data[i];
3960       }
3961     } else if (nxpncihal_ctrl.phNxpNciGpioInfo.state == GPIO_STORE) {
3962       NXPLOG_NCIHAL_D("%s: Storing GPIO Values...", __func__);
3963       nxpncihal_ctrl.phNxpNciGpioInfo.values[0] = p_rx_data[9];
3964       nxpncihal_ctrl.phNxpNciGpioInfo.values[1] = p_rx_data[8];
3965     } else if (nxpncihal_ctrl.phNxpNciGpioInfo.state == GPIO_RESTORE) {
3966       NXPLOG_NCIHAL_D("%s: Restoring GPIO Values...", __func__);
3967       nxpncihal_ctrl.phNxpNciGpioInfo.values[0] = p_rx_data[9];
3968       nxpncihal_ctrl.phNxpNciGpioInfo.values[1] = p_rx_data[8];
3969     }
3970   }
3971 
3972   if (p_rx_data[2] && (config_access == true)) {
3973     if (p_rx_data[3] != NFCSTATUS_SUCCESS) {
3974       NXPLOG_NCIHAL_W("Invalid Data from config file.");
3975       config_success = false;
3976     }
3977   }
3978 }
3979 /******************************************************************************
3980  * Function         phNxpNciHal_initialize_mifare_flag
3981  *
3982  * Description      This function gets the value for Mfc flags.
3983  *
3984  * Returns          void
3985  *
3986  ******************************************************************************/
phNxpNciHal_initialize_mifare_flag()3987 static void phNxpNciHal_initialize_mifare_flag() {
3988   unsigned long num = 0;
3989   bEnableMfcReader = false;
3990   // 1: Enable Mifare Classic protocol in RF Discovery.
3991   // 0: Remove Mifare Classic protocol in RF Discovery.
3992   if (GetNxpNumValue(NAME_MIFARE_READER_ENABLE, &num, sizeof(num))) {
3993     bEnableMfcReader = (num == 0) ? false : true;
3994   }
3995 }
3996 
3997 /*****************************************************************************
3998  * Function         phNxpNciHal_send_get_cfgs
3999  *
4000  * Description      This function is called to  send get configs
4001  *                  for all the types in get_cfg_arr.
4002  *                  Response of getConfigs(EEPROM stored) will be
4003  *                  compared with request coming from MW during discovery.
4004  *                  If same, then current setConfigs will be dropped
4005  *
4006  * Returns          Returns NFCSTATUS_SUCCESS if sending cmd is successful and
4007  *                  response is received.
4008  *
4009  *****************************************************************************/
phNxpNciHal_send_get_cfgs()4010 NFCSTATUS phNxpNciHal_send_get_cfgs() {
4011   NXPLOG_NCIHAL_D("%s Enter", __func__);
4012   NFCSTATUS status = NFCSTATUS_FAILED;
4013   uint8_t num_cfgs = sizeof(get_cfg_arr) / sizeof(uint8_t);
4014   uint8_t cfg_count = 0, retry_cnt = 0;
4015   if (mGetCfg_info != NULL) {
4016     mGetCfg_info->isGetcfg = true;
4017   }
4018   uint8_t cmd_get_cfg[] = {0x20, 0x03, 0x02, 0x01, 0x00};
4019 
4020   while (cfg_count < num_cfgs) {
4021     cmd_get_cfg[sizeof(cmd_get_cfg) - 1] = get_cfg_arr[cfg_count];
4022 
4023   retry_get_cfg:
4024     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_get_cfg), cmd_get_cfg);
4025     if (status != NFCSTATUS_SUCCESS && retry_cnt < 3) {
4026       NXPLOG_NCIHAL_E("cmd_get_cfg failed");
4027       retry_cnt++;
4028       goto retry_get_cfg;
4029     }
4030     if (retry_cnt == 3) {
4031       break;
4032     }
4033     cfg_count++;
4034     retry_cnt = 0;
4035   }
4036   mGetCfg_info->isGetcfg = false;
4037   return status;
4038 }
4039 
4040 /*******************************************************************************
4041 **
4042 ** Function         phNxpNciHal_configFeatureList
4043 **
4044 ** Description      Configures the featureList based on chip type &
4045 **                  Configure fragmentation length based on chip type.
4046 **                  HW Version information number will provide chipType.
4047 **                  HW Version can be obtained from CORE_INIT_RESPONSE(NCI 1.0)
4048 **                  or CORE_RST_NTF(NCI 2.0)
4049 **
4050 ** Parameters       CORE_INIT_RESPONSE/CORE_RST_NTF, len
4051 **
4052 ** Returns          none
4053 *******************************************************************************/
phNxpNciHal_configFeatureList(uint8_t * init_rsp,uint16_t rsp_len)4054 void phNxpNciHal_configFeatureList(uint8_t* init_rsp, uint16_t rsp_len) {
4055   nxpncihal_ctrl.chipType = pConfigFL->processChipType(init_rsp, rsp_len);
4056   tNFC_chipType chipType = nxpncihal_ctrl.chipType;
4057   bool is4KFragementSupported = false;
4058   NXPLOG_NCIHAL_D("%s chipType = %s", __func__, pConfigFL->product[chipType]);
4059   CONFIGURE_FEATURELIST(chipType);
4060   if (IS_CHIP_TYPE_EQ(sn300u)) {
4061     if (!GetNxpNumValue(NAME_NXP_4K_FWDNLD_SUPPORT, &is4KFragementSupported,
4062                         sizeof(is4KFragementSupported))) {
4063       is4KFragementSupported = false;
4064     }
4065   }
4066   NXPLOG_NCIHAL_D("%s 4K FW download support = %x", __func__,
4067                   is4KFragementSupported);
4068   CONFIGURE_4K_SUPPORT(is4KFragementSupported);
4069   /* update fragment len based on the chip type.*/
4070   phTmlNfc_IoCtl(phTmlNfc_e_setFragmentSize);
4071 }
4072 
4073 /*******************************************************************************
4074 **
4075 ** Function         phNxpNciHal_UpdateFwStatus
4076 **
4077 ** Description      It shall be called to update the FW download status to the
4078 **                  libnfc-nci.
4079 **
4080 ** Parameters       fwStatus: FW update status
4081 **
4082 ** Returns          void
4083 *******************************************************************************/
phNxpNciHal_UpdateFwStatus(HalNfcFwUpdateStatus fwStatus)4084 static void phNxpNciHal_UpdateFwStatus(HalNfcFwUpdateStatus fwStatus) {
4085   static phLibNfc_Message_t msg;
4086   static uint8_t status;
4087   if (RfFwRegionDnld_handle == NULL) {
4088     /* If proprietary feature not supported */
4089     return;
4090   }
4091   NXPLOG_NCIHAL_D("phNxpNciHal_UpdateFwStatus Enter");
4092 
4093   status = (uint8_t)fwStatus;
4094   msg.eMsgType = HAL_NFC_FW_UPDATE_STATUS_EVT;
4095   msg.pMsgData = &status;
4096   msg.Size = sizeof(status);
4097   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
4098                         (phLibNfc_Message_t*)&msg);
4099   return;
4100 }
4101 
4102 /*******************************************************************************
4103 **
4104 ** Function         phNxpNciHal_configureLxDebugMode
4105 **
4106 ** Description      Helper function to configure LxDebug modes
4107 **
4108 ** Parameters       none
4109 **
4110 ** Returns          void
4111 *******************************************************************************/
phNxpNciHal_configureLxDebugMode()4112 void phNxpNciHal_configureLxDebugMode() {
4113   NFCSTATUS status = NFCSTATUS_SUCCESS;
4114   unsigned long lx_debug_cfg = 0;
4115   uint8_t isfound = 0;
4116   static uint8_t cmd_lxdebug[] = {0x20, 0x02, 0x06, 0x01, 0xA0,
4117                                   0x1D, 0x02, 0x00, 0x00};
4118 
4119   isfound = GetNxpNumValue(NAME_NXP_CORE_PROP_SYSTEM_DEBUG, &lx_debug_cfg,
4120                            sizeof(lx_debug_cfg));
4121 
4122   if (isfound) {
4123     if (lx_debug_cfg & LX_DEBUG_CFG_MASK_RFU) {
4124       NXPLOG_NCIHAL_E(
4125           "One or more RFU bits are enabled.\nMasking the RFU bits");
4126       lx_debug_cfg = lx_debug_cfg & ~LX_DEBUG_CFG_MASK_RFU;
4127     }
4128     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_L1_EVENT) {
4129       NXPLOG_NCIHAL_D("Enable L1 RF NTF debugs");
4130     }
4131     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_L2_EVENT) {
4132       NXPLOG_NCIHAL_D("Enable L2 RF NTF debugs (CE)");
4133     }
4134     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_FELICA_RF) {
4135       NXPLOG_NCIHAL_D("Enable all Felica CM events");
4136     }
4137     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_FELICA_SYSCODE) {
4138       NXPLOG_NCIHAL_D("Enable Felica System Code");
4139     }
4140     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_L2_EVENT_READER) {
4141       NXPLOG_NCIHAL_D("Enable L2 RF NTF debugs (Reader)");
4142     }
4143     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_MOD_DETECTED_EVENT) {
4144       NXPLOG_NCIHAL_D("Enable Modulation detected event");
4145     }
4146     if (lx_debug_cfg & LX_DEBUG_CFG_ENABLE_CMA_EVENTS) {
4147       NXPLOG_NCIHAL_D("Enable CMA events");
4148     }
4149 
4150     cmd_lxdebug[7] = (uint8_t)(lx_debug_cfg & LX_DEBUG_CFG_MASK);
4151     cmd_lxdebug[8] = (uint8_t)((lx_debug_cfg & LX_DEBUG_CFG_MASK) >> 8);
4152   }
4153   if (lx_debug_cfg == LX_DEBUG_CFG_DISABLE) {
4154     NXPLOG_NCIHAL_D("Disable LxDebug");
4155   }
4156   status = phNxpNciHal_send_ext_cmd(
4157       sizeof(cmd_lxdebug) / sizeof(cmd_lxdebug[0]), cmd_lxdebug);
4158   if (status != NFCSTATUS_SUCCESS) {
4159     NXPLOG_NCIHAL_E("Set lxDebug config failed");
4160   }
4161 }
4162 
4163 /*******************************************************************************
4164 **
4165 ** Function         phNxpNciHal_initializeRegRfFwDnld(void)
4166 **
4167 ** Description      Loads the module & initializes function pointers for Region
4168 **                  based RF & FW update module
4169 **
4170 ** Parameters       none
4171 **
4172 ** Returns          void
4173 *******************************************************************************/
phNxpNciHal_initializeRegRfFwDnld()4174 void phNxpNciHal_initializeRegRfFwDnld() {
4175   // Getting pointer to RF & RF Region Code Download module
4176   RfFwRegionDnld_handle =
4177       dlopen("/system/vendor/lib64/libonebinary.so", RTLD_NOW);
4178   if (RfFwRegionDnld_handle == NULL) {
4179     NXPLOG_NCIHAL_D(
4180         "Error : opening (/system/vendor/lib64/libonebinary.so) !!");
4181     return;
4182   }
4183   if ((fpVerInfoStoreInEeprom = (fpVerInfoStoreInEeprom_t)dlsym(
4184            RfFwRegionDnld_handle, "read_version_info_and_store_in_eeprom")) ==
4185       NULL) {
4186     NXPLOG_NCIHAL_D(
4187         "Error while linking (read_version_info_and_store_in_eeprom) !!");
4188     return;
4189   }
4190   if ((fpRegRfFwDndl = (fpRegRfFwDndl_t)dlsym(RfFwRegionDnld_handle,
4191                                               "RegRfFwDndl")) == NULL) {
4192     NXPLOG_NCIHAL_D("Error while linking (RegRfFwDndl) !!");
4193     return;
4194   }
4195   if ((fpPropConfCover = (fpPropConfCover_t)dlsym(RfFwRegionDnld_handle,
4196                                                   "prop_conf_cover")) == NULL) {
4197     NXPLOG_NCIHAL_D("Error while linking (prop_conf_cover) !!");
4198     return;
4199   }
4200   if ((fpDoAntennaActivity = (fpDoAntennaActivity_t)dlsym(
4201            RfFwRegionDnld_handle, "DoAntennaActivity")) == NULL) {
4202     NXPLOG_NCIHAL_E("Error while linking (DoAntennaActivity) !!");
4203     return;
4204   }
4205 }
4206 
4207 /*******************************************************************************
4208 **
4209 ** Function         phNxpNciHal_deinitializeRegRfFwDnld(void)
4210 **
4211 ** Description      Resets the module handle & all the function pointers for
4212 **                  Region based RF & FW update module
4213 **
4214 ** Parameters       none
4215 **
4216 ** Returns          void
4217 *******************************************************************************/
phNxpNciHal_deinitializeRegRfFwDnld()4218 void phNxpNciHal_deinitializeRegRfFwDnld() {
4219   if (RfFwRegionDnld_handle != NULL) {
4220     NXPLOG_NCIHAL_D("closing libonebinary.so");
4221     fpVerInfoStoreInEeprom = NULL;
4222     fpRegRfFwDndl = NULL;
4223     fpPropConfCover = NULL;
4224     dlclose(RfFwRegionDnld_handle);
4225     RfFwRegionDnld_handle = NULL;
4226     fpDoAntennaActivity = NULL;
4227   }
4228 }
4229 
4230 /******************************************************************************
4231  * Function         phNxpNciHal_setVerboseLogging
4232  *
4233  * Description      This function enables the nfc_debug_enabled
4234  *
4235  * Returns          void
4236  *
4237  *****************************************************************************/
4238 
phNxpNciHal_setVerboseLogging(bool enable)4239 void phNxpNciHal_setVerboseLogging(bool enable) { nfc_debug_enabled = enable; }
4240 
4241 /******************************************************************************
4242  * Function         phNxpNciHal_getVerboseLogging
4243  *
4244  * Description      This function returns the value of nfc_debug_enabled
4245  *
4246  * Returns          void
4247  *
4248  *****************************************************************************/
4249 
phNxpNciHal_getVerboseLogging()4250 bool phNxpNciHal_getVerboseLogging() { return nfc_debug_enabled; }
4251 
4252 /******************************************************************************
4253  * Function         phNxpNciHal_check_and_recover_fw
4254  *
4255  * Description      This function  performs fw recovery using force fw download
4256  *                  followed by power reset if it requires.
4257  *
4258  * Returns          void
4259  *
4260  *****************************************************************************/
4261 
phNxpNciHal_check_and_recover_fw()4262 static void phNxpNciHal_check_and_recover_fw() {
4263   NXPLOG_NCIHAL_D("%s: Entry", __func__);
4264   uint8_t cmd_reset_nci_rs[] = {0x20, 0x00, 0x01, 0x80};  // switch to DL mode
4265   NFCSTATUS status = NFCSTATUS_FAILED;
4266   int32_t core_reset_count =
4267       phNxpNciHal_getVendorProp_int32(core_reset_ntf_count_prop_name, 0);
4268   if (core_reset_count < CORE_RESET_NTF_RECOVERY_REQ_COUNT) {
4269     return;
4270   }
4271   NXPLOG_NCIHAL_D("FW Recovery is required");
4272   if (core_reset_count <= CORE_RESET_NTF_RECOVERY_REQ_COUNT + 1) {
4273     // check if there is a new  reset NTF or time out after 1600ms
4274     // as interval b/w 2 consecutive NTF is 1.4 secs
4275     struct timespec ts;
4276 
4277     clock_gettime(CLOCK_MONOTONIC, &ts);
4278     // Normalize timespec
4279     ts.tv_sec += MAX_WAIT_MS_FOR_RESET_NTF / 1000;
4280     ts.tv_nsec += (MAX_WAIT_MS_FOR_RESET_NTF % 1000) * 1000000;
4281     if (ts.tv_nsec >= NS_PER_S) {
4282       ts.tv_sec++;
4283       ts.tv_nsec -= NS_PER_S;
4284     }
4285 
4286     int s;
4287     while ((s = sem_timedwait_monotonic_np(&sem_reset_ntf_received, &ts)) ==
4288                -1 &&
4289            errno == EINTR) {
4290       continue; /* Restart if interrupted by handler */
4291     }
4292     if (s == -1) {
4293       NXPLOG_NCIHAL_D("sem_timedwait failed. errno = %d", errno);
4294     }
4295     if (NFCSTATUS_SUCCESS !=
4296         phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci_rs), cmd_reset_nci_rs)) {
4297       NXPLOG_NCIHAL_E(
4298           "failed to switch in fw download mode through nci core reset");
4299     }
4300 
4301     status = phNxpNciHal_getChipInfoInFwDnldMode(false);
4302     if (status != NFCSTATUS_SUCCESS) {
4303       NXPLOG_NCIHAL_E("phNxpNciHal_getChipInfoInFwDnldMode Failed");
4304       status = NFCSTATUS_FAILED;
4305     }
4306   }
4307   if (status != NFCSTATUS_SUCCESS) {
4308     if ((phTmlNfc_IoCtl(phTmlNfc_e_PullVenLow) != NFCSTATUS_SUCCESS) ||
4309         (phTmlNfc_IoCtl(phTmlNfc_e_PullVenHigh) != NFCSTATUS_SUCCESS)) {
4310       NXPLOG_NCIHAL_E("Power reset failed during fw recovery");
4311       return;
4312     }
4313     if (phNxpNciHal_getChipInfoInFwDnldMode(false) != NFCSTATUS_SUCCESS) {
4314       NXPLOG_NCIHAL_E("phNxpNciHal_getChipInfoInFwDnldMode Failed");
4315       return;
4316     }
4317   }
4318   /* entered in recovery mode now reset the counter */
4319   if (NFCSTATUS_SUCCESS !=
4320       phNxpNciHal_setVendorProp(core_reset_ntf_count_prop_name, "0")) {
4321     NXPLOG_NCIHAL_E("setting core_reset_ntf_count_prop failed");
4322   }
4323   if (phNxpNciHal_force_fw_download(0x00, true) != NFCSTATUS_SUCCESS) {
4324     NXPLOG_NCIHAL_D("FW Recovery Failed");
4325   } else {
4326     NXPLOG_NCIHAL_D("FW Recovery SUCCESS");
4327   }
4328 }
4329