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