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