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