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