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 (data_len < NORMAL_MODE_HEADER_LEN) {
939   /* Avoid OOB Read */
940     android_errorWriteLog(0x534e4554, "128530069");
941   } else if (p_data[0] == 0x21 && p_data[1] == 0x06 && p_data[2] == 0x01 &&
942       EnableP2P_PrioLogic == true) {
943     NXPLOG_NCIHAL_D("P2P priority logic busy: Disable it.");
944     phNxpNciHal_clean_P2P_Prio();
945   }
946 #endif
947 
948   /* Check for NXP ext before sending write */
949   status =
950       phNxpNciHal_write_ext(&nxpncihal_ctrl.cmd_len, nxpncihal_ctrl.p_cmd_data,
951                             &nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
952   if (status != NFCSTATUS_SUCCESS) {
953     /* Do not send packet to PN54X, send response directly */
954     msg.eMsgType = NCI_HAL_RX_MSG;
955     msg.pMsgData = NULL;
956     msg.Size = 0;
957 
958     phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
959                           (phLibNfc_Message_t*)&msg);
960     goto clean_and_return;
961   }
962 
963   CONCURRENCY_LOCK();
964   data_len = phNxpNciHal_write_unlocked(nxpncihal_ctrl.cmd_len,
965                                         nxpncihal_ctrl.p_cmd_data);
966   CONCURRENCY_UNLOCK();
967 
968   if (icode_send_eof == 1) {
969     usleep(10000);
970     icode_send_eof = 2;
971     status = phNxpNciHal_send_ext_cmd(3, cmd_icode_eof);
972     if (status != NFCSTATUS_SUCCESS) {
973       NXPLOG_NCIHAL_E("ICODE end of frame command failed");
974     }
975   }
976 
977 clean_and_return:
978   /* No data written */
979   return data_len;
980 }
981 
982 /******************************************************************************
983  * Function         phNxpNciHal_write_unlocked
984  *
985  * Description      This is the actual function which is being called by
986  *                  phNxpNciHal_write. This function writes the data to NFCC.
987  *                  It waits till write callback provide the result of write
988  *                  process.
989  *
990  * Returns          It returns number of bytes successfully written to NFCC.
991  *
992  ******************************************************************************/
phNxpNciHal_write_unlocked(uint16_t data_len,const uint8_t * p_data)993 int phNxpNciHal_write_unlocked(uint16_t data_len, const uint8_t* p_data) {
994   NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER;
995   phNxpNciHal_Sem_t cb_data;
996   nxpncihal_ctrl.retry_cnt = 0;
997   static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00,
998                                 0xC7, 0xD4, 0x00, 0x00};
999   /* Create the local semaphore */
1000   if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
1001     NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked Create cb data failed");
1002     data_len = 0;
1003     goto clean_and_return;
1004   }
1005 
1006   /* Create local copy of cmd_data */
1007   memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
1008   nxpncihal_ctrl.cmd_len = data_len;
1009 
1010   /* check for write synchronyztion */
1011   if(phNxpNciHal_check_ncicmd_write_window(nxpncihal_ctrl.cmd_len,
1012                          nxpncihal_ctrl.p_cmd_data) != NFCSTATUS_SUCCESS) {
1013     NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked Create cb data failed");
1014     data_len = 0;
1015     goto clean_and_return;
1016   }
1017 
1018   NfccPowerTracker::getInstance().ProcessCmd(
1019       (uint8_t *)nxpncihal_ctrl.p_cmd_data, (uint16_t)nxpncihal_ctrl.cmd_len);
1020 
1021 retry:
1022 
1023   data_len = nxpncihal_ctrl.cmd_len;
1024 
1025   status = phTmlNfc_Write(
1026       (uint8_t*)nxpncihal_ctrl.p_cmd_data, (uint16_t)nxpncihal_ctrl.cmd_len,
1027       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_write_complete,
1028       (void*)&cb_data);
1029   if (status != NFCSTATUS_PENDING) {
1030     NXPLOG_NCIHAL_E("write_unlocked status error");
1031     data_len = 0;
1032     goto clean_and_return;
1033   }
1034 
1035   /* Wait for callback response */
1036   if (SEM_WAIT(cb_data)) {
1037     NXPLOG_NCIHAL_E("write_unlocked semaphore error");
1038     data_len = 0;
1039     goto clean_and_return;
1040   }
1041 
1042   if (cb_data.status != NFCSTATUS_SUCCESS) {
1043     data_len = 0;
1044     if (nxpncihal_ctrl.retry_cnt++ < MAX_RETRY_COUNT) {
1045       NXPLOG_NCIHAL_D(
1046           "write_unlocked failed - PN54X Maybe in Standby Mode - Retry");
1047       /* 10ms delay to give NFCC wake up delay */
1048       usleep(1000 * 10);
1049       goto retry;
1050     } else {
1051       NXPLOG_NCIHAL_E(
1052           "write_unlocked failed - PN54X Maybe in Standby Mode (max count = "
1053           "0x%x)",
1054           nxpncihal_ctrl.retry_cnt);
1055 
1056       sem_post(&(nxpncihal_ctrl.syncSpiNfc));
1057 
1058       status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1059 
1060       if (NFCSTATUS_SUCCESS == status) {
1061         NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
1062       } else {
1063         NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
1064       }
1065       if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL &&
1066           nxpncihal_ctrl.p_rx_data != NULL &&
1067           nxpncihal_ctrl.hal_open_status == true) {
1068         NXPLOG_NCIHAL_D(
1069             "Send the Core Reset NTF to upper layer, which will trigger the "
1070             "recovery\n");
1071         // Send the Core Reset NTF to upper layer, which will trigger the
1072         // recovery.
1073         nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf);
1074         memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf));
1075         (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
1076                                                  nxpncihal_ctrl.p_rx_data);
1077       }
1078     }
1079   }
1080 
1081 clean_and_return:
1082   phNxpNciHal_cleanup_cb_data(&cb_data);
1083   return data_len;
1084 }
1085 
1086 /******************************************************************************
1087  * Function         phNxpNciHal_write_complete
1088  *
1089  * Description      This function handles write callback.
1090  *
1091  * Returns          void.
1092  *
1093  ******************************************************************************/
phNxpNciHal_write_complete(void * pContext,phTmlNfc_TransactInfo_t * pInfo)1094 static void phNxpNciHal_write_complete(void* pContext,
1095                                        phTmlNfc_TransactInfo_t* pInfo) {
1096   phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
1097   if (pInfo->wStatus == NFCSTATUS_SUCCESS) {
1098     NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus);
1099   } else {
1100     NXPLOG_NCIHAL_D("write error status = 0x%x", pInfo->wStatus);
1101   }
1102 
1103   p_cb_data->status = pInfo->wStatus;
1104 
1105   SEM_POST(p_cb_data);
1106 
1107   return;
1108 }
1109 
1110 /******************************************************************************
1111  * Function         phNxpNciHal_read_complete
1112  *
1113  * Description      This function is called whenever there is an NCI packet
1114  *                  received from NFCC. It could be RSP or NTF packet. This
1115  *                  function provide the received NCI packet to libnfc-nci
1116  *                  using data callback of libnfc-nci.
1117  *                  There is a pending read called from each
1118  *                  phNxpNciHal_read_complete so each a packet received from
1119  *                  NFCC can be provide to libnfc-nci.
1120  *
1121  * Returns          void.
1122  *
1123  ******************************************************************************/
phNxpNciHal_read_complete(void * pContext,phTmlNfc_TransactInfo_t * pInfo)1124 static void phNxpNciHal_read_complete(void* pContext,
1125                                       phTmlNfc_TransactInfo_t* pInfo) {
1126   NFCSTATUS status = NFCSTATUS_FAILED;
1127   int sem_val;
1128   UNUSED(pContext);
1129   if (nxpncihal_ctrl.read_retry_cnt == 1) {
1130     nxpncihal_ctrl.read_retry_cnt = 0;
1131   }
1132   if (pInfo->wStatus == NFCSTATUS_SUCCESS) {
1133     NXPLOG_NCIHAL_D("read successful status = 0x%x", pInfo->wStatus);
1134 
1135     sem_getvalue(&(nxpncihal_ctrl.syncSpiNfc), &sem_val);
1136     if(((pInfo->pBuff[0] & NCI_MT_MASK) == NCI_MT_RSP)  && sem_val == 0 ) {
1137         sem_post(&(nxpncihal_ctrl.syncSpiNfc));
1138     }
1139     /*Check the Omapi command response and store in dedicated buffer to solve sync issue*/
1140     if(pInfo->pBuff[0] == 0x4F && pInfo->pBuff[1] == 0x01 && pInfo->pBuff[2] == 0x01) {
1141         nxpncihal_ctrl.p_rx_ese_data = pInfo->pBuff;
1142         nxpncihal_ctrl.rx_ese_data_len = pInfo->wLength;
1143         SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1144     }
1145     else{
1146         nxpncihal_ctrl.p_rx_data = pInfo->pBuff;
1147         nxpncihal_ctrl.rx_data_len = pInfo->wLength;
1148         status = phNxpNciHal_process_ext_rsp(nxpncihal_ctrl.p_rx_data,
1149                                           &nxpncihal_ctrl.rx_data_len);
1150     }
1151 
1152     phNxpNciHal_print_res_status(pInfo->pBuff, &pInfo->wLength);
1153 
1154     if ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_NTF) {
1155       NfccPowerTracker::getInstance().ProcessNtf(nxpncihal_ctrl.p_rx_data,
1156                                                  nxpncihal_ctrl.rx_data_len);
1157     }
1158     /* Check if response should go to hal module only */
1159     if (nxpncihal_ctrl.hal_ext_enabled == TRUE &&
1160         (nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_RSP) {
1161       if (status == NFCSTATUS_FAILED) {
1162         NXPLOG_NCIHAL_D("enter into NFCC init recovery");
1163         nxpncihal_ctrl.ext_cb_data.status = status;
1164       }
1165       /* Unlock semaphore only for responses*/
1166       if ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_RSP ||
1167           ((icode_detected == true) && (icode_send_eof == 3))) {
1168         /* Unlock semaphore */
1169         SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1170       }
1171     }  // Notification Checking
1172     else if ((nxpncihal_ctrl.hal_ext_enabled == TRUE) &&
1173              ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_NTF) &&
1174              (nxpncihal_ctrl.nci_info.wait_for_ntf == TRUE)) {
1175       /* Unlock semaphore waiting for only  ntf*/
1176       SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1177       nxpncihal_ctrl.nci_info.wait_for_ntf = FALSE;
1178     } else if (bDisableLegacyMfcExtns && !sendRspToUpperLayer &&
1179                (nxpncihal_ctrl.p_rx_data[0x00] == 0x00)) {
1180       sendRspToUpperLayer = true;
1181       NFCSTATUS mfcRspStatus = NxpMfcReaderInstance.CheckMfcResponse(
1182           nxpncihal_ctrl.p_rx_data, nxpncihal_ctrl.rx_data_len);
1183       NXPLOG_NCIHAL_D("Mfc Response Status = 0x%x", mfcRspStatus);
1184       SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
1185     }
1186     /* Read successful send the event to higher layer */
1187     else if ((nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) &&
1188              (status == NFCSTATUS_SUCCESS)) {
1189       (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
1190                                                nxpncihal_ctrl.p_rx_data);
1191       //workaround for sync issue between SPI and NFC
1192       if ((nfcFL.chipType == pn557) && nxpncihal_ctrl.p_rx_data[0] == 0x62 &&
1193           nxpncihal_ctrl.p_rx_data[1] == 0x00 &&
1194           nxpncihal_ctrl.p_rx_data[3] == 0xC0 &&
1195           nxpncihal_ctrl.p_rx_data[4] == 0x00) {
1196         uint8_t nfcee_notifiations[3][9] = {
1197           {0x61, 0x0A, 0x06, 0x01, 0x00, 0x03, 0xC0, 0x80, 0x04},
1198           {0x61, 0x0A, 0x06, 0x01, 0x00, 0x03, 0xC0, 0x81, 0x04},
1199           {0x61, 0x0A, 0x06, 0x01, 0x00, 0x03, 0xC0, 0x82, 0x03},
1200         };
1201 
1202         for (int i = 0; i < 3; i++) {
1203           (*nxpncihal_ctrl.p_nfc_stack_data_cback)(sizeof(nfcee_notifiations[i]),
1204                                                nfcee_notifiations[i]);
1205         }
1206       }
1207     }
1208   } else {
1209     NXPLOG_NCIHAL_E("read error status = 0x%x", pInfo->wStatus);
1210   }
1211 
1212   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE &&
1213       nxpncihal_ctrl.nci_info.wait_for_ntf == FALSE) {
1214     NXPLOG_NCIHAL_D("Ignoring read, HAL close triggered");
1215     return;
1216   }
1217   /* Read again because read must be pending always.*/
1218   status = phTmlNfc_Read(
1219       Rx_data, NCI_MAX_DATA_LEN,
1220       (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
1221   if (status != NFCSTATUS_PENDING) {
1222     NXPLOG_NCIHAL_E("read status error status = %x", status);
1223     /* TODO: Not sure how to handle this ? */
1224   }
1225 
1226   return;
1227 }
1228 
1229 /******************************************************************************
1230  * Function         phNxpNciHal_core_initialized
1231  *
1232  * Description      This function is called by libnfc-nci after successful open
1233  *                  of NFCC. All proprietary setting for PN54X are done here.
1234  *                  After completion of proprietary settings notification is
1235  *                  provided to libnfc-nci through callback function.
1236  *
1237  * Returns          Always returns NFCSTATUS_SUCCESS (0).
1238  *
1239  ******************************************************************************/
phNxpNciHal_core_initialized(uint8_t * p_core_init_rsp_params)1240 int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params) {
1241   NFCSTATUS status = NFCSTATUS_SUCCESS;
1242   static uint8_t p2p_listen_mode_routing_cmd[] = {0x21, 0x01, 0x07, 0x00, 0x01,
1243                                                   0x01, 0x03, 0x00, 0x01, 0x05};
1244 
1245   uint8_t swp_full_pwr_mode_on_cmd[] = {0x20, 0x02, 0x05, 0x01,
1246                                         0xA0, 0xF1, 0x01, 0x01};
1247 
1248   static uint8_t cmd_ven_pulld_enable_nci[] = {0x20, 0x02, 0x05, 0x01,
1249                                                0xA0, 0x07, 0x01, 0x03};
1250 
1251   static uint8_t android_l_aid_matching_mode_on_cmd[] = {
1252       0x20, 0x02, 0x05, 0x01, 0xA0, 0x91, 0x01, 0x01};
1253   static uint8_t swp_switch_timeout_cmd[] = {0x20, 0x02, 0x06, 0x01, 0xA0,
1254                                              0xF3, 0x02, 0x00, 0x00};
1255   config_success = true;
1256   uint8_t* buffer = NULL;
1257   long bufflen = 260;
1258   long retlen = 0;
1259   int isfound;
1260 #if (NFC_NXP_HFO_SETTINGS == TRUE)
1261   /* Temp fix to re-apply the proper clock setting */
1262   int temp_fix = 1;
1263 #endif
1264   unsigned long num = 0;
1265   // initialize dummy FW recovery variables
1266   gRecFwRetryCount = 0;
1267   gRecFWDwnld = 0;
1268   // recovery --start
1269   /*NCI_INIT_CMD*/
1270   static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
1271   /*NCI_RESET_CMD*/
1272   static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01,
1273                                     0x00};  // keep configuration
1274   static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
1275   /* reset config cache */
1276   static uint8_t retry_core_init_cnt;
1277   if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
1278     return NFCSTATUS_FAILED;
1279   }
1280   if ((*p_core_init_rsp_params > 0) &&
1281       (*p_core_init_rsp_params < 4))  // initializing for recovery.
1282   {
1283   retry_core_init:
1284     config_access = false;
1285     if (buffer != NULL) {
1286       free(buffer);
1287       buffer = NULL;
1288     }
1289     if (retry_core_init_cnt > 3) {
1290       return NFCSTATUS_FAILED;
1291     }
1292 
1293     status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1294     if (NFCSTATUS_SUCCESS == status) {
1295       NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
1296     } else {
1297       NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
1298     }
1299 
1300     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
1301     if ((status != NFCSTATUS_SUCCESS) &&
1302         (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT)) {
1303       NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
1304       retry_core_init_cnt++;
1305       goto retry_core_init;
1306     } else if (status != NFCSTATUS_SUCCESS) {
1307       NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
1308       retry_core_init_cnt++;
1309       goto retry_core_init;
1310     }
1311 
1312     if (*p_core_init_rsp_params == 2) {
1313       NXPLOG_NCIHAL_E(" Last command is CORE_RESET!!");
1314       goto invoke_callback;
1315     }
1316     if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
1317       status =
1318           phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
1319     } else {
1320       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
1321     }
1322     if (status != NFCSTATUS_SUCCESS) {
1323       NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
1324       retry_core_init_cnt++;
1325       goto retry_core_init;
1326     }
1327 
1328     if (*p_core_init_rsp_params == 3) {
1329       NXPLOG_NCIHAL_E(" Last command is CORE_INIT!!");
1330       goto invoke_callback;
1331     }
1332   }
1333   // recovery --end
1334 
1335   buffer = (uint8_t*)malloc(bufflen * sizeof(uint8_t));
1336   if (NULL == buffer) {
1337     return NFCSTATUS_FAILED;
1338   }
1339   config_access = true;
1340   retlen = 0;
1341   isfound = GetNxpByteArrayValue(NAME_NXP_ACT_PROP_EXTN, (char*)buffer, bufflen,
1342                                  &retlen);
1343   if (retlen > 0) {
1344     /* NXP ACT Proprietary Ext */
1345     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1346     if (status != NFCSTATUS_SUCCESS) {
1347       NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
1348       retry_core_init_cnt++;
1349       goto retry_core_init;
1350     }
1351   }
1352 
1353   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ven_pulld_enable_nci),
1354                                     cmd_ven_pulld_enable_nci);
1355   if (status != NFCSTATUS_SUCCESS) {
1356     NXPLOG_NCIHAL_E("cmd_ven_pulld_enable_nci: Failed");
1357     retry_core_init_cnt++;
1358     goto retry_core_init;
1359   }
1360 
1361   if (fw_download_success == 1) {
1362     phNxpNciHal_hci_network_reset();
1363   }
1364 
1365   // Check if firmware download success
1366   status = phNxpNciHal_get_mw_eeprom();
1367   if (status != NFCSTATUS_SUCCESS) {
1368     NXPLOG_NCIHAL_E("NXP GET MW EEPROM AREA Proprietary Ext failed");
1369     retry_core_init_cnt++;
1370     goto retry_core_init;
1371   }
1372 
1373   //
1374   status = phNxpNciHal_check_clock_config();
1375   if (status != NFCSTATUS_SUCCESS) {
1376     NXPLOG_NCIHAL_E("phNxpNciHal_check_clock_config failed");
1377     retry_core_init_cnt++;
1378     goto retry_core_init;
1379   }
1380 
1381 #ifdef PN547C2_CLOCK_SETTING
1382   if (isNxpConfigModified() || (fw_download_success == 1) ||
1383       (phNxpNciClock.issetConfig)
1384 #if (NFC_NXP_HFO_SETTINGS == TRUE)
1385       || temp_fix == 1
1386 #endif
1387       ) {
1388     // phNxpNciHal_get_clk_freq();
1389     phNxpNciHal_set_clock();
1390     phNxpNciClock.issetConfig = false;
1391 #if (NFC_NXP_HFO_SETTINGS == TRUE)
1392     if (temp_fix == 1) {
1393       NXPLOG_NCIHAL_D(
1394           "Applying Default Clock setting and DPLL register at power on");
1395       /*
1396       # A0, 0D, 06, 06, 83, 55, 2A, 04, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_GEAR_REG
1397       # A0, 0D, 06, 06, 82, 33, 14, 17, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_REG
1398       # A0, 0D, 06, 06, 84, AA, 85, 00, 80 RF_CLIF_CFG_TARGET
1399       CLIF_DPLL_INIT_FREQ_REG
1400       # A0, 0D, 06, 06, 81, 63, 00, 00, 00 RF_CLIF_CFG_TARGET
1401       CLIF_DPLL_CONTROL_REG
1402       */
1403       static uint8_t cmd_dpll_set_reg_nci[] = {
1404           0x20, 0x02, 0x25, 0x04, 0xA0, 0x0D, 0x06, 0x06, 0x83, 0x55,
1405           0x2A, 0x04, 0x00, 0xA0, 0x0D, 0x06, 0x06, 0x82, 0x33, 0x14,
1406           0x17, 0x00, 0xA0, 0x0D, 0x06, 0x06, 0x84, 0xAA, 0x85, 0x00,
1407           0x80, 0xA0, 0x0D, 0x06, 0x06, 0x81, 0x63, 0x00, 0x00, 0x00};
1408 
1409       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_dpll_set_reg_nci),
1410                                         cmd_dpll_set_reg_nci);
1411       if (status != NFCSTATUS_SUCCESS) {
1412         NXPLOG_NCIHAL_E("NXP DPLL REG ACT Proprietary Ext failed");
1413         retry_core_init_cnt++;
1414         goto retry_core_init;
1415       }
1416       /* reset the NFCC after applying the clock setting and DPLL setting */
1417       // phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1418       temp_fix = 0;
1419       goto retry_core_init;
1420     }
1421 #endif
1422   }
1423 #endif
1424 
1425   retlen = 0;
1426   config_access = true;
1427   isfound = GetNxpByteArrayValue(NAME_NXP_NFC_PROFILE_EXTN, (char*)buffer,
1428                                  bufflen, &retlen);
1429   if (retlen > 0) {
1430     /* NXP ACT Proprietary Ext */
1431     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1432     if (status != NFCSTATUS_SUCCESS) {
1433       NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
1434       retry_core_init_cnt++;
1435       goto retry_core_init;
1436     }
1437   }
1438 
1439   if (isNxpConfigModified() || (fw_download_success == 1)) {
1440     retlen = 0;
1441     fw_download_success = 0;
1442 
1443     NXPLOG_NCIHAL_D("Performing TVDD Settings");
1444     isfound = GetNxpNumValue(NAME_NXP_EXT_TVDD_CFG, &num, sizeof(num));
1445     if (isfound > 0) {
1446       if (num == 1) {
1447         isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_1, (char*)buffer,
1448                                        bufflen, &retlen);
1449         if (retlen > 0) {
1450           status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1451           if (status != NFCSTATUS_SUCCESS) {
1452             NXPLOG_NCIHAL_E("EXT TVDD CFG 1 Settings failed");
1453             retry_core_init_cnt++;
1454             goto retry_core_init;
1455           }
1456         }
1457       } else if (num == 2) {
1458         isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_2, (char*)buffer,
1459                                        bufflen, &retlen);
1460         if (retlen > 0) {
1461           status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1462           if (status != NFCSTATUS_SUCCESS) {
1463             NXPLOG_NCIHAL_E("EXT TVDD CFG 2 Settings failed");
1464             retry_core_init_cnt++;
1465             goto retry_core_init;
1466           }
1467         }
1468       } else if (num == 3) {
1469         isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_3, (char*)buffer,
1470                                        bufflen, &retlen);
1471         if (retlen > 0) {
1472           status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1473           if (status != NFCSTATUS_SUCCESS) {
1474             NXPLOG_NCIHAL_E("EXT TVDD CFG 3 Settings failed");
1475             retry_core_init_cnt++;
1476             goto retry_core_init;
1477           }
1478         }
1479       } else {
1480         NXPLOG_NCIHAL_E("Wrong Configuration Value %ld", num);
1481       }
1482     }
1483     retlen = 0;
1484     config_access = false;
1485     NXPLOG_NCIHAL_D("Performing RF Settings BLK 1");
1486     isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_1, (char*)buffer,
1487                                    bufflen, &retlen);
1488     if (retlen > 0) {
1489       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1490       if (status == NFCSTATUS_SUCCESS) {
1491         status = phNxpNciHal_CheckRFCmdRespStatus();
1492         /*STATUS INVALID PARAM 0x09*/
1493         if (status == 0x09) {
1494           phNxpNciHalRFConfigCmdRecSequence();
1495           retry_core_init_cnt++;
1496           goto retry_core_init;
1497         }
1498       } else
1499           if (status != NFCSTATUS_SUCCESS) {
1500         NXPLOG_NCIHAL_E("RF Settings BLK 1 failed");
1501         retry_core_init_cnt++;
1502         goto retry_core_init;
1503       }
1504     }
1505     retlen = 0;
1506 
1507     NXPLOG_NCIHAL_D("Performing RF Settings BLK 2");
1508     isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_2, (char*)buffer,
1509                                    bufflen, &retlen);
1510     if (retlen > 0) {
1511       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1512       if (status == NFCSTATUS_SUCCESS) {
1513         status = phNxpNciHal_CheckRFCmdRespStatus();
1514         /*STATUS INVALID PARAM 0x09*/
1515         if (status == 0x09) {
1516           phNxpNciHalRFConfigCmdRecSequence();
1517           retry_core_init_cnt++;
1518           goto retry_core_init;
1519         }
1520       } else
1521           if (status != NFCSTATUS_SUCCESS) {
1522         NXPLOG_NCIHAL_E("RF Settings BLK 2 failed");
1523         retry_core_init_cnt++;
1524         goto retry_core_init;
1525       }
1526     }
1527     retlen = 0;
1528 
1529     NXPLOG_NCIHAL_D("Performing RF Settings BLK 3");
1530     isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_3, (char*)buffer,
1531                                    bufflen, &retlen);
1532     if (retlen > 0) {
1533       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1534       if (status == NFCSTATUS_SUCCESS) {
1535         status = phNxpNciHal_CheckRFCmdRespStatus();
1536         /*STATUS INVALID PARAM 0x09*/
1537         if (status == 0x09) {
1538           phNxpNciHalRFConfigCmdRecSequence();
1539           retry_core_init_cnt++;
1540           goto retry_core_init;
1541         }
1542       } else
1543           if (status != NFCSTATUS_SUCCESS) {
1544         NXPLOG_NCIHAL_E("RF Settings BLK 3 failed");
1545         retry_core_init_cnt++;
1546         goto retry_core_init;
1547       }
1548     }
1549     retlen = 0;
1550 
1551     NXPLOG_NCIHAL_D("Performing RF Settings BLK 4");
1552     isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_4, (char*)buffer,
1553                                    bufflen, &retlen);
1554     if (retlen > 0) {
1555       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1556       if (status == NFCSTATUS_SUCCESS) {
1557         status = phNxpNciHal_CheckRFCmdRespStatus();
1558         /*STATUS INVALID PARAM 0x09*/
1559         if (status == 0x09) {
1560           phNxpNciHalRFConfigCmdRecSequence();
1561           retry_core_init_cnt++;
1562           goto retry_core_init;
1563         }
1564       } else
1565           if (status != NFCSTATUS_SUCCESS) {
1566         NXPLOG_NCIHAL_E("RF Settings BLK 4 failed");
1567         retry_core_init_cnt++;
1568         goto retry_core_init;
1569       }
1570     }
1571     retlen = 0;
1572 
1573     NXPLOG_NCIHAL_D("Performing RF Settings BLK 5");
1574     isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_5, (char*)buffer,
1575                                    bufflen, &retlen);
1576     if (retlen > 0) {
1577       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1578       if (status == NFCSTATUS_SUCCESS) {
1579         status = phNxpNciHal_CheckRFCmdRespStatus();
1580         /*STATUS INVALID PARAM 0x09*/
1581         if (status == 0x09) {
1582           phNxpNciHalRFConfigCmdRecSequence();
1583           retry_core_init_cnt++;
1584           goto retry_core_init;
1585         }
1586       } else
1587           if (status != NFCSTATUS_SUCCESS) {
1588         NXPLOG_NCIHAL_E("RF Settings BLK 5 failed");
1589         retry_core_init_cnt++;
1590         goto retry_core_init;
1591       }
1592     }
1593     retlen = 0;
1594 
1595     NXPLOG_NCIHAL_D("Performing RF Settings BLK 6");
1596     isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_6, (char*)buffer,
1597                                    bufflen, &retlen);
1598     if (retlen > 0) {
1599       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1600       if (status == NFCSTATUS_SUCCESS) {
1601         status = phNxpNciHal_CheckRFCmdRespStatus();
1602         /*STATUS INVALID PARAM 0x09*/
1603         if (status == 0x09) {
1604           phNxpNciHalRFConfigCmdRecSequence();
1605           retry_core_init_cnt++;
1606           goto retry_core_init;
1607         }
1608       } else
1609           if (status != NFCSTATUS_SUCCESS) {
1610         NXPLOG_NCIHAL_E("RF Settings BLK 6 failed");
1611         retry_core_init_cnt++;
1612         goto retry_core_init;
1613       }
1614     }
1615     retlen = 0;
1616     config_access = true;
1617     NXPLOG_NCIHAL_D("Performing NAME_NXP_CORE_CONF_EXTN Settings");
1618     isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF_EXTN, (char*)buffer,
1619                                    bufflen, &retlen);
1620     if (retlen > 0) {
1621       /* NXP ACT Proprietary Ext */
1622       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1623       if (status != NFCSTATUS_SUCCESS) {
1624         NXPLOG_NCIHAL_E("NXP Core configuration failed");
1625         retry_core_init_cnt++;
1626         goto retry_core_init;
1627       }
1628     }
1629 
1630     retlen = 0;
1631     config_access = false;
1632     isfound = GetNxpByteArrayValue(NAME_NXP_CORE_RF_FIELD, (char*)buffer,
1633                                    bufflen, &retlen);
1634     if (retlen > 0) {
1635       /* NXP ACT Proprietary Ext */
1636       status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1637       if (status == NFCSTATUS_SUCCESS) {
1638         status = phNxpNciHal_CheckRFCmdRespStatus();
1639         /*STATUS INVALID PARAM 0x09*/
1640         if (status == 0x09) {
1641           phNxpNciHalRFConfigCmdRecSequence();
1642           retry_core_init_cnt++;
1643           goto retry_core_init;
1644         }
1645       } else
1646           if (status != NFCSTATUS_SUCCESS) {
1647         NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
1648         retry_core_init_cnt++;
1649         goto retry_core_init;
1650       }
1651     }
1652     config_access = true;
1653 
1654     retlen = 0;
1655     /* NXP SWP switch timeout Setting*/
1656     if (GetNxpNumValue(NAME_NXP_SWP_SWITCH_TIMEOUT, (void*)&retlen,
1657                        sizeof(retlen))) {
1658       // Check the permissible range [0 - 60]
1659       if (0 <= retlen && retlen <= 60) {
1660         if (0 < retlen) {
1661           unsigned int timeout = retlen * 1000;
1662           unsigned int timeoutHx = 0x0000;
1663 
1664           char tmpbuffer[10] = {0};
1665           snprintf((char*)tmpbuffer, 10, "%04x", timeout);
1666           sscanf((char*)tmpbuffer, "%x", &timeoutHx);
1667 
1668           swp_switch_timeout_cmd[7] = (timeoutHx & 0xFF);
1669           swp_switch_timeout_cmd[8] = ((timeoutHx & 0xFF00) >> 8);
1670         }
1671 
1672         status = phNxpNciHal_send_ext_cmd(sizeof(swp_switch_timeout_cmd),
1673                                           swp_switch_timeout_cmd);
1674         if (status != NFCSTATUS_SUCCESS) {
1675           NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed");
1676           retry_core_init_cnt++;
1677           goto retry_core_init;
1678         }
1679       } else {
1680         NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed - out of range!");
1681       }
1682     }
1683 
1684     status = phNxpNciHal_china_tianjin_rf_setting();
1685     if (status != NFCSTATUS_SUCCESS) {
1686       NXPLOG_NCIHAL_E("phNxpNciHal_china_tianjin_rf_setting failed");
1687       retry_core_init_cnt++;
1688       goto retry_core_init;
1689     }
1690     // Update eeprom value
1691     status = phNxpNciHal_set_mw_eeprom();
1692     if (status != NFCSTATUS_SUCCESS) {
1693       NXPLOG_NCIHAL_E("NXP Update MW EEPROM Proprietary Ext failed");
1694     }
1695   }
1696 
1697   retlen = 0;
1698 
1699   isfound =
1700       GetNxpByteArrayValue(NAME_NXP_CORE_CONF, (char*)buffer, bufflen, &retlen);
1701   if (retlen > 0) {
1702     /* NXP ACT Proprietary Ext */
1703     status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1704     if (status != NFCSTATUS_SUCCESS) {
1705       NXPLOG_NCIHAL_E("Core Set Config failed");
1706       retry_core_init_cnt++;
1707       goto retry_core_init;
1708     }
1709   }
1710 
1711   config_access = false;
1712   // if recovery mode and length of last command is 0 then only reset the P2P
1713   // listen mode routing.
1714   if ((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4) &&
1715       p_core_init_rsp_params[35] == 0) {
1716     /* P2P listen mode routing */
1717     status = phNxpNciHal_send_ext_cmd(sizeof(p2p_listen_mode_routing_cmd),
1718                                       p2p_listen_mode_routing_cmd);
1719     if (status != NFCSTATUS_SUCCESS) {
1720       NXPLOG_NCIHAL_E("P2P listen mode routing failed");
1721       retry_core_init_cnt++;
1722       goto retry_core_init;
1723     }
1724   }
1725 
1726   retlen = 0;
1727 
1728   /* SWP FULL PWR MODE SETTING ON */
1729   if (GetNxpNumValue(NAME_NXP_SWP_FULL_PWR_ON, (void*)&retlen,
1730                      sizeof(retlen))) {
1731     if (1 == retlen) {
1732       status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd),
1733                                         swp_full_pwr_mode_on_cmd);
1734       if (status != NFCSTATUS_SUCCESS) {
1735         NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING ON CMD FAILED");
1736         retry_core_init_cnt++;
1737         goto retry_core_init;
1738       }
1739     } else {
1740       swp_full_pwr_mode_on_cmd[7] = 0x00;
1741       status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd),
1742                                         swp_full_pwr_mode_on_cmd);
1743       if (status != NFCSTATUS_SUCCESS) {
1744         NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING OFF CMD FAILED");
1745         retry_core_init_cnt++;
1746         goto retry_core_init;
1747       }
1748     }
1749   }
1750 
1751   /* Android L AID Matching Platform Setting*/
1752   if ((nfcFL.chipType != pn557) && GetNxpNumValue(NAME_AID_MATCHING_PLATFORM, (void*)&retlen,
1753                      sizeof(retlen))) {
1754     if (1 == retlen) {
1755       status =
1756           phNxpNciHal_send_ext_cmd(sizeof(android_l_aid_matching_mode_on_cmd),
1757                                    android_l_aid_matching_mode_on_cmd);
1758       if (status != NFCSTATUS_SUCCESS) {
1759         NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
1760         retry_core_init_cnt++;
1761         goto retry_core_init;
1762       }
1763     } else if (2 == retlen) {
1764       android_l_aid_matching_mode_on_cmd[7] = 0x00;
1765       status =
1766           phNxpNciHal_send_ext_cmd(sizeof(android_l_aid_matching_mode_on_cmd),
1767                                    android_l_aid_matching_mode_on_cmd);
1768       if (status != NFCSTATUS_SUCCESS) {
1769         NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
1770         retry_core_init_cnt++;
1771         goto retry_core_init;
1772       }
1773     }
1774   }
1775 
1776   if ((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)) {
1777     static phLibNfc_Message_t msg;
1778     uint16_t tmp_len = 0;
1779     uint8_t uicc_set_mode[] = {0x22, 0x01, 0x02, 0x02, 0x01};
1780     uint8_t set_screen_state[] = {0x2F, 0x15, 01, 00};  // SCREEN ON
1781     uint8_t nfcc_core_conn_create[] = {0x20, 0x04, 0x06, 0x03, 0x01,
1782                                        0x01, 0x02, 0x01, 0x01};
1783     uint8_t nfcc_mode_set_on[] = {0x22, 0x01, 0x02, 0x01, 0x01};
1784 
1785     NXPLOG_NCIHAL_W(
1786         "Sending DH and NFCC core connection command as raw packet!!");
1787     status = phNxpNciHal_send_ext_cmd(sizeof(nfcc_core_conn_create),
1788                                       nfcc_core_conn_create);
1789 
1790     if (status != NFCSTATUS_SUCCESS) {
1791       NXPLOG_NCIHAL_E(
1792           "Sending DH and NFCC core connection command as raw packet!! Failed");
1793       retry_core_init_cnt++;
1794       goto retry_core_init;
1795     }
1796 
1797     NXPLOG_NCIHAL_W("Sending DH and NFCC mode set as raw packet!!");
1798     status =
1799         phNxpNciHal_send_ext_cmd(sizeof(nfcc_mode_set_on), nfcc_mode_set_on);
1800 
1801     if (status != NFCSTATUS_SUCCESS) {
1802       NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!! Failed");
1803       retry_core_init_cnt++;
1804       goto retry_core_init;
1805     }
1806 
1807     NXPLOG_NCIHAL_W("Sending UICC Select Command as raw packet!!");
1808     status = phNxpNciHal_send_ext_cmd(sizeof(uicc_set_mode), uicc_set_mode);
1809     if (status != NFCSTATUS_SUCCESS) {
1810       NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!! Failed");
1811       retry_core_init_cnt++;
1812       goto retry_core_init;
1813     }
1814 
1815     if (*(p_core_init_rsp_params + 1) == 1)  // RF state is Discovery!!
1816     {
1817       NXPLOG_NCIHAL_W("Sending Set Screen ON State Command as raw packet!!");
1818       status =
1819           phNxpNciHal_send_ext_cmd(sizeof(set_screen_state), set_screen_state);
1820       if (status != NFCSTATUS_SUCCESS) {
1821         NXPLOG_NCIHAL_E(
1822             "Sending Set Screen ON State Command as raw packet!! Failed");
1823         retry_core_init_cnt++;
1824         goto retry_core_init;
1825       }
1826 
1827       NXPLOG_NCIHAL_W("Sending discovery as raw packet!!");
1828       status = phNxpNciHal_send_ext_cmd(p_core_init_rsp_params[2],
1829                                         (uint8_t*)&p_core_init_rsp_params[3]);
1830       if (status != NFCSTATUS_SUCCESS) {
1831         NXPLOG_NCIHAL_E("Sending discovery as raw packet Failed");
1832         retry_core_init_cnt++;
1833         goto retry_core_init;
1834       }
1835 
1836     } else {
1837       NXPLOG_NCIHAL_W("Sending Set Screen OFF State Command as raw packet!!");
1838       set_screen_state[3] = 0x01;  // Screen OFF
1839       status =
1840           phNxpNciHal_send_ext_cmd(sizeof(set_screen_state), set_screen_state);
1841       if (status != NFCSTATUS_SUCCESS) {
1842         NXPLOG_NCIHAL_E(
1843             "Sending Set Screen OFF State Command as raw packet!! Failed");
1844         retry_core_init_cnt++;
1845         goto retry_core_init;
1846       }
1847     }
1848     NXPLOG_NCIHAL_W("Sending last command for Recovery ");
1849 
1850     if (p_core_init_rsp_params[35] > 0) {  // if length of last command is 0
1851                                            // then it doesn't need to send last
1852                                            // command.
1853       if (!(((p_core_init_rsp_params[36] == 0x21) &&
1854              (p_core_init_rsp_params[37] == 0x03)) &&
1855             (*(p_core_init_rsp_params + 1) == 1)) &&
1856           !((p_core_init_rsp_params[36] == 0x21) &&
1857             (p_core_init_rsp_params[37] == 0x06) &&
1858             (p_core_init_rsp_params[39] == 0x00) &&
1859             (*(p_core_init_rsp_params + 1) == 0x00)))
1860       // if last command is discovery and RF status is also discovery state,
1861       // then it doesn't need to execute or similarly
1862       // if the last command is deactivate to idle and RF status is also idle ,
1863       // no need to execute the command .
1864       {
1865         tmp_len = p_core_init_rsp_params[35];
1866 
1867         /* Check for NXP ext before sending write */
1868         status = phNxpNciHal_write_ext(
1869             &tmp_len, (uint8_t*)&p_core_init_rsp_params[36],
1870             &nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
1871         if (status != NFCSTATUS_SUCCESS) {
1872           if (buffer) {
1873             free(buffer);
1874             buffer = NULL;
1875           }
1876           /* Do not send packet to PN54X, send response directly */
1877           msg.eMsgType = NCI_HAL_RX_MSG;
1878           msg.pMsgData = NULL;
1879           msg.Size = 0;
1880 
1881           phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1882                                 (phLibNfc_Message_t*)&msg);
1883           return NFCSTATUS_SUCCESS;
1884         }
1885 
1886         p_core_init_rsp_params[35] = (uint8_t)tmp_len;
1887 
1888         status = phNxpNciHal_send_ext_cmd(
1889             p_core_init_rsp_params[35], (uint8_t*)&p_core_init_rsp_params[36]);
1890         if (status != NFCSTATUS_SUCCESS) {
1891           NXPLOG_NCIHAL_E("Sending last command for Recovery Failed");
1892           retry_core_init_cnt++;
1893           goto retry_core_init;
1894         }
1895       }
1896     }
1897   }
1898 
1899   retry_core_init_cnt = 0;
1900 
1901   if (buffer) {
1902     free(buffer);
1903     buffer = NULL;
1904   }
1905   // initialize dummy FW recovery variables
1906   gRecFWDwnld = 0;
1907   gRecFwRetryCount = 0;
1908   if (!((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)))
1909     phNxpNciHal_core_initialized_complete(status);
1910   else {
1911   invoke_callback:
1912     config_access = false;
1913     if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) {
1914       *p_core_init_rsp_params = 0;
1915       NXPLOG_NCIHAL_W("Invoking data callback!!");
1916       (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
1917                                                nxpncihal_ctrl.p_rx_data);
1918     }
1919   }
1920 
1921   if (config_success == false) return NFCSTATUS_FAILED;
1922 #ifdef PN547C2_CLOCK_SETTING
1923   if (isNxpConfigModified()) {
1924     updateNxpConfigTimestamp();
1925   }
1926 #endif
1927   return NFCSTATUS_SUCCESS;
1928 }
1929 
1930 #ifdef FactoryOTA
phNxpNciHal_isFactoryOTAModeActive()1931 void phNxpNciHal_isFactoryOTAModeActive() {
1932   uint8_t check_factoryOTA[] = {0x20, 0x03, 0x05, 0x02, 0xA0, 0x08, 0xA0, 0x88};
1933   NFCSTATUS status = NFCSTATUS_FAILED;
1934   NXPLOG_NCIHAL_D("check FactoryOTA mode status");
1935 
1936   status = phNxpNciHal_send_ext_cmd(sizeof(check_factoryOTA), check_factoryOTA);
1937 
1938   if (status == NFCSTATUS_SUCCESS) {
1939     if(nxpncihal_ctrl.p_rx_data[9] == 0x1 && nxpncihal_ctrl.p_rx_data[13] == 0x1) {
1940       NXPLOG_NCIHAL_D("FactoryOTA mode is active");
1941     } else {
1942       NXPLOG_NCIHAL_D("FactoryOTA mode is disabled");
1943     }
1944   } else {
1945     NXPLOG_NCIHAL_E("Fail to get FactoryOTA mode status");
1946   }
1947   return;
1948 }
1949 
phNxpNciHal_disableFactoryOTAMode()1950 NFCSTATUS phNxpNciHal_disableFactoryOTAMode() {
1951   // NFCC GPIO output control
1952   uint8_t nfcc_system_gpio[] = {0x20, 0x02, 0x06, 0x01, 0xA0, 0x08, 0x02, 0x00, 0x00};
1953   // NFCC automatically sets GPIO once a specific RF pattern is detected
1954   uint8_t nfcc_gpio_pattern[] = {0x20, 0x02, 0x08, 0x01, 0xA0, 0x88, 0x04, 0x00, 0x96, 0x96, 0x03};
1955 
1956   NFCSTATUS status = NFCSTATUS_SUCCESS;
1957   NXPLOG_NCIHAL_D("Disable FactoryOTA mode");
1958   status = phNxpNciHal_send_ext_cmd(sizeof(nfcc_system_gpio), nfcc_system_gpio);
1959   if (status != NFCSTATUS_SUCCESS ) {
1960     NXPLOG_NCIHAL_E("Can't disable A008 for FactoryOTA mode");
1961   }
1962   status = phNxpNciHal_send_ext_cmd(sizeof(nfcc_gpio_pattern), nfcc_gpio_pattern);
1963   if (status != NFCSTATUS_SUCCESS ) {
1964     NXPLOG_NCIHAL_E("Can't disable A088 for FactoryOTA mode");
1965   }
1966   return status;
1967 }
1968 #endif
1969 
1970 /******************************************************************************
1971  * Function         phNxpNciHal_CheckRFCmdRespStatus
1972  *
1973  * Description      This function is called to check the resp status of
1974  *                  RF update commands.
1975  *
1976  * Returns          NFCSTATUS_SUCCESS           if successful,
1977  *                  NFCSTATUS_INVALID_PARAMETER if parameter is inavlid
1978  *                  NFCSTATUS_FAILED            if failed response
1979  *
1980  ******************************************************************************/
phNxpNciHal_CheckRFCmdRespStatus()1981 NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus() {
1982   NFCSTATUS status = NFCSTATUS_SUCCESS;
1983   static uint16_t INVALID_PARAM = 0x09;
1984   if ((nxpncihal_ctrl.rx_data_len > 0) && (nxpncihal_ctrl.p_rx_data[2] > 0)) {
1985     if (nxpncihal_ctrl.p_rx_data[3] == 0x09) {
1986       status = INVALID_PARAM;
1987     } else if (nxpncihal_ctrl.p_rx_data[3] != NFCSTATUS_SUCCESS) {
1988       status = NFCSTATUS_FAILED;
1989     }
1990   }
1991   return status;
1992 }
1993 /******************************************************************************
1994  * Function         phNxpNciHalRFConfigCmdRecSequence
1995  *
1996  * Description      This function is called to handle dummy FW recovery sequence
1997  *                  Whenever RF settings are failed to apply with invalid param
1998  *                  response, recovery mechanism includes dummy firmware
1999  *download
2000  *                  followed by firmware download and then config settings. The
2001  *dummy
2002  *                  firmware changes the major number of the firmware inside
2003  *NFCC.
2004  *                  Then actual firmware dowenload will be successful. This can
2005  *be
2006  *                  retried maximum three times.
2007  *
2008  * Returns          Always returns NFCSTATUS_SUCCESS
2009  *
2010  ******************************************************************************/
phNxpNciHalRFConfigCmdRecSequence()2011 NFCSTATUS phNxpNciHalRFConfigCmdRecSequence() {
2012   NFCSTATUS status = NFCSTATUS_SUCCESS;
2013   uint16_t recFWState = 1;
2014   gRecFWDwnld = true;
2015   gRecFwRetryCount++;
2016   if (gRecFwRetryCount > 0x03) {
2017     NXPLOG_NCIHAL_D("Max retry count for RF config FW recovery exceeded ");
2018     gRecFWDwnld = false;
2019     return NFCSTATUS_FAILED;
2020   }
2021   do {
2022     status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
2023     phDnldNfc_InitImgInfo();
2024     if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion()) {
2025       fw_download_success = 0;
2026       status = phNxpNciHal_fw_download();
2027       if (status == NFCSTATUS_SUCCESS) {
2028         fw_download_success = 1;
2029       }
2030       status = phTmlNfc_Read(
2031           nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN,
2032           (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
2033       if (status != NFCSTATUS_PENDING) {
2034         NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
2035         phOsalNfc_Timer_Cleanup();
2036         phTmlNfc_Shutdown();
2037         status = NFCSTATUS_FAILED;
2038       }
2039       break;
2040     }
2041     gRecFWDwnld = false;
2042   } while (recFWState--);
2043   gRecFWDwnld = false;
2044   return status;
2045 }
2046 /******************************************************************************
2047  * Function         phNxpNciHal_core_initialized_complete
2048  *
2049  * Description      This function is called when phNxpNciHal_core_initialized
2050  *                  complete all proprietary command exchanges. This function
2051  *                  informs libnfc-nci about completion of core initialize
2052  *                  and result of that through callback.
2053  *
2054  * Returns          void.
2055  *
2056  ******************************************************************************/
phNxpNciHal_core_initialized_complete(NFCSTATUS status)2057 static void phNxpNciHal_core_initialized_complete(NFCSTATUS status) {
2058   static phLibNfc_Message_t msg;
2059 
2060   if (status == NFCSTATUS_SUCCESS) {
2061     msg.eMsgType = NCI_HAL_POST_INIT_CPLT_MSG;
2062   } else {
2063     msg.eMsgType = NCI_HAL_ERROR_MSG;
2064   }
2065   msg.pMsgData = NULL;
2066   msg.Size = 0;
2067 
2068   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
2069                         (phLibNfc_Message_t*)&msg);
2070 
2071   return;
2072 }
2073 
2074 /******************************************************************************
2075  * Function         phNxpNciHal_pre_discover
2076  *
2077  * Description      This function is called by libnfc-nci to perform any
2078  *                  proprietary exchange before RF discovery.
2079  *
2080  * Returns          It always returns NFCSTATUS_SUCCESS (0).
2081  *
2082  ******************************************************************************/
phNxpNciHal_pre_discover(void)2083 int phNxpNciHal_pre_discover(void) {
2084   /* Nothing to do here for initial version */
2085   return NFCSTATUS_SUCCESS;
2086 }
2087 
2088 /******************************************************************************
2089  * Function         phNxpNciHal_close
2090  *
2091  * Description      This function close the NFCC interface and free all
2092  *                  resources.This is called by libnfc-nci on NFC service stop.
2093  *
2094  * Returns          Always return NFCSTATUS_SUCCESS (0).
2095  *
2096  ******************************************************************************/
phNxpNciHal_close(bool bShutdown)2097 int phNxpNciHal_close(bool bShutdown) {
2098   NFCSTATUS status;
2099   /*NCI_RESET_CMD*/
2100   static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
2101 
2102   static uint8_t cmd_ven_disable_nci[] = {0x20, 0x02, 0x05, 0x01,
2103                                          0xA0, 0x07, 0x01, 0x02};
2104 
2105   AutoThreadMutex a(sHalFnLock);
2106   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
2107     NXPLOG_NCIHAL_D("phNxpNciHal_close is already closed, ignoring close");
2108     return NFCSTATUS_FAILED;
2109   }
2110 
2111   CONCURRENCY_LOCK();
2112 
2113   int sem_val;
2114   sem_getvalue(&(nxpncihal_ctrl.syncSpiNfc), &sem_val);
2115   if(sem_val == 0 ) {
2116       sem_post(&(nxpncihal_ctrl.syncSpiNfc));
2117   }
2118   if(!bShutdown){
2119     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ven_disable_nci), cmd_ven_disable_nci);
2120     if(status != NFCSTATUS_SUCCESS) {
2121       NXPLOG_NCIHAL_E("CMD_VEN_DISABLE_NCI: Failed");
2122     }
2123   }
2124 #ifdef FactoryOTA
2125   char valueStr[PROPERTY_VALUE_MAX] = {0};
2126   bool factoryOTA_terminate = false;
2127   int len = property_get("persist.factoryota.reboot", valueStr, "normal");
2128   if (len > 0) {
2129     factoryOTA_terminate = (len == 9 && (memcmp(valueStr, "terminate", len) == 0)) ? true : false;
2130   }
2131   NXPLOG_NCIHAL_D("factoryOTA_terminate: %d", factoryOTA_terminate);
2132   if (factoryOTA_terminate) {
2133     phNxpNciHal_disableFactoryOTAMode();
2134     phNxpNciHal_isFactoryOTAModeActive();
2135   }
2136 #endif
2137   nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
2138 
2139   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
2140   if (status != NFCSTATUS_SUCCESS) {
2141     NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
2142   }
2143 
2144   sem_destroy(&nxpncihal_ctrl.syncSpiNfc);
2145 
2146   if (NULL != gpphTmlNfc_Context->pDevHandle) {
2147     phNxpNciHal_close_complete(NFCSTATUS_SUCCESS);
2148     /* Abort any pending read and write */
2149     status = phTmlNfc_ReadAbort();
2150     status = phTmlNfc_WriteAbort();
2151 
2152     phOsalNfc_Timer_Cleanup();
2153 
2154     status = phTmlNfc_Shutdown();
2155 
2156     if (0 != pthread_join(nxpncihal_ctrl.client_thread, (void **)NULL)) {
2157       NXPLOG_TML_E("Fail to kill client thread!");
2158     }
2159 
2160     phTmlNfc_CleanUp();
2161 
2162     phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
2163 
2164     memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
2165 
2166     NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed");
2167   }
2168   NfccPowerTracker::getInstance().Pause();
2169   CONCURRENCY_UNLOCK();
2170 
2171   phNxpNciHal_cleanup_monitor();
2172 
2173   /* Return success always */
2174   return NFCSTATUS_SUCCESS;
2175 }
2176 
2177 /******************************************************************************
2178  * Function         phNxpNciHal_close_complete
2179  *
2180  * Description      This function inform libnfc-nci about result of
2181  *                  phNxpNciHal_close.
2182  *
2183  * Returns          void.
2184  *
2185  ******************************************************************************/
phNxpNciHal_close_complete(NFCSTATUS status)2186 void phNxpNciHal_close_complete(NFCSTATUS status) {
2187   static phLibNfc_Message_t msg;
2188 
2189   if (status == NFCSTATUS_SUCCESS) {
2190     msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
2191   } else {
2192     msg.eMsgType = NCI_HAL_ERROR_MSG;
2193   }
2194   msg.pMsgData = NULL;
2195   msg.Size = 0;
2196 
2197   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
2198 
2199   return;
2200 }
2201 
2202 /******************************************************************************
2203  * Function         phNxpNciHal_configDiscShutdown
2204  *
2205  * Description      Enable the CE and VEN config during shutdown.
2206  *
2207  * Returns          Always return NFCSTATUS_SUCCESS (0).
2208  *
2209  ******************************************************************************/
phNxpNciHal_configDiscShutdown(void)2210 int phNxpNciHal_configDiscShutdown(void) {
2211   NFCSTATUS status;
2212   NfccPowerTracker::getInstance().Reset();
2213 
2214   status = phNxpNciHal_close(true);
2215   if(status != NFCSTATUS_SUCCESS) {
2216     NXPLOG_NCIHAL_E("NCI_HAL_CLOSE: Failed");
2217   }
2218 
2219   /* Return success always */
2220   return NFCSTATUS_SUCCESS;
2221 }
2222 
2223 /******************************************************************************
2224  * Function         phNxpNciHal_getVendorConfig
2225  *
2226  * Description      This function can be used by HAL to inform
2227  *                 to update vendor configuration parametres
2228  *
2229  * Returns          void.
2230  *
2231  ******************************************************************************/
2232 
phNxpNciHal_getVendorConfig(android::hardware::nfc::V1_1::NfcConfig & config)2233 void phNxpNciHal_getVendorConfig(android::hardware::nfc::V1_1::NfcConfig& config) {
2234   unsigned long num = 0;
2235   std::array<uint8_t, NXP_MAX_CONFIG_STRING_LEN> buffer;
2236   buffer.fill(0);
2237   long retlen = 0;
2238   memset(&config, 0x00, sizeof(android::hardware::nfc::V1_1::NfcConfig));
2239 
2240   config.nfaPollBailOutMode = true;
2241   if (GetNxpNumValue(NAME_ISO_DEP_MAX_TRANSCEIVE, &num, sizeof(num))) {
2242     config.maxIsoDepTransceiveLength = num;
2243   }
2244   if (GetNxpNumValue(NAME_DEFAULT_OFFHOST_ROUTE, &num, sizeof(num))) {
2245     config.defaultOffHostRoute = num;
2246   }
2247   if (GetNxpNumValue(NAME_DEFAULT_NFCF_ROUTE, &num, sizeof(num))) {
2248     config.defaultOffHostRouteFelica = num;
2249   }
2250   if (GetNxpNumValue(NAME_DEFAULT_SYS_CODE_ROUTE, &num, sizeof(num))) {
2251     config.defaultSystemCodeRoute = num;
2252   }
2253   if (GetNxpNumValue(NAME_DEFAULT_SYS_CODE_PWR_STATE, &num, sizeof(num))) {
2254     config.defaultSystemCodePowerState = num;
2255   }
2256   if (GetNxpNumValue(NAME_DEFAULT_ROUTE, &num, sizeof(num))) {
2257     config.defaultRoute = num;
2258   }
2259   if (GetNxpByteArrayValue(NAME_DEVICE_HOST_WHITE_LIST, (char*)buffer.data(), buffer.size(), &retlen)) {
2260     config.hostWhitelist.resize(retlen);
2261     for(int i=0; i<retlen; i++)
2262       config.hostWhitelist[i] = buffer[i];
2263   }
2264   if (GetNxpNumValue(NAME_OFF_HOST_ESE_PIPE_ID, &num, sizeof(num))) {
2265     config.offHostESEPipeId = num;
2266   }
2267   if (GetNxpNumValue(NAME_OFF_HOST_SIM_PIPE_ID, &num, sizeof(num))) {
2268     config.offHostSIMPipeId = num;
2269   }
2270   if ((GetNxpByteArrayValue(NAME_NFA_PROPRIETARY_CFG, (char*)buffer.data(), buffer.size(), &retlen))
2271          && (retlen == 9)) {
2272     config.nfaProprietaryCfg.protocol18092Active = (uint8_t) buffer[0];
2273     config.nfaProprietaryCfg.protocolBPrime = (uint8_t) buffer[1];
2274     config.nfaProprietaryCfg.protocolDual = (uint8_t) buffer[2];
2275     config.nfaProprietaryCfg.protocol15693 = (uint8_t) buffer[3];
2276     config.nfaProprietaryCfg.protocolKovio = (uint8_t) buffer[4];
2277     config.nfaProprietaryCfg.protocolMifare = (uint8_t) buffer[5];
2278     config.nfaProprietaryCfg.discoveryPollKovio = (uint8_t) buffer[6];
2279     config.nfaProprietaryCfg.discoveryPollBPrime = (uint8_t) buffer[7];
2280     config.nfaProprietaryCfg.discoveryListenBPrime = (uint8_t) buffer[8];
2281   } else {
2282     memset(&config.nfaProprietaryCfg, 0xFF, sizeof(ProtocolDiscoveryConfig));
2283   }
2284   if ((GetNxpNumValue(NAME_PRESENCE_CHECK_ALGORITHM, &num, sizeof(num))) && (num <= 2) ) {
2285       config.presenceCheckAlgorithm = (PresenceCheckAlgorithm)num;
2286   }
2287 }
2288 
2289 /******************************************************************************
2290  * Function         phNxpNciHal_getVendorConfig_1_2
2291  *
2292  * Description      This function can be used by HAL to inform
2293  *                 to update vendor configuration parametres
2294  *
2295  * Returns          void.
2296  *
2297  ******************************************************************************/
2298 
phNxpNciHal_getVendorConfig_1_2(android::hardware::nfc::V1_2::NfcConfig & config)2299 void phNxpNciHal_getVendorConfig_1_2(android::hardware::nfc::V1_2::NfcConfig& config) {
2300   unsigned long num = 0;
2301   std::array<uint8_t, NXP_MAX_CONFIG_STRING_LEN> buffer;
2302   buffer.fill(0);
2303   long retlen = 0;
2304   memset(&config, 0x00, sizeof(android::hardware::nfc::V1_2::NfcConfig));
2305   phNxpNciHal_getVendorConfig(config.v1_1);
2306 
2307   if (GetNxpByteArrayValue(NAME_OFFHOST_ROUTE_UICC, (char*)buffer.data(), buffer.size(), &retlen)) {
2308     config.offHostRouteUicc.resize(retlen);
2309     for(int i=0; i<retlen; i++)
2310       config.offHostRouteUicc[i] = buffer[i];
2311   }
2312 
2313   if (GetNxpByteArrayValue(NAME_OFFHOST_ROUTE_ESE, (char*)buffer.data(), buffer.size(), &retlen)) {
2314     config.offHostRouteEse.resize(retlen);
2315     for(int i=0; i<retlen; i++)
2316       config.offHostRouteEse[i] = buffer[i];
2317   }
2318 
2319   if (GetNxpNumValue(NAME_DEFAULT_ISODEP_ROUTE, &num, sizeof(num))) {
2320       config.defaultIsoDepRoute = num;
2321   }
2322 
2323 }
2324 
2325 /******************************************************************************
2326  * Function         phNxpNciHal_notify_i2c_fragmentation
2327  *
2328  * Description      This function can be used by HAL to inform
2329  *                 libnfc-nci that i2c fragmentation is enabled/disabled
2330  *
2331  * Returns          void.
2332  *
2333  ******************************************************************************/
phNxpNciHal_notify_i2c_fragmentation(void)2334 void phNxpNciHal_notify_i2c_fragmentation(void) {
2335   if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
2336     /*inform libnfc-nci that i2c fragmentation is enabled/disabled */
2337     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT,
2338                                         HAL_NFC_STATUS_OK);
2339   }
2340 }
2341 /******************************************************************************
2342  * Function         phNxpNciHal_control_granted
2343  *
2344  * Description      Called by libnfc-nci when NFCC control is granted to HAL.
2345  *
2346  * Returns          Always returns NFCSTATUS_SUCCESS (0).
2347  *
2348  ******************************************************************************/
phNxpNciHal_control_granted(void)2349 int phNxpNciHal_control_granted(void) {
2350   /* Take the concurrency lock so no other calls from upper layer
2351    * will be allowed
2352    */
2353   CONCURRENCY_LOCK();
2354 
2355   if (NULL != nxpncihal_ctrl.p_control_granted_cback) {
2356     (*nxpncihal_ctrl.p_control_granted_cback)();
2357   }
2358   /* At the end concurrency unlock so calls from upper layer will
2359    * be allowed
2360    */
2361   CONCURRENCY_UNLOCK();
2362   return NFCSTATUS_SUCCESS;
2363 }
2364 
2365 /******************************************************************************
2366  * Function         phNxpNciHal_request_control
2367  *
2368  * Description      This function can be used by HAL to request control of
2369  *                  NFCC to libnfc-nci. When control is provided to HAL it is
2370  *                  notified through phNxpNciHal_control_granted.
2371  *
2372  * Returns          void.
2373  *
2374  ******************************************************************************/
phNxpNciHal_request_control(void)2375 void phNxpNciHal_request_control(void) {
2376   if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
2377     /* Request Control of NCI Controller from NCI NFC Stack */
2378     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_REQUEST_CONTROL_EVT,
2379                                         HAL_NFC_STATUS_OK);
2380   }
2381 
2382   return;
2383 }
2384 
2385 /******************************************************************************
2386  * Function         phNxpNciHal_release_control
2387  *
2388  * Description      This function can be used by HAL to release the control of
2389  *                  NFCC back to libnfc-nci.
2390  *
2391  * Returns          void.
2392  *
2393  ******************************************************************************/
phNxpNciHal_release_control(void)2394 void phNxpNciHal_release_control(void) {
2395   if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
2396     /* Release Control of NCI Controller to NCI NFC Stack */
2397     (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_RELEASE_CONTROL_EVT,
2398                                         HAL_NFC_STATUS_OK);
2399   }
2400 
2401   return;
2402 }
2403 
2404 /******************************************************************************
2405  * Function         phNxpNciHal_power_cycle
2406  *
2407  * Description      This function is called by libnfc-nci when power cycling is
2408  *                  performed. When processing is complete it is notified to
2409  *                  libnfc-nci through phNxpNciHal_power_cycle_complete.
2410  *
2411  * Returns          Always return NFCSTATUS_SUCCESS (0).
2412  *
2413  ******************************************************************************/
phNxpNciHal_power_cycle(void)2414 int phNxpNciHal_power_cycle(void) {
2415   NXPLOG_NCIHAL_D("Power Cycle");
2416   NFCSTATUS status = NFCSTATUS_FAILED;
2417   if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
2418     NXPLOG_NCIHAL_D("Power Cycle failed due to hal status not open");
2419     return NFCSTATUS_FAILED;
2420   }
2421   status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
2422 
2423   if (NFCSTATUS_SUCCESS == status) {
2424     NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
2425   } else {
2426     NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
2427   }
2428   phNxpNciHal_power_cycle_complete(NFCSTATUS_SUCCESS);
2429   return NFCSTATUS_SUCCESS;
2430 }
2431 
2432 /******************************************************************************
2433  * Function         phNxpNciHal_power_cycle_complete
2434  *
2435  * Description      This function is called to provide the status of
2436  *                  phNxpNciHal_power_cycle to libnfc-nci through callback.
2437  *
2438  * Returns          void.
2439  *
2440  ******************************************************************************/
phNxpNciHal_power_cycle_complete(NFCSTATUS status)2441 static void phNxpNciHal_power_cycle_complete(NFCSTATUS status) {
2442   static phLibNfc_Message_t msg;
2443 
2444   if (status == NFCSTATUS_SUCCESS) {
2445     msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
2446   } else {
2447     msg.eMsgType = NCI_HAL_ERROR_MSG;
2448   }
2449   msg.pMsgData = NULL;
2450   msg.Size = 0;
2451 
2452   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
2453 
2454   return;
2455 }
2456 /******************************************************************************
2457  * Function         phNxpNciHal_check_ncicmd_write_window
2458  *
2459  * Description      This function is called to check the write synchroniztion
2460  *                  status if write already aquired then wait for corresponding
2461                     read to complete.
2462  *
2463  * Returns          return 0 on success and -1 on fail.
2464  *
2465  ******************************************************************************/
2466 
phNxpNciHal_check_ncicmd_write_window(uint16_t cmd_len,uint8_t * p_cmd)2467 int phNxpNciHal_check_ncicmd_write_window(uint16_t cmd_len, uint8_t* p_cmd) {
2468   UNUSED(cmd_len);
2469   NFCSTATUS status = NFCSTATUS_FAILED;
2470   int sem_timedout = 2, s;
2471   struct timespec ts;
2472   if ((p_cmd[0] & 0xF0) == 0x20) {
2473     clock_gettime(CLOCK_REALTIME, &ts);
2474     ts.tv_sec += sem_timedout;
2475 
2476     while ((s = sem_timedwait(&nxpncihal_ctrl.syncSpiNfc, &ts)) == -1 &&
2477            errno == EINTR)
2478       continue; /* Restart if interrupted by handler */
2479 
2480     if (s != -1) {
2481       status = NFCSTATUS_SUCCESS;
2482     }
2483   } else {
2484     /* cmd window check not required for writing data packet */
2485     status = NFCSTATUS_SUCCESS;
2486   }
2487   return status;
2488 }
2489 
2490 /******************************************************************************
2491  * Function         phNxpNciHal_ioctl
2492  *
2493  * Description      This function is called by jni when wired mode is
2494  *                  performed.First Pn54x driver will give the access
2495  *                  permission whether wired mode is allowed or not
2496  *                  arg (0):
2497  * Returns          return 0 on success and -1 on fail, On success
2498  *                  update the acutual state of operation in arg pointer
2499  *
2500  ******************************************************************************/
phNxpNciHal_ioctl(long arg,void * p_data)2501 int phNxpNciHal_ioctl(long arg, void* p_data) {
2502   NXPLOG_NCIHAL_D("%s : enter - arg = %ld", __func__, arg);
2503   nfc_nci_IoctlInOutData_t* pInpOutData = (nfc_nci_IoctlInOutData_t*)p_data;
2504   int ret = -1;
2505   long level;
2506   level=pInpOutData->inp.level;
2507   if(nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE)
2508    {
2509        NFCSTATUS status = NFCSTATUS_FAILED;
2510        status = phNxpNciHal_MinOpen();
2511        if(status != NFCSTATUS_SUCCESS )
2512        {
2513          pInpOutData->out.data.nciRsp.p_rsp[3]=1;
2514          return -1;
2515        }
2516    }
2517   switch (arg) {
2518     case HAL_NFC_IOCTL_SPI_DWP_SYNC:
2519            {
2520                   ret = phNxpNciHal_send_ese_hal_cmd(pInpOutData->inp.data.nciCmd.cmd_len,
2521                                      pInpOutData->inp.data.nciCmd.p_cmd);
2522                   pInpOutData->out.data.nciRsp.rsp_len = nxpncihal_ctrl.rx_ese_data_len;
2523                   if ((nxpncihal_ctrl.rx_ese_data_len > 0) &&
2524                     (nxpncihal_ctrl.rx_ese_data_len <= MAX_IOCTL_TRANSCEIVE_RESP_LEN) &&
2525                             (nxpncihal_ctrl.p_rx_ese_data != NULL)) {
2526                   memcpy(pInpOutData->out.data.nciRsp.p_rsp, nxpncihal_ctrl.p_rx_ese_data,
2527                     nxpncihal_ctrl.rx_ese_data_len);
2528                   }
2529 
2530                   if(pInpOutData->out.data.nciRsp.p_rsp[0] == 0x4F && pInpOutData->out.data.nciRsp.p_rsp[1] == 0x01
2531                       && pInpOutData->out.data.nciRsp.p_rsp[2] == 0x01 && pInpOutData->out.data.nciRsp.p_rsp[3] == 0x00
2532                       && pInpOutData->inp.data.nciCmd.p_cmd[3] == 0x01)
2533                   {
2534                       NXPLOG_NCIHAL_D("OMAPI COMMAND for Open SUCCESS : 0x%x",pInpOutData->out.data.nciRsp.p_rsp[3]);
2535                       ret=pInpOutData->out.data.nciRsp.p_rsp[3];
2536                   }
2537                   else if(pInpOutData->out.data.nciRsp.p_rsp[0] == 0x4F && pInpOutData->out.data.nciRsp.p_rsp[1] == 0x01
2538                       && pInpOutData->out.data.nciRsp.p_rsp[2] == 0x01 && pInpOutData->out.data.nciRsp.p_rsp[3] == 0x00
2539                       && pInpOutData->inp.data.nciCmd.p_cmd[3] == 0x00)
2540 
2541                   {
2542                       NXPLOG_NCIHAL_D("OMAPI COMMAND for Close SUCCESS : 0x%x",pInpOutData->out.data.nciRsp.p_rsp[3]);
2543                       ret=pInpOutData->out.data.nciRsp.p_rsp[3];
2544                   }
2545                   else{
2546                       NXPLOG_NCIHAL_D("OMAPI COMMAND FAILURE : 0x%x",pInpOutData->out.data.nciRsp.p_rsp[3]);
2547                       ret=pInpOutData->out.data.nciRsp.p_rsp[3]=3; //magic number for omapi failure
2548                   }
2549        }
2550       break;
2551     case HAL_NFC_SET_SPM_PWR:
2552         ret = phPalEse_spi_ioctl(phPalEse_e_ChipRst, gpphTmlNfc_Context->pDevHandle, level);
2553         if ((nxpncihal_ctrl.halStatus == HAL_STATUS_MIN_OPEN) && (level == 0x01)) {
2554           NXPLOG_NCIHAL_D(" HAL close after SPI close , while NFC is Off");
2555           phNxpNciHal_close(false);
2556         }
2557         break;
2558     case HAL_NFC_SET_POWER_SCHEME:
2559          ret = phPalEse_spi_ioctl(phPalEse_e_SetPowerScheme,gpphTmlNfc_Context->pDevHandle,level);
2560          break;
2561     case HAL_NFC_GET_SPM_STATUS:
2562          ret = phPalEse_spi_ioctl(phPalEse_e_GetSPMStatus, gpphTmlNfc_Context->pDevHandle,level);
2563          break;
2564     case HAL_NFC_GET_ESE_ACCESS:
2565          ret = phPalEse_spi_ioctl(phPalEse_e_GetEseAccess, gpphTmlNfc_Context->pDevHandle, level);
2566          break;
2567     case HAL_NFC_SET_DWNLD_STATUS:
2568          ret = phPalEse_spi_ioctl(phPalEse_e_SetJcopDwnldState, gpphTmlNfc_Context->pDevHandle, level);
2569          break;
2570     case HAL_NFC_INHIBIT_PWR_CNTRL:
2571          ret = phPalEse_spi_ioctl(phPalEse_e_DisablePwrCntrl, gpphTmlNfc_Context->pDevHandle, level);
2572          break;
2573     case HAL_NFC_IOCTL_RF_STATUS_UPDATE:
2574         NXPLOG_NCIHAL_D("HAL_NFC_IOCTL_RF_STATUS_UPDATE Enter value is %d: \n",pInpOutData->inp.data.nciCmd.p_cmd[0]);
2575         if(gpEseAdapt !=  NULL)
2576         ret = gpEseAdapt->HalIoctl(HAL_NFC_IOCTL_RF_STATUS_UPDATE,pInpOutData);
2577         break;
2578     default:
2579       NXPLOG_NCIHAL_E("%s : Wrong arg = %ld", __func__, arg);
2580       break;
2581     }
2582   NXPLOG_NCIHAL_D("%s : exit - ret = %d", __func__, ret);
2583   return ret;
2584 }
2585 
2586 
2587 /******************************************************************************
2588  * Function         phNxpNciHal_get_mw_eeprom
2589  *
2590  * Description      This function is called to retreive data in mw eeprom area
2591  *
2592  * Returns          NFCSTATUS.
2593  *
2594  ******************************************************************************/
phNxpNciHal_get_mw_eeprom(void)2595 static NFCSTATUS phNxpNciHal_get_mw_eeprom(void) {
2596   NFCSTATUS status = NFCSTATUS_SUCCESS;
2597   uint8_t retry_cnt = 0;
2598   static uint8_t get_mw_eeprom_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x0F};
2599 
2600 retry_send_ext:
2601   if (retry_cnt > 3) {
2602     return NFCSTATUS_FAILED;
2603   }
2604 
2605   phNxpNciMwEepromArea.isGetEepromArea = true;
2606   status =
2607       phNxpNciHal_send_ext_cmd(sizeof(get_mw_eeprom_cmd), get_mw_eeprom_cmd);
2608   if (status != NFCSTATUS_SUCCESS) {
2609     NXPLOG_NCIHAL_D("unable to get the mw eeprom data");
2610     phNxpNciMwEepromArea.isGetEepromArea = false;
2611     retry_cnt++;
2612     goto retry_send_ext;
2613   }
2614   phNxpNciMwEepromArea.isGetEepromArea = false;
2615 
2616   if (phNxpNciMwEepromArea.p_rx_data[12]) {
2617     fw_download_success = 1;
2618   }
2619   return status;
2620 }
2621 
2622 /******************************************************************************
2623  * Function         phNxpNciHal_set_mw_eeprom
2624  *
2625  * Description      This function is called to update data in mw eeprom area
2626  *
2627  * Returns          void.
2628  *
2629  ******************************************************************************/
phNxpNciHal_set_mw_eeprom(void)2630 static NFCSTATUS phNxpNciHal_set_mw_eeprom(void) {
2631   NFCSTATUS status = NFCSTATUS_SUCCESS;
2632   uint8_t retry_cnt = 0;
2633   uint8_t set_mw_eeprom_cmd[39] = {0};
2634   uint8_t cmd_header[] = {0x20, 0x02, 0x24, 0x01, 0xA0, 0x0F, 0x20};
2635 
2636   memcpy(set_mw_eeprom_cmd, cmd_header, sizeof(cmd_header));
2637   phNxpNciMwEepromArea.p_rx_data[12] = 0;
2638   memcpy(set_mw_eeprom_cmd + sizeof(cmd_header), phNxpNciMwEepromArea.p_rx_data,
2639          sizeof(phNxpNciMwEepromArea.p_rx_data));
2640 
2641 retry_send_ext:
2642   if (retry_cnt > 3) {
2643     return NFCSTATUS_FAILED;
2644   }
2645 
2646   status =
2647       phNxpNciHal_send_ext_cmd(sizeof(set_mw_eeprom_cmd), set_mw_eeprom_cmd);
2648   if (status != NFCSTATUS_SUCCESS) {
2649     NXPLOG_NCIHAL_D("unable to update the mw eeprom data");
2650     retry_cnt++;
2651     goto retry_send_ext;
2652   }
2653   return status;
2654 }
2655 
2656 /******************************************************************************
2657  * Function         phNxpNciHal_set_clock
2658  *
2659  * Description      This function is called after successfull download
2660  *                  to apply the clock setting provided in config file
2661  *
2662  * Returns          void.
2663  *
2664  ******************************************************************************/
phNxpNciHal_set_clock(void)2665 static void phNxpNciHal_set_clock(void) {
2666   NFCSTATUS status = NFCSTATUS_FAILED;
2667   int retryCount = 0;
2668 
2669 retrySetclock:
2670   phNxpNciClock.isClockSet = true;
2671   if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) {
2672     static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x09, 0x02, 0xA0, 0x03,
2673                                       0x01, 0x11, 0xA0, 0x04, 0x01, 0x01};
2674     uint8_t param_clock_src = 0x00;
2675     if((nfcFL.chipType != pn553)&&(nfcFL.chipType != pn557)) {
2676       uint8_t param_clock_src = CLK_SRC_PLL;
2677       param_clock_src = param_clock_src << 3;
2678     }
2679 
2680     if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) {
2681       param_clock_src |= 0x00;
2682     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) {
2683       param_clock_src |= 0x01;
2684     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) {
2685       param_clock_src |= 0x02;
2686     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) {
2687       param_clock_src |= 0x03;
2688     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) {
2689       param_clock_src |= 0x04;
2690     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) {
2691       param_clock_src |= 0x05;
2692     } else {
2693       NXPLOG_NCIHAL_E("Wrong clock freq, send default [email protected]");
2694       if((nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) {
2695         param_clock_src = 0x01;
2696       } else {
2697         param_clock_src = 0x11;
2698       }
2699     }
2700 
2701     set_clock_cmd[7] = param_clock_src;
2702     set_clock_cmd[11] = nxpprofile_ctrl.bTimeout;
2703     status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
2704     if (status != NFCSTATUS_SUCCESS) {
2705       NXPLOG_NCIHAL_E("PLL colck setting failed !!");
2706     }
2707   } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) {
2708     static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x05, 0x01,
2709                                       0xA0, 0x03, 0x01, 0x08};
2710     status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
2711     if (status != NFCSTATUS_SUCCESS) {
2712       NXPLOG_NCIHAL_E("XTAL colck setting failed !!");
2713     }
2714   } else {
2715     NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
2716   }
2717 
2718   // Checking for SET CONFG SUCCESS, re-send the command  if not.
2719   phNxpNciClock.isClockSet = false;
2720   if (phNxpNciClock.p_rx_data[3] != NFCSTATUS_SUCCESS) {
2721     if (retryCount++ < 3) {
2722       NXPLOG_NCIHAL_D("Set-clk failed retry again ");
2723       goto retrySetclock;
2724     } else {
2725       NXPLOG_NCIHAL_E("Set clk  failed -  max count = 0x%x exceeded ",
2726                       retryCount);
2727       //            NXPLOG_NCIHAL_E("Set Config is failed for Clock Due to
2728       //            elctrical disturbances, aborting the NFC process");
2729       //            abort ();
2730     }
2731   }
2732 }
2733 
2734 /******************************************************************************
2735  * Function         phNxpNciHal_check_clock_config
2736  *
2737  * Description      This function is called after successfull download
2738  *                  to check if clock settings in config file and chip
2739  *                  is same
2740  *
2741  * Returns          void.
2742  *
2743  ******************************************************************************/
phNxpNciHal_check_clock_config(void)2744 NFCSTATUS phNxpNciHal_check_clock_config(void) {
2745   NFCSTATUS status = NFCSTATUS_SUCCESS;
2746   uint8_t param_clock_src;
2747   static uint8_t get_clock_cmd[] = {0x20, 0x03, 0x07, 0x03, 0xA0,
2748                                     0x02, 0xA0, 0x03, 0xA0, 0x04};
2749   phNxpNciClock.isClockSet = true;
2750   phNxpNciHal_get_clk_freq();
2751   status = phNxpNciHal_send_ext_cmd(sizeof(get_clock_cmd), get_clock_cmd);
2752 
2753   if (status != NFCSTATUS_SUCCESS) {
2754     NXPLOG_NCIHAL_E("unable to retrieve get_clk_src_sel");
2755     return status;
2756   }
2757   param_clock_src = check_config_parameter();
2758   if (phNxpNciClock.p_rx_data[12] == param_clock_src &&
2759       phNxpNciClock.p_rx_data[16] == nxpprofile_ctrl.bTimeout) {
2760     phNxpNciClock.issetConfig = false;
2761   } else {
2762     phNxpNciClock.issetConfig = true;
2763   }
2764   phNxpNciClock.isClockSet = false;
2765 
2766   return status;
2767 }
2768 
2769 /******************************************************************************
2770  * Function         phNxpNciHal_china_tianjin_rf_setting
2771  *
2772  * Description      This function is called to check RF Setting
2773  *
2774  * Returns          Status.
2775  *
2776  ******************************************************************************/
phNxpNciHal_china_tianjin_rf_setting(void)2777 NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void) {
2778   NFCSTATUS status = NFCSTATUS_SUCCESS;
2779   int isfound = 0;
2780   int rf_enable = false;
2781   int rf_val = 0;
2782   int send_flag;
2783   uint8_t retry_cnt = 0;
2784   int enable_bit = 0;
2785   static uint8_t get_rf_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x85};
2786 
2787 retry_send_ext:
2788   if (retry_cnt > 3) {
2789     return NFCSTATUS_FAILED;
2790   }
2791   send_flag = true;
2792   phNxpNciRfSet.isGetRfSetting = true;
2793   status = phNxpNciHal_send_ext_cmd(sizeof(get_rf_cmd), get_rf_cmd);
2794   if (status != NFCSTATUS_SUCCESS) {
2795     NXPLOG_NCIHAL_E("unable to get the RF setting");
2796     phNxpNciRfSet.isGetRfSetting = false;
2797     retry_cnt++;
2798     goto retry_send_ext;
2799   }
2800   phNxpNciRfSet.isGetRfSetting = false;
2801   if (phNxpNciRfSet.p_rx_data[3] != 0x00) {
2802     NXPLOG_NCIHAL_E("GET_CONFIG_RSP is FAILED for CHINA TIANJIN");
2803     return status;
2804   }
2805   rf_val = phNxpNciRfSet.p_rx_data[10];
2806   isfound = (GetNxpNumValue(NAME_NXP_CHINA_TIANJIN_RF_ENABLED,
2807                             (void*)&rf_enable, sizeof(rf_enable)));
2808   if (isfound > 0) {
2809     enable_bit = rf_val & 0x40;
2810     if ((enable_bit != 0x40) && (rf_enable == 1)) {
2811       phNxpNciRfSet.p_rx_data[10] |= 0x40;  // Enable if it is disabled
2812     } else if ((enable_bit == 0x40) && (rf_enable == 0)) {
2813       phNxpNciRfSet.p_rx_data[10] &= 0xBF;  // Disable if it is Enabled
2814     } else {
2815       send_flag = false;  // No need to change in RF setting
2816     }
2817 
2818     if (send_flag == true) {
2819       static uint8_t set_rf_cmd[] = {0x20, 0x02, 0x08, 0x01, 0xA0, 0x85,
2820                                      0x04, 0x50, 0x08, 0x68, 0x00};
2821       memcpy(&set_rf_cmd[4], &phNxpNciRfSet.p_rx_data[5], 7);
2822       status = phNxpNciHal_send_ext_cmd(sizeof(set_rf_cmd), set_rf_cmd);
2823       if (status != NFCSTATUS_SUCCESS) {
2824         NXPLOG_NCIHAL_E("unable to set the RF setting");
2825         retry_cnt++;
2826         goto retry_send_ext;
2827       }
2828     }
2829   }
2830 
2831   return status;
2832 }
2833 
2834 /******************************************************************************
2835  * Function         phNxpNciHal_gpio_restore
2836  *
2837  * Description      This function restores the gpio values into eeprom
2838  *
2839  * Returns          void
2840  *
2841  ******************************************************************************/
phNxpNciHal_gpio_restore(phNxpNciHal_GpioInfoState state)2842 static void phNxpNciHal_gpio_restore(phNxpNciHal_GpioInfoState state) {
2843   NFCSTATUS status = NFCSTATUS_SUCCESS;
2844   uint8_t get_gpio_values_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x00};
2845   uint8_t set_gpio_values_cmd[] = {0x20, 0x02, 0x00, 0x01, 0xA0, 0x00, 0x20,
2846                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2847                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2848                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2849                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2850 
2851   if(state == GPIO_STORE) {
2852     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_STORE;
2853     get_gpio_values_cmd[5] = 0x08;
2854     status = phNxpNciHal_send_ext_cmd(sizeof(get_gpio_values_cmd), get_gpio_values_cmd);
2855     if (status != NFCSTATUS_SUCCESS) {
2856       NXPLOG_NCIHAL_E("Failed to get GPIO values!!!\n");
2857       return;
2858     }
2859 
2860     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_STORE_DONE;
2861     set_gpio_values_cmd[2] = 0x24;
2862     set_gpio_values_cmd[5] = 0x14;
2863     set_gpio_values_cmd[7] = nxpncihal_ctrl.phNxpNciGpioInfo.values[0];
2864     set_gpio_values_cmd[8] = nxpncihal_ctrl.phNxpNciGpioInfo.values[1];
2865     status = phNxpNciHal_send_ext_cmd(sizeof(set_gpio_values_cmd), set_gpio_values_cmd);
2866     if (status != NFCSTATUS_SUCCESS) {
2867       NXPLOG_NCIHAL_E("Failed to set GPIO values!!!\n");
2868       return;
2869     }
2870   } else if(state == GPIO_RESTORE) {
2871     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_RESTORE;
2872     get_gpio_values_cmd[5] = 0x14;
2873     status = phNxpNciHal_send_ext_cmd(sizeof(get_gpio_values_cmd), get_gpio_values_cmd);
2874     if (status != NFCSTATUS_SUCCESS) {
2875       NXPLOG_NCIHAL_E("Failed to get GPIO values!!!\n");
2876       return;
2877     }
2878 
2879     nxpncihal_ctrl.phNxpNciGpioInfo.state = GPIO_RESTORE_DONE;
2880     set_gpio_values_cmd[2] = 0x06;
2881     set_gpio_values_cmd[5] = 0x08; //update TAG
2882     set_gpio_values_cmd[6] = 0x02; //update length
2883     set_gpio_values_cmd[7] = nxpncihal_ctrl.phNxpNciGpioInfo.values[0];
2884     set_gpio_values_cmd[8] = nxpncihal_ctrl.phNxpNciGpioInfo.values[1];
2885     status = phNxpNciHal_send_ext_cmd(9, set_gpio_values_cmd);
2886     if (status != NFCSTATUS_SUCCESS) {
2887       NXPLOG_NCIHAL_E("Failed to set GPIO values!!!\n");
2888       return;
2889     }
2890   } else {
2891       NXPLOG_NCIHAL_E("GPIO Restore Invalid Option!!!\n");
2892   }
2893 }
2894 
2895 /******************************************************************************
2896  * Function         phNxpNciHal_nfcc_core_reset_init
2897  *
2898  * Description      Helper function to do nfcc core reset & core init
2899  *
2900  * Returns          Status
2901  *
2902  ******************************************************************************/
phNxpNciHal_nfcc_core_reset_init()2903 NFCSTATUS phNxpNciHal_nfcc_core_reset_init() {
2904   NFCSTATUS status = NFCSTATUS_FAILED;
2905   uint8_t retry_cnt = 0;
2906   uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x01};
2907 
2908 retry_core_reset:
2909   status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
2910   if ((status != NFCSTATUS_SUCCESS) && (retry_cnt < 3)) {
2911     NXPLOG_NCIHAL_D("Retry: NCI_CORE_RESET");
2912     retry_cnt++;
2913     goto retry_core_reset;
2914   } else if (status != NFCSTATUS_SUCCESS) {
2915       NXPLOG_NCIHAL_E("NCI_CORE_RESET failed!!!\n");
2916       return status;
2917   }
2918 
2919   retry_cnt = 0;
2920   uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
2921   uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
2922 retry_core_init:
2923   if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
2924     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
2925   } else {
2926     status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
2927   }
2928 
2929   if ((status != NFCSTATUS_SUCCESS) && (retry_cnt < 3)) {
2930     NXPLOG_NCIHAL_D("Retry: NCI_CORE_INIT\n");
2931     retry_cnt++;
2932     goto retry_core_init;
2933   } else if (status != NFCSTATUS_SUCCESS) {
2934     NXPLOG_NCIHAL_E("NCI_CORE_INIT failed!!!\n");
2935     return status;
2936   }
2937 
2938   return status;
2939 }
2940 
2941 /******************************************************************************
2942  * Function         phNxpNciHal_getChipInfoInFwDnldMode
2943  *
2944  * Description      Helper function to get the chip info in download mode
2945  *
2946  * Returns          Status
2947  *
2948  ******************************************************************************/
phNxpNciHal_getChipInfoInFwDnldMode(void)2949 NFCSTATUS phNxpNciHal_getChipInfoInFwDnldMode(void) {
2950   NFCSTATUS status = NFCSTATUS_FAILED;
2951   uint8_t retry_cnt = 0;
2952   uint8_t get_chip_info_cmd[] = {0x00, 0x04, 0xF1, 0x00,
2953                                  0x00, 0x00, 0x6E, 0xEF};
2954   NXPLOG_NCIHAL_D("%s:enter", __func__);
2955 retry:
2956   status =
2957       phNxpNciHal_send_ext_cmd(sizeof(get_chip_info_cmd), get_chip_info_cmd);
2958   if (status != NFCSTATUS_SUCCESS) {
2959     if (retry_cnt < 3) {
2960       NXPLOG_NCIHAL_D("Retry: get chip info");
2961       retry_cnt++;
2962       goto retry;
2963     } else {
2964       NXPLOG_NCIHAL_E("Failed: get chip info");
2965     }
2966   } else {
2967     phNxpNciHal_configFeatureList(nxpncihal_ctrl.p_rx_data,
2968                                   nxpncihal_ctrl.rx_data_len);
2969   }
2970   NXPLOG_NCIHAL_D("%s:exit  status: 0x%02x", __func__, status);
2971   return status;
2972 }
2973 
check_config_parameter()2974 int check_config_parameter() {
2975   uint8_t param_clock_src = CLK_SRC_PLL;
2976   if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) {
2977     if((nfcFL.chipType != pn553)&&(nfcFL.chipType != pn557)) {
2978       param_clock_src = param_clock_src << 3;
2979     }
2980     if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) {
2981       param_clock_src |= 0x00;
2982     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) {
2983       param_clock_src |= 0x01;
2984     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) {
2985       param_clock_src |= 0x02;
2986     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) {
2987       param_clock_src |= 0x03;
2988     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) {
2989       param_clock_src |= 0x04;
2990     } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) {
2991       param_clock_src |= 0x05;
2992     } else {
2993       NXPLOG_NCIHAL_E("Wrong clock freq, send default [email protected]");
2994       param_clock_src = 0x11;
2995     }
2996   } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) {
2997     param_clock_src = 0x08;
2998 
2999   } else {
3000     NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
3001   }
3002   return param_clock_src;
3003 }
3004 /******************************************************************************
3005  * Function         phNxpNciHal_enable_i2c_fragmentation
3006  *
3007  * Description      This function is called to process the response status
3008  *                  and print the status byte.
3009  *
3010  * Returns          void.
3011  *
3012  ******************************************************************************/
phNxpNciHal_enable_i2c_fragmentation()3013 void phNxpNciHal_enable_i2c_fragmentation() {
3014   NFCSTATUS status = NFCSTATUS_FAILED;
3015   static uint8_t fragmentation_enable_config_cmd[] = {0x20, 0x02, 0x05, 0x01,
3016                                                       0xA0, 0x05, 0x01, 0x10};
3017   long i2c_status = 0x00;
3018   long config_i2c_vlaue = 0xff;
3019   /*NCI_RESET_CMD*/
3020   static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
3021   /*NCI_INIT_CMD*/
3022   static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
3023   static uint8_t cmd_init_nci2_0[] = {0x20, 0x01, 0x02, 0x00, 0x00};
3024   static uint8_t get_i2c_fragmentation_cmd[] = {0x20, 0x03, 0x03,
3025                                                 0x01, 0xA0, 0x05};
3026   if (GetNxpNumValue(NAME_NXP_I2C_FRAGMENTATION_ENABLED, (void*)&i2c_status,
3027                  sizeof(i2c_status)) == true) {
3028     NXPLOG_FWDNLD_D("I2C status : %ld",i2c_status);
3029   } else {
3030     NXPLOG_FWDNLD_E("I2C status read not succeeded. Default value : %ld",i2c_status);
3031   }
3032   status = phNxpNciHal_send_ext_cmd(sizeof(get_i2c_fragmentation_cmd),
3033                                     get_i2c_fragmentation_cmd);
3034   if (status != NFCSTATUS_SUCCESS) {
3035     NXPLOG_NCIHAL_E("unable to retrieve  get_i2c_fragmentation_cmd");
3036   } else {
3037     if (nxpncihal_ctrl.p_rx_data[8] == 0x10) {
3038       config_i2c_vlaue = 0x01;
3039       phNxpNciHal_notify_i2c_fragmentation();
3040       phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
3041     } else if (nxpncihal_ctrl.p_rx_data[8] == 0x00) {
3042       config_i2c_vlaue = 0x00;
3043     }
3044     // if the value already matches, nothing to be done
3045     if (config_i2c_vlaue != i2c_status) {
3046       if (i2c_status == 0x01) {
3047         /* NXP I2C fragmenation enabled*/
3048         status =
3049             phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd),
3050                                      fragmentation_enable_config_cmd);
3051         if (status != NFCSTATUS_SUCCESS) {
3052           NXPLOG_NCIHAL_E("NXP fragmentation enable failed");
3053         }
3054       } else if (i2c_status == 0x00 || config_i2c_vlaue == 0xff) {
3055         fragmentation_enable_config_cmd[7] = 0x00;
3056         /* NXP I2C fragmentation disabled*/
3057         status =
3058             phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd),
3059                                      fragmentation_enable_config_cmd);
3060         if (status != NFCSTATUS_SUCCESS) {
3061           NXPLOG_NCIHAL_E("NXP fragmentation disable failed");
3062         }
3063       }
3064       status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
3065       if (status != NFCSTATUS_SUCCESS) {
3066         NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
3067       }
3068       if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
3069         status =
3070             phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
3071       } else {
3072         status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
3073       }
3074       if (status != NFCSTATUS_SUCCESS) {
3075         NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
3076       } else if (i2c_status == 0x01) {
3077         phNxpNciHal_notify_i2c_fragmentation();
3078         phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
3079       }
3080     }
3081   }
3082 }
3083 /******************************************************************************
3084  * Function         phNxpNciHal_do_se_session_reset
3085  *
3086  * Description      This function is called to set the session id to default
3087  *                  value.
3088  *
3089  * Returns          NFCSTATUS.
3090  *
3091  ******************************************************************************/
phNxpNciHal_do_se_session_reset(void)3092 static NFCSTATUS phNxpNciHal_do_se_session_reset(void) {
3093   static uint8_t reset_se_session_identity_set[] = {
3094       0x20, 0x02, 0x17, 0x02, 0xA0, 0xEA, 0x08, 0xFF, 0xFF,
3095       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xEB, 0x08,
3096       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
3097   NFCSTATUS status = phNxpNciHal_send_ext_cmd(sizeof(reset_se_session_identity_set),
3098                                   reset_se_session_identity_set);
3099   NXPLOG_NCIHAL_D("%s status = %x ",__func__, status);
3100   return status;
3101 }
3102 /******************************************************************************
3103  * Function         phNxpNciHal_do_factory_reset
3104  *
3105  * Description      This function is called during factory reset to clear/reset
3106  *                  nfc sub-system persistant data.
3107  *
3108  * Returns          void.
3109  *
3110  ******************************************************************************/
phNxpNciHal_do_factory_reset(void)3111 void phNxpNciHal_do_factory_reset(void) {
3112   NFCSTATUS status = NFCSTATUS_FAILED;
3113   if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
3114     status = phNxpNciHal_MinOpen();
3115     if (status != NFCSTATUS_SUCCESS ) {
3116       NXPLOG_NCIHAL_E("%s: NXP Nfc Open failed", __func__);
3117       return;
3118     }
3119   }
3120   status = phNxpNciHal_do_se_session_reset();
3121   if (status != NFCSTATUS_SUCCESS) {
3122     NXPLOG_NCIHAL_E("%s failed. status = %x ",__func__, status);
3123   }
3124 }
3125 /******************************************************************************
3126  * Function         phNxpNciHal_hci_network_reset
3127  *
3128  * Description      This function resets the session id's of all the se's
3129  *                  in the HCI network and notify to HCI_NETWORK_RESET event to
3130  *                  NFC HAL Client.
3131  *
3132  * Returns          void.
3133  *
3134  ******************************************************************************/
phNxpNciHal_hci_network_reset(void)3135 static void phNxpNciHal_hci_network_reset(void) {
3136   static phLibNfc_Message_t msg;
3137   msg.pMsgData = NULL;
3138   msg.Size = 0;
3139 
3140   NFCSTATUS status = phNxpNciHal_do_se_session_reset();
3141 
3142   if (status != NFCSTATUS_SUCCESS) {
3143     msg.eMsgType = NCI_HAL_ERROR_MSG;
3144   } else {
3145     msg.eMsgType = NCI_HAL_HCI_NETWORK_RESET_MSG;
3146   }
3147   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
3148 }
3149 
3150 /*******************************************************************************
3151 **
3152 ** Function         phNxpNciHal_configFeatureList
3153 **
3154 ** Description      Configures the featureList based on chip type
3155 **                  HW Version information number will provide chipType.
3156 **                  HW Version can be obtained from CORE_INIT_RESPONSE(NCI 1.0)
3157 **                  or CORE_RST_NTF(NCI 2.0) or PROPREITARY RSP (FW download
3158 *                   mode)
3159 **
3160 ** Parameters       CORE_INIT_RESPONSE/CORE_RST_NTF/PROPREITARY RSP, len
3161 **
3162 ** Returns          none
3163 *******************************************************************************/
phNxpNciHal_configFeatureList(uint8_t * msg,uint16_t msg_len)3164 void phNxpNciHal_configFeatureList(uint8_t* msg, uint16_t msg_len) {
3165   tNFC_chipType chipType = pConfigFL->getChipType(msg, msg_len);
3166   CONFIGURE_FEATURELIST(chipType);
3167   NXPLOG_NCIHAL_D("%s chipType = %d", __func__, chipType);
3168 }
3169 
3170 /******************************************************************************
3171  * Function         phNxpNciHal_print_res_status
3172  *
3173  * Description      This function is called to process the response status
3174  *                  and print the status byte.
3175  *
3176  * Returns          void.
3177  *
3178  ******************************************************************************/
phNxpNciHal_print_res_status(uint8_t * p_rx_data,uint16_t * p_len)3179 static void phNxpNciHal_print_res_status(uint8_t* p_rx_data, uint16_t* p_len) {
3180   static uint8_t response_buf[][30] = {"STATUS_OK",
3181                                        "STATUS_REJECTED",
3182                                        "STATUS_RF_FRAME_CORRUPTED",
3183                                        "STATUS_FAILED",
3184                                        "STATUS_NOT_INITIALIZED",
3185                                        "STATUS_SYNTAX_ERROR",
3186                                        "STATUS_SEMANTIC_ERROR",
3187                                        "RFU",
3188                                        "RFU",
3189                                        "STATUS_INVALID_PARAM",
3190                                        "STATUS_MESSAGE_SIZE_EXCEEDED",
3191                                        "STATUS_UNDEFINED"};
3192   int status_byte;
3193   if (p_rx_data[0] == 0x40 && (p_rx_data[1] == 0x02 || p_rx_data[1] == 0x03)) {
3194     if (p_rx_data[2] && p_rx_data[3] <= 10) {
3195       status_byte = p_rx_data[CORE_RES_STATUS_BYTE];
3196       NXPLOG_NCIHAL_D("%s: response status =%s", __func__,
3197                       response_buf[status_byte]);
3198     } else {
3199       NXPLOG_NCIHAL_D("%s: response status =%s", __func__, response_buf[11]);
3200     }
3201     if (phNxpNciClock.isClockSet) {
3202       int i;
3203       for (i = 0; i < *p_len; i++) {
3204         phNxpNciClock.p_rx_data[i] = p_rx_data[i];
3205       }
3206     }
3207 
3208     else if (phNxpNciRfSet.isGetRfSetting) {
3209       int i;
3210       for (i = 0; i < *p_len; i++) {
3211         phNxpNciRfSet.p_rx_data[i] = p_rx_data[i];
3212         // NXPLOG_NCIHAL_D("%s: response status =0x%x",__func__,p_rx_data[i]);
3213       }
3214     } else if (phNxpNciMwEepromArea.isGetEepromArea) {
3215       int i;
3216       for (i = 8; i < *p_len; i++) {
3217         phNxpNciMwEepromArea.p_rx_data[i - 8] = p_rx_data[i];
3218       }
3219     } else if (nxpncihal_ctrl.phNxpNciGpioInfo.state == GPIO_STORE) {
3220         NXPLOG_NCIHAL_D("%s: Storing GPIO Values...", __func__);
3221         nxpncihal_ctrl.phNxpNciGpioInfo.values[0] = p_rx_data[9];
3222         nxpncihal_ctrl.phNxpNciGpioInfo.values[1] = p_rx_data[8];
3223     } else if (nxpncihal_ctrl.phNxpNciGpioInfo.state == GPIO_RESTORE) {
3224         NXPLOG_NCIHAL_D("%s: Restoring GPIO Values...", __func__);
3225         nxpncihal_ctrl.phNxpNciGpioInfo.values[0] = p_rx_data[9];
3226         nxpncihal_ctrl.phNxpNciGpioInfo.values[1] = p_rx_data[8];
3227     }
3228 }
3229 
3230   if (p_rx_data[2] && (config_access == true)) {
3231     if (p_rx_data[3] != NFCSTATUS_SUCCESS) {
3232       NXPLOG_NCIHAL_W("Invalid Data from config file.");
3233       config_success = false;
3234     }
3235   }
3236 }
3237 
3238 /******************************************************************************
3239  * Function         phNxpNciHal_initialize_mifare_flag
3240  *
3241  * Description      This function gets the value for Mfc flags.
3242  *
3243  * Returns          void
3244  *
3245  ******************************************************************************/
phNxpNciHal_initialize_mifare_flag()3246 static void phNxpNciHal_initialize_mifare_flag() {
3247   unsigned long num = 0;
3248   bEnableMfcReader = false;
3249   bDisableLegacyMfcExtns = true;
3250   //1: Enable Mifare Classic protocol in RF Discovery.
3251   //0: Remove Mifare Classic protocol in RF Discovery.
3252   if(GetNxpNumValue(NAME_MIFARE_READER_ENABLE, &num, sizeof(num))) {
3253     bEnableMfcReader = (num == 0) ? false : true;
3254   }
3255   //1: Use legacy JNI MFC extns.
3256   //0: Disable legacy JNI MFC extns, use hal MFC Extns instead.
3257   if(GetNxpNumValue(NAME_LEGACY_MIFARE_READER, &num, sizeof(num))) {
3258     bDisableLegacyMfcExtns = (num == 0) ? true : false;
3259   }
3260 }
3261