1 /*
2  * Copyright (C) 2012-2019 NXP Semiconductors
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 #include <EseAdaptation.h>
17 #include <cutils/properties.h>
18 #include <log/log.h>
19 #include <phDal4Nfc_messageQueueLib.h>
20 #include <phDnldNfc.h>
21 #include <phNxpConfig.h>
22 #include <phNxpLog.h>
23 #include <phNxpNciHal.h>
24 #include <phNxpNciHal_Adaptation.h>
25 #include <phNxpNciHal_Dnld.h>
26 #include <phNxpNciHal_NfcDepSWPrio.h>
27 #include <phNxpNciHal_ext.h>
28 #include <phTmlNfc.h>
29 #include <sys/stat.h>
30 #include "NfccPowerTracker.h"
31 #include "hal_nxpese.h"
32 #include "hal_nxpnfc.h"
33 #include "spi_spm.h"
34 
35 using namespace android::hardware::nfc::V1_1;
36 using namespace android::hardware::nfc::V1_2;
37 using android::hardware::nfc::V1_1::NfcEvent;
38 
39 /*********************** Global Variables *************************************/
40 #define PN547C2_CLOCK_SETTING
41 #define CORE_RES_STATUS_BYTE 3
42 
43 bool bEnableMfcExtns = false;
44 bool bEnableMfcReader = false;
45 bool bDisableLegacyMfcExtns = true;
46 
47 /* Processing of ISO 15693 EOF */
48 extern uint8_t icode_send_eof;
49 extern uint8_t icode_detected;
50 static uint8_t cmd_icode_eof[] = {0x00, 0x00, 0x00};
51 
52 /* FW download success flag */
53 static uint8_t fw_download_success = 0;
54 
55 static uint8_t config_access = false;
56 static uint8_t config_success = true;
57 
58 static ThreadMutex sHalFnLock;
59 
60 /* NCI HAL Control structure */
61 phNxpNciHal_Control_t nxpncihal_ctrl;
62 
63 /* NXP Poll Profile structure */
64 phNxpNciProfile_Control_t nxpprofile_ctrl;
65 
66 /* TML Context */
67 extern phTmlNfc_Context_t* gpphTmlNfc_Context;
68 extern void phTmlNfc_set_fragmentation_enabled(
69     phTmlNfc_i2cfragmentation_t result);
70 /* global variable to get FW version from NCI response*/
71 uint32_t wFwVerRsp;
72 EseAdaptation* gpEseAdapt = NULL;
73 /* External global variable to get FW version */
74 extern uint16_t wFwVer;
75 extern uint16_t fw_maj_ver;
76 extern uint16_t rom_version;
77 extern uint8_t gRecFWDwnld;
78 static uint8_t gRecFwRetryCount;  // variable to hold recovery FW retry count
79 static uint8_t Rx_data[NCI_MAX_DATA_LEN];
80 extern int phPalEse_spi_ioctl(phPalEse_ControlCode_t eControlCode,
81                               void* pDevHandle, long level);
82 uint32_t timeoutTimerId = 0;
83 bool nfc_debug_enabled = true;
84 static bool sIsForceFwDownloadReqd = false;
85 
86 /*  Used to send Callback Transceive data during Mifare Write.
87  *  If this flag is enabled, no need to send response to Upper layer */
88 bool sendRspToUpperLayer = true;
89 
90 phNxpNciHal_Sem_t config_data;
91 
92 phNxpNciClock_t phNxpNciClock = {0, {0}, false};
93 
94 phNxpNciRfSetting_t phNxpNciRfSet = {false, {0}};
95 
96 phNxpNciMwEepromArea_t phNxpNciMwEepromArea = {false, {0}};
97 
98 /**************** local methods used in this file only ************************/
99 static NFCSTATUS phNxpNciHal_fw_download(void);
100 static void phNxpNciHal_open_complete(NFCSTATUS status);
101 static void phNxpNciHal_MinOpen_complete(NFCSTATUS status);
102 static void phNxpNciHal_write_complete(void* pContext,
103                                        phTmlNfc_TransactInfo_t* pInfo);
104 static void phNxpNciHal_read_complete(void* pContext,
105                                       phTmlNfc_TransactInfo_t* pInfo);
106 static void phNxpNciHal_close_complete(NFCSTATUS status);
107 static void phNxpNciHal_core_initialized_complete(NFCSTATUS status);
108 static void phNxpNciHal_power_cycle_complete(NFCSTATUS status);
109 static void phNxpNciHal_kill_client_thread(
110     phNxpNciHal_Control_t* p_nxpncihal_ctrl);
111 static void* phNxpNciHal_client_thread(void* arg);
112 static void phNxpNciHal_get_clk_freq(void);
113 static void phNxpNciHal_set_clock(void);
114 static void phNxpNciHal_hci_network_reset(void);
115 static NFCSTATUS phNxpNciHal_do_se_session_reset(void);
116 static void phNxpNciHal_print_res_status(uint8_t* p_rx_data, uint16_t* p_len);
117 static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void);
118 static void phNxpNciHal_enable_i2c_fragmentation();
119 static NFCSTATUS phNxpNciHal_get_mw_eeprom(void);
120 static NFCSTATUS phNxpNciHal_set_mw_eeprom(void);
121 static int phNxpNciHal_fw_mw_ver_check();
122 NFCSTATUS phNxpNciHal_check_clock_config(void);
123 NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void);
124 static void phNxpNciHal_gpio_restore(phNxpNciHal_GpioInfoState state);
125 static void phNxpNciHal_initialize_debug_enabled_flag();
126 static void phNxpNciHal_initialize_mifare_flag();
127 NFCSTATUS phNxpNciHal_nfcc_core_reset_init();
128 NFCSTATUS phNxpNciHal_getChipInfoInFwDnldMode(void);
129 static NFCSTATUS phNxpNciHalRFConfigCmdRecSequence();
130 static NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus();
131 int check_config_parameter();
132 #ifdef FactoryOTA
133 void phNxpNciHal_isFactoryOTAModeActive();
134 static NFCSTATUS phNxpNciHal_disableFactoryOTAMode(void);
135 #endif
136 /******************************************************************************
137  * Function         phNxpNciHal_initialize_debug_enabled_flag
138  *
139  * Description      This function gets the value for nfc_debug_enabled
140  *
141  * Returns          void
142  *
143  ******************************************************************************/
phNxpNciHal_initialize_debug_enabled_flag()144 static void phNxpNciHal_initialize_debug_enabled_flag() {
145   unsigned long num = 0;
146   char valueStr[PROPERTY_VALUE_MAX] = {0};
147   if (GetNxpNumValue(NAME_NFC_DEBUG_ENABLED, &num, sizeof(num))) {
148     nfc_debug_enabled = (num == 0) ? false : true;
149   }
150 
151   int len = property_get("nfc.debug_enabled", valueStr, "");
152   if (len > 0) {
153     // let Android property override .conf variable
154     unsigned debug_enabled = 0;
155     sscanf(valueStr, "%u", &debug_enabled);
156     nfc_debug_enabled = (debug_enabled == 0) ? false : true;
157   }
158   NXPLOG_NCIHAL_D("nfc_debug_enabled : %d", nfc_debug_enabled);
159 }
160 
161 /******************************************************************************
162  * Function         phNxpNciHal_client_thread
163  *
164  * Description      This function is a thread handler which handles all TML and
165  *                  NCI messages.
166  *
167  * Returns          void
168  *
169  ******************************************************************************/
phNxpNciHal_client_thread(void * arg)170 static void* phNxpNciHal_client_thread(void* arg) {
171   phNxpNciHal_Control_t* p_nxpncihal_ctrl = (phNxpNciHal_Control_t*)arg;
172   phLibNfc_Message_t msg;
173 
174   NXPLOG_NCIHAL_D("thread started");
175 
176   p_nxpncihal_ctrl->thread_running = 1;
177 
178   while (p_nxpncihal_ctrl->thread_running == 1) {
179     /* Fetch next message from the NFC stack message queue */
180     if (phDal4Nfc_msgrcv(p_nxpncihal_ctrl->gDrvCfg.nClientId, &msg, 0, 0) ==
181         -1) {
182       NXPLOG_NCIHAL_E("NFC client received bad message");
183       continue;
184     }
185 
186     if (p_nxpncihal_ctrl->thread_running == 0) {
187       break;
188     }
189 
190     switch (msg.eMsgType) {
191       case PH_LIBNFC_DEFERREDCALL_MSG: {
192         phLibNfc_DeferredCall_t* deferCall =
193             (phLibNfc_DeferredCall_t*)(msg.pMsgData);
194 
195         REENTRANCE_LOCK();
196         deferCall->pCallback(deferCall->pParameter);
197         REENTRANCE_UNLOCK();
198 
199         break;
200       }
201 
202       case NCI_HAL_OPEN_CPLT_MSG: {
203         REENTRANCE_LOCK();
204         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
205           /* Send the event */
206           (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT,
207                                               HAL_NFC_STATUS_OK);
208         }
209         REENTRANCE_UNLOCK();
210         break;
211       }
212 
213       case NCI_HAL_CLOSE_CPLT_MSG: {
214         REENTRANCE_LOCK();
215         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
216           /* Send the event */
217           (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_CLOSE_CPLT_EVT,
218                                               HAL_NFC_STATUS_OK);
219         }
220         phNxpNciHal_kill_client_thread(&nxpncihal_ctrl);
221         REENTRANCE_UNLOCK();
222         break;
223       }
224 
225       case NCI_HAL_POST_INIT_CPLT_MSG: {
226         REENTRANCE_LOCK();
227         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
228           /* Send the event */
229           (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_POST_INIT_CPLT_EVT,
230                                               HAL_NFC_STATUS_OK);
231         }
232         REENTRANCE_UNLOCK();
233         break;
234       }
235 
236       case NCI_HAL_PRE_DISCOVER_CPLT_MSG: {
237         REENTRANCE_LOCK();
238         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
239           /* Send the event */
240           (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_PRE_DISCOVER_CPLT_EVT,
241                                               HAL_NFC_STATUS_OK);
242         }
243         REENTRANCE_UNLOCK();
244         break;
245       }
246 
247       case NCI_HAL_HCI_NETWORK_RESET_MSG: {
248         REENTRANCE_LOCK();
249         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
250           /* Send the event */
251           (*nxpncihal_ctrl.p_nfc_stack_cback)(
252               (uint32_t)NfcEvent::HCI_NETWORK_RESET, HAL_NFC_STATUS_OK);
253         }
254         REENTRANCE_UNLOCK();
255         break;
256       }
257 
258       case NCI_HAL_ERROR_MSG: {
259         REENTRANCE_LOCK();
260         if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
261           /* Send the event */
262           (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ERROR_EVT,
263                                               HAL_NFC_STATUS_FAILED);
264         }
265         REENTRANCE_UNLOCK();
266         break;
267       }
268 
269       case NCI_HAL_RX_MSG: {
270         REENTRANCE_LOCK();
271         if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) {
272           (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rsp_len,
273                                                    nxpncihal_ctrl.p_rsp_data);
274         }
275         REENTRANCE_UNLOCK();
276         break;
277       }
278     }
279   }
280 
281   NXPLOG_NCIHAL_D("NxpNciHal thread stopped");
282 
283   return NULL;
284 }
285 
286 /******************************************************************************
287  * Function         phNxpNciHal_kill_client_thread
288  *
289  * Description      This function safely kill the client thread and clean all
290  *                  resources.
291  *
292  * Returns          void.
293  *
294  ******************************************************************************/
phNxpNciHal_kill_client_thread(phNxpNciHal_Control_t * p_nxpncihal_ctrl)295 static void phNxpNciHal_kill_client_thread(
296     phNxpNciHal_Control_t* p_nxpncihal_ctrl) {
297   NXPLOG_NCIHAL_D("Terminating phNxpNciHal client thread...");
298 
299   p_nxpncihal_ctrl->p_nfc_stack_cback = NULL;
300   p_nxpncihal_ctrl->p_nfc_stack_data_cback = NULL;
301   p_nxpncihal_ctrl->thread_running = 0;
302 
303   return;
304 }
305 
306 /******************************************************************************
307  * Function         phNxpNciHal_fw_download
308  *
309  * Description      This function download the PN54X secure firmware to IC. If
310  *                  firmware version in Android filesystem and firmware in the
311  *                  IC is same then firmware download will return with success
312  *                  without downloading the firmware.
313  *
314  * Returns          NFCSTATUS_SUCCESS if firmware download successful
315  *                  NFCSTATUS_FAILED in case of failure
316  *                  NFCSTATUS_REJECTED if FW version is invalid or if hardware
317  *                                     criteria is not matching
318  *
319  ******************************************************************************/
phNxpNciHal_fw_download(void)320 static NFCSTATUS phNxpNciHal_fw_download(void) {
321   if (NFCSTATUS_SUCCESS != phNxpNciHal_CheckValidFwVersion()) {
322     return NFCSTATUS_REJECTED;
323   }
324 
325   nfc_nci_IoctlInOutData_t data;
326   memset(&data, 0x00, sizeof(nfc_nci_IoctlInOutData_t));
327   data.inp.level =
328       0x03;  // ioctl call arg value to get eSE power GPIO value = 0x03
329   int ese_gpio_value = phNxpNciHal_ioctl(HAL_NFC_GET_SPM_STATUS, &data);
330   NXPLOG_NCIHAL_D("eSE Power GPIO value = %d", ese_gpio_value);
331   if (ese_gpio_value != 0) {
332     NXPLOG_NCIHAL_E("FW download denied while SPI in use, Continue NFC init");
333     return NFCSTATUS_REJECTED;
334   }
335   nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_UNKNOWN;
336   phNxpNciHal_gpio_restore(GPIO_STORE);
337 
338   int fw_retry_count = 0;
339   NFCSTATUS status = NFCSTATUS_REJECTED;
340   NXPLOG_NCIHAL_D("Starting FW update");
341   do {
342     fw_download_success = 0;
343     phNxpNciHal_get_clk_freq();
344     status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
345     if (NFCSTATUS_SUCCESS != status) {
346       fw_retry_count++;
347       NXPLOG_NCIHAL_D("Retrying: FW download");
348       continue;
349     }
350 
351     if (sIsForceFwDownloadReqd) {
352       status = phNxpNciHal_getChipInfoInFwDnldMode();
353       if (status != NFCSTATUS_SUCCESS) {
354         NXPLOG_NCIHAL_E("Unknown chip type, FW can't be upgraded");
355         return status;
356       }
357     }
358 
359     /* Set the obtained device handle to download module */
360     phDnldNfc_SetHwDevHandle();
361     NXPLOG_NCIHAL_D("Calling Seq handler for FW Download \n");
362     status = phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal,
363                                          nxpprofile_ctrl.bClkFreqVal);
364     if (status != NFCSTATUS_SUCCESS) {
365       phTmlNfc_ReadAbort();
366       phDnldNfc_ReSetHwDevHandle();
367       fw_retry_count++;
368       NXPLOG_NCIHAL_D("Retrying: FW download");
369       android_errorWriteLog(0x534e4554, "192614125");
370     }
371   } while ((fw_retry_count < 3) && (status != NFCSTATUS_SUCCESS));
372 
373   if (status != NFCSTATUS_SUCCESS) {
374     if (NFCSTATUS_SUCCESS != phNxpNciHal_fw_mw_ver_check()) {
375       NXPLOG_NCIHAL_D("Chip Version Middleware Version mismatch!!!!");
376       phOsalNfc_Timer_Cleanup();
377       phTmlNfc_Shutdown_CleanUp();
378       status = NFCSTATUS_FAILED;
379     } else {
380       NXPLOG_NCIHAL_E("FW download failed, Continue NFCC init");
381     }
382   } else {
383     status = NFCSTATUS_SUCCESS;
384     fw_download_success = 1;
385   }
386 
387   /*Keep Read Pending on I2C*/
388   NFCSTATUS readRestoreStatus = NFCSTATUS_FAILED;
389   readRestoreStatus = phTmlNfc_Read(
390       nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN,
391       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
392   if (readRestoreStatus != NFCSTATUS_PENDING) {
393     NXPLOG_NCIHAL_E("TML Read status error status = %x", readRestoreStatus);
394     readRestoreStatus = phTmlNfc_Shutdown_CleanUp();
395     if (readRestoreStatus != NFCSTATUS_SUCCESS) {
396       NXPLOG_NCIHAL_E("TML Shutdown failed. Status  = %x", readRestoreStatus);
397     }
398   }
399   phDnldNfc_ReSetHwDevHandle();
400 
401   if (status == NFCSTATUS_SUCCESS) {
402     status = phNxpNciHal_nfcc_core_reset_init();
403     if (status == NFCSTATUS_SUCCESS) {
404       phNxpNciHal_gpio_restore(GPIO_RESTORE);
405     } else {
406       NXPLOG_NCIHAL_D("Failed to restore GPIO values!!!\n");
407     }
408   }
409 
410   return status;
411 }
412 
413 /******************************************************************************
414  * Function         phNxpNciHal_CheckValidFwVersion
415  *
416  * Description      This function checks the valid FW for Mobile device.
417  *                  If the FW doesn't belong the Mobile device it further
418  *                  checks nxp config file to override.
419  *
420  * Returns          NFCSTATUS_SUCCESS if valid fw version found
421  *                  NFCSTATUS_NOT_ALLOWED in case of FW not valid for mobile
422  *                  device
423  *
424  ******************************************************************************/
phNxpNciHal_CheckValidFwVersion(void)425 static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void) {
426   NFCSTATUS status = NFCSTATUS_NOT_ALLOWED;
427   const unsigned char sfw_infra_major_no = 0x02;
428   unsigned char ufw_current_major_no = 0x00;
429   unsigned long num = 0;
430   int isfound = 0;
431   unsigned char fw_major_no = ((wFwVerRsp >> 8) & 0x000000FF);
432 
433   /* extract the firmware's major no */
434   ufw_current_major_no = ((0x00FF) & (wFwVer >> 8U));
435 
436   if (ufw_current_major_no >= fw_major_no) {
437     status = NFCSTATUS_SUCCESS;
438   } else if (ufw_current_major_no == sfw_infra_major_no) {
439     if (rom_version == FW_MOBILE_ROM_VERSION_PN553 &&
440         nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
441       NXPLOG_NCIHAL_D(" PN81A  allow Fw download with major number =  0x%x",
442                       ufw_current_major_no);
443       status = NFCSTATUS_SUCCESS;
444     } else {
445       /* Check the nxp config file if still want to go for download */
446       /* By default NAME_NXP_FW_PROTECION_OVERRIDE will not be defined in config
447          file.
448          If user really want to override the Infra firmware over mobile
449          firmware, please
450          put "NXP_FW_PROTECION_OVERRIDE=0x01" in libnfc-nxp.conf file.
451          Please note once Infra firmware downloaded to Mobile device, The device
452          can never be updated to Mobile firmware*/
453       isfound =
454           GetNxpNumValue(NAME_NXP_FW_PROTECION_OVERRIDE, &num, sizeof(num));
455       if (isfound > 0) {
456         if (num == 0x01) {
457           NXPLOG_NCIHAL_D("Override Infra FW over Mobile");
458           status = NFCSTATUS_SUCCESS;
459         } else {
460           NXPLOG_NCIHAL_D(
461               "Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE "
462               "invalid value)");
463         }
464       } else {
465         NXPLOG_NCIHAL_D(
466             "Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE not "
467             "defined)");
468       }
469     }
470   } else if (gRecFWDwnld == TRUE) {
471     status = NFCSTATUS_SUCCESS;
472   } else if (wFwVerRsp == 0) {
473     NXPLOG_NCIHAL_E(
474         "FW Version not received by NCI command >>> Force Firmware download");
475     status = NFCSTATUS_SUCCESS;
476   } else {
477     NXPLOG_NCIHAL_E("Wrong FW Version >>> Firmware download not allowed");
478   }
479 
480   return status;
481 }
482 
phNxpNciHal_get_clk_freq(void)483 static void phNxpNciHal_get_clk_freq(void) {
484   unsigned long num = 0;
485   int isfound = 0;
486 
487   nxpprofile_ctrl.bClkSrcVal = 0;
488   nxpprofile_ctrl.bClkFreqVal = 0;
489   nxpprofile_ctrl.bTimeout = 0;
490 
491   isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &num, sizeof(num));
492   if (isfound > 0) {
493     nxpprofile_ctrl.bClkSrcVal = num;
494   }
495 
496   num = 0;
497   isfound = 0;
498   isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &num, sizeof(num));
499   if (isfound > 0) {
500     nxpprofile_ctrl.bClkFreqVal = num;
501   }
502 
503   num = 0;
504   isfound = 0;
505   isfound = GetNxpNumValue(NAME_NXP_SYS_CLOCK_TO_CFG, &num, sizeof(num));
506   if (isfound > 0) {
507     nxpprofile_ctrl.bTimeout = num;
508   }
509 
510   NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkSrcVal = 0x%x",
511                   nxpprofile_ctrl.bClkSrcVal);
512   NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x",
513                   nxpprofile_ctrl.bClkFreqVal);
514   NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x",
515                   nxpprofile_ctrl.bTimeout);
516 
517   if ((nxpprofile_ctrl.bClkSrcVal < CLK_SRC_XTAL) ||
518       (nxpprofile_ctrl.bClkSrcVal > CLK_SRC_PLL)) {
519     NXPLOG_FWDNLD_E(
520         "Clock source value is wrong in config file, setting it as default");
521     nxpprofile_ctrl.bClkSrcVal = NXP_SYS_CLK_SRC_SEL;
522   }
523   if (nxpprofile_ctrl.bClkFreqVal == CLK_SRC_PLL &&
524       (nxpprofile_ctrl.bClkFreqVal < CLK_FREQ_13MHZ ||
525        nxpprofile_ctrl.bClkFreqVal > CLK_FREQ_52MHZ)) {
526     NXPLOG_FWDNLD_E(
527         "Clock frequency value is wrong in config file, setting it as default");
528     nxpprofile_ctrl.bClkFreqVal = NXP_SYS_CLK_FREQ_SEL;
529   }
530   if ((nxpprofile_ctrl.bTimeout < CLK_TO_CFG_DEF) ||
531       (nxpprofile_ctrl.bTimeout > CLK_TO_CFG_MAX)) {
532     NXPLOG_FWDNLD_E(
533         "Clock timeout value is wrong in config file, setting it as default");
534     nxpprofile_ctrl.bTimeout = CLK_TO_CFG_DEF;
535   }
536 }
537 
538 /******************************************************************************
539  * Function         phNxpNciHal_MinOpen
540  *
541  * Description      This function initializes the least required resources to
542  *                  communicate to NFCC.This is mainly used to communicate to
543  *                  NFCC when NFC service is not available.
544  *
545  *
546  * Returns          This function return NFCSTATUS_SUCCESS (0) in case of
547  *                  success. In case of failure returns other failure value.
548  *
549  ******************************************************************************/
phNxpNciHal_MinOpen()550 int phNxpNciHal_MinOpen() {
551   phOsalNfc_Config_t tOsalConfig;
552   phTmlNfc_Config_t tTmlConfig;
553   char* nfc_dev_node = NULL;
554   const uint16_t max_len = 260;
555   NFCSTATUS wConfigStatus = NFCSTATUS_SUCCESS;
556   NFCSTATUS status = NFCSTATUS_SUCCESS;
557   NXPLOG_NCIHAL_D("phNxpNci_MinOpen(): enter");
558   /*NCI_INIT_CMD*/
559   static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
560   /*NCI_RESET_CMD*/
561   static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
562   /*NCI2_0_INIT_CMD*/
563   static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
564 
565   AutoThreadMutex a(sHalFnLock);
566   if (nxpncihal_ctrl.halStatus == HAL_STATUS_MIN_OPEN) {
567     NXPLOG_NCIHAL_D("phNxpNciHal_MinOpen(): already open");
568     return NFCSTATUS_SUCCESS;
569   }
570   /* reset config cache */
571   resetNxpConfig();
572 
573   int init_retry_cnt = 0;
574   int8_t ret_val = 0x00;
575 
576   phNxpNciHal_initialize_debug_enabled_flag();
577   /* initialize trace level */
578   phNxpLog_InitializeLogLevel();
579 
580   /* initialize Mifare flags*/
581   phNxpNciHal_initialize_mifare_flag();
582 
583   /*Create the timer for extns write response*/
584   timeoutTimerId = phOsalNfc_Timer_Create();
585 
586   if (phNxpNciHal_init_monitor() == NULL) {
587     NXPLOG_NCIHAL_E("Init monitor failed");
588     return NFCSTATUS_FAILED;
589   }
590 
591   CONCURRENCY_LOCK();
592   memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
593   memset(&tOsalConfig, 0x00, sizeof(tOsalConfig));
594   memset(&tTmlConfig, 0x00, sizeof(tTmlConfig));
595   memset(&nxpprofile_ctrl, 0, sizeof(phNxpNciProfile_Control_t));
596 
597   /*Init binary semaphore for Spi Nfc synchronization*/
598   if (0 != sem_init(&nxpncihal_ctrl.syncSpiNfc, 0, 1)) {
599     NXPLOG_NCIHAL_E("sem_init() FAiled, errno = 0x%02X", errno);
600     goto clean_and_return;
601   }
602 
603   /* By default HAL status is HAL_STATUS_OPEN */
604   nxpncihal_ctrl.halStatus = HAL_STATUS_OPEN;
605   gpEseAdapt = &EseAdaptation::GetInstance();
606   gpEseAdapt->Initialize();
607 
608   /*nci version NCI_VERSION_UNKNOWN version by default*/
609   nxpncihal_ctrl.nci_info.nci_version = NCI_VERSION_UNKNOWN;
610   /* Read the nfc device node name */
611   nfc_dev_node = (char*)malloc(max_len * sizeof(char));
612   if (nfc_dev_node == NULL) {
613     NXPLOG_NCIHAL_D("malloc of nfc_dev_node failed ");
614     goto clean_and_return;
615   } else if (!GetNxpStrValue(NAME_NXP_NFC_DEV_NODE, nfc_dev_node, max_len)) {
616     NXPLOG_NCIHAL_D(
617         "Invalid nfc device node name keeping the default device node "
618         "/dev/pn54x");
619     strlcpy(nfc_dev_node, "/dev/pn54x", (max_len * sizeof(char)));
620   }
621 
622   /* Configure hardware link */
623   nxpncihal_ctrl.gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
624   nxpncihal_ctrl.gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C; /* For PN54X */
625   tTmlConfig.pDevName = (int8_t*)nfc_dev_node;
626   tOsalConfig.dwCallbackThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId;
627   tOsalConfig.pLogFile = NULL;
628   tTmlConfig.dwGetMsgThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId;
629 
630   /* Initialize TML layer */
631   wConfigStatus = phTmlNfc_Init(&tTmlConfig);
632   if (wConfigStatus != NFCSTATUS_SUCCESS) {
633     NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
634     goto clean_and_return;
635   } else {
636     if (nfc_dev_node != NULL) {
637       free(nfc_dev_node);
638       nfc_dev_node = NULL;
639     }
640   }
641 
642   /* Create the client thread */
643   ret_val = pthread_create(&nxpncihal_ctrl.client_thread, NULL,
644                            phNxpNciHal_client_thread, &nxpncihal_ctrl);
645   if (ret_val != 0) {
646     NXPLOG_NCIHAL_E("pthread_create failed");
647     wConfigStatus = phTmlNfc_Shutdown_CleanUp();
648     goto clean_and_return;
649   }
650 
651   CONCURRENCY_UNLOCK();
652 
653   /* call read pending */
654   status = phTmlNfc_Read(
655       nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN,
656       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
657   if (status != NFCSTATUS_PENDING) {
658     NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
659     wConfigStatus = phTmlNfc_Shutdown_CleanUp();
660     wConfigStatus = NFCSTATUS_FAILED;
661     goto clean_and_return;
662   }
663 
664   phNxpNciHal_ext_init();
665 
666 init_retry:
667   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
668   if (status == NFCSTATUS_SUCCESS) {
669     sIsForceFwDownloadReqd = false;
670   } else if (sIsForceFwDownloadReqd) {
671     /* MinOpen can be called from either NFC on or any NFC IOCTL calls from
672      * SPI HAL or system/nfc while Minopen is not done/success, which can
673      * trigger Force FW update during every Minopen. To avoid multiple Force
674      * Force FW upadted return if Force FW update is already done */
675     NXPLOG_NCIHAL_E("%s: Failed after Force FW updated. Exit", __func__);
676     return NFCSTATUS_FAILED;
677   }
678   sIsForceFwDownloadReqd = (status != NFCSTATUS_SUCCESS) &&
679                            (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT);
680   if (sIsForceFwDownloadReqd) {
681     NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
682     wConfigStatus = NFCSTATUS_FAILED;
683     goto force_download;
684   } else if (status != NFCSTATUS_SUCCESS) {
685     NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
686     if (init_retry_cnt < 3) {
687       init_retry_cnt++;
688       (void)phNxpNciHal_power_cycle();
689       goto init_retry;
690     } else
691       init_retry_cnt = 0;
692     wConfigStatus = phTmlNfc_Shutdown_CleanUp();
693     wConfigStatus = NFCSTATUS_FAILED;
694     goto clean_and_return;
695   }
696 
697   if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
698     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
699   } else {
700     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
701     /*If chipType is pn557 or PN81A(PN553_TC) and if the chip is in 1.0 mode,
702       Force it to 2.0 mode. To confirm the PN553_TC/PN81A chip, FW version check
703       is also added */
704     bool pn81A_pn553_chip =
705         (nfcFL.chipType == pn553) && ((wFwVerRsp >> 8 & 0xFFFF) == 0x1102);
706     if ((status == NFCSTATUS_SUCCESS) &&
707         ((nfcFL.chipType == pn557) || pn81A_pn553_chip)) {
708       NXPLOG_NCIHAL_D("Chip is in NCI1.0 mode reset the chip to 2.0 mode");
709       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
710       if (status == NFCSTATUS_SUCCESS) {
711         status =
712             phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
713         if (status == NFCSTATUS_SUCCESS) {
714           goto init_retry;
715         }
716       }
717     }
718   }
719   if (status != NFCSTATUS_SUCCESS) {
720     NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
721     if (init_retry_cnt < 3) {
722       init_retry_cnt++;
723       (void)phNxpNciHal_power_cycle();
724       goto init_retry;
725     } else
726       init_retry_cnt = 0;
727     wConfigStatus = phTmlNfc_Shutdown_CleanUp();
728     wConfigStatus = NFCSTATUS_FAILED;
729     goto clean_and_return;
730   }
731   phNxpNciHal_enable_i2c_fragmentation();
732   /*Get FW version from device*/
733   status = phDnldNfc_InitImgInfo();
734   if (status != NFCSTATUS_SUCCESS) {
735     NXPLOG_NCIHAL_E("Image information extraction Failed!!");
736   }
737   NXPLOG_NCIHAL_D("FW version for FW file = 0x%x", wFwVer);
738   NXPLOG_NCIHAL_D("FW version from device = 0x%x", wFwVerRsp);
739   if ((wFwVerRsp & 0x0000FFFF) == wFwVer) {
740     NXPLOG_NCIHAL_D("FW update not required");
741     phDnldNfc_ReSetHwDevHandle();
742   } else {
743   force_download:
744     status = phNxpNciHal_fw_download();
745     if (NFCSTATUS_FAILED == status) {
746       wConfigStatus = NFCSTATUS_FAILED;
747       NXPLOG_NCIHAL_D("FW download Failed");
748       goto clean_and_return;
749     } else if (NFCSTATUS_REJECTED == status) {
750       wConfigStatus = NFCSTATUS_SUCCESS;
751       NXPLOG_NCIHAL_D("FW download Rejected. Continuiing Nfc Init");
752     } else {
753       wConfigStatus = NFCSTATUS_SUCCESS;
754       NXPLOG_NCIHAL_D("FW download Success");
755     }
756   }
757   NfccPowerTracker::getInstance().Initialize();
758   /* Call open complete */
759   phNxpNciHal_MinOpen_complete(wConfigStatus);
760   NXPLOG_NCIHAL_D("phNxpNciHal_MinOpen(): exit");
761   return wConfigStatus;
762 
763 clean_and_return:
764   CONCURRENCY_UNLOCK();
765   if (nfc_dev_node != NULL) {
766     free(nfc_dev_node);
767     nfc_dev_node = NULL;
768   }
769   /* Report error status */
770   phNxpNciHal_cleanup_monitor();
771   nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
772   return NFCSTATUS_FAILED;
773 }
774 
775 /******************************************************************************
776  * Function         phNxpNciHal_open
777  *
778  * Description      This function is called by libnfc-nci during the
779  *                  initialization of the NFCC. It opens the physical connection
780  *                  with NFCC (PN54X) and creates required client thread for
781  *                  operation.
782  *                  After open is complete, status is informed to libnfc-nci
783  *                  through callback function.
784  *
785  * Returns          This function return NFCSTATUS_SUCCESS (0) in case of
786  *                  success. In case of failure returns other failure value.
787  *
788  ******************************************************************************/
phNxpNciHal_open(nfc_stack_callback_t * p_cback,nfc_stack_data_callback_t * p_data_cback)789 int phNxpNciHal_open(nfc_stack_callback_t* p_cback,
790                      nfc_stack_data_callback_t* p_data_cback) {
791   NFCSTATUS wConfigStatus = NFCSTATUS_SUCCESS;
792   NFCSTATUS status = NFCSTATUS_SUCCESS;
793 
794   if (nxpncihal_ctrl.halStatus == HAL_STATUS_OPEN) {
795     NXPLOG_NCIHAL_D("phNxpNciHal_open already open");
796     return NFCSTATUS_SUCCESS;
797   } else if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
798     status = phNxpNciHal_MinOpen();
799     if (status != NFCSTATUS_SUCCESS) {
800       NXPLOG_NCIHAL_E("phNxpNciHal_MinOpen failed");
801       goto clean_and_return;
802     }
803   } /*else its already in MIN_OPEN state. continue with rest of functionality*/
804   nxpncihal_ctrl.p_nfc_stack_cback = p_cback;
805   nxpncihal_ctrl.p_nfc_stack_data_cback = p_data_cback;
806 
807   /* Call open complete */
808   phNxpNciHal_open_complete(wConfigStatus);
809 
810   return wConfigStatus;
811 
812 clean_and_return:
813   CONCURRENCY_UNLOCK();
814   /* Report error status */
815   if (p_cback != NULL) {
816     (*p_cback)(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
817   }
818 
819   nxpncihal_ctrl.p_nfc_stack_cback = NULL;
820   nxpncihal_ctrl.p_nfc_stack_data_cback = NULL;
821   phNxpNciHal_cleanup_monitor();
822   nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
823   return NFCSTATUS_FAILED;
824 }
825 
826 /******************************************************************************
827  * Function         phNxpNciHal_fw_mw_check
828  *
829  * Description      This function inform the status of phNxpNciHal_fw_mw_check
830  *                  function to libnfc-nci.
831  *
832  * Returns          int.
833  *
834  ******************************************************************************/
phNxpNciHal_fw_mw_ver_check()835 int phNxpNciHal_fw_mw_ver_check() {
836   NFCSTATUS status = NFCSTATUS_FAILED;
837   if (((nfcFL.chipType == pn557) || (nfcFL.chipType == pn81T)) &&
838       (rom_version == FW_MOBILE_ROM_VERSION_PN557) && (fw_maj_ver == 0x01)) {
839     status = NFCSTATUS_SUCCESS;
840   } else if (((nfcFL.chipType == pn553) || (nfcFL.chipType == pn80T)) &&
841              (rom_version == FW_MOBILE_ROM_VERSION_PN553) &&
842              (fw_maj_ver == 0x01 || fw_maj_ver == 0x02)) {
843     status = NFCSTATUS_SUCCESS;
844   } else if (((nfcFL.chipType == pn551) || (nfcFL.chipType == pn67T)) &&
845              (rom_version == FW_MOBILE_ROM_VERSION_PN551) &&
846              (fw_maj_ver == 0x05)) {
847     status = NFCSTATUS_SUCCESS;
848   }
849   return status;
850 }
851 /******************************************************************************
852  * Function         phNxpNciHal_MinOpen_complete
853  *
854  * Description      This function updates the status of
855  *phNxpNciHal_MinOpen_complete to halstatus.
856  *
857  * Returns          void.
858  *
859  ******************************************************************************/
phNxpNciHal_MinOpen_complete(NFCSTATUS status)860 static void phNxpNciHal_MinOpen_complete(NFCSTATUS status) {
861   if (status == NFCSTATUS_SUCCESS) {
862     nxpncihal_ctrl.halStatus = HAL_STATUS_MIN_OPEN;
863   }
864 
865   return;
866 }
867 
868 /******************************************************************************
869  * Function         phNxpNciHal_open_complete
870  *
871  * Description      This function inform the status of phNxpNciHal_open
872  *                  function to libnfc-nci.
873  *
874  * Returns          void.
875  *
876  ******************************************************************************/
phNxpNciHal_open_complete(NFCSTATUS status)877 static void phNxpNciHal_open_complete(NFCSTATUS status) {
878   static phLibNfc_Message_t msg;
879 
880   if (status == NFCSTATUS_SUCCESS) {
881     msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
882     nxpncihal_ctrl.hal_open_status = true;
883     nxpncihal_ctrl.halStatus = HAL_STATUS_OPEN;
884   } else {
885     msg.eMsgType = NCI_HAL_ERROR_MSG;
886   }
887 
888   msg.pMsgData = NULL;
889   msg.Size = 0;
890 
891   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
892                         (phLibNfc_Message_t*)&msg);
893 
894   return;
895 }
896 
897 /******************************************************************************
898  * Function         phNxpNciHal_write
899  *
900  * Description      This function write the data to NFCC through physical
901  *                  interface (e.g. I2C) using the PN54X driver interface.
902  *                  Before sending the data to NFCC, phNxpNciHal_write_ext
903  *                  is called to check if there is any extension processing
904  *                  is required for the NCI packet being sent out.
905  *
906  * Returns          It returns number of bytes successfully written to NFCC.
907  *
908  ******************************************************************************/
phNxpNciHal_write(uint16_t data_len,const uint8_t * p_data)909 int phNxpNciHal_write(uint16_t data_len, const uint8_t* p_data) {
910   if (bDisableLegacyMfcExtns && bEnableMfcExtns && p_data[0] == 0x00) {
911     return NxpMfcReaderInstance.Write(data_len, p_data);
912   }
913   return phNxpNciHal_write_internal(data_len, p_data);
914 }
915 
916 /******************************************************************************
917  * Function         phNxpNciHal_write_internal
918  *
919  * Description      This function write the data to NFCC through physical
920  *                  interface (e.g. I2C) using the PN54X driver interface.
921  *                  Before sending the data to NFCC, phNxpNciHal_write_ext
922  *                  is called to check if there is any extension processing
923  *                  is required for the NCI packet being sent out.
924  *
925  * Returns          It returns number of bytes successfully written to NFCC.
926  *
927  ******************************************************************************/
phNxpNciHal_write_internal(uint16_t data_len,const uint8_t * p_data)928 int phNxpNciHal_write_internal(uint16_t data_len, const uint8_t* p_data) {
929   NFCSTATUS status = NFCSTATUS_FAILED;
930   static phLibNfc_Message_t msg;
931   if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
932     return NFCSTATUS_FAILED;
933   }
934   if (data_len > NCI_MAX_DATA_LEN) {
935     NXPLOG_NCIHAL_E("cmd_len exceeds limit NCI_MAX_DATA_LEN");
936     android_errorWriteLog(0x534e4554, "121267042");
937     goto clean_and_return;
938   }
939   /* Create local copy of cmd_data */
940   memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
941   nxpncihal_ctrl.cmd_len = data_len;
942 #ifdef P2P_PRIO_LOGIC_HAL_IMP
943   /* Specific logic to block RF disable when P2P priority logic is busy */
944   if (data_len < NORMAL_MODE_HEADER_LEN) {
945     /* Avoid OOB Read */
946     android_errorWriteLog(0x534e4554, "128530069");
947   } else if (p_data[0] == 0x21 && p_data[1] == 0x06 && p_data[2] == 0x01 &&
948              EnableP2P_PrioLogic == true) {
949     NXPLOG_NCIHAL_D("P2P priority logic busy: Disable it.");
950     phNxpNciHal_clean_P2P_Prio();
951   }
952 #endif
953 
954   /* Check for NXP ext before sending write */
955   status =
956       phNxpNciHal_write_ext(&nxpncihal_ctrl.cmd_len, nxpncihal_ctrl.p_cmd_data,
957                             &nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
958   if (status != NFCSTATUS_SUCCESS) {
959     /* Do not send packet to PN54X, send response directly */
960     msg.eMsgType = NCI_HAL_RX_MSG;
961     msg.pMsgData = NULL;
962     msg.Size = 0;
963 
964     phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
965                           (phLibNfc_Message_t*)&msg);
966     goto clean_and_return;
967   }
968 
969   CONCURRENCY_LOCK();
970   data_len = phNxpNciHal_write_unlocked(nxpncihal_ctrl.cmd_len,
971                                         nxpncihal_ctrl.p_cmd_data);
972   CONCURRENCY_UNLOCK();
973 
974   if (icode_send_eof == 1) {
975     usleep(10000);
976     icode_send_eof = 2;
977     status = phNxpNciHal_send_ext_cmd(3, cmd_icode_eof);
978     if (status != NFCSTATUS_SUCCESS) {
979       NXPLOG_NCIHAL_E("ICODE end of frame command failed");
980     }
981   }
982 
983 clean_and_return:
984   /* No data written */
985   return data_len;
986 }
987 
988 /******************************************************************************
989  * Function         phNxpNciHal_write_unlocked
990  *
991  * Description      This is the actual function which is being called by
992  *                  phNxpNciHal_write. This function writes the data to NFCC.
993  *                  It waits till write callback provide the result of write
994  *                  process.
995  *
996  * Returns          It returns number of bytes successfully written to NFCC.
997  *
998  ******************************************************************************/
phNxpNciHal_write_unlocked(uint16_t data_len,const uint8_t * p_data)999 int phNxpNciHal_write_unlocked(uint16_t data_len, const uint8_t* p_data) {
1000   NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER;
1001   phNxpNciHal_Sem_t cb_data;
1002   nxpncihal_ctrl.retry_cnt = 0;
1003   static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00,
1004                                 0xC7, 0xD4, 0x00, 0x00};
1005   /* Create the local semaphore */
1006   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
1007     NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked Create cb data failed");
1008     data_len = 0;
1009     goto clean_and_return;
1010   }
1011 
1012   /* Create local copy of cmd_data */
1013   memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
1014   nxpncihal_ctrl.cmd_len = data_len;
1015 
1016   /* check for write synchronyztion */
1017   if (phNxpNciHal_check_ncicmd_write_window(nxpncihal_ctrl.cmd_len,
1018                                             nxpncihal_ctrl.p_cmd_data) !=
1019       NFCSTATUS_SUCCESS) {
1020     NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked Create cb data failed");
1021     data_len = 0;
1022     goto clean_and_return;
1023   }
1024 
1025   NfccPowerTracker::getInstance().ProcessCmd(
1026       (uint8_t*)nxpncihal_ctrl.p_cmd_data, (uint16_t)nxpncihal_ctrl.cmd_len);
1027 
1028 retry:
1029 
1030   data_len = nxpncihal_ctrl.cmd_len;
1031 
1032   status = phTmlNfc_Write(
1033       (uint8_t*)nxpncihal_ctrl.p_cmd_data, (uint16_t)nxpncihal_ctrl.cmd_len,
1034       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_write_complete,
1035       (void*)&cb_data);
1036   if (status != NFCSTATUS_PENDING) {
1037     NXPLOG_NCIHAL_E("write_unlocked status error");
1038     data_len = 0;
1039     goto clean_and_return;
1040   }
1041 
1042   /* Wait for callback response */
1043   if (SEM_WAIT(cb_data)) {
1044     NXPLOG_NCIHAL_E("write_unlocked semaphore error");
1045     data_len = 0;
1046     goto clean_and_return;
1047   }
1048 
1049   if (cb_data.status != NFCSTATUS_SUCCESS) {
1050     data_len = 0;
1051     if (nxpncihal_ctrl.retry_cnt++ < MAX_RETRY_COUNT) {
1052       NXPLOG_NCIHAL_D(
1053           "write_unlocked failed - PN54X Maybe in Standby Mode - Retry");
1054       /* 10ms delay to give NFCC wake up delay */
1055       usleep(1000 * 10);
1056       goto retry;
1057     } else {
1058       NXPLOG_NCIHAL_E(
1059           "write_unlocked failed - PN54X Maybe in Standby Mode (max count = "
1060           "0x%x)",
1061           nxpncihal_ctrl.retry_cnt);
1062 
1063       sem_post(&(nxpncihal_ctrl.syncSpiNfc));
1064 
1065       status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1066 
1067       if (NFCSTATUS_SUCCESS == status) {
1068         NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
1069       } else {
1070         NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
1071       }
1072       if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL &&
1073           nxpncihal_ctrl.p_rx_data != NULL &&
1074           nxpncihal_ctrl.hal_open_status == true) {
1075         NXPLOG_NCIHAL_D(
1076             "Send the Core Reset NTF to upper layer, which will trigger the "
1077             "recovery\n");
1078         // Send the Core Reset NTF to upper layer, which will trigger the
1079         // recovery.
1080         nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf);
1081         memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf));
1082         (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
1083                                                  nxpncihal_ctrl.p_rx_data);
1084       }
1085     }
1086   }
1087 
1088 clean_and_return:
1089   phNxpNciHal_cleanup_cb_data(&cb_data);
1090   return data_len;
1091 }
1092 
1093 /******************************************************************************
1094  * Function         phNxpNciHal_write_complete
1095  *
1096  * Description      This function handles write callback.
1097  *
1098  * Returns          void.
1099  *
1100  ******************************************************************************/
phNxpNciHal_write_complete(void * pContext,phTmlNfc_TransactInfo_t * pInfo)1101 static void phNxpNciHal_write_complete(void* pContext,
1102                                        phTmlNfc_TransactInfo_t* pInfo) {
1103   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
1104   if (pInfo->wStatus == NFCSTATUS_SUCCESS) {
1105     NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus);
1106   } else {
1107     NXPLOG_NCIHAL_D("write error status = 0x%x", pInfo->wStatus);
1108   }
1109 
1110   p_cb_data->status = pInfo->wStatus;
1111 
1112   SEM_POST(p_cb_data);
1113 
1114   return;
1115 }
1116 
1117 /******************************************************************************
1118  * Function         phNxpNciHal_read_complete
1119  *
1120  * Description      This function is called whenever there is an NCI packet
1121  *                  received from NFCC. It could be RSP or NTF packet. This
1122  *                  function provide the received NCI packet to libnfc-nci
1123  *                  using data callback of libnfc-nci.
1124  *                  There is a pending read called from each
1125  *                  phNxpNciHal_read_complete so each a packet received from
1126  *                  NFCC can be provide to libnfc-nci.
1127  *
1128  * Returns          void.
1129  *
1130  ******************************************************************************/
phNxpNciHal_read_complete(void * pContext,phTmlNfc_TransactInfo_t * pInfo)1131 static void phNxpNciHal_read_complete(void* pContext,
1132                                       phTmlNfc_TransactInfo_t* pInfo) {
1133   NFCSTATUS status = NFCSTATUS_FAILED;
1134   int sem_val;
1135   UNUSED(pContext);
1136   if (nxpncihal_ctrl.read_retry_cnt == 1) {
1137     nxpncihal_ctrl.read_retry_cnt = 0;
1138   }
1139   if (pInfo->wStatus == NFCSTATUS_SUCCESS) {
1140     NXPLOG_NCIHAL_D("read successful status = 0x%x", pInfo->wStatus);
1141 
1142     sem_getvalue(&(nxpncihal_ctrl.syncSpiNfc), &sem_val);
1143     if (((pInfo->pBuff[0] & NCI_MT_MASK) == NCI_MT_RSP) && sem_val == 0) {
1144       sem_post(&(nxpncihal_ctrl.syncSpiNfc));
1145     }
1146     /*Check the Omapi command response and store in dedicated buffer to solve
1147      * sync issue*/
1148     if (pInfo->pBuff[0] == 0x4F && pInfo->pBuff[1] == 0x01 &&
1149         pInfo->pBuff[2] == 0x01) {
1150       nxpncihal_ctrl.p_rx_ese_data = pInfo->pBuff;
1151       nxpncihal_ctrl.rx_ese_data_len = pInfo->wLength;
1152       SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1153     } else {
1154       nxpncihal_ctrl.p_rx_data = pInfo->pBuff;
1155       nxpncihal_ctrl.rx_data_len = pInfo->wLength;
1156       status = phNxpNciHal_process_ext_rsp(nxpncihal_ctrl.p_rx_data,
1157                                            &nxpncihal_ctrl.rx_data_len);
1158     }
1159 
1160     phNxpNciHal_print_res_status(pInfo->pBuff, &pInfo->wLength);
1161 
1162     if ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_NTF) {
1163       NfccPowerTracker::getInstance().ProcessNtf(nxpncihal_ctrl.p_rx_data,
1164                                                  nxpncihal_ctrl.rx_data_len);
1165     }
1166     /* Check if response should go to hal module only */
1167     if (nxpncihal_ctrl.hal_ext_enabled == TRUE &&
1168         (nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_RSP) {
1169       if (status == NFCSTATUS_FAILED) {
1170         NXPLOG_NCIHAL_D("enter into NFCC init recovery");
1171         nxpncihal_ctrl.ext_cb_data.status = status;
1172       }
1173       /* Unlock semaphore only for responses*/
1174       if ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_RSP ||
1175           ((icode_detected == true) && (icode_send_eof == 3))) {
1176         /* Unlock semaphore */
1177         SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1178       }
1179     }  // Notification Checking
1180     else if ((nxpncihal_ctrl.hal_ext_enabled == TRUE) &&
1181              ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_NTF) &&
1182              (nxpncihal_ctrl.nci_info.wait_for_ntf == TRUE)) {
1183       /* Unlock semaphore waiting for only  ntf*/
1184       SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1185       nxpncihal_ctrl.nci_info.wait_for_ntf = FALSE;
1186     } else if (bDisableLegacyMfcExtns && !sendRspToUpperLayer &&
1187                (nxpncihal_ctrl.p_rx_data[0x00] == 0x00)) {
1188       sendRspToUpperLayer = true;
1189       NFCSTATUS mfcRspStatus = NxpMfcReaderInstance.CheckMfcResponse(
1190           nxpncihal_ctrl.p_rx_data, nxpncihal_ctrl.rx_data_len);
1191       NXPLOG_NCIHAL_D("Mfc Response Status = 0x%x", mfcRspStatus);
1192       SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1193     }
1194     /* Read successful send the event to higher layer */
1195     else if ((nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) &&
1196              (status == NFCSTATUS_SUCCESS)) {
1197       (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
1198                                                nxpncihal_ctrl.p_rx_data);
1199       // workaround for sync issue between SPI and NFC
1200       if ((nfcFL.chipType == pn557) && nxpncihal_ctrl.p_rx_data[0] == 0x62 &&
1201           nxpncihal_ctrl.p_rx_data[1] == 0x00 &&
1202           nxpncihal_ctrl.p_rx_data[3] == 0xC0 &&
1203           nxpncihal_ctrl.p_rx_data[4] == 0x00) {
1204         uint8_t nfcee_notifiations[3][9] = {
1205             {0x61, 0x0A, 0x06, 0x01, 0x00, 0x03, 0xC0, 0x80, 0x04},
1206             {0x61, 0x0A, 0x06, 0x01, 0x00, 0x03, 0xC0, 0x81, 0x04},
1207             {0x61, 0x0A, 0x06, 0x01, 0x00, 0x03, 0xC0, 0x82, 0x03},
1208         };
1209 
1210         for (int i = 0; i < 3; i++) {
1211           (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
1212               sizeof(nfcee_notifiations[i]), nfcee_notifiations[i]);
1213         }
1214       }
1215     }
1216   } else {
1217     NXPLOG_NCIHAL_E("read error status = 0x%x", pInfo->wStatus);
1218   }
1219 
1220   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE &&
1221       nxpncihal_ctrl.nci_info.wait_for_ntf == FALSE) {
1222     NXPLOG_NCIHAL_D("Ignoring read, HAL close triggered");
1223     return;
1224   }
1225   /* Read again because read must be pending always.*/
1226   status = phTmlNfc_Read(
1227       Rx_data, NCI_MAX_DATA_LEN,
1228       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
1229   if (status != NFCSTATUS_PENDING) {
1230     NXPLOG_NCIHAL_E("read status error status = %x", status);
1231     /* TODO: Not sure how to handle this ? */
1232   }
1233 
1234   return;
1235 }
1236 
1237 /******************************************************************************
1238  * Function         phNxpNciHal_core_initialized
1239  *
1240  * Description      This function is called by libnfc-nci after successful open
1241  *                  of NFCC. All proprietary setting for PN54X are done here.
1242  *                  After completion of proprietary settings notification is
1243  *                  provided to libnfc-nci through callback function.
1244  *
1245  * Returns          Always returns NFCSTATUS_SUCCESS (0).
1246  *
1247  ******************************************************************************/
phNxpNciHal_core_initialized(uint16_t core_init_rsp_params_len,uint8_t * p_core_init_rsp_params)1248 int phNxpNciHal_core_initialized(uint16_t core_init_rsp_params_len,
1249                                  uint8_t* p_core_init_rsp_params) {
1250   NFCSTATUS status = NFCSTATUS_SUCCESS;
1251   static uint8_t p2p_listen_mode_routing_cmd[] = {0x21, 0x01, 0x07, 0x00, 0x01,
1252                                                   0x01, 0x03, 0x00, 0x01, 0x05};
1253 
1254   uint8_t swp_full_pwr_mode_on_cmd[] = {0x20, 0x02, 0x05, 0x01,
1255                                         0xA0, 0xF1, 0x01, 0x01};
1256 
1257   static uint8_t cmd_ven_pulld_enable_nci[] = {0x20, 0x02, 0x05, 0x01,
1258                                                0xA0, 0x07, 0x01, 0x03};
1259 
1260   static uint8_t android_l_aid_matching_mode_on_cmd[] = {
1261       0x20, 0x02, 0x05, 0x01, 0xA0, 0x91, 0x01, 0x01};
1262   static uint8_t swp_switch_timeout_cmd[] = {0x20, 0x02, 0x06, 0x01, 0xA0,
1263                                              0xF3, 0x02, 0x00, 0x00};
1264   config_success = true;
1265   uint8_t* buffer = NULL;
1266   long bufflen = 260;
1267   long retlen = 0;
1268   int isfound;
1269 #if (NFC_NXP_HFO_SETTINGS == TRUE)
1270   /* Temp fix to re-apply the proper clock setting */
1271   int temp_fix = 1;
1272 #endif
1273   unsigned long num = 0;
1274   // initialize dummy FW recovery variables
1275   gRecFwRetryCount = 0;
1276   gRecFWDwnld = 0;
1277   // recovery --start
1278   /*NCI_INIT_CMD*/
1279   static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
1280   /*NCI_RESET_CMD*/
1281   static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01,
1282                                     0x00};  // keep configuration
1283   static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
1284   /* reset config cache */
1285   static uint8_t retry_core_init_cnt;
1286   if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
1287     return NFCSTATUS_FAILED;
1288   }
1289   if (core_init_rsp_params_len >= 1 && (*p_core_init_rsp_params > 0) &&
1290       (*p_core_init_rsp_params < 4))  // initializing for recovery.
1291   {
1292   retry_core_init:
1293     config_access = false;
1294     if (buffer != NULL) {
1295       free(buffer);
1296       buffer = NULL;
1297     }
1298     if (retry_core_init_cnt > 3) {
1299       return NFCSTATUS_FAILED;
1300     }
1301 
1302     status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1303     if (NFCSTATUS_SUCCESS == status) {
1304       NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
1305     } else {
1306       NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
1307     }
1308 
1309     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
1310     if ((status != NFCSTATUS_SUCCESS) &&
1311         (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT)) {
1312       NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
1313       retry_core_init_cnt++;
1314       goto retry_core_init;
1315     } else if (status != NFCSTATUS_SUCCESS) {
1316       NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
1317       retry_core_init_cnt++;
1318       goto retry_core_init;
1319     }
1320 
1321     if (*p_core_init_rsp_params == 2) {
1322       NXPLOG_NCIHAL_E(" Last command is CORE_RESET!!");
1323       goto invoke_callback;
1324     }
1325     if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
1326       status =
1327           phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
1328     } else {
1329       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
1330     }
1331     if (status != NFCSTATUS_SUCCESS) {
1332       NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
1333       retry_core_init_cnt++;
1334       goto retry_core_init;
1335     }
1336 
1337     if (*p_core_init_rsp_params == 3) {
1338       NXPLOG_NCIHAL_E(" Last command is CORE_INIT!!");
1339       goto invoke_callback;
1340     }
1341   }
1342   // recovery --end
1343 
1344   buffer = (uint8_t*)malloc(bufflen * sizeof(uint8_t));
1345   if (NULL == buffer) {
1346     return NFCSTATUS_FAILED;
1347   }
1348   config_access = true;
1349   retlen = 0;
1350   isfound = GetNxpByteArrayValue(NAME_NXP_ACT_PROP_EXTN, (char*)buffer, bufflen,
1351                                  &retlen);
1352   if (retlen > 0) {
1353     /* NXP ACT Proprietary Ext */
1354     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1355     if (status != NFCSTATUS_SUCCESS) {
1356       NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
1357       retry_core_init_cnt++;
1358       goto retry_core_init;
1359     }
1360   }
1361 
1362   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ven_pulld_enable_nci),
1363                                     cmd_ven_pulld_enable_nci);
1364   if (status != NFCSTATUS_SUCCESS) {
1365     NXPLOG_NCIHAL_E("cmd_ven_pulld_enable_nci: Failed");
1366     retry_core_init_cnt++;
1367     goto retry_core_init;
1368   }
1369 
1370   if (fw_download_success == 1) {
1371     phNxpNciHal_hci_network_reset();
1372   }
1373 
1374   // Check if firmware download success
1375   status = phNxpNciHal_get_mw_eeprom();
1376   if (status != NFCSTATUS_SUCCESS) {
1377     NXPLOG_NCIHAL_E("NXP GET MW EEPROM AREA Proprietary Ext failed");
1378     retry_core_init_cnt++;
1379     goto retry_core_init;
1380   }
1381 
1382   //
1383   status = phNxpNciHal_check_clock_config();
1384   if (status != NFCSTATUS_SUCCESS) {
1385     NXPLOG_NCIHAL_E("phNxpNciHal_check_clock_config failed");
1386     retry_core_init_cnt++;
1387     goto retry_core_init;
1388   }
1389 
1390 #ifdef PN547C2_CLOCK_SETTING
1391   if (isNxpConfigModified() || (fw_download_success == 1) ||
1392       (phNxpNciClock.issetConfig)
1393 #if (NFC_NXP_HFO_SETTINGS == TRUE)
1394       || temp_fix == 1
1395 #endif
1396   ) {
1397     // phNxpNciHal_get_clk_freq();
1398     phNxpNciHal_set_clock();
1399     phNxpNciClock.issetConfig = false;
1400 #if (NFC_NXP_HFO_SETTINGS == TRUE)
1401     if (temp_fix == 1) {
1402       NXPLOG_NCIHAL_D(
1403           "Applying Default Clock setting and DPLL register at power on");
1404       /*
1405       # A0, 0D, 06, 06, 83, 55, 2A, 04, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_GEAR_REG
1406       # A0, 0D, 06, 06, 82, 33, 14, 17, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_REG
1407       # A0, 0D, 06, 06, 84, AA, 85, 00, 80 RF_CLIF_CFG_TARGET
1408       CLIF_DPLL_INIT_FREQ_REG
1409       # A0, 0D, 06, 06, 81, 63, 00, 00, 00 RF_CLIF_CFG_TARGET
1410       CLIF_DPLL_CONTROL_REG
1411       */
1412       static uint8_t cmd_dpll_set_reg_nci[] = {
1413           0x20, 0x02, 0x25, 0x04, 0xA0, 0x0D, 0x06, 0x06, 0x83, 0x55,
1414           0x2A, 0x04, 0x00, 0xA0, 0x0D, 0x06, 0x06, 0x82, 0x33, 0x14,
1415           0x17, 0x00, 0xA0, 0x0D, 0x06, 0x06, 0x84, 0xAA, 0x85, 0x00,
1416           0x80, 0xA0, 0x0D, 0x06, 0x06, 0x81, 0x63, 0x00, 0x00, 0x00};
1417 
1418       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_dpll_set_reg_nci),
1419                                         cmd_dpll_set_reg_nci);
1420       if (status != NFCSTATUS_SUCCESS) {
1421         NXPLOG_NCIHAL_E("NXP DPLL REG ACT Proprietary Ext failed");
1422         retry_core_init_cnt++;
1423         goto retry_core_init;
1424       }
1425       /* reset the NFCC after applying the clock setting and DPLL setting */
1426       // phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1427       temp_fix = 0;
1428       goto retry_core_init;
1429     }
1430 #endif
1431   }
1432 #endif
1433 
1434   retlen = 0;
1435   config_access = true;
1436   isfound = GetNxpByteArrayValue(NAME_NXP_NFC_PROFILE_EXTN, (char*)buffer,
1437                                  bufflen, &retlen);
1438   if (retlen > 0) {
1439     /* NXP ACT Proprietary Ext */
1440     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1441     if (status != NFCSTATUS_SUCCESS) {
1442       NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
1443       retry_core_init_cnt++;
1444       goto retry_core_init;
1445     }
1446   }
1447 
1448   if (isNxpConfigModified() || (fw_download_success == 1)) {
1449     retlen = 0;
1450     fw_download_success = 0;
1451 
1452     NXPLOG_NCIHAL_D("Performing TVDD Settings");
1453     isfound = GetNxpNumValue(NAME_NXP_EXT_TVDD_CFG, &num, sizeof(num));
1454     if (isfound > 0) {
1455       if (num == 1) {
1456         isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_1, (char*)buffer,
1457                                        bufflen, &retlen);
1458         if (retlen > 0) {
1459           status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1460           if (status != NFCSTATUS_SUCCESS) {
1461             NXPLOG_NCIHAL_E("EXT TVDD CFG 1 Settings failed");
1462             retry_core_init_cnt++;
1463             goto retry_core_init;
1464           }
1465         }
1466       } else if (num == 2) {
1467         isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_2, (char*)buffer,
1468                                        bufflen, &retlen);
1469         if (retlen > 0) {
1470           status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1471           if (status != NFCSTATUS_SUCCESS) {
1472             NXPLOG_NCIHAL_E("EXT TVDD CFG 2 Settings failed");
1473             retry_core_init_cnt++;
1474             goto retry_core_init;
1475           }
1476         }
1477       } else if (num == 3) {
1478         isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_3, (char*)buffer,
1479                                        bufflen, &retlen);
1480         if (retlen > 0) {
1481           status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1482           if (status != NFCSTATUS_SUCCESS) {
1483             NXPLOG_NCIHAL_E("EXT TVDD CFG 3 Settings failed");
1484             retry_core_init_cnt++;
1485             goto retry_core_init;
1486           }
1487         }
1488       } else {
1489         NXPLOG_NCIHAL_E("Wrong Configuration Value %ld", num);
1490       }
1491     }
1492     retlen = 0;
1493     config_access = false;
1494     NXPLOG_NCIHAL_D("Performing RF Settings BLK 1");
1495     isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_1, (char*)buffer,
1496                                    bufflen, &retlen);
1497     if (retlen > 0) {
1498       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1499       if (status == NFCSTATUS_SUCCESS) {
1500         status = phNxpNciHal_CheckRFCmdRespStatus();
1501         /*STATUS INVALID PARAM 0x09*/
1502         if (status == 0x09) {
1503           phNxpNciHalRFConfigCmdRecSequence();
1504           retry_core_init_cnt++;
1505           goto retry_core_init;
1506         }
1507       } else if (status != NFCSTATUS_SUCCESS) {
1508         NXPLOG_NCIHAL_E("RF Settings BLK 1 failed");
1509         retry_core_init_cnt++;
1510         goto retry_core_init;
1511       }
1512     }
1513     retlen = 0;
1514 
1515     NXPLOG_NCIHAL_D("Performing RF Settings BLK 2");
1516     isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_2, (char*)buffer,
1517                                    bufflen, &retlen);
1518     if (retlen > 0) {
1519       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1520       if (status == NFCSTATUS_SUCCESS) {
1521         status = phNxpNciHal_CheckRFCmdRespStatus();
1522         /*STATUS INVALID PARAM 0x09*/
1523         if (status == 0x09) {
1524           phNxpNciHalRFConfigCmdRecSequence();
1525           retry_core_init_cnt++;
1526           goto retry_core_init;
1527         }
1528       } else if (status != NFCSTATUS_SUCCESS) {
1529         NXPLOG_NCIHAL_E("RF Settings BLK 2 failed");
1530         retry_core_init_cnt++;
1531         goto retry_core_init;
1532       }
1533     }
1534     retlen = 0;
1535 
1536     NXPLOG_NCIHAL_D("Performing RF Settings BLK 3");
1537     isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_3, (char*)buffer,
1538                                    bufflen, &retlen);
1539     if (retlen > 0) {
1540       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1541       if (status == NFCSTATUS_SUCCESS) {
1542         status = phNxpNciHal_CheckRFCmdRespStatus();
1543         /*STATUS INVALID PARAM 0x09*/
1544         if (status == 0x09) {
1545           phNxpNciHalRFConfigCmdRecSequence();
1546           retry_core_init_cnt++;
1547           goto retry_core_init;
1548         }
1549       } else if (status != NFCSTATUS_SUCCESS) {
1550         NXPLOG_NCIHAL_E("RF Settings BLK 3 failed");
1551         retry_core_init_cnt++;
1552         goto retry_core_init;
1553       }
1554     }
1555     retlen = 0;
1556 
1557     NXPLOG_NCIHAL_D("Performing RF Settings BLK 4");
1558     isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_4, (char*)buffer,
1559                                    bufflen, &retlen);
1560     if (retlen > 0) {
1561       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1562       if (status == NFCSTATUS_SUCCESS) {
1563         status = phNxpNciHal_CheckRFCmdRespStatus();
1564         /*STATUS INVALID PARAM 0x09*/
1565         if (status == 0x09) {
1566           phNxpNciHalRFConfigCmdRecSequence();
1567           retry_core_init_cnt++;
1568           goto retry_core_init;
1569         }
1570       } else if (status != NFCSTATUS_SUCCESS) {
1571         NXPLOG_NCIHAL_E("RF Settings BLK 4 failed");
1572         retry_core_init_cnt++;
1573         goto retry_core_init;
1574       }
1575     }
1576     retlen = 0;
1577 
1578     NXPLOG_NCIHAL_D("Performing RF Settings BLK 5");
1579     isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_5, (char*)buffer,
1580                                    bufflen, &retlen);
1581     if (retlen > 0) {
1582       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1583       if (status == NFCSTATUS_SUCCESS) {
1584         status = phNxpNciHal_CheckRFCmdRespStatus();
1585         /*STATUS INVALID PARAM 0x09*/
1586         if (status == 0x09) {
1587           phNxpNciHalRFConfigCmdRecSequence();
1588           retry_core_init_cnt++;
1589           goto retry_core_init;
1590         }
1591       } else if (status != NFCSTATUS_SUCCESS) {
1592         NXPLOG_NCIHAL_E("RF Settings BLK 5 failed");
1593         retry_core_init_cnt++;
1594         goto retry_core_init;
1595       }
1596     }
1597     retlen = 0;
1598 
1599     NXPLOG_NCIHAL_D("Performing RF Settings BLK 6");
1600     isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_6, (char*)buffer,
1601                                    bufflen, &retlen);
1602     if (retlen > 0) {
1603       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1604       if (status == NFCSTATUS_SUCCESS) {
1605         status = phNxpNciHal_CheckRFCmdRespStatus();
1606         /*STATUS INVALID PARAM 0x09*/
1607         if (status == 0x09) {
1608           phNxpNciHalRFConfigCmdRecSequence();
1609           retry_core_init_cnt++;
1610           goto retry_core_init;
1611         }
1612       } else if (status != NFCSTATUS_SUCCESS) {
1613         NXPLOG_NCIHAL_E("RF Settings BLK 6 failed");
1614         retry_core_init_cnt++;
1615         goto retry_core_init;
1616       }
1617     }
1618     retlen = 0;
1619     config_access = true;
1620     NXPLOG_NCIHAL_D("Performing NAME_NXP_CORE_CONF_EXTN Settings");
1621     isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF_EXTN, (char*)buffer,
1622                                    bufflen, &retlen);
1623     if (retlen > 0) {
1624       /* NXP ACT Proprietary Ext */
1625       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1626       if (status != NFCSTATUS_SUCCESS) {
1627         NXPLOG_NCIHAL_E("NXP Core configuration failed");
1628         retry_core_init_cnt++;
1629         goto retry_core_init;
1630       }
1631     }
1632 
1633     retlen = 0;
1634     config_access = false;
1635     isfound = GetNxpByteArrayValue(NAME_NXP_CORE_RF_FIELD, (char*)buffer,
1636                                    bufflen, &retlen);
1637     if (retlen > 0) {
1638       /* NXP ACT Proprietary Ext */
1639       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1640       if (status == NFCSTATUS_SUCCESS) {
1641         status = phNxpNciHal_CheckRFCmdRespStatus();
1642         /*STATUS INVALID PARAM 0x09*/
1643         if (status == 0x09) {
1644           phNxpNciHalRFConfigCmdRecSequence();
1645           retry_core_init_cnt++;
1646           goto retry_core_init;
1647         }
1648       } else if (status != NFCSTATUS_SUCCESS) {
1649         NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
1650         retry_core_init_cnt++;
1651         goto retry_core_init;
1652       }
1653     }
1654     config_access = true;
1655 
1656     retlen = 0;
1657     /* NXP SWP switch timeout Setting*/
1658     if (GetNxpNumValue(NAME_NXP_SWP_SWITCH_TIMEOUT, (void*)&retlen,
1659                        sizeof(retlen))) {
1660       // Check the permissible range [0 - 60]
1661       if (0 <= retlen && retlen <= 60) {
1662         if (0 < retlen) {
1663           unsigned int timeout = (uint32_t)retlen * 1000;
1664           unsigned int timeoutHx = 0x0000;
1665 
1666           char tmpbuffer[10] = {0};
1667           snprintf((char*)tmpbuffer, 10, "%04x", timeout);
1668           sscanf((char*)tmpbuffer, "%x", &timeoutHx);
1669 
1670           swp_switch_timeout_cmd[7] = (timeoutHx & 0xFF);
1671           swp_switch_timeout_cmd[8] = ((timeoutHx & 0xFF00) >> 8);
1672         }
1673 
1674         status = phNxpNciHal_send_ext_cmd(sizeof(swp_switch_timeout_cmd),
1675                                           swp_switch_timeout_cmd);
1676         if (status != NFCSTATUS_SUCCESS) {
1677           NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed");
1678           retry_core_init_cnt++;
1679           goto retry_core_init;
1680         }
1681       } else {
1682         NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed - out of range!");
1683       }
1684     }
1685 
1686     status = phNxpNciHal_china_tianjin_rf_setting();
1687     if (status != NFCSTATUS_SUCCESS) {
1688       NXPLOG_NCIHAL_E("phNxpNciHal_china_tianjin_rf_setting failed");
1689       retry_core_init_cnt++;
1690       goto retry_core_init;
1691     }
1692     // Update eeprom value
1693     status = phNxpNciHal_set_mw_eeprom();
1694     if (status != NFCSTATUS_SUCCESS) {
1695       NXPLOG_NCIHAL_E("NXP Update MW EEPROM Proprietary Ext failed");
1696     }
1697   }
1698 
1699   retlen = 0;
1700 
1701   isfound =
1702       GetNxpByteArrayValue(NAME_NXP_CORE_CONF, (char*)buffer, bufflen, &retlen);
1703   if (retlen > 0) {
1704     /* NXP ACT Proprietary Ext */
1705     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1706     if (status != NFCSTATUS_SUCCESS) {
1707       NXPLOG_NCIHAL_E("Core Set Config failed");
1708       retry_core_init_cnt++;
1709       goto retry_core_init;
1710     }
1711   }
1712 
1713   config_access = false;
1714   // if recovery mode and length of last command is 0 then only reset the P2P
1715   // listen mode routing.
1716   if (core_init_rsp_params_len >= 36 && (*p_core_init_rsp_params > 0) &&
1717       (*p_core_init_rsp_params < 4) && p_core_init_rsp_params[35] == 0) {
1718     /* P2P listen mode routing */
1719     status = phNxpNciHal_send_ext_cmd(sizeof(p2p_listen_mode_routing_cmd),
1720                                       p2p_listen_mode_routing_cmd);
1721     if (status != NFCSTATUS_SUCCESS) {
1722       NXPLOG_NCIHAL_E("P2P listen mode routing failed");
1723       retry_core_init_cnt++;
1724       goto retry_core_init;
1725     }
1726   }
1727 
1728   retlen = 0;
1729 
1730   /* SWP FULL PWR MODE SETTING ON */
1731   if (GetNxpNumValue(NAME_NXP_SWP_FULL_PWR_ON, (void*)&retlen,
1732                      sizeof(retlen))) {
1733     if (1 == retlen) {
1734       status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd),
1735                                         swp_full_pwr_mode_on_cmd);
1736       if (status != NFCSTATUS_SUCCESS) {
1737         NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING ON CMD FAILED");
1738         retry_core_init_cnt++;
1739         goto retry_core_init;
1740       }
1741     } else {
1742       swp_full_pwr_mode_on_cmd[7] = 0x00;
1743       status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd),
1744                                         swp_full_pwr_mode_on_cmd);
1745       if (status != NFCSTATUS_SUCCESS) {
1746         NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING OFF CMD FAILED");
1747         retry_core_init_cnt++;
1748         goto retry_core_init;
1749       }
1750     }
1751   }
1752 
1753   /* Android L AID Matching Platform Setting*/
1754   if ((nfcFL.chipType != pn557) &&
1755       GetNxpNumValue(NAME_AID_MATCHING_PLATFORM, (void*)&retlen,
1756                      sizeof(retlen))) {
1757     if (1 == retlen) {
1758       status =
1759           phNxpNciHal_send_ext_cmd(sizeof(android_l_aid_matching_mode_on_cmd),
1760                                    android_l_aid_matching_mode_on_cmd);
1761       if (status != NFCSTATUS_SUCCESS) {
1762         NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
1763         retry_core_init_cnt++;
1764         goto retry_core_init;
1765       }
1766     } else if (2 == retlen) {
1767       android_l_aid_matching_mode_on_cmd[7] = 0x00;
1768       status =
1769           phNxpNciHal_send_ext_cmd(sizeof(android_l_aid_matching_mode_on_cmd),
1770                                    android_l_aid_matching_mode_on_cmd);
1771       if (status != NFCSTATUS_SUCCESS) {
1772         NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
1773         retry_core_init_cnt++;
1774         goto retry_core_init;
1775       }
1776     }
1777   }
1778 
1779   if (core_init_rsp_params_len >= 1 && (*p_core_init_rsp_params > 0) &&
1780       (*p_core_init_rsp_params < 4)) {
1781     static phLibNfc_Message_t msg;
1782     uint16_t tmp_len = 0;
1783     uint8_t uicc_set_mode[] = {0x22, 0x01, 0x02, 0x02, 0x01};
1784     uint8_t set_screen_state[] = {0x2F, 0x15, 01, 00};  // SCREEN ON
1785     uint8_t nfcc_core_conn_create[] = {0x20, 0x04, 0x06, 0x03, 0x01,
1786                                        0x01, 0x02, 0x01, 0x01};
1787     uint8_t nfcc_mode_set_on[] = {0x22, 0x01, 0x02, 0x01, 0x01};
1788 
1789     NXPLOG_NCIHAL_W(
1790         "Sending DH and NFCC core connection command as raw packet!!");
1791     status = phNxpNciHal_send_ext_cmd(sizeof(nfcc_core_conn_create),
1792                                       nfcc_core_conn_create);
1793 
1794     if (status != NFCSTATUS_SUCCESS) {
1795       NXPLOG_NCIHAL_E(
1796           "Sending DH and NFCC core connection command as raw packet!! Failed");
1797       retry_core_init_cnt++;
1798       goto retry_core_init;
1799     }
1800 
1801     NXPLOG_NCIHAL_W("Sending DH and NFCC mode set as raw packet!!");
1802     status =
1803         phNxpNciHal_send_ext_cmd(sizeof(nfcc_mode_set_on), nfcc_mode_set_on);
1804 
1805     if (status != NFCSTATUS_SUCCESS) {
1806       NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!! Failed");
1807       retry_core_init_cnt++;
1808       goto retry_core_init;
1809     }
1810 
1811     NXPLOG_NCIHAL_W("Sending UICC Select Command as raw packet!!");
1812     status = phNxpNciHal_send_ext_cmd(sizeof(uicc_set_mode), uicc_set_mode);
1813     if (status != NFCSTATUS_SUCCESS) {
1814       NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!! Failed");
1815       retry_core_init_cnt++;
1816       goto retry_core_init;
1817     }
1818 
1819     if (core_init_rsp_params_len >= 4 &&
1820         *(p_core_init_rsp_params + 1) == 1)  // RF state is Discovery!!
1821     {
1822       NXPLOG_NCIHAL_W("Sending Set Screen ON State Command as raw packet!!");
1823       status =
1824           phNxpNciHal_send_ext_cmd(sizeof(set_screen_state), set_screen_state);
1825       if (status != NFCSTATUS_SUCCESS) {
1826         NXPLOG_NCIHAL_E(
1827             "Sending Set Screen ON State Command as raw packet!! Failed");
1828         retry_core_init_cnt++;
1829         goto retry_core_init;
1830       }
1831 
1832       if (p_core_init_rsp_params[2] > (core_init_rsp_params_len - 3)) {
1833         return NFCSTATUS_FAILED;
1834       }
1835       NXPLOG_NCIHAL_W("Sending discovery as raw packet!!");
1836       status = phNxpNciHal_send_ext_cmd(p_core_init_rsp_params[2],
1837                                         (uint8_t*)&p_core_init_rsp_params[3]);
1838       if (status != NFCSTATUS_SUCCESS) {
1839         NXPLOG_NCIHAL_E("Sending discovery as raw packet Failed");
1840         retry_core_init_cnt++;
1841         goto retry_core_init;
1842       }
1843 
1844     } else {
1845       NXPLOG_NCIHAL_W("Sending Set Screen OFF State Command as raw packet!!");
1846       set_screen_state[3] = 0x01;  // Screen OFF
1847       status =
1848           phNxpNciHal_send_ext_cmd(sizeof(set_screen_state), set_screen_state);
1849       if (status != NFCSTATUS_SUCCESS) {
1850         NXPLOG_NCIHAL_E(
1851             "Sending Set Screen OFF State Command as raw packet!! Failed");
1852         retry_core_init_cnt++;
1853         goto retry_core_init;
1854       }
1855     }
1856     NXPLOG_NCIHAL_W("Sending last command for Recovery ");
1857 
1858     if (core_init_rsp_params_len >= 40 &&
1859         p_core_init_rsp_params[35] > 0) {  // if length of last command is 0
1860                                            // then it doesn't need to send last
1861                                            // command.
1862       if (!(((p_core_init_rsp_params[36] == 0x21) &&
1863              (p_core_init_rsp_params[37] == 0x03)) &&
1864             (*(p_core_init_rsp_params + 1) == 1)) &&
1865           !((p_core_init_rsp_params[36] == 0x21) &&
1866             (p_core_init_rsp_params[37] == 0x06) &&
1867             (p_core_init_rsp_params[39] == 0x00) &&
1868             (*(p_core_init_rsp_params + 1) == 0x00)))
1869       // if last command is discovery and RF status is also discovery state,
1870       // then it doesn't need to execute or similarly
1871       // if the last command is deactivate to idle and RF status is also idle ,
1872       // no need to execute the command .
1873       {
1874         tmp_len = p_core_init_rsp_params[35];
1875 
1876         /* Check for NXP ext before sending write */
1877         status = phNxpNciHal_write_ext(
1878             &tmp_len, (uint8_t*)&p_core_init_rsp_params[36],
1879             &nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
1880         if (status != NFCSTATUS_SUCCESS) {
1881           if (buffer) {
1882             free(buffer);
1883             buffer = NULL;
1884           }
1885           /* Do not send packet to PN54X, send response directly */
1886           msg.eMsgType = NCI_HAL_RX_MSG;
1887           msg.pMsgData = NULL;
1888           msg.Size = 0;
1889 
1890           phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1891                                 (phLibNfc_Message_t*)&msg);
1892           return NFCSTATUS_SUCCESS;
1893         }
1894 
1895         p_core_init_rsp_params[35] = (uint8_t)tmp_len;
1896         if (p_core_init_rsp_params[35] > (core_init_rsp_params_len - 36)) {
1897           return NFCSTATUS_FAILED;
1898         }
1899         status = phNxpNciHal_send_ext_cmd(
1900             p_core_init_rsp_params[35], (uint8_t*)&p_core_init_rsp_params[36]);
1901         if (status != NFCSTATUS_SUCCESS) {
1902           NXPLOG_NCIHAL_E("Sending last command for Recovery Failed");
1903           retry_core_init_cnt++;
1904           goto retry_core_init;
1905         }
1906       }
1907     }
1908   }
1909 
1910   retry_core_init_cnt = 0;
1911 
1912   if (buffer) {
1913     free(buffer);
1914     buffer = NULL;
1915   }
1916   // initialize dummy FW recovery variables
1917   gRecFWDwnld = 0;
1918   gRecFwRetryCount = 0;
1919   if (core_init_rsp_params_len >= 1 &&
1920       !((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)))
1921     phNxpNciHal_core_initialized_complete(status);
1922   else {
1923   invoke_callback:
1924     config_access = false;
1925     if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) {
1926       if (core_init_rsp_params_len) *p_core_init_rsp_params = 0;
1927       NXPLOG_NCIHAL_W("Invoking data callback!!");
1928       (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
1929                                                nxpncihal_ctrl.p_rx_data);
1930     }
1931   }
1932 
1933   if (config_success == false) return NFCSTATUS_FAILED;
1934 #ifdef PN547C2_CLOCK_SETTING
1935   if (isNxpConfigModified()) {
1936     updateNxpConfigTimestamp();
1937   }
1938 #endif
1939   return NFCSTATUS_SUCCESS;
1940 }
1941 
1942 #ifdef FactoryOTA
phNxpNciHal_isFactoryOTAModeActive()1943 void phNxpNciHal_isFactoryOTAModeActive() {
1944   uint8_t check_factoryOTA[] = {0x20, 0x03, 0x05, 0x02, 0xA0, 0x08, 0xA0, 0x88};
1945   NFCSTATUS status = NFCSTATUS_FAILED;
1946   NXPLOG_NCIHAL_D("check FactoryOTA mode status");
1947 
1948   status = phNxpNciHal_send_ext_cmd(sizeof(check_factoryOTA), check_factoryOTA);
1949 
1950   if (status == NFCSTATUS_SUCCESS) {
1951     if (nxpncihal_ctrl.p_rx_data[9] == 0x1 &&
1952         nxpncihal_ctrl.p_rx_data[13] == 0x1) {
1953       NXPLOG_NCIHAL_D("FactoryOTA mode is active");
1954     } else {
1955       NXPLOG_NCIHAL_D("FactoryOTA mode is disabled");
1956     }
1957   } else {
1958     NXPLOG_NCIHAL_E("Fail to get FactoryOTA mode status");
1959   }
1960   return;
1961 }
1962 
phNxpNciHal_disableFactoryOTAMode()1963 NFCSTATUS phNxpNciHal_disableFactoryOTAMode() {
1964   // NFCC GPIO output control
1965   uint8_t nfcc_system_gpio[] = {0x20, 0x02, 0x06, 0x01, 0xA0,
1966                                 0x08, 0x02, 0x00, 0x00};
1967   // NFCC automatically sets GPIO once a specific RF pattern is detected
1968   uint8_t nfcc_gpio_pattern[] = {0x20, 0x02, 0x08, 0x01, 0xA0, 0x88,
1969                                  0x04, 0x00, 0x96, 0x96, 0x03};
1970 
1971   NFCSTATUS status = NFCSTATUS_SUCCESS;
1972   NXPLOG_NCIHAL_D("Disable FactoryOTA mode");
1973   status = phNxpNciHal_send_ext_cmd(sizeof(nfcc_system_gpio), nfcc_system_gpio);
1974   if (status != NFCSTATUS_SUCCESS) {
1975     NXPLOG_NCIHAL_E("Can't disable A008 for FactoryOTA mode");
1976   }
1977   status =
1978       phNxpNciHal_send_ext_cmd(sizeof(nfcc_gpio_pattern), nfcc_gpio_pattern);
1979   if (status != NFCSTATUS_SUCCESS) {
1980     NXPLOG_NCIHAL_E("Can't disable A088 for FactoryOTA mode");
1981   }
1982   return status;
1983 }
1984 #endif
1985 
1986 /******************************************************************************
1987  * Function         phNxpNciHal_CheckRFCmdRespStatus
1988  *
1989  * Description      This function is called to check the resp status of
1990  *                  RF update commands.
1991  *
1992  * Returns          NFCSTATUS_SUCCESS           if successful,
1993  *                  NFCSTATUS_INVALID_PARAMETER if parameter is inavlid
1994  *                  NFCSTATUS_FAILED            if failed response
1995  *
1996  ******************************************************************************/
phNxpNciHal_CheckRFCmdRespStatus()1997 NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus() {
1998   NFCSTATUS status = NFCSTATUS_SUCCESS;
1999   static uint16_t INVALID_PARAM = 0x09;
2000   if ((nxpncihal_ctrl.rx_data_len > 0) && (nxpncihal_ctrl.p_rx_data[2] > 0)) {
2001     if (nxpncihal_ctrl.p_rx_data[3] == 0x09) {
2002       status = INVALID_PARAM;
2003     } else if (nxpncihal_ctrl.p_rx_data[3] != NFCSTATUS_SUCCESS) {
2004       status = NFCSTATUS_FAILED;
2005     }
2006   }
2007   return status;
2008 }
2009 /******************************************************************************
2010  * Function         phNxpNciHalRFConfigCmdRecSequence
2011  *
2012  * Description      This function is called to handle dummy FW recovery sequence
2013  *                  Whenever RF settings are failed to apply with invalid param
2014  *                  response, recovery mechanism includes dummy firmware
2015  *download
2016  *                  followed by firmware download and then config settings. The
2017  *dummy
2018  *                  firmware changes the major number of the firmware inside
2019  *NFCC.
2020  *                  Then actual firmware dowenload will be successful. This can
2021  *be
2022  *                  retried maximum three times.
2023  *
2024  * Returns          Always returns NFCSTATUS_SUCCESS
2025  *
2026  ******************************************************************************/
phNxpNciHalRFConfigCmdRecSequence()2027 NFCSTATUS phNxpNciHalRFConfigCmdRecSequence() {
2028   NFCSTATUS status = NFCSTATUS_SUCCESS;
2029   uint16_t recFWState = 1;
2030   gRecFWDwnld = true;
2031   gRecFwRetryCount++;
2032   if (gRecFwRetryCount > 0x03) {
2033     NXPLOG_NCIHAL_D("Max retry count for RF config FW recovery exceeded ");
2034     gRecFWDwnld = false;
2035     return NFCSTATUS_FAILED;
2036   }
2037   do {
2038     status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
2039     phDnldNfc_InitImgInfo();
2040     if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion()) {
2041       fw_download_success = 0;
2042       status = phNxpNciHal_fw_download();
2043       if (status == NFCSTATUS_SUCCESS) {
2044         fw_download_success = 1;
2045       }
2046       status = phTmlNfc_Read(
2047           nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN,
2048           (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
2049       if (status != NFCSTATUS_PENDING) {
2050         NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
2051         phOsalNfc_Timer_Cleanup();
2052         phTmlNfc_Shutdown();
2053         status = NFCSTATUS_FAILED;
2054       }
2055       break;
2056     }
2057     gRecFWDwnld = false;
2058   } while (recFWState--);
2059   gRecFWDwnld = false;
2060   return status;
2061 }
2062 /******************************************************************************
2063  * Function         phNxpNciHal_core_initialized_complete
2064  *
2065  * Description      This function is called when phNxpNciHal_core_initialized
2066  *                  complete all proprietary command exchanges. This function
2067  *                  informs libnfc-nci about completion of core initialize
2068  *                  and result of that through callback.
2069  *
2070  * Returns          void.
2071  *
2072  ******************************************************************************/
phNxpNciHal_core_initialized_complete(NFCSTATUS status)2073 static void phNxpNciHal_core_initialized_complete(NFCSTATUS status) {
2074   static phLibNfc_Message_t msg;
2075 
2076   if (status == NFCSTATUS_SUCCESS) {
2077     msg.eMsgType = NCI_HAL_POST_INIT_CPLT_MSG;
2078   } else {
2079     msg.eMsgType = NCI_HAL_ERROR_MSG;
2080   }
2081   msg.pMsgData = NULL;
2082   msg.Size = 0;
2083 
2084   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
2085                         (phLibNfc_Message_t*)&msg);
2086 
2087   return;
2088 }
2089 
2090 /******************************************************************************
2091  * Function         phNxpNciHal_pre_discover
2092  *
2093  * Description      This function is called by libnfc-nci to perform any
2094  *                  proprietary exchange before RF discovery.
2095  *
2096  * Returns          It always returns NFCSTATUS_SUCCESS (0).
2097  *
2098  ******************************************************************************/
phNxpNciHal_pre_discover(void)2099 int phNxpNciHal_pre_discover(void) {
2100   /* Nothing to do here for initial version */
2101   return NFCSTATUS_SUCCESS;
2102 }
2103 
2104 /******************************************************************************
2105  * Function         phNxpNciHal_close
2106  *
2107  * Description      This function close the NFCC interface and free all
2108  *                  resources.This is called by libnfc-nci on NFC service stop.
2109  *
2110  * Returns          Always return NFCSTATUS_SUCCESS (0).
2111  *
2112  ******************************************************************************/
phNxpNciHal_close(bool bShutdown)2113 int phNxpNciHal_close(bool bShutdown) {
2114   NFCSTATUS status;
2115   /*NCI_RESET_CMD*/
2116   static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
2117 
2118   static uint8_t cmd_ven_disable_nci[] = {0x20, 0x02, 0x05, 0x01,
2119                                           0xA0, 0x07, 0x01, 0x02};
2120 
2121   AutoThreadMutex a(sHalFnLock);
2122   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
2123     NXPLOG_NCIHAL_D("phNxpNciHal_close is already closed, ignoring close");
2124     return NFCSTATUS_FAILED;
2125   }
2126 
2127   CONCURRENCY_LOCK();
2128 
2129   int sem_val;
2130   sem_getvalue(&(nxpncihal_ctrl.syncSpiNfc), &sem_val);
2131   if (sem_val == 0) {
2132     sem_post(&(nxpncihal_ctrl.syncSpiNfc));
2133   }
2134   if (!bShutdown) {
2135     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ven_disable_nci),
2136                                       cmd_ven_disable_nci);
2137     if (status != NFCSTATUS_SUCCESS) {
2138       NXPLOG_NCIHAL_E("CMD_VEN_DISABLE_NCI: Failed");
2139     }
2140   }
2141 #ifdef FactoryOTA
2142   char valueStr[PROPERTY_VALUE_MAX] = {0};
2143   bool factoryOTA_terminate = false;
2144   int len = property_get("persist.factoryota.reboot", valueStr, "normal");
2145   if (len > 0) {
2146     factoryOTA_terminate =
2147         (len == 9 && (memcmp(valueStr, "terminate", len) == 0)) ? true : false;
2148   }
2149   NXPLOG_NCIHAL_D("factoryOTA_terminate: %d", factoryOTA_terminate);
2150   if (factoryOTA_terminate) {
2151     phNxpNciHal_disableFactoryOTAMode();
2152     phNxpNciHal_isFactoryOTAModeActive();
2153   }
2154 #endif
2155   nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
2156 
2157   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
2158   if (status != NFCSTATUS_SUCCESS) {
2159     NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
2160   }
2161 
2162   sem_destroy(&nxpncihal_ctrl.syncSpiNfc);
2163 
2164   if (NULL != gpphTmlNfc_Context->pDevHandle) {
2165     phNxpNciHal_close_complete(NFCSTATUS_SUCCESS);
2166     /* Abort any pending read and write */
2167     status = phTmlNfc_ReadAbort();
2168     status = phTmlNfc_WriteAbort();
2169 
2170     phOsalNfc_Timer_Cleanup();
2171 
2172     status = phTmlNfc_Shutdown();
2173 
2174     if (0 != pthread_join(nxpncihal_ctrl.client_thread, (void**)NULL)) {
2175       NXPLOG_TML_E("Fail to kill client thread!");
2176     }
2177 
2178     phTmlNfc_CleanUp();
2179 
2180     phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
2181 
2182     memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
2183 
2184     NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed");
2185   }
2186   NfccPowerTracker::getInstance().Pause();
2187   CONCURRENCY_UNLOCK();
2188 
2189   phNxpNciHal_cleanup_monitor();
2190 
2191   /* Return success always */
2192   return NFCSTATUS_SUCCESS;
2193 }
2194 
2195 /******************************************************************************
2196  * Function         phNxpNciHal_close_complete
2197  *
2198  * Description      This function inform libnfc-nci about result of
2199  *                  phNxpNciHal_close.
2200  *
2201  * Returns          void.
2202  *
2203  ******************************************************************************/
phNxpNciHal_close_complete(NFCSTATUS status)2204 void phNxpNciHal_close_complete(NFCSTATUS status) {
2205   static phLibNfc_Message_t msg;
2206 
2207   if (status == NFCSTATUS_SUCCESS) {
2208     msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
2209   } else {
2210     msg.eMsgType = NCI_HAL_ERROR_MSG;
2211   }
2212   msg.pMsgData = NULL;
2213   msg.Size = 0;
2214 
2215   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
2216 
2217   return;
2218 }
2219 
2220 /******************************************************************************
2221  * Function         phNxpNciHal_configDiscShutdown
2222  *
2223  * Description      Enable the CE and VEN config during shutdown.
2224  *
2225  * Returns          Always return NFCSTATUS_SUCCESS (0).
2226  *
2227  ******************************************************************************/
phNxpNciHal_configDiscShutdown(void)2228 int phNxpNciHal_configDiscShutdown(void) {
2229   NFCSTATUS status;
2230   NfccPowerTracker::getInstance().Reset();
2231 
2232   status = phNxpNciHal_close(true);
2233   if (status != NFCSTATUS_SUCCESS) {
2234     NXPLOG_NCIHAL_E("NCI_HAL_CLOSE: Failed");
2235   }
2236 
2237   /* Return success always */
2238   return NFCSTATUS_SUCCESS;
2239 }
2240 
2241 /******************************************************************************
2242  * Function         phNxpNciHal_getVendorConfig
2243  *
2244  * Description      This function can be used by HAL to inform
2245  *                 to update vendor configuration parametres
2246  *
2247  * Returns          void.
2248  *
2249  ******************************************************************************/
2250 
phNxpNciHal_getVendorConfig(android::hardware::nfc::V1_1::NfcConfig & config)2251 void phNxpNciHal_getVendorConfig(
2252     android::hardware::nfc::V1_1::NfcConfig& config) {
2253   unsigned long num = 0;
2254   std::array<uint8_t, NXP_MAX_CONFIG_STRING_LEN> buffer;
2255   buffer.fill(0);
2256   long retlen = 0;
2257   memset(&config, 0x00, sizeof(android::hardware::nfc::V1_1::NfcConfig));
2258 
2259   config.nfaPollBailOutMode = true;
2260   if (GetNxpNumValue(NAME_ISO_DEP_MAX_TRANSCEIVE, &num, sizeof(num))) {
2261     config.maxIsoDepTransceiveLength = (uint32_t)num;
2262   }
2263   if (GetNxpNumValue(NAME_DEFAULT_OFFHOST_ROUTE, &num, sizeof(num))) {
2264     config.defaultOffHostRoute = (uint8_t)num;
2265   }
2266   if (GetNxpNumValue(NAME_DEFAULT_NFCF_ROUTE, &num, sizeof(num))) {
2267     config.defaultOffHostRouteFelica = (uint8_t)num;
2268   }
2269   if (GetNxpNumValue(NAME_DEFAULT_SYS_CODE_ROUTE, &num, sizeof(num))) {
2270     config.defaultSystemCodeRoute = (uint8_t)num;
2271   }
2272   if (GetNxpNumValue(NAME_DEFAULT_SYS_CODE_PWR_STATE, &num, sizeof(num))) {
2273     config.defaultSystemCodePowerState = (uint8_t)num;
2274   }
2275   if (GetNxpNumValue(NAME_DEFAULT_ROUTE, &num, sizeof(num))) {
2276     config.defaultRoute = (uint8_t)num;
2277   }
2278   if (GetNxpByteArrayValue(NAME_DEVICE_HOST_WHITE_LIST, (char*)buffer.data(),
2279                            buffer.size(), &retlen)) {
2280     config.hostWhitelist.resize(retlen);
2281     for (long i = 0; i < retlen; i++) config.hostWhitelist[i] = buffer[i];
2282   }
2283   if (GetNxpNumValue(NAME_OFF_HOST_ESE_PIPE_ID, &num, sizeof(num))) {
2284     config.offHostESEPipeId = (uint8_t)num;
2285   }
2286   if (GetNxpNumValue(NAME_OFF_HOST_SIM_PIPE_ID, &num, sizeof(num))) {
2287     config.offHostSIMPipeId = (uint8_t)num;
2288   }
2289   if ((GetNxpByteArrayValue(NAME_NFA_PROPRIETARY_CFG, (char*)buffer.data(),
2290                             buffer.size(), &retlen)) &&
2291       (retlen == 9)) {
2292     config.nfaProprietaryCfg.protocol18092Active = (uint8_t)buffer[0];
2293     config.nfaProprietaryCfg.protocolBPrime = (uint8_t)buffer[1];
2294     config.nfaProprietaryCfg.protocolDual = (uint8_t)buffer[2];
2295     config.nfaProprietaryCfg.protocol15693 = (uint8_t)buffer[3];
2296     config.nfaProprietaryCfg.protocolKovio = (uint8_t)buffer[4];
2297     config.nfaProprietaryCfg.protocolMifare = (uint8_t)buffer[5];
2298     config.nfaProprietaryCfg.discoveryPollKovio = (uint8_t)buffer[6];
2299     config.nfaProprietaryCfg.discoveryPollBPrime = (uint8_t)buffer[7];
2300     config.nfaProprietaryCfg.discoveryListenBPrime = (uint8_t)buffer[8];
2301   } else {
2302     memset(&config.nfaProprietaryCfg, 0xFF, sizeof(ProtocolDiscoveryConfig));
2303   }
2304   if ((GetNxpNumValue(NAME_PRESENCE_CHECK_ALGORITHM, &num, sizeof(num))) &&
2305       (num <= 2)) {
2306     config.presenceCheckAlgorithm = (PresenceCheckAlgorithm)num;
2307   }
2308 }
2309 
2310 /******************************************************************************
2311  * Function         phNxpNciHal_getVendorConfig_1_2
2312  *
2313  * Description      This function can be used by HAL to inform
2314  *                 to update vendor configuration parametres
2315  *
2316  * Returns          void.
2317  *
2318  ******************************************************************************/
2319 
phNxpNciHal_getVendorConfig_1_2(android::hardware::nfc::V1_2::NfcConfig & config)2320 void phNxpNciHal_getVendorConfig_1_2(
2321     android::hardware::nfc::V1_2::NfcConfig& config) {
2322   unsigned long num = 0;
2323   std::array<uint8_t, NXP_MAX_CONFIG_STRING_LEN> buffer;
2324   buffer.fill(0);
2325   long retlen = 0;
2326   memset(&config, 0x00, sizeof(android::hardware::nfc::V1_2::NfcConfig));
2327   phNxpNciHal_getVendorConfig(config.v1_1);
2328 
2329   if (GetNxpByteArrayValue(NAME_OFFHOST_ROUTE_UICC, (char*)buffer.data(),
2330                            buffer.size(), &retlen)) {
2331     config.offHostRouteUicc.resize(retlen);
2332     for (int i = 0; i < retlen; i++) config.offHostRouteUicc[i] = buffer[i];
2333   }
2334 
2335   if (GetNxpByteArrayValue(NAME_OFFHOST_ROUTE_ESE, (char*)buffer.data(),
2336                            buffer.size(), &retlen)) {
2337     config.offHostRouteEse.resize(retlen);
2338     for (int i = 0; i < retlen; i++) config.offHostRouteEse[i] = buffer[i];
2339   }
2340 
2341   if (GetNxpNumValue(NAME_DEFAULT_ISODEP_ROUTE, &num, sizeof(num))) {
2342     config.defaultIsoDepRoute = num;
2343   }
2344 }
2345 
2346 /******************************************************************************
2347  * Function         phNxpNciHal_notify_i2c_fragmentation
2348  *
2349  * Description      This function can be used by HAL to inform
2350  *                 libnfc-nci that i2c fragmentation is enabled/disabled
2351  *
2352  * Returns          void.
2353  *
2354  ******************************************************************************/
phNxpNciHal_notify_i2c_fragmentation(void)2355 void phNxpNciHal_notify_i2c_fragmentation(void) {
2356   if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
2357     /*inform libnfc-nci that i2c fragmentation is enabled/disabled */
2358     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT,
2359                                         HAL_NFC_STATUS_OK);
2360   }
2361 }
2362 /******************************************************************************
2363  * Function         phNxpNciHal_control_granted
2364  *
2365  * Description      Called by libnfc-nci when NFCC control is granted to HAL.
2366  *
2367  * Returns          Always returns NFCSTATUS_SUCCESS (0).
2368  *
2369  ******************************************************************************/
phNxpNciHal_control_granted(void)2370 int phNxpNciHal_control_granted(void) {
2371   /* Take the concurrency lock so no other calls from upper layer
2372    * will be allowed
2373    */
2374   CONCURRENCY_LOCK();
2375 
2376   if (NULL != nxpncihal_ctrl.p_control_granted_cback) {
2377     (*nxpncihal_ctrl.p_control_granted_cback)();
2378   }
2379   /* At the end concurrency unlock so calls from upper layer will
2380    * be allowed
2381    */
2382   CONCURRENCY_UNLOCK();
2383   return NFCSTATUS_SUCCESS;
2384 }
2385 
2386 /******************************************************************************
2387  * Function         phNxpNciHal_request_control
2388  *
2389  * Description      This function can be used by HAL to request control of
2390  *                  NFCC to libnfc-nci. When control is provided to HAL it is
2391  *                  notified through phNxpNciHal_control_granted.
2392  *
2393  * Returns          void.
2394  *
2395  ******************************************************************************/
phNxpNciHal_request_control(void)2396 void phNxpNciHal_request_control(void) {
2397   if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
2398     /* Request Control of NCI Controller from NCI NFC Stack */
2399     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_REQUEST_CONTROL_EVT,
2400                                         HAL_NFC_STATUS_OK);
2401   }
2402 
2403   return;
2404 }
2405 
2406 /******************************************************************************
2407  * Function         phNxpNciHal_release_control
2408  *
2409  * Description      This function can be used by HAL to release the control of
2410  *                  NFCC back to libnfc-nci.
2411  *
2412  * Returns          void.
2413  *
2414  ******************************************************************************/
phNxpNciHal_release_control(void)2415 void phNxpNciHal_release_control(void) {
2416   if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
2417     /* Release Control of NCI Controller to NCI NFC Stack */
2418     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_RELEASE_CONTROL_EVT,
2419                                         HAL_NFC_STATUS_OK);
2420   }
2421 
2422   return;
2423 }
2424 
2425 /******************************************************************************
2426  * Function         phNxpNciHal_power_cycle
2427  *
2428  * Description      This function is called by libnfc-nci when power cycling is
2429  *                  performed. When processing is complete it is notified to
2430  *                  libnfc-nci through phNxpNciHal_power_cycle_complete.
2431  *
2432  * Returns          Always return NFCSTATUS_SUCCESS (0).
2433  *
2434  ******************************************************************************/
phNxpNciHal_power_cycle(void)2435 int phNxpNciHal_power_cycle(void) {
2436   NXPLOG_NCIHAL_D("Power Cycle");
2437   NFCSTATUS status = NFCSTATUS_FAILED;
2438   if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
2439     NXPLOG_NCIHAL_D("Power Cycle failed due to hal status not open");
2440     return NFCSTATUS_FAILED;
2441   }
2442   status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
2443 
2444   if (NFCSTATUS_SUCCESS == status) {
2445     NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
2446   } else {
2447     NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
2448   }
2449   phNxpNciHal_power_cycle_complete(NFCSTATUS_SUCCESS);
2450   return NFCSTATUS_SUCCESS;
2451 }
2452 
2453 /******************************************************************************
2454  * Function         phNxpNciHal_power_cycle_complete
2455  *
2456  * Description      This function is called to provide the status of
2457  *                  phNxpNciHal_power_cycle to libnfc-nci through callback.
2458  *
2459  * Returns          void.
2460  *
2461  ******************************************************************************/
phNxpNciHal_power_cycle_complete(NFCSTATUS status)2462 static void phNxpNciHal_power_cycle_complete(NFCSTATUS status) {
2463   static phLibNfc_Message_t msg;
2464 
2465   if (status == NFCSTATUS_SUCCESS) {
2466     msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
2467   } else {
2468     msg.eMsgType = NCI_HAL_ERROR_MSG;
2469   }
2470   msg.pMsgData = NULL;
2471   msg.Size = 0;
2472 
2473   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
2474 
2475   return;
2476 }
2477 /******************************************************************************
2478  * Function         phNxpNciHal_check_ncicmd_write_window
2479  *
2480  * Description      This function is called to check the write synchroniztion
2481  *                  status if write already aquired then wait for corresponding
2482                     read to complete.
2483  *
2484  * Returns          return 0 on success and -1 on fail.
2485  *
2486  ******************************************************************************/
2487 
phNxpNciHal_check_ncicmd_write_window(uint16_t cmd_len,uint8_t * p_cmd)2488 int phNxpNciHal_check_ncicmd_write_window(uint16_t cmd_len, uint8_t* p_cmd) {
2489   NFCSTATUS status = NFCSTATUS_FAILED;
2490   int sem_timedout = 2, s;
2491   struct timespec ts;
2492 
2493   if (cmd_len < 1) {
2494     android_errorWriteLog(0x534e4554, "153880357");
2495     return NFCSTATUS_FAILED;
2496   }
2497 
2498   if ((p_cmd[0] & 0xF0) == 0x20) {
2499     clock_gettime(CLOCK_REALTIME, &ts);
2500     ts.tv_sec += sem_timedout;
2501 
2502     while ((s = sem_timedwait(&nxpncihal_ctrl.syncSpiNfc, &ts)) == -1 &&
2503            errno == EINTR)
2504       continue; /* Restart if interrupted by handler */
2505 
2506     if (s != -1) {
2507       status = NFCSTATUS_SUCCESS;
2508     }
2509   } else {
2510     /* cmd window check not required for writing data packet */
2511     status = NFCSTATUS_SUCCESS;
2512   }
2513   return status;
2514 }
2515 
2516 /******************************************************************************
2517  * Function         phNxpNciHal_ioctl
2518  *
2519  * Description      This function is called by jni when wired mode is
2520  *                  performed.First Pn54x driver will give the access
2521  *                  permission whether wired mode is allowed or not
2522  *                  arg (0):
2523  * Returns          return 0 on success and -1 on fail, On success
2524  *                  update the acutual state of operation in arg pointer
2525  *
2526  ******************************************************************************/
phNxpNciHal_ioctl(long arg,void * p_data)2527 int phNxpNciHal_ioctl(long arg, void* p_data) {
2528   NXPLOG_NCIHAL_D("%s : enter - arg = %ld", __func__, arg);
2529   nfc_nci_IoctlInOutData_t* pInpOutData = (nfc_nci_IoctlInOutData_t*)p_data;
2530   int ret = -1;
2531   long level;
2532   level = pInpOutData->inp.level;
2533   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
2534     NFCSTATUS status = NFCSTATUS_FAILED;
2535     status = phNxpNciHal_MinOpen();
2536     if (status != NFCSTATUS_SUCCESS) {
2537       pInpOutData->out.data.nciRsp.p_rsp[3] = 1;
2538       return -1;
2539     }
2540   }
2541   switch (arg) {
2542     case HAL_NFC_IOCTL_SPI_DWP_SYNC: {
2543       ret = phNxpNciHal_send_ese_hal_cmd(pInpOutData->inp.data.nciCmd.cmd_len,
2544                                          pInpOutData->inp.data.nciCmd.p_cmd);
2545       pInpOutData->out.data.nciRsp.rsp_len = nxpncihal_ctrl.rx_ese_data_len;
2546       if ((nxpncihal_ctrl.rx_ese_data_len > 0) &&
2547           (nxpncihal_ctrl.rx_ese_data_len <= MAX_IOCTL_TRANSCEIVE_RESP_LEN) &&
2548           (nxpncihal_ctrl.p_rx_ese_data != NULL)) {
2549         memcpy(pInpOutData->out.data.nciRsp.p_rsp, nxpncihal_ctrl.p_rx_ese_data,
2550                nxpncihal_ctrl.rx_ese_data_len);
2551       }
2552 
2553       if (pInpOutData->out.data.nciRsp.p_rsp[0] == 0x4F &&
2554           pInpOutData->out.data.nciRsp.p_rsp[1] == 0x01 &&
2555           pInpOutData->out.data.nciRsp.p_rsp[2] == 0x01 &&
2556           pInpOutData->out.data.nciRsp.p_rsp[3] == 0x00 &&
2557           pInpOutData->inp.data.nciCmd.p_cmd[3] == 0x01) {
2558         NXPLOG_NCIHAL_D("OMAPI COMMAND for Open SUCCESS : 0x%x",
2559                         pInpOutData->out.data.nciRsp.p_rsp[3]);
2560         ret = pInpOutData->out.data.nciRsp.p_rsp[3];
2561       } else if (pInpOutData->out.data.nciRsp.p_rsp[0] == 0x4F &&
2562                  pInpOutData->out.data.nciRsp.p_rsp[1] == 0x01 &&
2563                  pInpOutData->out.data.nciRsp.p_rsp[2] == 0x01 &&
2564                  pInpOutData->out.data.nciRsp.p_rsp[3] == 0x00 &&
2565                  pInpOutData->inp.data.nciCmd.p_cmd[3] == 0x00)
2566 
2567       {
2568         NXPLOG_NCIHAL_D("OMAPI COMMAND for Close SUCCESS : 0x%x",
2569                         pInpOutData->out.data.nciRsp.p_rsp[3]);
2570         ret = pInpOutData->out.data.nciRsp.p_rsp[3];
2571       } else {
2572         NXPLOG_NCIHAL_D("OMAPI COMMAND FAILURE : 0x%x",
2573                         pInpOutData->out.data.nciRsp.p_rsp[3]);
2574         ret = pInpOutData->out.data.nciRsp.p_rsp[3] =
2575             3;  // magic number for omapi failure
2576       }
2577     } break;
2578     case HAL_NFC_SET_SPM_PWR:
2579       ret = phPalEse_spi_ioctl(phPalEse_e_ChipRst,
2580                                gpphTmlNfc_Context->pDevHandle, level);
2581       if ((nxpncihal_ctrl.halStatus == HAL_STATUS_MIN_OPEN) &&
2582           (level == 0x01)) {
2583         NXPLOG_NCIHAL_D(" HAL close after SPI close , while NFC is Off");
2584         phNxpNciHal_close(false);
2585       }
2586       break;
2587     case HAL_NFC_SET_POWER_SCHEME:
2588       ret = phPalEse_spi_ioctl(phPalEse_e_SetPowerScheme,
2589                                gpphTmlNfc_Context->pDevHandle, level);
2590       break;
2591     case HAL_NFC_GET_SPM_STATUS:
2592       ret = phPalEse_spi_ioctl(phPalEse_e_GetSPMStatus,
2593                                gpphTmlNfc_Context->pDevHandle, level);
2594       break;
2595     case HAL_NFC_GET_ESE_ACCESS:
2596       ret = phPalEse_spi_ioctl(phPalEse_e_GetEseAccess,
2597                                gpphTmlNfc_Context->pDevHandle, level);
2598       break;
2599     case HAL_NFC_SET_DWNLD_STATUS:
2600       ret = phPalEse_spi_ioctl(phPalEse_e_SetJcopDwnldState,
2601                                gpphTmlNfc_Context->pDevHandle, level);
2602       break;
2603     case HAL_NFC_INHIBIT_PWR_CNTRL:
2604       ret = phPalEse_spi_ioctl(phPalEse_e_DisablePwrCntrl,
2605                                gpphTmlNfc_Context->pDevHandle, level);
2606       break;
2607     case HAL_NFC_IOCTL_RF_STATUS_UPDATE:
2608       NXPLOG_NCIHAL_D("HAL_NFC_IOCTL_RF_STATUS_UPDATE Enter value is %d: \n",
2609                       pInpOutData->inp.data.nciCmd.p_cmd[0]);
2610       if (gpEseAdapt != NULL)
2611         ret = gpEseAdapt->HalIoctl(HAL_NFC_IOCTL_RF_STATUS_UPDATE, pInpOutData);
2612       break;
2613     default:
2614       NXPLOG_NCIHAL_E("%s : Wrong arg = %ld", __func__, arg);
2615       break;
2616   }
2617   NXPLOG_NCIHAL_D("%s : exit - ret = %d", __func__, ret);
2618   return ret;
2619 }
2620 
2621 /******************************************************************************
2622  * Function         phNxpNciHal_get_mw_eeprom
2623  *
2624  * Description      This function is called to retreive data in mw eeprom area
2625  *
2626  * Returns          NFCSTATUS.
2627  *
2628  ******************************************************************************/
phNxpNciHal_get_mw_eeprom(void)2629 static NFCSTATUS phNxpNciHal_get_mw_eeprom(void) {
2630   NFCSTATUS status = NFCSTATUS_SUCCESS;
2631   uint8_t retry_cnt = 0;
2632   static uint8_t get_mw_eeprom_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x0F};
2633 
2634 retry_send_ext:
2635   if (retry_cnt > 3) {
2636     return NFCSTATUS_FAILED;
2637   }
2638 
2639   phNxpNciMwEepromArea.isGetEepromArea = true;
2640   status =
2641       phNxpNciHal_send_ext_cmd(sizeof(get_mw_eeprom_cmd), get_mw_eeprom_cmd);
2642   if (status != NFCSTATUS_SUCCESS) {
2643     NXPLOG_NCIHAL_D("unable to get the mw eeprom data");
2644     phNxpNciMwEepromArea.isGetEepromArea = false;
2645     retry_cnt++;
2646     goto retry_send_ext;
2647   }
2648   phNxpNciMwEepromArea.isGetEepromArea = false;
2649 
2650   if (phNxpNciMwEepromArea.p_rx_data[12]) {
2651     fw_download_success = 1;
2652   }
2653   return status;
2654 }
2655 
2656 /******************************************************************************
2657  * Function         phNxpNciHal_set_mw_eeprom
2658  *
2659  * Description      This function is called to update data in mw eeprom area
2660  *
2661  * Returns          void.
2662  *
2663  ******************************************************************************/
phNxpNciHal_set_mw_eeprom(void)2664 static NFCSTATUS phNxpNciHal_set_mw_eeprom(void) {
2665   NFCSTATUS status = NFCSTATUS_SUCCESS;
2666   uint8_t retry_cnt = 0;
2667   uint8_t set_mw_eeprom_cmd[39] = {0};
2668   uint8_t cmd_header[] = {0x20, 0x02, 0x24, 0x01, 0xA0, 0x0F, 0x20};
2669 
2670   memcpy(set_mw_eeprom_cmd, cmd_header, sizeof(cmd_header));
2671   phNxpNciMwEepromArea.p_rx_data[12] = 0;
2672   memcpy(set_mw_eeprom_cmd + sizeof(cmd_header), phNxpNciMwEepromArea.p_rx_data,
2673          sizeof(phNxpNciMwEepromArea.p_rx_data));
2674 
2675 retry_send_ext:
2676   if (retry_cnt > 3) {
2677     return NFCSTATUS_FAILED;
2678   }
2679 
2680   status =
2681       phNxpNciHal_send_ext_cmd(sizeof(set_mw_eeprom_cmd), set_mw_eeprom_cmd);
2682   if (status != NFCSTATUS_SUCCESS) {
2683     NXPLOG_NCIHAL_D("unable to update the mw eeprom data");
2684     retry_cnt++;
2685     goto retry_send_ext;
2686   }
2687   return status;
2688 }
2689 
2690 /******************************************************************************
2691  * Function         phNxpNciHal_set_clock
2692  *
2693  * Description      This function is called after successfull download
2694  *                  to apply the clock setting provided in config file
2695  *
2696  * Returns          void.
2697  *
2698  ******************************************************************************/
phNxpNciHal_set_clock(void)2699 static void phNxpNciHal_set_clock(void) {
2700   NFCSTATUS status = NFCSTATUS_FAILED;
2701   int retryCount = 0;
2702 
2703 retrySetclock:
2704   phNxpNciClock.isClockSet = true;
2705   if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) {
2706     static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x09, 0x02, 0xA0, 0x03,
2707                                       0x01, 0x11, 0xA0, 0x04, 0x01, 0x01};
2708     uint8_t param_clock_src = 0x00;
2709     if ((nfcFL.chipType != pn553) && (nfcFL.chipType != pn557)) {
2710       uint8_t param_clock_src = CLK_SRC_PLL;
2711       param_clock_src = param_clock_src << 3;
2712     }
2713 
2714     if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) {
2715       param_clock_src |= 0x00;
2716     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) {
2717       param_clock_src |= 0x01;
2718     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) {
2719       param_clock_src |= 0x02;
2720     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) {
2721       param_clock_src |= 0x03;
2722     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) {
2723       param_clock_src |= 0x04;
2724     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) {
2725       param_clock_src |= 0x05;
2726     } else {
2727       NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
2728       if ((nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) {
2729         param_clock_src = 0x01;
2730       } else {
2731         param_clock_src = 0x11;
2732       }
2733     }
2734 
2735     set_clock_cmd[7] = param_clock_src;
2736     set_clock_cmd[11] = nxpprofile_ctrl.bTimeout;
2737     status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
2738     if (status != NFCSTATUS_SUCCESS) {
2739       NXPLOG_NCIHAL_E("PLL colck setting failed !!");
2740     }
2741   } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) {
2742     static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x05, 0x01,
2743                                       0xA0, 0x03, 0x01, 0x08};
2744     status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
2745     if (status != NFCSTATUS_SUCCESS) {
2746       NXPLOG_NCIHAL_E("XTAL colck setting failed !!");
2747     }
2748   } else {
2749     NXPLOG_NCIHAL_E("Wrong clock source. Don't apply any modification")
2750   }
2751 
2752   // Checking for SET CONFG SUCCESS, re-send the command  if not.
2753   phNxpNciClock.isClockSet = false;
2754   if (phNxpNciClock.p_rx_data[3] != NFCSTATUS_SUCCESS) {
2755     if (retryCount++ < 3) {
2756       NXPLOG_NCIHAL_D("Set-clk failed retry again ");
2757       goto retrySetclock;
2758     } else {
2759       NXPLOG_NCIHAL_E("Set clk  failed -  max count = 0x%x exceeded ",
2760                       retryCount);
2761       //            NXPLOG_NCIHAL_E("Set Config is failed for Clock Due to
2762       //            elctrical disturbances, aborting the NFC process");
2763       //            abort ();
2764     }
2765   }
2766 }
2767 
2768 /******************************************************************************
2769  * Function         phNxpNciHal_check_clock_config
2770  *
2771  * Description      This function is called after successfull download
2772  *                  to check if clock settings in config file and chip
2773  *                  is same
2774  *
2775  * Returns          void.
2776  *
2777  ******************************************************************************/
phNxpNciHal_check_clock_config(void)2778 NFCSTATUS phNxpNciHal_check_clock_config(void) {
2779   NFCSTATUS status = NFCSTATUS_SUCCESS;
2780   uint8_t param_clock_src;
2781   static uint8_t get_clock_cmd[] = {0x20, 0x03, 0x07, 0x03, 0xA0,
2782                                     0x02, 0xA0, 0x03, 0xA0, 0x04};
2783   phNxpNciClock.isClockSet = true;
2784   phNxpNciHal_get_clk_freq();
2785   status = phNxpNciHal_send_ext_cmd(sizeof(get_clock_cmd), get_clock_cmd);
2786 
2787   if (status != NFCSTATUS_SUCCESS) {
2788     NXPLOG_NCIHAL_E("unable to retrieve get_clk_src_sel");
2789     return status;
2790   }
2791   param_clock_src = check_config_parameter();
2792   if (phNxpNciClock.p_rx_data[12] == param_clock_src &&
2793       phNxpNciClock.p_rx_data[16] == nxpprofile_ctrl.bTimeout) {
2794     phNxpNciClock.issetConfig = false;
2795   } else {
2796     phNxpNciClock.issetConfig = true;
2797   }
2798   phNxpNciClock.isClockSet = false;
2799 
2800   return status;
2801 }
2802 
2803 /******************************************************************************
2804  * Function         phNxpNciHal_china_tianjin_rf_setting
2805  *
2806  * Description      This function is called to check RF Setting
2807  *
2808  * Returns          Status.
2809  *
2810  ******************************************************************************/
phNxpNciHal_china_tianjin_rf_setting(void)2811 NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void) {
2812   NFCSTATUS status = NFCSTATUS_SUCCESS;
2813   int isfound = 0;
2814   int rf_enable = false;
2815   int rf_val = 0;
2816   int send_flag;
2817   uint8_t retry_cnt = 0;
2818   int enable_bit = 0;
2819   static uint8_t get_rf_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x85};
2820 
2821 retry_send_ext:
2822   if (retry_cnt > 3) {
2823     return NFCSTATUS_FAILED;
2824   }
2825   send_flag = true;
2826   phNxpNciRfSet.isGetRfSetting = true;
2827   status = phNxpNciHal_send_ext_cmd(sizeof(get_rf_cmd), get_rf_cmd);
2828   if (status != NFCSTATUS_SUCCESS) {
2829     NXPLOG_NCIHAL_E("unable to get the RF setting");
2830     phNxpNciRfSet.isGetRfSetting = false;
2831     retry_cnt++;
2832     goto retry_send_ext;
2833   }
2834   phNxpNciRfSet.isGetRfSetting = false;
2835   if (phNxpNciRfSet.p_rx_data[3] != 0x00) {
2836     NXPLOG_NCIHAL_E("GET_CONFIG_RSP is FAILED for CHINA TIANJIN");
2837     return status;
2838   }
2839   rf_val = phNxpNciRfSet.p_rx_data[10];
2840   isfound = (GetNxpNumValue(NAME_NXP_CHINA_TIANJIN_RF_ENABLED,
2841                             (void*)&rf_enable, sizeof(rf_enable)));
2842   if (isfound > 0) {
2843     enable_bit = rf_val & 0x40;
2844     if ((enable_bit != 0x40) && (rf_enable == 1)) {
2845       phNxpNciRfSet.p_rx_data[10] |= 0x40;  // Enable if it is disabled
2846     } else if ((enable_bit == 0x40) && (rf_enable == 0)) {
2847       phNxpNciRfSet.p_rx_data[10] &= 0xBF;  // Disable if it is Enabled
2848     } else {
2849       send_flag = false;  // No need to change in RF setting
2850     }
2851 
2852     if (send_flag == true) {
2853       static uint8_t set_rf_cmd[] = {0x20, 0x02, 0x08, 0x01, 0xA0, 0x85,
2854                                      0x04, 0x50, 0x08, 0x68, 0x00};
2855       memcpy(&set_rf_cmd[4], &phNxpNciRfSet.p_rx_data[5], 7);
2856       status = phNxpNciHal_send_ext_cmd(sizeof(set_rf_cmd), set_rf_cmd);
2857       if (status != NFCSTATUS_SUCCESS) {
2858         NXPLOG_NCIHAL_E("unable to set the RF setting");
2859         retry_cnt++;
2860         goto retry_send_ext;
2861       }
2862     }
2863   }
2864 
2865   return status;
2866 }
2867 
2868 /******************************************************************************
2869  * Function         phNxpNciHal_gpio_restore
2870  *
2871  * Description      This function restores the gpio values into eeprom
2872  *
2873  * Returns          void
2874  *
2875  ******************************************************************************/
phNxpNciHal_gpio_restore(phNxpNciHal_GpioInfoState state)2876 static void phNxpNciHal_gpio_restore(phNxpNciHal_GpioInfoState state) {
2877   NFCSTATUS status = NFCSTATUS_SUCCESS;
2878   uint8_t get_gpio_values_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x00};
2879   uint8_t set_gpio_values_cmd[] = {
2880       0x20, 0x02, 0x00, 0x01, 0xA0, 0x00, 0x20, 0x00, 0x00, 0x00,
2881       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2882       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2883       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2884 
2885   if (state == GPIO_STORE) {
2886     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_STORE;
2887     get_gpio_values_cmd[5] = 0x08;
2888     status = phNxpNciHal_send_ext_cmd(sizeof(get_gpio_values_cmd),
2889                                       get_gpio_values_cmd);
2890     if (status != NFCSTATUS_SUCCESS) {
2891       NXPLOG_NCIHAL_E("Failed to get GPIO values!!!\n");
2892       return;
2893     }
2894 
2895     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_STORE_DONE;
2896     set_gpio_values_cmd[2] = 0x24;
2897     set_gpio_values_cmd[5] = 0x14;
2898     set_gpio_values_cmd[7] = nxpncihal_ctrl.phNxpNciGpioInfo.values[0];
2899     set_gpio_values_cmd[8] = nxpncihal_ctrl.phNxpNciGpioInfo.values[1];
2900     status = phNxpNciHal_send_ext_cmd(sizeof(set_gpio_values_cmd),
2901                                       set_gpio_values_cmd);
2902     if (status != NFCSTATUS_SUCCESS) {
2903       NXPLOG_NCIHAL_E("Failed to set GPIO values!!!\n");
2904       return;
2905     }
2906   } else if (state == GPIO_RESTORE) {
2907     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_RESTORE;
2908     get_gpio_values_cmd[5] = 0x14;
2909     status = phNxpNciHal_send_ext_cmd(sizeof(get_gpio_values_cmd),
2910                                       get_gpio_values_cmd);
2911     if (status != NFCSTATUS_SUCCESS) {
2912       NXPLOG_NCIHAL_E("Failed to get GPIO values!!!\n");
2913       return;
2914     }
2915 
2916     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_RESTORE_DONE;
2917     set_gpio_values_cmd[2] = 0x06;
2918     set_gpio_values_cmd[5] = 0x08;  // update TAG
2919     set_gpio_values_cmd[6] = 0x02;  // update length
2920     set_gpio_values_cmd[7] = nxpncihal_ctrl.phNxpNciGpioInfo.values[0];
2921     set_gpio_values_cmd[8] = nxpncihal_ctrl.phNxpNciGpioInfo.values[1];
2922     status = phNxpNciHal_send_ext_cmd(9, set_gpio_values_cmd);
2923     if (status != NFCSTATUS_SUCCESS) {
2924       NXPLOG_NCIHAL_E("Failed to set GPIO values!!!\n");
2925       return;
2926     }
2927   } else {
2928     NXPLOG_NCIHAL_E("GPIO Restore Invalid Option!!!\n");
2929   }
2930 }
2931 
2932 /******************************************************************************
2933  * Function         phNxpNciHal_nfcc_core_reset_init
2934  *
2935  * Description      Helper function to do nfcc core reset & core init
2936  *
2937  * Returns          Status
2938  *
2939  ******************************************************************************/
phNxpNciHal_nfcc_core_reset_init()2940 NFCSTATUS phNxpNciHal_nfcc_core_reset_init() {
2941   NFCSTATUS status = NFCSTATUS_FAILED;
2942   uint8_t retry_cnt = 0;
2943   uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x01};
2944 
2945 retry_core_reset:
2946   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
2947   if ((status != NFCSTATUS_SUCCESS) && (retry_cnt < 3)) {
2948     NXPLOG_NCIHAL_D("Retry: NCI_CORE_RESET");
2949     retry_cnt++;
2950     goto retry_core_reset;
2951   } else if (status != NFCSTATUS_SUCCESS) {
2952     NXPLOG_NCIHAL_E("NCI_CORE_RESET failed!!!\n");
2953     return status;
2954   }
2955 
2956   retry_cnt = 0;
2957   uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
2958   uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
2959 retry_core_init:
2960   if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
2961     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
2962   } else {
2963     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
2964   }
2965 
2966   if ((status != NFCSTATUS_SUCCESS) && (retry_cnt < 3)) {
2967     NXPLOG_NCIHAL_D("Retry: NCI_CORE_INIT\n");
2968     retry_cnt++;
2969     goto retry_core_init;
2970   } else if (status != NFCSTATUS_SUCCESS) {
2971     NXPLOG_NCIHAL_E("NCI_CORE_INIT failed!!!\n");
2972     return status;
2973   }
2974 
2975   return status;
2976 }
2977 
2978 /******************************************************************************
2979  * Function         phNxpNciHal_getChipInfoInFwDnldMode
2980  *
2981  * Description      Helper function to get the chip info in download mode
2982  *
2983  * Returns          Status
2984  *
2985  ******************************************************************************/
phNxpNciHal_getChipInfoInFwDnldMode(void)2986 NFCSTATUS phNxpNciHal_getChipInfoInFwDnldMode(void) {
2987   NFCSTATUS status = NFCSTATUS_FAILED;
2988   uint8_t retry_cnt = 0;
2989   uint8_t get_chip_info_cmd[] = {0x00, 0x04, 0xF1, 0x00,
2990                                  0x00, 0x00, 0x6E, 0xEF};
2991   NXPLOG_NCIHAL_D("%s:enter", __func__);
2992 retry:
2993   status =
2994       phNxpNciHal_send_ext_cmd(sizeof(get_chip_info_cmd), get_chip_info_cmd);
2995   if (status != NFCSTATUS_SUCCESS) {
2996     if (retry_cnt < 3) {
2997       NXPLOG_NCIHAL_D("Retry: get chip info");
2998       retry_cnt++;
2999       goto retry;
3000     } else {
3001       NXPLOG_NCIHAL_E("Failed: get chip info");
3002     }
3003   } else {
3004     phNxpNciHal_configFeatureList(nxpncihal_ctrl.p_rx_data,
3005                                   nxpncihal_ctrl.rx_data_len);
3006   }
3007   NXPLOG_NCIHAL_D("%s:exit  status: 0x%02x", __func__, status);
3008   return status;
3009 }
3010 
check_config_parameter()3011 int check_config_parameter() {
3012   uint8_t param_clock_src = CLK_SRC_PLL;
3013   if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) {
3014     if ((nfcFL.chipType != pn553) && (nfcFL.chipType != pn557)) {
3015       param_clock_src = param_clock_src << 3;
3016     }
3017     if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) {
3018       param_clock_src |= 0x00;
3019     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) {
3020       param_clock_src |= 0x01;
3021     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) {
3022       param_clock_src |= 0x02;
3023     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) {
3024       param_clock_src |= 0x03;
3025     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) {
3026       param_clock_src |= 0x04;
3027     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) {
3028       param_clock_src |= 0x05;
3029     } else {
3030       NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
3031       param_clock_src = 0x11;
3032     }
3033   } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) {
3034     param_clock_src = 0x08;
3035 
3036   } else {
3037     NXPLOG_NCIHAL_E("Wrong clock source. Don't apply any modification")
3038   }
3039   return param_clock_src;
3040 }
3041 /******************************************************************************
3042  * Function         phNxpNciHal_enable_i2c_fragmentation
3043  *
3044  * Description      This function is called to process the response status
3045  *                  and print the status byte.
3046  *
3047  * Returns          void.
3048  *
3049  ******************************************************************************/
phNxpNciHal_enable_i2c_fragmentation()3050 void phNxpNciHal_enable_i2c_fragmentation() {
3051   NFCSTATUS status = NFCSTATUS_FAILED;
3052   static uint8_t fragmentation_enable_config_cmd[] = {0x20, 0x02, 0x05, 0x01,
3053                                                       0xA0, 0x05, 0x01, 0x10};
3054   long i2c_status = 0x00;
3055   long config_i2c_vlaue = 0xff;
3056   /*NCI_RESET_CMD*/
3057   static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
3058   /*NCI_INIT_CMD*/
3059   static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
3060   static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
3061   static uint8_t get_i2c_fragmentation_cmd[] = {0x20, 0x03, 0x03,
3062                                                 0x01, 0xA0, 0x05};
3063   if (GetNxpNumValue(NAME_NXP_I2C_FRAGMENTATION_ENABLED, (void*)&i2c_status,
3064                      sizeof(i2c_status)) == true) {
3065     NXPLOG_FWDNLD_D("I2C status : %ld", i2c_status);
3066   } else {
3067     NXPLOG_FWDNLD_E("I2C status read not succeeded. Default value : %ld",
3068                     i2c_status);
3069   }
3070   status = phNxpNciHal_send_ext_cmd(sizeof(get_i2c_fragmentation_cmd),
3071                                     get_i2c_fragmentation_cmd);
3072   if (status != NFCSTATUS_SUCCESS) {
3073     NXPLOG_NCIHAL_E("unable to retrieve  get_i2c_fragmentation_cmd");
3074   } else {
3075     if (nxpncihal_ctrl.p_rx_data[8] == 0x10) {
3076       config_i2c_vlaue = 0x01;
3077       phNxpNciHal_notify_i2c_fragmentation();
3078       phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
3079     } else if (nxpncihal_ctrl.p_rx_data[8] == 0x00) {
3080       config_i2c_vlaue = 0x00;
3081     }
3082     // if the value already matches, nothing to be done
3083     if (config_i2c_vlaue != i2c_status) {
3084       if (i2c_status == 0x01) {
3085         /* NXP I2C fragmenation enabled*/
3086         status =
3087             phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd),
3088                                      fragmentation_enable_config_cmd);
3089         if (status != NFCSTATUS_SUCCESS) {
3090           NXPLOG_NCIHAL_E("NXP fragmentation enable failed");
3091         }
3092       } else if (i2c_status == 0x00 || config_i2c_vlaue == 0xff) {
3093         fragmentation_enable_config_cmd[7] = 0x00;
3094         /* NXP I2C fragmentation disabled*/
3095         status =
3096             phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd),
3097                                      fragmentation_enable_config_cmd);
3098         if (status != NFCSTATUS_SUCCESS) {
3099           NXPLOG_NCIHAL_E("NXP fragmentation disable failed");
3100         }
3101       }
3102       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
3103       if (status != NFCSTATUS_SUCCESS) {
3104         NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
3105       }
3106       if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
3107         status =
3108             phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
3109       } else {
3110         status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
3111       }
3112       if (status != NFCSTATUS_SUCCESS) {
3113         NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
3114       } else if (i2c_status == 0x01) {
3115         phNxpNciHal_notify_i2c_fragmentation();
3116         phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
3117       }
3118     }
3119   }
3120 }
3121 /******************************************************************************
3122  * Function         phNxpNciHal_do_se_session_reset
3123  *
3124  * Description      This function is called to set the session id to default
3125  *                  value.
3126  *
3127  * Returns          NFCSTATUS.
3128  *
3129  ******************************************************************************/
phNxpNciHal_do_se_session_reset(void)3130 static NFCSTATUS phNxpNciHal_do_se_session_reset(void) {
3131   static uint8_t reset_se_session_identity_set[] = {
3132       0x20, 0x02, 0x17, 0x02, 0xA0, 0xEA, 0x08, 0xFF, 0xFF,
3133       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xEB, 0x08,
3134       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
3135   NFCSTATUS status = phNxpNciHal_send_ext_cmd(
3136       sizeof(reset_se_session_identity_set), reset_se_session_identity_set);
3137   NXPLOG_NCIHAL_D("%s status = %x ", __func__, status);
3138   return status;
3139 }
3140 /******************************************************************************
3141  * Function         phNxpNciHal_do_factory_reset
3142  *
3143  * Description      This function is called during factory reset to clear/reset
3144  *                  nfc sub-system persistant data.
3145  *
3146  * Returns          void.
3147  *
3148  ******************************************************************************/
phNxpNciHal_do_factory_reset(void)3149 void phNxpNciHal_do_factory_reset(void) {
3150   NFCSTATUS status = NFCSTATUS_FAILED;
3151   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
3152     status = phNxpNciHal_MinOpen();
3153     if (status != NFCSTATUS_SUCCESS) {
3154       NXPLOG_NCIHAL_E("%s: NXP Nfc Open failed", __func__);
3155       return;
3156     }
3157   }
3158   status = phNxpNciHal_do_se_session_reset();
3159   if (status != NFCSTATUS_SUCCESS) {
3160     NXPLOG_NCIHAL_E("%s failed. status = %x ", __func__, status);
3161   }
3162 }
3163 /******************************************************************************
3164  * Function         phNxpNciHal_hci_network_reset
3165  *
3166  * Description      This function resets the session id's of all the se's
3167  *                  in the HCI network and notify to HCI_NETWORK_RESET event to
3168  *                  NFC HAL Client.
3169  *
3170  * Returns          void.
3171  *
3172  ******************************************************************************/
phNxpNciHal_hci_network_reset(void)3173 static void phNxpNciHal_hci_network_reset(void) {
3174   static phLibNfc_Message_t msg;
3175   msg.pMsgData = NULL;
3176   msg.Size = 0;
3177 
3178   NFCSTATUS status = phNxpNciHal_do_se_session_reset();
3179 
3180   if (status != NFCSTATUS_SUCCESS) {
3181     msg.eMsgType = NCI_HAL_ERROR_MSG;
3182   } else {
3183     msg.eMsgType = NCI_HAL_HCI_NETWORK_RESET_MSG;
3184   }
3185   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
3186 }
3187 
3188 /*******************************************************************************
3189 **
3190 ** Function         phNxpNciHal_configFeatureList
3191 **
3192 ** Description      Configures the featureList based on chip type
3193 **                  HW Version information number will provide chipType.
3194 **                  HW Version can be obtained from CORE_INIT_RESPONSE(NCI 1.0)
3195 **                  or CORE_RST_NTF(NCI 2.0) or PROPREITARY RSP (FW download
3196 *                   mode)
3197 **
3198 ** Parameters       CORE_INIT_RESPONSE/CORE_RST_NTF/PROPREITARY RSP, len
3199 **
3200 ** Returns          none
3201 *******************************************************************************/
phNxpNciHal_configFeatureList(uint8_t * msg,uint16_t msg_len)3202 void phNxpNciHal_configFeatureList(uint8_t* msg, uint16_t msg_len) {
3203   tNFC_chipType chipType = pConfigFL->getChipType(msg, msg_len);
3204   CONFIGURE_FEATURELIST(chipType);
3205   NXPLOG_NCIHAL_D("%s chipType = %d", __func__, chipType);
3206 }
3207 
3208 /******************************************************************************
3209  * Function         phNxpNciHal_print_res_status
3210  *
3211  * Description      This function is called to process the response status
3212  *                  and print the status byte.
3213  *
3214  * Returns          void.
3215  *
3216  ******************************************************************************/
phNxpNciHal_print_res_status(uint8_t * p_rx_data,uint16_t * p_len)3217 static void phNxpNciHal_print_res_status(uint8_t* p_rx_data, uint16_t* p_len) {
3218   static uint8_t response_buf[][30] = {"STATUS_OK",
3219                                        "STATUS_REJECTED",
3220                                        "STATUS_RF_FRAME_CORRUPTED",
3221                                        "STATUS_FAILED",
3222                                        "STATUS_NOT_INITIALIZED",
3223                                        "STATUS_SYNTAX_ERROR",
3224                                        "STATUS_SEMANTIC_ERROR",
3225                                        "RFU",
3226                                        "RFU",
3227                                        "STATUS_INVALID_PARAM",
3228                                        "STATUS_MESSAGE_SIZE_EXCEEDED",
3229                                        "STATUS_UNDEFINED"};
3230   int status_byte;
3231   if (p_rx_data[0] == 0x40 && (p_rx_data[1] == 0x02 || p_rx_data[1] == 0x03)) {
3232     if (p_rx_data[2] && p_rx_data[3] <= 10) {
3233       status_byte = p_rx_data[CORE_RES_STATUS_BYTE];
3234       NXPLOG_NCIHAL_D("%s: response status =%s", __func__,
3235                       response_buf[status_byte]);
3236     } else {
3237       NXPLOG_NCIHAL_D("%s: response status =%s", __func__, response_buf[11]);
3238     }
3239     if (phNxpNciClock.isClockSet) {
3240       int i, len = sizeof(phNxpNciClock.p_rx_data);
3241       if (*p_len > len) {
3242         android_errorWriteLog(0x534e4554, "169257710");
3243       } else {
3244         len = *p_len;
3245       }
3246       for (i = 0; i < len; i++) {
3247         phNxpNciClock.p_rx_data[i] = p_rx_data[i];
3248       }
3249     }
3250 
3251     else if (phNxpNciRfSet.isGetRfSetting) {
3252       int i, len = sizeof(phNxpNciRfSet.p_rx_data);
3253       if (*p_len > len) {
3254         android_errorWriteLog(0x534e4554, "169258733");
3255       } else {
3256         len = *p_len;
3257       }
3258       for (i = 0; i < len; i++) {
3259         phNxpNciRfSet.p_rx_data[i] = p_rx_data[i];
3260         // NXPLOG_NCIHAL_D("%s: response status =0x%x",__func__,p_rx_data[i]);
3261       }
3262     } else if (phNxpNciMwEepromArea.isGetEepromArea) {
3263       int i, len = sizeof(phNxpNciMwEepromArea.p_rx_data) + 8;
3264       if (*p_len > len) {
3265         android_errorWriteLog(0x534e4554, "169258884");
3266       } else {
3267         len = *p_len;
3268       }
3269       for (i = 8; i < len; i++) {
3270         phNxpNciMwEepromArea.p_rx_data[i - 8] = p_rx_data[i];
3271       }
3272     } else if (nxpncihal_ctrl.phNxpNciGpioInfo.state == GPIO_STORE) {
3273       NXPLOG_NCIHAL_D("%s: Storing GPIO Values...", __func__);
3274       nxpncihal_ctrl.phNxpNciGpioInfo.values[0] = p_rx_data[9];
3275       nxpncihal_ctrl.phNxpNciGpioInfo.values[1] = p_rx_data[8];
3276     } else if (nxpncihal_ctrl.phNxpNciGpioInfo.state == GPIO_RESTORE) {
3277       NXPLOG_NCIHAL_D("%s: Restoring GPIO Values...", __func__);
3278       nxpncihal_ctrl.phNxpNciGpioInfo.values[0] = p_rx_data[9];
3279       nxpncihal_ctrl.phNxpNciGpioInfo.values[1] = p_rx_data[8];
3280     }
3281   }
3282 
3283   if (p_rx_data[2] && (config_access == true)) {
3284     if (p_rx_data[3] != NFCSTATUS_SUCCESS) {
3285       NXPLOG_NCIHAL_W("Invalid Data from config file.");
3286       config_success = false;
3287     }
3288   }
3289 }
3290 
3291 /******************************************************************************
3292  * Function         phNxpNciHal_initialize_mifare_flag
3293  *
3294  * Description      This function gets the value for Mfc flags.
3295  *
3296  * Returns          void
3297  *
3298  ******************************************************************************/
phNxpNciHal_initialize_mifare_flag()3299 static void phNxpNciHal_initialize_mifare_flag() {
3300   unsigned long num = 0;
3301   bEnableMfcReader = false;
3302   bDisableLegacyMfcExtns = true;
3303   // 1: Enable Mifare Classic protocol in RF Discovery.
3304   // 0: Remove Mifare Classic protocol in RF Discovery.
3305   if (GetNxpNumValue(NAME_MIFARE_READER_ENABLE, &num, sizeof(num))) {
3306     bEnableMfcReader = (num == 0) ? false : true;
3307   }
3308   // 1: Use legacy JNI MFC extns.
3309   // 0: Disable legacy JNI MFC extns, use hal MFC Extns instead.
3310   if (GetNxpNumValue(NAME_LEGACY_MIFARE_READER, &num, sizeof(num))) {
3311     bDisableLegacyMfcExtns = (num == 0) ? true : false;
3312   }
3313 }
3314