1 /*
2 * Copyright (C) 2012-2014 NXP Semiconductors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <phDal4Nfc_messageQueueLib.h>
18 #include <phDnldNfc.h>
19 #include <phNxpConfig.h>
20 #include <phNxpLog.h>
21 #include <phNxpNciHal.h>
22 #include <phNxpNciHal_Adaptation.h>
23 #include <phNxpNciHal_Dnld.h>
24 #include <phNxpNciHal_Kovio.h>
25 #include <phNxpNciHal_NfcDepSWPrio.h>
26 #include <phNxpNciHal_ext.h>
27 #include <phTmlNfc.h>
28 #include <sys/stat.h>
29 /*********************** Global Variables *************************************/
30 #define PN547C2_CLOCK_SETTING
31 #undef PN547C2_FACTORY_RESET_DEBUG
32 #define CORE_RES_STATUS_BYTE 3
33
34 /* Processing of ISO 15693 EOF */
35 extern uint8_t icode_send_eof;
36 extern uint8_t icode_detected;
37 static uint8_t cmd_icode_eof[] = {0x00, 0x00, 0x00};
38
39 /* FW download success flag */
40 static uint8_t fw_download_success = 0;
41
42 static uint8_t config_access = false;
43 /* NCI HAL Control structure */
44 phNxpNciHal_Control_t nxpncihal_ctrl;
45
46 /* NXP Poll Profile structure */
47 phNxpNciProfile_Control_t nxpprofile_ctrl;
48
49 /* TML Context */
50 extern phTmlNfc_Context_t* gpphTmlNfc_Context;
51 extern void phTmlNfc_set_fragmentation_enabled(
52 phTmlNfc_i2cfragmentation_t result);
53 /* global variable to get FW version from NCI response*/
54 uint32_t wFwVerRsp;
55 /* External global variable to get FW version */
56 extern uint16_t wFwVer;
57
58 extern uint16_t fw_maj_ver;
59 extern uint16_t rom_version;
60 extern int send_to_upper_kovio;
61 extern int kovio_detected;
62 extern int disable_kovio;
63 #if (NFC_NXP_CHIP_TYPE != PN547C2)
64 extern uint8_t gRecFWDwnld;
65 static uint8_t gRecFwRetryCount; // variable to hold dummy FW recovery count
66 #endif
67 static uint8_t Rx_data[NCI_MAX_DATA_LEN];
68
69 #if (NFC_NXP_CHIP_TYPE == PN548C2)
70 uint8_t discovery_cmd[50] = {0};
71 uint8_t discovery_cmd_len = 0;
72 #endif
73 extern bool_t rf_deactive_cmd;
74 uint32_t timeoutTimerId = 0;
75 phNxpNciHal_Sem_t config_data;
76
77 phNxpNciClock_t phNxpNciClock = {0, {0}, false};
78
79 phNxpNciRfSetting_t phNxpNciRfSet = {false, {0}};
80
81 phNxpNciMwEepromArea_t phNxpNciMwEepromArea = {false, {0}};
82
83 /**************** local methods used in this file only ************************/
84 static NFCSTATUS phNxpNciHal_fw_download(void);
85 static void phNxpNciHal_open_complete(NFCSTATUS status);
86 static void phNxpNciHal_write_complete(void* pContext,
87 phTmlNfc_TransactInfo_t* pInfo);
88 static void phNxpNciHal_read_complete(void* pContext,
89 phTmlNfc_TransactInfo_t* pInfo);
90 static void phNxpNciHal_close_complete(NFCSTATUS status);
91 static void phNxpNciHal_core_initialized_complete(NFCSTATUS status);
92 static void phNxpNciHal_pre_discover_complete(NFCSTATUS status);
93 static void phNxpNciHal_power_cycle_complete(NFCSTATUS status);
94 static void phNxpNciHal_kill_client_thread(
95 phNxpNciHal_Control_t* p_nxpncihal_ctrl);
96 static void* phNxpNciHal_client_thread(void* arg);
97 static void phNxpNciHal_get_clk_freq(void);
98 static void phNxpNciHal_set_clock(void);
99 static void phNxpNciHal_check_factory_reset(void);
100 static void phNxpNciHal_print_res_status(uint8_t* p_rx_data, uint16_t* p_len);
101 static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void);
102 static void phNxpNciHal_enable_i2c_fragmentation();
103 static NFCSTATUS phNxpNciHal_get_mw_eeprom(void);
104 static NFCSTATUS phNxpNciHal_set_mw_eeprom(void);
105 static int phNxpNciHal_fw_mw_ver_check();
106 NFCSTATUS phNxpNciHal_check_clock_config(void);
107 NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void);
108 #if (NFC_NXP_CHIP_TYPE != PN547C2)
109 static NFCSTATUS phNxpNciHalRFConfigCmdRecSequence();
110 static NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus();
111 #endif
112 int check_config_parameter();
113
114 /******************************************************************************
115 * Function phNxpNciHal_client_thread
116 *
117 * Description This function is a thread handler which handles all TML and
118 * NCI messages.
119 *
120 * Returns void
121 *
122 ******************************************************************************/
phNxpNciHal_client_thread(void * arg)123 static void* phNxpNciHal_client_thread(void* arg) {
124 phNxpNciHal_Control_t* p_nxpncihal_ctrl = (phNxpNciHal_Control_t*)arg;
125 phLibNfc_Message_t msg;
126
127 NXPLOG_NCIHAL_D("thread started");
128
129 p_nxpncihal_ctrl->thread_running = 1;
130
131 while (p_nxpncihal_ctrl->thread_running == 1) {
132 /* Fetch next message from the NFC stack message queue */
133 if (phDal4Nfc_msgrcv(p_nxpncihal_ctrl->gDrvCfg.nClientId, &msg, 0, 0) ==
134 -1) {
135 NXPLOG_NCIHAL_E("NFC client received bad message");
136 continue;
137 }
138
139 if (p_nxpncihal_ctrl->thread_running == 0) {
140 break;
141 }
142
143 switch (msg.eMsgType) {
144 case PH_LIBNFC_DEFERREDCALL_MSG: {
145 phLibNfc_DeferredCall_t* deferCall =
146 (phLibNfc_DeferredCall_t*)(msg.pMsgData);
147
148 REENTRANCE_LOCK();
149 deferCall->pCallback(deferCall->pParameter);
150 REENTRANCE_UNLOCK();
151
152 break;
153 }
154
155 case NCI_HAL_OPEN_CPLT_MSG: {
156 REENTRANCE_LOCK();
157 if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
158 /* Send the event */
159 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT,
160 HAL_NFC_STATUS_OK);
161 }
162 REENTRANCE_UNLOCK();
163 break;
164 }
165
166 case NCI_HAL_CLOSE_CPLT_MSG: {
167 REENTRANCE_LOCK();
168 if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
169 /* Send the event */
170 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_CLOSE_CPLT_EVT,
171 HAL_NFC_STATUS_OK);
172 phNxpNciHal_kill_client_thread(&nxpncihal_ctrl);
173 }
174 REENTRANCE_UNLOCK();
175 break;
176 }
177
178 case NCI_HAL_POST_INIT_CPLT_MSG: {
179 REENTRANCE_LOCK();
180 if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
181 /* Send the event */
182 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_POST_INIT_CPLT_EVT,
183 HAL_NFC_STATUS_OK);
184 }
185 REENTRANCE_UNLOCK();
186 break;
187 }
188
189 case NCI_HAL_PRE_DISCOVER_CPLT_MSG: {
190 REENTRANCE_LOCK();
191 if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
192 /* Send the event */
193 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_PRE_DISCOVER_CPLT_EVT,
194 HAL_NFC_STATUS_OK);
195 }
196 REENTRANCE_UNLOCK();
197 break;
198 }
199
200 case NCI_HAL_ERROR_MSG: {
201 REENTRANCE_LOCK();
202 if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
203 /* Send the event */
204 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ERROR_EVT,
205 HAL_NFC_STATUS_FAILED);
206 }
207 REENTRANCE_UNLOCK();
208 break;
209 }
210
211 case NCI_HAL_RX_MSG: {
212 REENTRANCE_LOCK();
213 if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) {
214 (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rsp_len,
215 nxpncihal_ctrl.p_rsp_data);
216 }
217 REENTRANCE_UNLOCK();
218 break;
219 }
220 }
221 }
222
223 NXPLOG_NCIHAL_D("NxpNciHal thread stopped");
224
225 return NULL;
226 }
227
228 /******************************************************************************
229 * Function phNxpNciHal_kill_client_thread
230 *
231 * Description This function safely kill the client thread and clean all
232 * resources.
233 *
234 * Returns void.
235 *
236 ******************************************************************************/
phNxpNciHal_kill_client_thread(phNxpNciHal_Control_t * p_nxpncihal_ctrl)237 static void phNxpNciHal_kill_client_thread(
238 phNxpNciHal_Control_t* p_nxpncihal_ctrl) {
239 NXPLOG_NCIHAL_D("Terminating phNxpNciHal client thread...");
240
241 p_nxpncihal_ctrl->p_nfc_stack_cback = NULL;
242 p_nxpncihal_ctrl->p_nfc_stack_data_cback = NULL;
243 p_nxpncihal_ctrl->thread_running = 0;
244
245 return;
246 }
247
248 /******************************************************************************
249 * Function phNxpNciHal_fw_download
250 *
251 * Description This function download the PN54X secure firmware to IC. If
252 * firmware version in Android filesystem and firmware in the
253 * IC is same then firmware download will return with success
254 * without downloading the firmware.
255 *
256 * Returns NFCSTATUS_SUCCESS if firmware download successful
257 * NFCSTATUS_FAILED in case of failure
258 *
259 ******************************************************************************/
phNxpNciHal_fw_download(void)260 static NFCSTATUS phNxpNciHal_fw_download(void) {
261 NFCSTATUS status = NFCSTATUS_FAILED;
262
263 phNxpNciHal_get_clk_freq();
264 status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
265 if (NFCSTATUS_SUCCESS == status) {
266 /* Set the obtained device handle to download module */
267 phDnldNfc_SetHwDevHandle();
268 NXPLOG_NCIHAL_D("Calling Seq handler for FW Download \n");
269 status = phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal,
270 nxpprofile_ctrl.bClkFreqVal);
271 phDnldNfc_ReSetHwDevHandle();
272 } else {
273 status = NFCSTATUS_FAILED;
274 }
275
276 return status;
277 }
278
279 /******************************************************************************
280 * Function phNxpNciHal_CheckValidFwVersion
281 *
282 * Description This function checks the valid FW for Mobile device.
283 * If the FW doesn't belong the Mobile device it further
284 * checks nxp config file to override.
285 *
286 * Returns NFCSTATUS_SUCCESS if valid fw version found
287 * NFCSTATUS_NOT_ALLOWED in case of FW not valid for mobile
288 * device
289 *
290 ******************************************************************************/
phNxpNciHal_CheckValidFwVersion(void)291 static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void) {
292 NFCSTATUS status = NFCSTATUS_NOT_ALLOWED;
293 #if (NFC_NXP_CHIP_TYPE == PN551)
294 const unsigned char sfw_mobile_major_no = 0x05;
295 #else
296 const unsigned char sfw_mobile_major_no = 0x01;
297 #endif
298 const unsigned char sfw_infra_major_no = 0x02;
299 unsigned char ufw_current_major_no = 0x00;
300 unsigned long num = 0;
301 int isfound = 0;
302
303 /* extract the firmware's major no */
304 ufw_current_major_no = ((0x00FF) & (wFwVer >> 8U));
305
306 NXPLOG_NCIHAL_D("%s current_major_no = 0x%x", __func__, ufw_current_major_no);
307 if (ufw_current_major_no == sfw_mobile_major_no) {
308 status = NFCSTATUS_SUCCESS;
309 } else if (ufw_current_major_no == sfw_infra_major_no) {
310 /* Check the nxp config file if still want to go for download */
311 /* By default NAME_NXP_FW_PROTECION_OVERRIDE will not be defined in config
312 file.
313 If user really want to override the Infra firmware over mobile firmware,
314 please
315 put "NXP_FW_PROTECION_OVERRIDE=0x01" in libnfc-nxp.conf file.
316 Please note once Infra firmware downloaded to Mobile device, The device
317 can never be updated to Mobile firmware*/
318 isfound = GetNxpNumValue(NAME_NXP_FW_PROTECION_OVERRIDE, &num, sizeof(num));
319 if (isfound > 0) {
320 if (num == 0x01) {
321 NXPLOG_NCIHAL_D("Override Infra FW over Mobile");
322 status = NFCSTATUS_SUCCESS;
323 } else {
324 NXPLOG_NCIHAL_D(
325 "Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE invalid "
326 "value)");
327 }
328 } else {
329 NXPLOG_NCIHAL_D(
330 "Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE not "
331 "defiend)");
332 }
333 }
334 #if (NFC_NXP_CHIP_TYPE != PN547C2)
335 else if (gRecFWDwnld == true) {
336 status = NFCSTATUS_SUCCESS;
337 }
338 #endif
339 else if (wFwVerRsp == 0) {
340 NXPLOG_NCIHAL_E(
341 "FW Version not received by NCI command >>> Force Firmware download");
342 status = NFCSTATUS_SUCCESS;
343 } else {
344 NXPLOG_NCIHAL_E("Wrong FW Version >>> Firmware download not allowed");
345 }
346
347 return status;
348 }
349
phNxpNciHal_get_clk_freq(void)350 static void phNxpNciHal_get_clk_freq(void) {
351 unsigned long num = 0;
352 int isfound = 0;
353
354 nxpprofile_ctrl.bClkSrcVal = 0;
355 nxpprofile_ctrl.bClkFreqVal = 0;
356 nxpprofile_ctrl.bTimeout = 0;
357
358 isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &num, sizeof(num));
359 if (isfound > 0) {
360 nxpprofile_ctrl.bClkSrcVal = num;
361 }
362
363 num = 0;
364 isfound = 0;
365 isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &num, sizeof(num));
366 if (isfound > 0) {
367 nxpprofile_ctrl.bClkFreqVal = num;
368 }
369
370 num = 0;
371 isfound = 0;
372 isfound = GetNxpNumValue(NAME_NXP_SYS_CLOCK_TO_CFG, &num, sizeof(num));
373 if (isfound > 0) {
374 nxpprofile_ctrl.bTimeout = num;
375 }
376
377 NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkSrcVal = 0x%x",
378 nxpprofile_ctrl.bClkSrcVal);
379 NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x",
380 nxpprofile_ctrl.bClkFreqVal);
381 NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x",
382 nxpprofile_ctrl.bTimeout);
383
384 if ((nxpprofile_ctrl.bClkSrcVal < CLK_SRC_XTAL) ||
385 (nxpprofile_ctrl.bClkSrcVal > CLK_SRC_PLL)) {
386 NXPLOG_FWDNLD_E(
387 "Clock source value is wrong in config file, setting it as default");
388 nxpprofile_ctrl.bClkSrcVal = NXP_SYS_CLK_SRC_SEL;
389 }
390 if ((nxpprofile_ctrl.bClkFreqVal < CLK_FREQ_13MHZ) ||
391 (nxpprofile_ctrl.bClkFreqVal > CLK_FREQ_52MHZ)) {
392 NXPLOG_FWDNLD_E(
393 "Clock frequency value is wrong in config file, setting it as default");
394 nxpprofile_ctrl.bClkFreqVal = NXP_SYS_CLK_FREQ_SEL;
395 }
396 if ((nxpprofile_ctrl.bTimeout < CLK_TO_CFG_DEF) ||
397 (nxpprofile_ctrl.bTimeout > CLK_TO_CFG_MAX)) {
398 NXPLOG_FWDNLD_E(
399 "Clock timeout value is wrong in config file, setting it as default");
400 nxpprofile_ctrl.bTimeout = CLK_TO_CFG_DEF;
401 }
402 }
403
404 /******************************************************************************
405 * Function phNxpNciHal_open
406 *
407 * Description This function is called by libnfc-nci during the
408 * initialization of the NFCC. It opens the physical connection
409 * with NFCC (PN54X) and creates required client thread for
410 * operation.
411 * After open is complete, status is informed to libnfc-nci
412 * through callback function.
413 *
414 * Returns This function return NFCSTATUS_SUCCES (0) in case of success
415 * In case of failure returns other failure value.
416 *
417 ******************************************************************************/
phNxpNciHal_open(nfc_stack_callback_t * p_cback,nfc_stack_data_callback_t * p_data_cback)418 int phNxpNciHal_open(nfc_stack_callback_t* p_cback,
419 nfc_stack_data_callback_t* p_data_cback) {
420 phOsalNfc_Config_t tOsalConfig;
421 phTmlNfc_Config_t tTmlConfig;
422 char* nfc_dev_node = NULL;
423 const uint16_t max_len = 260;
424 NFCSTATUS wConfigStatus = NFCSTATUS_SUCCESS;
425 NFCSTATUS status = NFCSTATUS_SUCCESS;
426 /*NCI_INIT_CMD*/
427 static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
428 /*NCI_RESET_CMD*/
429 static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
430
431 if (nxpncihal_ctrl.halStatus == HAL_STATUS_OPEN) {
432 NXPLOG_NCIHAL_E("phNxpNciHal_open already open");
433 return NFCSTATUS_SUCCESS;
434 }
435 /* reset config cache */
436 resetNxpConfig();
437
438 int init_retry_cnt = 0;
439 int8_t ret_val = 0x00;
440
441 /* initialize trace level */
442 phNxpLog_InitializeLogLevel();
443
444 /*Create the timer for extns write response*/
445 timeoutTimerId = phOsalNfc_Timer_Create();
446
447 if (phNxpNciHal_init_monitor() == NULL) {
448 NXPLOG_NCIHAL_E("Init monitor failed");
449 return NFCSTATUS_FAILED;
450 }
451
452 CONCURRENCY_LOCK();
453 memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
454 memset(&tOsalConfig, 0x00, sizeof(tOsalConfig));
455 memset(&tTmlConfig, 0x00, sizeof(tTmlConfig));
456 memset(&nxpprofile_ctrl, 0, sizeof(phNxpNciProfile_Control_t));
457
458 /* By default HAL status is HAL_STATUS_OPEN */
459 nxpncihal_ctrl.halStatus = HAL_STATUS_OPEN;
460
461 nxpncihal_ctrl.p_nfc_stack_cback = p_cback;
462 nxpncihal_ctrl.p_nfc_stack_data_cback = p_data_cback;
463
464 /* Read the nfc device node name */
465 nfc_dev_node = (char*)malloc(max_len * sizeof(char));
466 if (nfc_dev_node == NULL) {
467 NXPLOG_NCIHAL_E("malloc of nfc_dev_node failed ");
468 goto clean_and_return;
469 } else if (!GetNxpStrValue(NAME_NXP_NFC_DEV_NODE, nfc_dev_node,
470 sizeof(nfc_dev_node))) {
471 NXPLOG_NCIHAL_E(
472 "Invalid nfc device node name keeping the default device node "
473 "/dev/pn54x");
474 strcpy(nfc_dev_node, "/dev/pn54x");
475 }
476
477 /* Configure hardware link */
478 nxpncihal_ctrl.gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
479 nxpncihal_ctrl.gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C; /* For PN54X */
480 tTmlConfig.pDevName = (int8_t*)nfc_dev_node;
481 tOsalConfig.dwCallbackThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId;
482 tOsalConfig.pLogFile = NULL;
483 tTmlConfig.dwGetMsgThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId;
484
485 #if (NFC_NXP_CHIP_TYPE == PN548C2)
486 memset(discovery_cmd, 0, sizeof(discovery_cmd));
487 discovery_cmd_len = 0;
488 #endif
489
490 /* Initialize TML layer */
491 wConfigStatus = phTmlNfc_Init(&tTmlConfig);
492 if (wConfigStatus != NFCSTATUS_SUCCESS) {
493 NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
494 goto clean_and_return;
495 } else {
496 if (nfc_dev_node != NULL) {
497 free(nfc_dev_node);
498 nfc_dev_node = NULL;
499 }
500 }
501
502 /* Create the client thread */
503 pthread_attr_t attr;
504 pthread_attr_init(&attr);
505 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
506 ret_val = pthread_create(&nxpncihal_ctrl.client_thread, &attr,
507 phNxpNciHal_client_thread, &nxpncihal_ctrl);
508 pthread_attr_destroy(&attr);
509 if (ret_val != 0) {
510 NXPLOG_NCIHAL_E("pthread_create failed");
511 wConfigStatus = phTmlNfc_Shutdown();
512 goto clean_and_return;
513 }
514
515 CONCURRENCY_UNLOCK();
516
517 /* call read pending */
518 status = phTmlNfc_Read(
519 nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN,
520 (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
521 if (status != NFCSTATUS_PENDING) {
522 NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
523 wConfigStatus = phTmlNfc_Shutdown();
524 wConfigStatus = NFCSTATUS_FAILED;
525 goto clean_and_return;
526 }
527
528 init_retry:
529
530 phNxpNciHal_ext_init();
531
532 status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
533 if ((status != NFCSTATUS_SUCCESS) &&
534 (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT)) {
535 NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
536 wConfigStatus = NFCSTATUS_FAILED;
537 goto force_download;
538 } else if (status != NFCSTATUS_SUCCESS) {
539 NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
540 if (init_retry_cnt < 3) {
541 init_retry_cnt++;
542 (void)phNxpNciHal_power_cycle();
543 goto init_retry;
544 } else
545 init_retry_cnt = 0;
546 wConfigStatus = phTmlNfc_Shutdown();
547 wConfigStatus = NFCSTATUS_FAILED;
548 goto clean_and_return;
549 }
550
551 status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
552 if (status != NFCSTATUS_SUCCESS) {
553 NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
554 if (init_retry_cnt < 3) {
555 init_retry_cnt++;
556 (void)phNxpNciHal_power_cycle();
557 goto init_retry;
558 } else
559 init_retry_cnt = 0;
560 wConfigStatus = phTmlNfc_Shutdown();
561 wConfigStatus = NFCSTATUS_FAILED;
562 goto clean_and_return;
563 }
564 phNxpNciHal_enable_i2c_fragmentation();
565 /*Get FW version from device*/
566 status = phDnldNfc_InitImgInfo();
567 NXPLOG_NCIHAL_D("FW version for FW file = 0x%x", wFwVer);
568 NXPLOG_NCIHAL_D("FW version from device = 0x%x", wFwVerRsp);
569 if ((wFwVerRsp & 0x0000FFFF) == wFwVer) {
570 NXPLOG_NCIHAL_D("FW uptodate not required");
571 phDnldNfc_ReSetHwDevHandle();
572 } else {
573 force_download:
574 if (wFwVerRsp == 0) {
575 phDnldNfc_InitImgInfo();
576 }
577 if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion()) {
578 NXPLOG_NCIHAL_D("FW update required");
579 fw_download_success = 0;
580 status = phNxpNciHal_fw_download();
581 if (status != NFCSTATUS_SUCCESS) {
582 if (NFCSTATUS_SUCCESS != phNxpNciHal_fw_mw_ver_check()) {
583 NXPLOG_NCIHAL_D("Chip Version Middleware Version mismatch!!!!");
584 /* Abort any pending read and write */
585 phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
586 phTmlNfc_ReadAbort();
587 phTmlNfc_WriteAbort();
588 phTmlNfc_Shutdown();
589 wConfigStatus = NFCSTATUS_FAILED;
590 goto clean_and_return;
591 }
592 NXPLOG_NCIHAL_E("FW Download failed - NFCC init will continue");
593 } else {
594 wConfigStatus = NFCSTATUS_SUCCESS;
595 fw_download_success = 1;
596 /* call read pending */
597 status = phTmlNfc_Read(
598 nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN,
599 (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
600 if (status != NFCSTATUS_PENDING) {
601 NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
602 wConfigStatus = phTmlNfc_Shutdown();
603 wConfigStatus = NFCSTATUS_FAILED;
604 goto clean_and_return;
605 }
606 }
607 } else {
608 if (wFwVerRsp == 0) phDnldNfc_ReSetHwDevHandle();
609 }
610 }
611 /* Call open complete */
612 phNxpNciHal_open_complete(wConfigStatus);
613
614 return wConfigStatus;
615
616 clean_and_return:
617 CONCURRENCY_UNLOCK();
618 if (nfc_dev_node != NULL) {
619 free(nfc_dev_node);
620 nfc_dev_node = NULL;
621 }
622 /* Report error status */
623 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT,
624 HAL_NFC_STATUS_FAILED);
625
626 nxpncihal_ctrl.p_nfc_stack_cback = NULL;
627 nxpncihal_ctrl.p_nfc_stack_data_cback = NULL;
628 phNxpNciHal_cleanup_monitor();
629 nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
630 return NFCSTATUS_FAILED;
631 }
632
633 /******************************************************************************
634 * Function phNxpNciHal_fw_mw_check
635 *
636 * Description This function inform the status of phNxpNciHal_fw_mw_check
637 * function to libnfc-nci.
638 *
639 * Returns int.
640 *
641 ******************************************************************************/
phNxpNciHal_fw_mw_ver_check()642 int phNxpNciHal_fw_mw_ver_check() {
643 NFCSTATUS status = NFCSTATUS_FAILED;
644 if (!strcmp(COMPILATION_MW, "PN551") && (rom_version == 0x10) &&
645 (fw_maj_ver == 0x05)) {
646 status = NFCSTATUS_SUCCESS;
647 } else if (!strcmp(COMPILATION_MW, "PN548C2") && (rom_version == 0x10) &&
648 (fw_maj_ver == 0x01)) {
649 status = NFCSTATUS_SUCCESS;
650 } else if (!strcmp(COMPILATION_MW, "PN547C2") && (rom_version == 0x08) &&
651 (fw_maj_ver == 0x01)) {
652 status = NFCSTATUS_SUCCESS;
653 }
654 return status;
655 }
656 /******************************************************************************
657 * Function phNxpNciHal_open_complete
658 *
659 * Description This function inform the status of phNxpNciHal_open
660 * function to libnfc-nci.
661 *
662 * Returns void.
663 *
664 ******************************************************************************/
phNxpNciHal_open_complete(NFCSTATUS status)665 static void phNxpNciHal_open_complete(NFCSTATUS status) {
666 static phLibNfc_Message_t msg;
667
668 if (status == NFCSTATUS_SUCCESS) {
669 msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
670 nxpncihal_ctrl.hal_open_status = true;
671 } else {
672 msg.eMsgType = NCI_HAL_ERROR_MSG;
673 }
674
675 msg.pMsgData = NULL;
676 msg.Size = 0;
677
678 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
679 (phLibNfc_Message_t*)&msg);
680
681 return;
682 }
683
684 /******************************************************************************
685 * Function phNxpNciHal_write
686 *
687 * Description This function write the data to NFCC through physical
688 * interface (e.g. I2C) using the PN54X driver interface.
689 * Before sending the data to NFCC, phNxpNciHal_write_ext
690 * is called to check if there is any extension processing
691 * is required for the NCI packet being sent out.
692 *
693 * Returns It returns number of bytes successfully written to NFCC.
694 *
695 ******************************************************************************/
phNxpNciHal_write(uint16_t data_len,const uint8_t * p_data)696 int phNxpNciHal_write(uint16_t data_len, const uint8_t* p_data) {
697 NFCSTATUS status = NFCSTATUS_FAILED;
698 static phLibNfc_Message_t msg;
699 if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
700 return NFCSTATUS_FAILED;
701 }
702 /* Create local copy of cmd_data */
703 memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
704 nxpncihal_ctrl.cmd_len = data_len;
705 if (nxpncihal_ctrl.cmd_len > NCI_MAX_DATA_LEN) {
706 NXPLOG_NCIHAL_D("cmd_len exceeds limit NCI_MAX_DATA_LEN");
707 goto clean_and_return;
708 }
709 #ifdef P2P_PRIO_LOGIC_HAL_IMP
710 /* Specific logic to block RF disable when P2P priority logic is busy */
711 if (p_data[0] == 0x21 && p_data[1] == 0x06 && p_data[2] == 0x01 &&
712 EnableP2P_PrioLogic == true) {
713 NXPLOG_NCIHAL_D("P2P priority logic busy: Disable it.");
714 phNxpNciHal_clean_P2P_Prio();
715 }
716 #endif
717 /* Specific logic to block RF disable when Kovio detection logic is active */
718 if (p_data[0] == 0x21 && p_data[1] == 0x06 && p_data[2] == 0x01) {
719 rf_deactive_cmd = true;
720 if (kovio_detected == true) {
721 NXPLOG_NCIHAL_D(
722 "Kovio detection logic is active: Set Flag to disable it.");
723 disable_kovio = 0x01;
724 }
725 }
726
727 /* Check for NXP ext before sending write */
728 status =
729 phNxpNciHal_write_ext(&nxpncihal_ctrl.cmd_len, nxpncihal_ctrl.p_cmd_data,
730 &nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
731 if (status != NFCSTATUS_SUCCESS) {
732 /* Do not send packet to PN54X, send response directly */
733 msg.eMsgType = NCI_HAL_RX_MSG;
734 msg.pMsgData = NULL;
735 msg.Size = 0;
736
737 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
738 (phLibNfc_Message_t*)&msg);
739 goto clean_and_return;
740 }
741
742 CONCURRENCY_LOCK();
743 data_len = phNxpNciHal_write_unlocked(nxpncihal_ctrl.cmd_len,
744 nxpncihal_ctrl.p_cmd_data);
745 CONCURRENCY_UNLOCK();
746
747 if (icode_send_eof == 1) {
748 usleep(10000);
749 icode_send_eof = 2;
750 phNxpNciHal_send_ext_cmd(3, cmd_icode_eof);
751 }
752
753 clean_and_return:
754 /* No data written */
755 return data_len;
756 }
757
758 /******************************************************************************
759 * Function phNxpNciHal_write_unlocked
760 *
761 * Description This is the actual function which is being called by
762 * phNxpNciHal_write. This function writes the data to NFCC.
763 * It waits till write callback provide the result of write
764 * process.
765 *
766 * Returns It returns number of bytes successfully written to NFCC.
767 *
768 ******************************************************************************/
phNxpNciHal_write_unlocked(uint16_t data_len,const uint8_t * p_data)769 int phNxpNciHal_write_unlocked(uint16_t data_len, const uint8_t* p_data) {
770 NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER;
771 phNxpNciHal_Sem_t cb_data;
772 nxpncihal_ctrl.retry_cnt = 0;
773 static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00,
774 0xC7, 0xD4, 0x00, 0x00};
775
776 /* Create the local semaphore */
777 if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS) {
778 NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked Create cb data failed");
779 data_len = 0;
780 goto clean_and_return;
781 }
782
783 /* Create local copy of cmd_data */
784 memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
785 nxpncihal_ctrl.cmd_len = data_len;
786
787 retry:
788
789 data_len = nxpncihal_ctrl.cmd_len;
790
791 status = phTmlNfc_Write(
792 (uint8_t*)nxpncihal_ctrl.p_cmd_data, (uint16_t)nxpncihal_ctrl.cmd_len,
793 (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_write_complete,
794 (void*)&cb_data);
795 if (status != NFCSTATUS_PENDING) {
796 NXPLOG_NCIHAL_E("write_unlocked status error");
797 data_len = 0;
798 goto clean_and_return;
799 }
800
801 /* Wait for callback response */
802 if (SEM_WAIT(cb_data)) {
803 NXPLOG_NCIHAL_E("write_unlocked semaphore error");
804 data_len = 0;
805 goto clean_and_return;
806 }
807
808 if (cb_data.status != NFCSTATUS_SUCCESS) {
809 data_len = 0;
810 if (nxpncihal_ctrl.retry_cnt++ < MAX_RETRY_COUNT) {
811 NXPLOG_NCIHAL_E(
812 "write_unlocked failed - PN54X Maybe in Standby Mode - Retry");
813 /* 1ms delay to give NFCC wake up delay */
814 usleep(1000);
815 goto retry;
816 } else {
817 NXPLOG_NCIHAL_E(
818 "write_unlocked failed - PN54X Maybe in Standby Mode (max count = "
819 "0x%x)",
820 nxpncihal_ctrl.retry_cnt);
821
822 status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
823
824 if (NFCSTATUS_SUCCESS == status) {
825 NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
826 } else {
827 NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
828 }
829 if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL &&
830 nxpncihal_ctrl.p_rx_data != NULL &&
831 nxpncihal_ctrl.hal_open_status == true) {
832 NXPLOG_NCIHAL_D(
833 "Send the Core Reset NTF to upper layer, which will trigger the "
834 "recovery\n");
835 // Send the Core Reset NTF to upper layer, which will trigger the
836 // recovery.
837 nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf);
838 memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf));
839 (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
840 nxpncihal_ctrl.p_rx_data);
841 }
842 }
843 }
844
845 clean_and_return:
846 phNxpNciHal_cleanup_cb_data(&cb_data);
847 return data_len;
848 }
849
850 /******************************************************************************
851 * Function phNxpNciHal_write_complete
852 *
853 * Description This function handles write callback.
854 *
855 * Returns void.
856 *
857 ******************************************************************************/
phNxpNciHal_write_complete(void * pContext,phTmlNfc_TransactInfo_t * pInfo)858 static void phNxpNciHal_write_complete(void* pContext,
859 phTmlNfc_TransactInfo_t* pInfo) {
860 phNxpNciHal_Sem_t* p_cb_data = (phNxpNciHal_Sem_t*)pContext;
861
862 if (pInfo->wStatus == NFCSTATUS_SUCCESS) {
863 NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus);
864 } else {
865 NXPLOG_NCIHAL_E("write error status = 0x%x", pInfo->wStatus);
866 }
867
868 p_cb_data->status = pInfo->wStatus;
869
870 SEM_POST(p_cb_data);
871
872 return;
873 }
874
875 /******************************************************************************
876 * Function phNxpNciHal_read_complete
877 *
878 * Description This function is called whenever there is an NCI packet
879 * received from NFCC. It could be RSP or NTF packet. This
880 * function provide the received NCI packet to libnfc-nci
881 * using data callback of libnfc-nci.
882 * There is a pending read called from each
883 * phNxpNciHal_read_complete so each a packet received from
884 * NFCC can be provide to libnfc-nci.
885 *
886 * Returns void.
887 *
888 ******************************************************************************/
phNxpNciHal_read_complete(void * pContext,phTmlNfc_TransactInfo_t * pInfo)889 static void phNxpNciHal_read_complete(void* pContext,
890 phTmlNfc_TransactInfo_t* pInfo) {
891 NFCSTATUS status = NFCSTATUS_FAILED;
892 UNUSED(pContext);
893 if (nxpncihal_ctrl.read_retry_cnt == 1) {
894 nxpncihal_ctrl.read_retry_cnt = 0;
895 }
896
897 if (pInfo->wStatus == NFCSTATUS_SUCCESS) {
898 NXPLOG_NCIHAL_D("read successful status = 0x%x", pInfo->wStatus);
899
900 nxpncihal_ctrl.p_rx_data = pInfo->pBuff;
901 nxpncihal_ctrl.rx_data_len = pInfo->wLength;
902
903 status = phNxpNciHal_process_ext_rsp(nxpncihal_ctrl.p_rx_data,
904 &nxpncihal_ctrl.rx_data_len);
905
906 phNxpNciHal_print_res_status(nxpncihal_ctrl.p_rx_data,
907 &nxpncihal_ctrl.rx_data_len);
908 /* Check if response should go to hal module only */
909 if (nxpncihal_ctrl.hal_ext_enabled == 1 &&
910 (nxpncihal_ctrl.p_rx_data[0x00] & 0xF0) == 0x40) {
911 if (status == NFCSTATUS_FAILED) {
912 NXPLOG_NCIHAL_D("enter into NFCC init recovery");
913 nxpncihal_ctrl.ext_cb_data.status = status;
914 }
915 /* Unlock semaphore only for responses*/
916 if ((nxpncihal_ctrl.p_rx_data[0x00] & 0xF0) == 0x40 ||
917 ((icode_detected == true) && (icode_send_eof == 3))) {
918 /* Unlock semaphore */
919 SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
920 }
921 }
922 /* Read successful send the event to higher layer */
923 else if ((nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) &&
924 (status == NFCSTATUS_SUCCESS) && (send_to_upper_kovio == 1)) {
925 (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
926 nxpncihal_ctrl.p_rx_data);
927 }
928 } else {
929 NXPLOG_NCIHAL_E("read error status = 0x%x", pInfo->wStatus);
930 }
931
932 if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
933 return;
934 }
935 /* Read again because read must be pending always.*/
936 status = phTmlNfc_Read(
937 Rx_data, NCI_MAX_DATA_LEN,
938 (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
939 if (status != NFCSTATUS_PENDING) {
940 NXPLOG_NCIHAL_E("read status error status = %x", status);
941 /* TODO: Not sure how to handle this ? */
942 }
943
944 return;
945 }
946
read_retry()947 void read_retry() {
948 /* Read again because read must be pending always.*/
949 NFCSTATUS status = phTmlNfc_Read(
950 Rx_data, NCI_MAX_DATA_LEN,
951 (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
952 if (status != NFCSTATUS_PENDING) {
953 NXPLOG_NCIHAL_E("read status error status = %x", status);
954 /* TODO: Not sure how to handle this ? */
955 }
956 }
957 /******************************************************************************
958 * Function phNxpNciHal_core_initialized
959 *
960 * Description This function is called by libnfc-nci after successful open
961 * of NFCC. All proprietary setting for PN54X are done here.
962 * After completion of proprietary settings notification is
963 * provided to libnfc-nci through callback function.
964 *
965 * Returns Always returns NFCSTATUS_SUCCESS (0).
966 *
967 ******************************************************************************/
phNxpNciHal_core_initialized(uint8_t * p_core_init_rsp_params)968 int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params) {
969 NFCSTATUS status = NFCSTATUS_SUCCESS;
970 static uint8_t p2p_listen_mode_routing_cmd[] = {0x21, 0x01, 0x07, 0x00, 0x01,
971 0x01, 0x03, 0x00, 0x01, 0x05};
972
973 uint8_t swp_full_pwr_mode_on_cmd[] = {0x20, 0x02, 0x05, 0x01,
974 0xA0, 0xF1, 0x01, 0x01};
975
976 static uint8_t android_l_aid_matching_mode_on_cmd[] = {
977 0x20, 0x02, 0x05, 0x01, 0xA0, 0x91, 0x01, 0x01};
978 static uint8_t swp_switch_timeout_cmd[] = {0x20, 0x02, 0x06, 0x01, 0xA0,
979 0xF3, 0x02, 0x00, 0x00};
980
981 uint8_t* buffer = NULL;
982 long bufflen = 260;
983 long retlen = 0;
984 int isfound;
985 /* Temp fix to re-apply the proper clock setting */
986 int temp_fix = 1;
987 unsigned long num = 0;
988 #if (NFC_NXP_CHIP_TYPE != PN547C2)
989 // initialize dummy FW recovery variables
990 gRecFwRetryCount = 0;
991 gRecFWDwnld = 0;
992 #endif
993 // recovery --start
994 /*NCI_INIT_CMD*/
995 static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
996 /*NCI_RESET_CMD*/
997 static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01,
998 0x00}; // keep configuration
999 /* reset config cache */
1000 static uint8_t retry_core_init_cnt;
1001 if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
1002 return NFCSTATUS_FAILED;
1003 }
1004 if ((*p_core_init_rsp_params > 0) &&
1005 (*p_core_init_rsp_params < 4)) // initializing for recovery.
1006 {
1007 retry_core_init:
1008 config_access = false;
1009 if (buffer != NULL) {
1010 free(buffer);
1011 buffer = NULL;
1012 }
1013 if (retry_core_init_cnt > 3) {
1014 return NFCSTATUS_FAILED;
1015 }
1016
1017 status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1018 if (NFCSTATUS_SUCCESS == status) {
1019 NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
1020 } else {
1021 NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
1022 }
1023
1024 status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
1025 if ((status != NFCSTATUS_SUCCESS) &&
1026 (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT)) {
1027 NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
1028 retry_core_init_cnt++;
1029 goto retry_core_init;
1030 } else if (status != NFCSTATUS_SUCCESS) {
1031 NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
1032 retry_core_init_cnt++;
1033 goto retry_core_init;
1034 }
1035
1036 if (*p_core_init_rsp_params == 2) {
1037 NXPLOG_NCIHAL_E(" Last command is CORE_RESET!!");
1038 goto invoke_callback;
1039 }
1040
1041 status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
1042 if (status != NFCSTATUS_SUCCESS) {
1043 NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
1044 retry_core_init_cnt++;
1045 goto retry_core_init;
1046 }
1047
1048 if (*p_core_init_rsp_params == 3) {
1049 NXPLOG_NCIHAL_E(" Last command is CORE_INIT!!");
1050 goto invoke_callback;
1051 }
1052 }
1053 // recovery --end
1054
1055 buffer = (uint8_t*)malloc(bufflen * sizeof(uint8_t));
1056 if (NULL == buffer) {
1057 return NFCSTATUS_FAILED;
1058 }
1059 config_access = true;
1060 retlen = 0;
1061 isfound = GetNxpByteArrayValue(NAME_NXP_ACT_PROP_EXTN, (char*)buffer, bufflen,
1062 &retlen);
1063 if (retlen > 0) {
1064 /* NXP ACT Proprietary Ext */
1065 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1066 if (status != NFCSTATUS_SUCCESS) {
1067 NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
1068 retry_core_init_cnt++;
1069 goto retry_core_init;
1070 }
1071 }
1072
1073 // Check if firmware download success
1074 status = phNxpNciHal_get_mw_eeprom();
1075 if (status != NFCSTATUS_SUCCESS) {
1076 NXPLOG_NCIHAL_E("NXP GET MW EEPROM AREA Proprietary Ext failed");
1077 retry_core_init_cnt++;
1078 goto retry_core_init;
1079 }
1080
1081 //
1082 status = phNxpNciHal_check_clock_config();
1083 if (status != NFCSTATUS_SUCCESS) {
1084 NXPLOG_NCIHAL_E("phNxpNciHal_check_clock_config failed");
1085 retry_core_init_cnt++;
1086 goto retry_core_init;
1087 }
1088
1089 #ifdef PN547C2_CLOCK_SETTING
1090 if ((fw_download_success == 1) || (phNxpNciClock.issetConfig)
1091 #if (NFC_NXP_HFO_SETTINGS == TRUE)
1092 || temp_fix == 1
1093 #endif
1094 ) {
1095 // phNxpNciHal_get_clk_freq();
1096 phNxpNciHal_set_clock();
1097 phNxpNciClock.issetConfig = false;
1098 #if (NFC_NXP_HFO_SETTINGS == TRUE)
1099 if (temp_fix == 1) {
1100 NXPLOG_NCIHAL_D(
1101 "Applying Default Clock setting and DPLL register at power on");
1102 /*
1103 # A0, 0D, 06, 06, 83, 55, 2A, 04, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_GEAR_REG
1104 # A0, 0D, 06, 06, 82, 33, 14, 17, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_REG
1105 # A0, 0D, 06, 06, 84, AA, 85, 00, 80 RF_CLIF_CFG_TARGET
1106 CLIF_DPLL_INIT_FREQ_REG
1107 # A0, 0D, 06, 06, 81, 63, 00, 00, 00 RF_CLIF_CFG_TARGET
1108 CLIF_DPLL_CONTROL_REG
1109 */
1110 static uint8_t cmd_dpll_set_reg_nci[] = {
1111 0x20, 0x02, 0x25, 0x04, 0xA0, 0x0D, 0x06, 0x06, 0x83, 0x55,
1112 0x2A, 0x04, 0x00, 0xA0, 0x0D, 0x06, 0x06, 0x82, 0x33, 0x14,
1113 0x17, 0x00, 0xA0, 0x0D, 0x06, 0x06, 0x84, 0xAA, 0x85, 0x00,
1114 0x80, 0xA0, 0x0D, 0x06, 0x06, 0x81, 0x63, 0x00, 0x00, 0x00};
1115
1116 status = phNxpNciHal_send_ext_cmd(sizeof(cmd_dpll_set_reg_nci),
1117 cmd_dpll_set_reg_nci);
1118 if (status != NFCSTATUS_SUCCESS) {
1119 NXPLOG_NCIHAL_E("NXP DPLL REG ACT Proprietary Ext failed");
1120 retry_core_init_cnt++;
1121 goto retry_core_init;
1122 }
1123 /* reset the NFCC after applying the clock setting and DPLL setting */
1124 // phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1125 temp_fix = 0;
1126 goto retry_core_init;
1127 }
1128 #endif
1129 }
1130 #endif
1131
1132 phNxpNciHal_check_factory_reset();
1133 retlen = 0;
1134 config_access = true;
1135 isfound = GetNxpByteArrayValue(NAME_NXP_NFC_PROFILE_EXTN, (char*)buffer,
1136 bufflen, &retlen);
1137 if (retlen > 0) {
1138 /* NXP ACT Proprietary Ext */
1139 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1140 if (status != NFCSTATUS_SUCCESS) {
1141 NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
1142 retry_core_init_cnt++;
1143 goto retry_core_init;
1144 }
1145 }
1146
1147 if (fw_download_success == 1) {
1148 retlen = 0;
1149 fw_download_success = 0;
1150
1151 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1152 NXPLOG_NCIHAL_D("Performing TVDD Settings");
1153 isfound = GetNxpNumValue(NAME_NXP_EXT_TVDD_CFG, &num, sizeof(num));
1154 if (isfound > 0) {
1155 if (num == 1) {
1156 isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_1, (char*)buffer,
1157 bufflen, &retlen);
1158 if (retlen > 0) {
1159 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1160 if (status != NFCSTATUS_SUCCESS) {
1161 NXPLOG_NCIHAL_E("EXT TVDD CFG 1 Settings failed");
1162 retry_core_init_cnt++;
1163 goto retry_core_init;
1164 }
1165 }
1166 } else if (num == 2) {
1167 isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_2, (char*)buffer,
1168 bufflen, &retlen);
1169 if (retlen > 0) {
1170 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1171 if (status != NFCSTATUS_SUCCESS) {
1172 NXPLOG_NCIHAL_E("EXT TVDD CFG 2 Settings failed");
1173 retry_core_init_cnt++;
1174 goto retry_core_init;
1175 }
1176 }
1177 } else if (num == 3) {
1178 isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_3, (char*)buffer,
1179 bufflen, &retlen);
1180 if (retlen > 0) {
1181 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1182 if (status != NFCSTATUS_SUCCESS) {
1183 NXPLOG_NCIHAL_E("EXT TVDD CFG 3 Settings failed");
1184 retry_core_init_cnt++;
1185 goto retry_core_init;
1186 }
1187 }
1188 } else {
1189 NXPLOG_NCIHAL_E("Wrong Configuration Value %ld", num);
1190 }
1191 }
1192 #endif
1193 retlen = 0;
1194 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1195 config_access = false;
1196 #endif
1197 NXPLOG_NCIHAL_D("Performing RF Settings BLK 1");
1198 isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_1, (char*)buffer,
1199 bufflen, &retlen);
1200 if (retlen > 0) {
1201 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1202 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1203 if (status == NFCSTATUS_SUCCESS) {
1204 status = phNxpNciHal_CheckRFCmdRespStatus();
1205 /*STATUS INVALID PARAM 0x09*/
1206 if (status == 0x09) {
1207 phNxpNciHalRFConfigCmdRecSequence();
1208 retry_core_init_cnt++;
1209 goto retry_core_init;
1210 }
1211 } else
1212 #endif
1213 if (status != NFCSTATUS_SUCCESS) {
1214 NXPLOG_NCIHAL_E("RF Settings BLK 1 failed");
1215 retry_core_init_cnt++;
1216 goto retry_core_init;
1217 }
1218 }
1219 retlen = 0;
1220
1221 NXPLOG_NCIHAL_D("Performing RF Settings BLK 2");
1222 isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_2, (char*)buffer,
1223 bufflen, &retlen);
1224 if (retlen > 0) {
1225 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1226 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1227 if (status == NFCSTATUS_SUCCESS) {
1228 status = phNxpNciHal_CheckRFCmdRespStatus();
1229 /*STATUS INVALID PARAM 0x09*/
1230 if (status == 0x09) {
1231 phNxpNciHalRFConfigCmdRecSequence();
1232 retry_core_init_cnt++;
1233 goto retry_core_init;
1234 }
1235 } else
1236 #endif
1237 if (status != NFCSTATUS_SUCCESS) {
1238 NXPLOG_NCIHAL_E("RF Settings BLK 2 failed");
1239 retry_core_init_cnt++;
1240 goto retry_core_init;
1241 }
1242 }
1243 retlen = 0;
1244
1245 NXPLOG_NCIHAL_D("Performing RF Settings BLK 3");
1246 isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_3, (char*)buffer,
1247 bufflen, &retlen);
1248 if (retlen > 0) {
1249 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1250 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1251 if (status == NFCSTATUS_SUCCESS) {
1252 status = phNxpNciHal_CheckRFCmdRespStatus();
1253 /*STATUS INVALID PARAM 0x09*/
1254 if (status == 0x09) {
1255 phNxpNciHalRFConfigCmdRecSequence();
1256 retry_core_init_cnt++;
1257 goto retry_core_init;
1258 }
1259 } else
1260 #endif
1261 if (status != NFCSTATUS_SUCCESS) {
1262 NXPLOG_NCIHAL_E("RF Settings BLK 3 failed");
1263 retry_core_init_cnt++;
1264 goto retry_core_init;
1265 }
1266 }
1267 retlen = 0;
1268
1269 NXPLOG_NCIHAL_D("Performing RF Settings BLK 4");
1270 isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_4, (char*)buffer,
1271 bufflen, &retlen);
1272 if (retlen > 0) {
1273 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1274 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1275 if (status == NFCSTATUS_SUCCESS) {
1276 status = phNxpNciHal_CheckRFCmdRespStatus();
1277 /*STATUS INVALID PARAM 0x09*/
1278 if (status == 0x09) {
1279 phNxpNciHalRFConfigCmdRecSequence();
1280 retry_core_init_cnt++;
1281 goto retry_core_init;
1282 }
1283 } else
1284 #endif
1285 if (status != NFCSTATUS_SUCCESS) {
1286 NXPLOG_NCIHAL_E("RF Settings BLK 4 failed");
1287 retry_core_init_cnt++;
1288 goto retry_core_init;
1289 }
1290 }
1291 retlen = 0;
1292
1293 NXPLOG_NCIHAL_D("Performing RF Settings BLK 5");
1294 isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_5, (char*)buffer,
1295 bufflen, &retlen);
1296 if (retlen > 0) {
1297 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1298 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1299 if (status == NFCSTATUS_SUCCESS) {
1300 status = phNxpNciHal_CheckRFCmdRespStatus();
1301 /*STATUS INVALID PARAM 0x09*/
1302 if (status == 0x09) {
1303 phNxpNciHalRFConfigCmdRecSequence();
1304 retry_core_init_cnt++;
1305 goto retry_core_init;
1306 }
1307 } else
1308 #endif
1309 if (status != NFCSTATUS_SUCCESS) {
1310 NXPLOG_NCIHAL_E("RF Settings BLK 5 failed");
1311 retry_core_init_cnt++;
1312 goto retry_core_init;
1313 }
1314 }
1315 retlen = 0;
1316
1317 NXPLOG_NCIHAL_D("Performing RF Settings BLK 6");
1318 isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_6, (char*)buffer,
1319 bufflen, &retlen);
1320 if (retlen > 0) {
1321 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1322 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1323 if (status == NFCSTATUS_SUCCESS) {
1324 status = phNxpNciHal_CheckRFCmdRespStatus();
1325 /*STATUS INVALID PARAM 0x09*/
1326 if (status == 0x09) {
1327 phNxpNciHalRFConfigCmdRecSequence();
1328 retry_core_init_cnt++;
1329 goto retry_core_init;
1330 }
1331 } else
1332 #endif
1333 if (status != NFCSTATUS_SUCCESS) {
1334 NXPLOG_NCIHAL_E("RF Settings BLK 6 failed");
1335 retry_core_init_cnt++;
1336 goto retry_core_init;
1337 }
1338 }
1339 retlen = 0;
1340 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1341 config_access = true;
1342 #endif
1343 NXPLOG_NCIHAL_D("Performing NAME_NXP_CORE_CONF_EXTN Settings");
1344 isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF_EXTN, (char*)buffer,
1345 bufflen, &retlen);
1346 if (retlen > 0) {
1347 /* NXP ACT Proprietary Ext */
1348 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1349 if (status != NFCSTATUS_SUCCESS) {
1350 NXPLOG_NCIHAL_E("NXP Core configuration failed");
1351 retry_core_init_cnt++;
1352 goto retry_core_init;
1353 }
1354 }
1355
1356 retlen = 0;
1357
1358 isfound = GetNxpByteArrayValue(NAME_NXP_CORE_MFCKEY_SETTING, (char*)buffer,
1359 bufflen, &retlen);
1360 if (retlen > 0) {
1361 /* NXP ACT Proprietary Ext */
1362 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1363 if (status != NFCSTATUS_SUCCESS) {
1364 NXPLOG_NCIHAL_E("Setting mifare keys failed");
1365 retry_core_init_cnt++;
1366 goto retry_core_init;
1367 }
1368 }
1369
1370 retlen = 0;
1371 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1372 config_access = false;
1373 #endif
1374 isfound = GetNxpByteArrayValue(NAME_NXP_CORE_RF_FIELD, (char*)buffer,
1375 bufflen, &retlen);
1376 if (retlen > 0) {
1377 /* NXP ACT Proprietary Ext */
1378 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1379 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1380 if (status == NFCSTATUS_SUCCESS) {
1381 status = phNxpNciHal_CheckRFCmdRespStatus();
1382 /*STATUS INVALID PARAM 0x09*/
1383 if (status == 0x09) {
1384 phNxpNciHalRFConfigCmdRecSequence();
1385 retry_core_init_cnt++;
1386 goto retry_core_init;
1387 }
1388 } else
1389 #endif
1390 if (status != NFCSTATUS_SUCCESS) {
1391 NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
1392 retry_core_init_cnt++;
1393 goto retry_core_init;
1394 }
1395 }
1396 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1397 config_access = true;
1398 #endif
1399
1400 retlen = 0;
1401 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1402 /* NXP SWP switch timeout Setting*/
1403 if (GetNxpNumValue(NAME_NXP_SWP_SWITCH_TIMEOUT, (void*)&retlen,
1404 sizeof(retlen))) {
1405 // Check the permissible range [0 - 60]
1406 if (0 <= retlen && retlen <= 60) {
1407 if (0 < retlen) {
1408 unsigned int timeout = retlen * 1000;
1409 unsigned int timeoutHx = 0x0000;
1410
1411 char tmpbuffer[10] = {0};
1412 snprintf((char*)tmpbuffer, 10, "%04x", timeout);
1413 sscanf((char*)tmpbuffer, "%x", &timeoutHx);
1414
1415 swp_switch_timeout_cmd[7] = (timeoutHx & 0xFF);
1416 swp_switch_timeout_cmd[8] = ((timeoutHx & 0xFF00) >> 8);
1417 }
1418
1419 status = phNxpNciHal_send_ext_cmd(sizeof(swp_switch_timeout_cmd),
1420 swp_switch_timeout_cmd);
1421 if (status != NFCSTATUS_SUCCESS) {
1422 NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed");
1423 retry_core_init_cnt++;
1424 goto retry_core_init;
1425 }
1426 } else {
1427 NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed - out of range!");
1428 }
1429 }
1430
1431 status = phNxpNciHal_china_tianjin_rf_setting();
1432 if (status != NFCSTATUS_SUCCESS) {
1433 NXPLOG_NCIHAL_E("phNxpNciHal_china_tianjin_rf_setting failed");
1434 return NFCSTATUS_FAILED;
1435 }
1436 #endif
1437 // Update eeprom value
1438 status = phNxpNciHal_set_mw_eeprom();
1439 if (status != NFCSTATUS_SUCCESS) {
1440 NXPLOG_NCIHAL_E("NXP Update MW EEPROM Proprietary Ext failed");
1441 }
1442 }
1443
1444 retlen = 0;
1445
1446 isfound = GetNxpByteArrayValue(NAME_NXP_CORE_STANDBY, (char*)buffer, bufflen,
1447 &retlen);
1448 if (retlen > 0) {
1449 /* NXP ACT Proprietary Ext */
1450 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1451 if (status != NFCSTATUS_SUCCESS) {
1452 NXPLOG_NCIHAL_E("Stand by mode enable failed");
1453 retry_core_init_cnt++;
1454 goto retry_core_init;
1455 }
1456 }
1457 retlen = 0;
1458
1459 isfound =
1460 GetNxpByteArrayValue(NAME_NXP_CORE_CONF, (char*)buffer, bufflen, &retlen);
1461 if (retlen > 0) {
1462 /* NXP ACT Proprietary Ext */
1463 status = phNxpNciHal_send_ext_cmd(retlen, buffer);
1464 if (status != NFCSTATUS_SUCCESS) {
1465 NXPLOG_NCIHAL_E("Core Set Config failed");
1466 retry_core_init_cnt++;
1467 goto retry_core_init;
1468 }
1469 }
1470
1471 config_access = false;
1472 // if recovery mode and length of last command is 0 then only reset the P2P
1473 // listen mode routing.
1474 if ((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4) &&
1475 p_core_init_rsp_params[35] == 0) {
1476 /* P2P listen mode routing */
1477 status = phNxpNciHal_send_ext_cmd(sizeof(p2p_listen_mode_routing_cmd),
1478 p2p_listen_mode_routing_cmd);
1479 if (status != NFCSTATUS_SUCCESS) {
1480 NXPLOG_NCIHAL_E("P2P listen mode routing failed");
1481 retry_core_init_cnt++;
1482 goto retry_core_init;
1483 }
1484 }
1485
1486 retlen = 0;
1487
1488 /* SWP FULL PWR MODE SETTING ON */
1489 if (GetNxpNumValue(NAME_NXP_SWP_FULL_PWR_ON, (void*)&retlen,
1490 sizeof(retlen))) {
1491 if (1 == retlen) {
1492 status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd),
1493 swp_full_pwr_mode_on_cmd);
1494 if (status != NFCSTATUS_SUCCESS) {
1495 NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING ON CMD FAILED");
1496 retry_core_init_cnt++;
1497 goto retry_core_init;
1498 }
1499 } else {
1500 swp_full_pwr_mode_on_cmd[7] = 0x00;
1501 status = phNxpNciHal_send_ext_cmd(sizeof(swp_full_pwr_mode_on_cmd),
1502 swp_full_pwr_mode_on_cmd);
1503 if (status != NFCSTATUS_SUCCESS) {
1504 NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING OFF CMD FAILED");
1505 retry_core_init_cnt++;
1506 goto retry_core_init;
1507 }
1508 }
1509 }
1510
1511 /* Android L AID Matching Platform Setting*/
1512 if (GetNxpNumValue(NAME_AID_MATCHING_PLATFORM, (void*)&retlen,
1513 sizeof(retlen))) {
1514 if (1 == retlen) {
1515 status =
1516 phNxpNciHal_send_ext_cmd(sizeof(android_l_aid_matching_mode_on_cmd),
1517 android_l_aid_matching_mode_on_cmd);
1518 if (status != NFCSTATUS_SUCCESS) {
1519 NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
1520 retry_core_init_cnt++;
1521 goto retry_core_init;
1522 }
1523 } else if (2 == retlen) {
1524 android_l_aid_matching_mode_on_cmd[7] = 0x00;
1525 status =
1526 phNxpNciHal_send_ext_cmd(sizeof(android_l_aid_matching_mode_on_cmd),
1527 android_l_aid_matching_mode_on_cmd);
1528 if (status != NFCSTATUS_SUCCESS) {
1529 NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
1530 retry_core_init_cnt++;
1531 goto retry_core_init;
1532 }
1533 }
1534 }
1535
1536 if ((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)) {
1537 static phLibNfc_Message_t msg;
1538 uint16_t tmp_len = 0;
1539 uint8_t uicc_set_mode[] = {0x22, 0x01, 0x02, 0x02, 0x01};
1540 uint8_t set_screen_state[] = {0x2F, 0x15, 01, 00}; // SCREEN ON
1541 uint8_t nfcc_core_conn_create[] = {0x20, 0x04, 0x06, 0x03, 0x01,
1542 0x01, 0x02, 0x01, 0x01};
1543 uint8_t nfcc_mode_set_on[] = {0x22, 0x01, 0x02, 0x01, 0x01};
1544
1545 NXPLOG_NCIHAL_E(
1546 "Sending DH and NFCC core connection command as raw packet!!");
1547 status = phNxpNciHal_send_ext_cmd(sizeof(nfcc_core_conn_create),
1548 nfcc_core_conn_create);
1549
1550 if (status != NFCSTATUS_SUCCESS) {
1551 NXPLOG_NCIHAL_E(
1552 "Sending DH and NFCC core connection command as raw packet!! Failed");
1553 retry_core_init_cnt++;
1554 goto retry_core_init;
1555 }
1556
1557 NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!!");
1558 status =
1559 phNxpNciHal_send_ext_cmd(sizeof(nfcc_mode_set_on), nfcc_mode_set_on);
1560
1561 if (status != NFCSTATUS_SUCCESS) {
1562 NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!! Failed");
1563 retry_core_init_cnt++;
1564 goto retry_core_init;
1565 }
1566
1567 NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!!");
1568 status = phNxpNciHal_send_ext_cmd(sizeof(uicc_set_mode), uicc_set_mode);
1569 if (status != NFCSTATUS_SUCCESS) {
1570 NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!! Failed");
1571 retry_core_init_cnt++;
1572 goto retry_core_init;
1573 }
1574
1575 if (*(p_core_init_rsp_params + 1) == 1) // RF state is Discovery!!
1576 {
1577 NXPLOG_NCIHAL_E("Sending Set Screen ON State Command as raw packet!!");
1578 status =
1579 phNxpNciHal_send_ext_cmd(sizeof(set_screen_state), set_screen_state);
1580 if (status != NFCSTATUS_SUCCESS) {
1581 NXPLOG_NCIHAL_E(
1582 "Sending Set Screen ON State Command as raw packet!! Failed");
1583 retry_core_init_cnt++;
1584 goto retry_core_init;
1585 }
1586
1587 NXPLOG_NCIHAL_E("Sending discovery as raw packet!!");
1588 status = phNxpNciHal_send_ext_cmd(p_core_init_rsp_params[2],
1589 (uint8_t*)&p_core_init_rsp_params[3]);
1590 if (status != NFCSTATUS_SUCCESS) {
1591 NXPLOG_NCIHAL_E("Sending discovery as raw packet Failed");
1592 retry_core_init_cnt++;
1593 goto retry_core_init;
1594 }
1595
1596 } else {
1597 NXPLOG_NCIHAL_E("Sending Set Screen OFF State Command as raw packet!!");
1598 set_screen_state[3] = 0x01; // Screen OFF
1599 status =
1600 phNxpNciHal_send_ext_cmd(sizeof(set_screen_state), set_screen_state);
1601 if (status != NFCSTATUS_SUCCESS) {
1602 NXPLOG_NCIHAL_E(
1603 "Sending Set Screen OFF State Command as raw packet!! Failed");
1604 retry_core_init_cnt++;
1605 goto retry_core_init;
1606 }
1607 }
1608 NXPLOG_NCIHAL_E("Sending last command for Recovery ");
1609
1610 if (p_core_init_rsp_params[35] > 0) { // if length of last command is 0
1611 // then it doesn't need to send last
1612 // command.
1613 if (!(((p_core_init_rsp_params[36] == 0x21) &&
1614 (p_core_init_rsp_params[37] == 0x03)) &&
1615 (*(p_core_init_rsp_params + 1) == 1)) &&
1616 !((p_core_init_rsp_params[36] == 0x21) &&
1617 (p_core_init_rsp_params[37] == 0x06) &&
1618 (p_core_init_rsp_params[39] == 0x00) &&
1619 (*(p_core_init_rsp_params + 1) == 0x00)))
1620 // if last command is discovery and RF status is also discovery state,
1621 // then it doesn't need to execute or similarly
1622 // if the last command is deactivate to idle and RF status is also idle ,
1623 // no need to execute the command .
1624 {
1625 tmp_len = p_core_init_rsp_params[35];
1626
1627 /* Check for NXP ext before sending write */
1628 status = phNxpNciHal_write_ext(
1629 &tmp_len, (uint8_t*)&p_core_init_rsp_params[36],
1630 &nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
1631 if (status != NFCSTATUS_SUCCESS) {
1632 if (buffer) {
1633 free(buffer);
1634 buffer = NULL;
1635 }
1636 /* Do not send packet to PN54X, send response directly */
1637 msg.eMsgType = NCI_HAL_RX_MSG;
1638 msg.pMsgData = NULL;
1639 msg.Size = 0;
1640
1641 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1642 (phLibNfc_Message_t*)&msg);
1643 return NFCSTATUS_SUCCESS;
1644 }
1645
1646 p_core_init_rsp_params[35] = (uint8_t)tmp_len;
1647
1648 status = phNxpNciHal_send_ext_cmd(
1649 p_core_init_rsp_params[35], (uint8_t*)&p_core_init_rsp_params[36]);
1650 if (status != NFCSTATUS_SUCCESS) {
1651 NXPLOG_NCIHAL_E("Sending last command for Recovery Failed");
1652 retry_core_init_cnt++;
1653 goto retry_core_init;
1654 }
1655 }
1656 }
1657 }
1658
1659 retry_core_init_cnt = 0;
1660
1661 if (buffer) {
1662 free(buffer);
1663 buffer = NULL;
1664 }
1665 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1666 // initialize dummy FW recovery variables
1667 gRecFWDwnld = 0;
1668 gRecFwRetryCount = 0;
1669 #endif
1670 if (!((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)))
1671 phNxpNciHal_core_initialized_complete(status);
1672 else {
1673 invoke_callback:
1674 config_access = false;
1675 if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) {
1676 *p_core_init_rsp_params = 0;
1677 NXPLOG_NCIHAL_E("Invoking data callback!!");
1678 (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len,
1679 nxpncihal_ctrl.p_rx_data);
1680 }
1681 }
1682
1683 #ifdef PN547C2_CLOCK_SETTING
1684 if (isNxpConfigModified()) {
1685 updateNxpConfigTimestamp();
1686 }
1687 #endif
1688 return NFCSTATUS_SUCCESS;
1689 }
1690 #if (NFC_NXP_CHIP_TYPE != PN547C2)
1691 /******************************************************************************
1692 * Function phNxpNciHal_CheckRFCmdRespStatus
1693 *
1694 * Description This function is called to check the resp status of
1695 * RF update commands.
1696 *
1697 * Returns NFCSTATUS_SUCCESS if successful,
1698 * NFCSTATUS_INVALID_PARAMETER if parameter is inavlid
1699 * NFCSTATUS_FAILED if failed response
1700 *
1701 ******************************************************************************/
phNxpNciHal_CheckRFCmdRespStatus()1702 NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus() {
1703 NFCSTATUS status = NFCSTATUS_SUCCESS;
1704 static uint16_t INVALID_PARAM = 0x09;
1705 if ((nxpncihal_ctrl.rx_data_len > 0) && (nxpncihal_ctrl.p_rx_data[2] > 0)) {
1706 if (nxpncihal_ctrl.p_rx_data[3] == 0x09) {
1707 status = INVALID_PARAM;
1708 } else if (nxpncihal_ctrl.p_rx_data[3] != NFCSTATUS_SUCCESS) {
1709 status = NFCSTATUS_FAILED;
1710 }
1711 }
1712 return status;
1713 }
1714 /******************************************************************************
1715 * Function phNxpNciHalRFConfigCmdRecSequence
1716 *
1717 * Description This function is called to handle dummy FW recovery sequence
1718 * Whenever RF settings are failed to apply with invalid param
1719 * response, recovery mechanism includes dummy firmware
1720 *download
1721 * followed by firmware download and then config settings. The
1722 *dummy
1723 * firmware changes the major number of the firmware inside
1724 *NFCC.
1725 * Then actual firmware dowenload will be successful. This can
1726 *be
1727 * retried maximum three times.
1728 *
1729 * Returns Always returns NFCSTATUS_SUCCESS
1730 *
1731 ******************************************************************************/
phNxpNciHalRFConfigCmdRecSequence()1732 NFCSTATUS phNxpNciHalRFConfigCmdRecSequence() {
1733 NFCSTATUS status = NFCSTATUS_SUCCESS;
1734 uint16_t recFWState = 1;
1735 gRecFWDwnld = true;
1736 gRecFwRetryCount++;
1737 if (gRecFwRetryCount > 0x03) {
1738 NXPLOG_NCIHAL_D("Max retry count for RF config FW recovery exceeded ");
1739 gRecFWDwnld = false;
1740 return NFCSTATUS_FAILED;
1741 }
1742 do {
1743 status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
1744 phDnldNfc_InitImgInfo();
1745 if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion()) {
1746 fw_download_success = 0;
1747 status = phNxpNciHal_fw_download();
1748 if (status == NFCSTATUS_SUCCESS) {
1749 fw_download_success = 1;
1750 status = phTmlNfc_Read(
1751 nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN,
1752 (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
1753 if (status != NFCSTATUS_PENDING) {
1754 NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
1755 phTmlNfc_Shutdown();
1756 status = NFCSTATUS_FAILED;
1757 break;
1758 }
1759 } else {
1760 status = NFCSTATUS_FAILED;
1761 break;
1762 }
1763 }
1764 gRecFWDwnld = false;
1765 } while (recFWState--);
1766 gRecFWDwnld = false;
1767 return status;
1768 }
1769 #endif
1770 /******************************************************************************
1771 * Function phNxpNciHal_core_initialized_complete
1772 *
1773 * Description This function is called when phNxpNciHal_core_initialized
1774 * complete all proprietary command exchanges. This function
1775 * informs libnfc-nci about completion of core initialize
1776 * and result of that through callback.
1777 *
1778 * Returns void.
1779 *
1780 ******************************************************************************/
phNxpNciHal_core_initialized_complete(NFCSTATUS status)1781 static void phNxpNciHal_core_initialized_complete(NFCSTATUS status) {
1782 static phLibNfc_Message_t msg;
1783
1784 if (status == NFCSTATUS_SUCCESS) {
1785 msg.eMsgType = NCI_HAL_POST_INIT_CPLT_MSG;
1786 } else {
1787 msg.eMsgType = NCI_HAL_ERROR_MSG;
1788 }
1789 msg.pMsgData = NULL;
1790 msg.Size = 0;
1791
1792 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
1793 (phLibNfc_Message_t*)&msg);
1794
1795 return;
1796 }
1797
1798 /******************************************************************************
1799 * Function phNxpNciHal_pre_discover
1800 *
1801 * Description This function is called by libnfc-nci to perform any
1802 * proprietary exchange before RF discovery. When proprietary
1803 * exchange is over completion is informed to libnfc-nci
1804 * through phNxpNciHal_pre_discover_complete function.
1805 *
1806 * Returns It always returns NFCSTATUS_SUCCESS (0).
1807 *
1808 ******************************************************************************/
phNxpNciHal_pre_discover(void)1809 int phNxpNciHal_pre_discover(void) {
1810 /* Nothing to do here for initial version */
1811 return NFCSTATUS_SUCCESS;
1812 }
1813
1814 /******************************************************************************
1815 * Function phNxpNciHal_pre_discover_complete
1816 *
1817 * Description This function informs libnfc-nci about completion and
1818 * status of phNxpNciHal_pre_discover through callback.
1819 *
1820 * Returns void.
1821 *
1822 ******************************************************************************/
phNxpNciHal_pre_discover_complete(NFCSTATUS status)1823 static void phNxpNciHal_pre_discover_complete(NFCSTATUS status) {
1824 static phLibNfc_Message_t msg;
1825
1826 if (status == NFCSTATUS_SUCCESS) {
1827 msg.eMsgType = NCI_HAL_PRE_DISCOVER_CPLT_MSG;
1828 } else {
1829 msg.eMsgType = NCI_HAL_ERROR_MSG;
1830 }
1831 msg.pMsgData = NULL;
1832 msg.Size = 0;
1833
1834 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
1835
1836 return;
1837 }
1838
1839 /******************************************************************************
1840 * Function phNxpNciHal_close
1841 *
1842 * Description This function close the NFCC interface and free all
1843 * resources.This is called by libnfc-nci on NFC service stop.
1844 *
1845 * Returns Always return NFCSTATUS_SUCCESS (0).
1846 *
1847 ******************************************************************************/
phNxpNciHal_close(void)1848 int phNxpNciHal_close(void) {
1849 NFCSTATUS status;
1850 /*NCI_RESET_CMD*/
1851 static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
1852
1853 static uint8_t cmd_ce_disc_nci[] = {0x21, 0x03, 0x07, 0x03, 0x80,
1854 0x01, 0x81, 0x01, 0x82, 0x01};
1855
1856 if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
1857 NXPLOG_NCIHAL_E("phNxpNciHal_close is already closed, ignoring close");
1858 return NFCSTATUS_FAILED;
1859 }
1860 CONCURRENCY_LOCK();
1861 status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_disc_nci), cmd_ce_disc_nci);
1862 if (status != NFCSTATUS_SUCCESS) {
1863 NXPLOG_NCIHAL_E("CMD_CE_DISC_NCI: Failed");
1864 }
1865
1866 nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
1867
1868 status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
1869 if (status != NFCSTATUS_SUCCESS) {
1870 NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
1871 }
1872
1873 if (NULL != gpphTmlNfc_Context->pDevHandle) {
1874 phNxpNciHal_close_complete(NFCSTATUS_SUCCESS);
1875 /* Abort any pending read and write */
1876 status = phTmlNfc_ReadAbort();
1877 status = phTmlNfc_WriteAbort();
1878
1879 phOsalNfc_Timer_Cleanup();
1880
1881 status = phTmlNfc_Shutdown();
1882
1883 phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
1884
1885 memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
1886
1887 NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed");
1888 }
1889
1890 CONCURRENCY_UNLOCK();
1891
1892 phNxpNciHal_cleanup_monitor();
1893
1894 /* Return success always */
1895 return NFCSTATUS_SUCCESS;
1896 }
1897
1898 /******************************************************************************
1899 * Function phNxpNciHal_close_complete
1900 *
1901 * Description This function inform libnfc-nci about result of
1902 * phNxpNciHal_close.
1903 *
1904 * Returns void.
1905 *
1906 ******************************************************************************/
phNxpNciHal_close_complete(NFCSTATUS status)1907 void phNxpNciHal_close_complete(NFCSTATUS status) {
1908 static phLibNfc_Message_t msg;
1909
1910 if (status == NFCSTATUS_SUCCESS) {
1911 msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
1912 } else {
1913 msg.eMsgType = NCI_HAL_ERROR_MSG;
1914 }
1915 msg.pMsgData = NULL;
1916 msg.Size = 0;
1917
1918 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
1919
1920 return;
1921 }
1922 /******************************************************************************
1923 * Function phNxpNciHal_notify_i2c_fragmentation
1924 *
1925 * Description This function can be used by HAL to inform
1926 * libnfc-nci that i2c fragmentation is enabled/disabled
1927 *
1928 * Returns void.
1929 *
1930 ******************************************************************************/
phNxpNciHal_notify_i2c_fragmentation(void)1931 void phNxpNciHal_notify_i2c_fragmentation(void) {
1932 if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
1933 /*inform libnfc-nci that i2c fragmentation is enabled/disabled */
1934 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT,
1935 HAL_NFC_STATUS_OK);
1936 }
1937 }
1938 /******************************************************************************
1939 * Function phNxpNciHal_control_granted
1940 *
1941 * Description Called by libnfc-nci when NFCC control is granted to HAL.
1942 *
1943 * Returns Always returns NFCSTATUS_SUCCESS (0).
1944 *
1945 ******************************************************************************/
phNxpNciHal_control_granted(void)1946 int phNxpNciHal_control_granted(void) {
1947 /* Take the concurrency lock so no other calls from upper layer
1948 * will be allowed
1949 */
1950 CONCURRENCY_LOCK();
1951
1952 if (NULL != nxpncihal_ctrl.p_control_granted_cback) {
1953 (*nxpncihal_ctrl.p_control_granted_cback)();
1954 }
1955 /* At the end concurrency unlock so calls from upper layer will
1956 * be allowed
1957 */
1958 CONCURRENCY_UNLOCK();
1959 return NFCSTATUS_SUCCESS;
1960 }
1961
1962 /******************************************************************************
1963 * Function phNxpNciHal_request_control
1964 *
1965 * Description This function can be used by HAL to request control of
1966 * NFCC to libnfc-nci. When control is provided to HAL it is
1967 * notified through phNxpNciHal_control_granted.
1968 *
1969 * Returns void.
1970 *
1971 ******************************************************************************/
phNxpNciHal_request_control(void)1972 void phNxpNciHal_request_control(void) {
1973 if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
1974 /* Request Control of NCI Controller from NCI NFC Stack */
1975 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_REQUEST_CONTROL_EVT,
1976 HAL_NFC_STATUS_OK);
1977 }
1978
1979 return;
1980 }
1981
1982 /******************************************************************************
1983 * Function phNxpNciHal_release_control
1984 *
1985 * Description This function can be used by HAL to release the control of
1986 * NFCC back to libnfc-nci.
1987 *
1988 * Returns void.
1989 *
1990 ******************************************************************************/
phNxpNciHal_release_control(void)1991 void phNxpNciHal_release_control(void) {
1992 if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
1993 /* Release Control of NCI Controller to NCI NFC Stack */
1994 (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_RELEASE_CONTROL_EVT,
1995 HAL_NFC_STATUS_OK);
1996 }
1997
1998 return;
1999 }
2000
2001 /******************************************************************************
2002 * Function phNxpNciHal_power_cycle
2003 *
2004 * Description This function is called by libnfc-nci when power cycling is
2005 * performed. When processing is complete it is notified to
2006 * libnfc-nci through phNxpNciHal_power_cycle_complete.
2007 *
2008 * Returns Always return NFCSTATUS_SUCCESS (0).
2009 *
2010 ******************************************************************************/
phNxpNciHal_power_cycle(void)2011 int phNxpNciHal_power_cycle(void) {
2012 NXPLOG_NCIHAL_D("Power Cycle");
2013 NFCSTATUS status = NFCSTATUS_FAILED;
2014 if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
2015 NXPLOG_NCIHAL_D("Power Cycle failed due to hal status not open");
2016 return NFCSTATUS_FAILED;
2017 }
2018 status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
2019
2020 if (NFCSTATUS_SUCCESS == status) {
2021 NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
2022 } else {
2023 NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
2024 }
2025
2026 phNxpNciHal_power_cycle_complete(NFCSTATUS_SUCCESS);
2027 return NFCSTATUS_SUCCESS;
2028 }
2029
2030 /******************************************************************************
2031 * Function phNxpNciHal_power_cycle_complete
2032 *
2033 * Description This function is called to provide the status of
2034 * phNxpNciHal_power_cycle to libnfc-nci through callback.
2035 *
2036 * Returns void.
2037 *
2038 ******************************************************************************/
phNxpNciHal_power_cycle_complete(NFCSTATUS status)2039 static void phNxpNciHal_power_cycle_complete(NFCSTATUS status) {
2040 static phLibNfc_Message_t msg;
2041
2042 if (status == NFCSTATUS_SUCCESS) {
2043 msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
2044 } else {
2045 msg.eMsgType = NCI_HAL_ERROR_MSG;
2046 }
2047 msg.pMsgData = NULL;
2048 msg.Size = 0;
2049
2050 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &msg);
2051
2052 return;
2053 }
2054
2055 /******************************************************************************
2056 * Function phNxpNciHal_get_mw_eeprom
2057 *
2058 * Description This function is called to retreive data in mw eeprom area
2059 *
2060 * Returns NFCSTATUS.
2061 *
2062 ******************************************************************************/
phNxpNciHal_get_mw_eeprom(void)2063 static NFCSTATUS phNxpNciHal_get_mw_eeprom(void) {
2064 NFCSTATUS status = NFCSTATUS_SUCCESS;
2065 uint8_t retry_cnt = 0;
2066 static uint8_t get_mw_eeprom_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x0F};
2067 uint8_t bConfig;
2068
2069 retry_send_ext:
2070 if (retry_cnt > 3) {
2071 return NFCSTATUS_FAILED;
2072 }
2073
2074 phNxpNciMwEepromArea.isGetEepromArea = true;
2075 status =
2076 phNxpNciHal_send_ext_cmd(sizeof(get_mw_eeprom_cmd), get_mw_eeprom_cmd);
2077 if (status != NFCSTATUS_SUCCESS) {
2078 NXPLOG_NCIHAL_E("unable to get the mw eeprom data");
2079 phNxpNciMwEepromArea.isGetEepromArea = false;
2080 retry_cnt++;
2081 goto retry_send_ext;
2082 }
2083 phNxpNciMwEepromArea.isGetEepromArea = false;
2084
2085 if (phNxpNciMwEepromArea.p_rx_data[12]) {
2086 fw_download_success = 1;
2087 }
2088 return status;
2089 }
2090
2091 /******************************************************************************
2092 * Function phNxpNciHal_set_mw_eeprom
2093 *
2094 * Description This function is called to update data in mw eeprom area
2095 *
2096 * Returns void.
2097 *
2098 ******************************************************************************/
phNxpNciHal_set_mw_eeprom(void)2099 static NFCSTATUS phNxpNciHal_set_mw_eeprom(void) {
2100 NFCSTATUS status = NFCSTATUS_SUCCESS;
2101 uint8_t retry_cnt = 0;
2102 uint8_t set_mw_eeprom_cmd[39] = {0};
2103 uint8_t cmd_header[] = {0x20, 0x02, 0x24, 0x01, 0xA0, 0x0F, 0x20};
2104
2105 memcpy(set_mw_eeprom_cmd, cmd_header, sizeof(cmd_header));
2106 phNxpNciMwEepromArea.p_rx_data[12] = 0;
2107 memcpy(set_mw_eeprom_cmd + sizeof(cmd_header), phNxpNciMwEepromArea.p_rx_data,
2108 sizeof(phNxpNciMwEepromArea.p_rx_data));
2109
2110 retry_send_ext:
2111 if (retry_cnt > 3) {
2112 return NFCSTATUS_FAILED;
2113 }
2114
2115 status =
2116 phNxpNciHal_send_ext_cmd(sizeof(set_mw_eeprom_cmd), set_mw_eeprom_cmd);
2117 if (status != NFCSTATUS_SUCCESS) {
2118 NXPLOG_NCIHAL_E("unable to update the mw eeprom data");
2119 retry_cnt++;
2120 goto retry_send_ext;
2121 }
2122 return status;
2123 }
2124
2125 /******************************************************************************
2126 * Function phNxpNciHal_set_clock
2127 *
2128 * Description This function is called after successfull download
2129 * to apply the clock setting provided in config file
2130 *
2131 * Returns void.
2132 *
2133 ******************************************************************************/
phNxpNciHal_set_clock(void)2134 static void phNxpNciHal_set_clock(void) {
2135 NFCSTATUS status = NFCSTATUS_FAILED;
2136 int retryCount = 0;
2137
2138 retrySetclock:
2139 phNxpNciClock.isClockSet = true;
2140 if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) {
2141 static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x09, 0x02, 0xA0, 0x03,
2142 0x01, 0x11, 0xA0, 0x04, 0x01, 0x01};
2143 uint8_t param_clock_src = CLK_SRC_PLL;
2144 param_clock_src = param_clock_src << 3;
2145
2146 if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) {
2147 param_clock_src |= 0x00;
2148 } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) {
2149 param_clock_src |= 0x01;
2150 } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) {
2151 param_clock_src |= 0x02;
2152 } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) {
2153 param_clock_src |= 0x03;
2154 } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) {
2155 param_clock_src |= 0x04;
2156 } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) {
2157 param_clock_src |= 0x05;
2158 } else {
2159 NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
2160 param_clock_src = 0x11;
2161 }
2162
2163 set_clock_cmd[7] = param_clock_src;
2164 set_clock_cmd[11] = nxpprofile_ctrl.bTimeout;
2165 status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
2166 if (status != NFCSTATUS_SUCCESS) {
2167 NXPLOG_NCIHAL_E("PLL colck setting failed !!");
2168 }
2169 } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) {
2170 static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x05, 0x01,
2171 0xA0, 0x03, 0x01, 0x08};
2172 status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
2173 if (status != NFCSTATUS_SUCCESS) {
2174 NXPLOG_NCIHAL_E("XTAL colck setting failed !!");
2175 }
2176 } else {
2177 NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
2178 }
2179
2180 // Checking for SET CONFG SUCCESS, re-send the command if not.
2181 phNxpNciClock.isClockSet = false;
2182 if (phNxpNciClock.p_rx_data[3] != NFCSTATUS_SUCCESS) {
2183 if (retryCount++ < 3) {
2184 NXPLOG_NCIHAL_E("Set-clk failed retry again ");
2185 goto retrySetclock;
2186 } else {
2187 NXPLOG_NCIHAL_D("Set clk failed - max count = 0x%x exceeded ",
2188 retryCount);
2189 // NXPLOG_NCIHAL_E("Set Config is failed for Clock Due to
2190 // elctrical disturbances, aborting the NFC process");
2191 // abort ();
2192 }
2193 }
2194 }
2195
2196 /******************************************************************************
2197 * Function phNxpNciHal_check_clock_config
2198 *
2199 * Description This function is called after successfull download
2200 * to check if clock settings in config file and chip
2201 * is same
2202 *
2203 * Returns void.
2204 *
2205 ******************************************************************************/
phNxpNciHal_check_clock_config(void)2206 NFCSTATUS phNxpNciHal_check_clock_config(void) {
2207 NFCSTATUS status = NFCSTATUS_SUCCESS;
2208 uint8_t param_clock_src;
2209 static uint8_t get_clock_cmd[] = {0x20, 0x03, 0x07, 0x03, 0xA0,
2210 0x02, 0xA0, 0x03, 0xA0, 0x04};
2211 phNxpNciClock.isClockSet = true;
2212 phNxpNciHal_get_clk_freq();
2213 status = phNxpNciHal_send_ext_cmd(sizeof(get_clock_cmd), get_clock_cmd);
2214
2215 if (status != NFCSTATUS_SUCCESS) {
2216 NXPLOG_NCIHAL_E("unable to retrieve get_clk_src_sel");
2217 return status;
2218 }
2219 param_clock_src = check_config_parameter();
2220 if (phNxpNciClock.p_rx_data[12] == param_clock_src &&
2221 phNxpNciClock.p_rx_data[16] == nxpprofile_ctrl.bTimeout) {
2222 phNxpNciClock.issetConfig = false;
2223 } else {
2224 phNxpNciClock.issetConfig = true;
2225 }
2226 phNxpNciClock.isClockSet = false;
2227
2228 return status;
2229 }
2230
2231 /******************************************************************************
2232 * Function phNxpNciHal_china_tianjin_rf_setting
2233 *
2234 * Description This function is called to check RF Setting
2235 *
2236 * Returns Status.
2237 *
2238 ******************************************************************************/
phNxpNciHal_china_tianjin_rf_setting(void)2239 NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void) {
2240 NFCSTATUS status = NFCSTATUS_SUCCESS;
2241 int isfound = 0;
2242 int rf_enable = false;
2243 int rf_val = 0;
2244 int send_flag;
2245 uint8_t retry_cnt = 0;
2246 int enable_bit = 0;
2247 static uint8_t get_rf_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x85};
2248
2249 retry_send_ext:
2250 if (retry_cnt > 3) {
2251 return NFCSTATUS_FAILED;
2252 }
2253 send_flag = true;
2254 phNxpNciRfSet.isGetRfSetting = true;
2255 status = phNxpNciHal_send_ext_cmd(sizeof(get_rf_cmd), get_rf_cmd);
2256 if (status != NFCSTATUS_SUCCESS) {
2257 NXPLOG_NCIHAL_E("unable to get the RF setting");
2258 phNxpNciRfSet.isGetRfSetting = false;
2259 retry_cnt++;
2260 goto retry_send_ext;
2261 }
2262 phNxpNciRfSet.isGetRfSetting = false;
2263 if (phNxpNciRfSet.p_rx_data[3] != 0x00) {
2264 NXPLOG_NCIHAL_E("GET_CONFIG_RSP is FAILED for CHINA TIANJIN");
2265 return status;
2266 }
2267 rf_val = phNxpNciRfSet.p_rx_data[10];
2268 isfound = (GetNxpNumValue(NAME_NXP_CHINA_TIANJIN_RF_ENABLED,
2269 (void*)&rf_enable, sizeof(rf_enable)));
2270 if (isfound > 0) {
2271 enable_bit = rf_val & 0x40;
2272 if ((enable_bit != 0x40) && (rf_enable == 1)) {
2273 phNxpNciRfSet.p_rx_data[10] |= 0x40; // Enable if it is disabled
2274 } else if ((enable_bit == 0x40) && (rf_enable == 0)) {
2275 phNxpNciRfSet.p_rx_data[10] &= 0xBF; // Disable if it is Enabled
2276 } else {
2277 send_flag = false; // No need to change in RF setting
2278 }
2279
2280 if (send_flag == true) {
2281 static uint8_t set_rf_cmd[] = {0x20, 0x02, 0x08, 0x01, 0xA0, 0x85,
2282 0x04, 0x50, 0x08, 0x68, 0x00};
2283 memcpy(&set_rf_cmd[4], &phNxpNciRfSet.p_rx_data[5], 7);
2284 status = phNxpNciHal_send_ext_cmd(sizeof(set_rf_cmd), set_rf_cmd);
2285 if (status != NFCSTATUS_SUCCESS) {
2286 NXPLOG_NCIHAL_E("unable to set the RF setting");
2287 retry_cnt++;
2288 goto retry_send_ext;
2289 }
2290 }
2291 }
2292
2293 return status;
2294 }
2295
check_config_parameter()2296 int check_config_parameter() {
2297 NFCSTATUS status = NFCSTATUS_FAILED;
2298 uint8_t param_clock_src = CLK_SRC_PLL;
2299 if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL) {
2300 param_clock_src = param_clock_src << 3;
2301
2302 if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ) {
2303 param_clock_src |= 0x00;
2304 } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ) {
2305 param_clock_src |= 0x01;
2306 } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ) {
2307 param_clock_src |= 0x02;
2308 } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ) {
2309 param_clock_src |= 0x03;
2310 } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ) {
2311 param_clock_src |= 0x04;
2312 } else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ) {
2313 param_clock_src |= 0x05;
2314 } else {
2315 NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
2316 param_clock_src = 0x11;
2317 }
2318 } else if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL) {
2319 param_clock_src = 0x08;
2320
2321 } else {
2322 NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
2323 }
2324 return param_clock_src;
2325 }
2326 /******************************************************************************
2327 * Function phNxpNciHal_enable_i2c_fragmentation
2328 *
2329 * Description This function is called to process the response status
2330 * and print the status byte.
2331 *
2332 * Returns void.
2333 *
2334 ******************************************************************************/
phNxpNciHal_enable_i2c_fragmentation()2335 void phNxpNciHal_enable_i2c_fragmentation() {
2336 NFCSTATUS status = NFCSTATUS_FAILED;
2337 static uint8_t fragmentation_enable_config_cmd[] = {0x20, 0x02, 0x05, 0x01,
2338 0xA0, 0x05, 0x01, 0x10};
2339 int isfound = 0;
2340 long i2c_status = 0x00;
2341 long config_i2c_vlaue = 0xff;
2342 /*NCI_RESET_CMD*/
2343 static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
2344 /*NCI_INIT_CMD*/
2345 static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
2346 static uint8_t get_i2c_fragmentation_cmd[] = {0x20, 0x03, 0x03,
2347 0x01, 0xA0, 0x05};
2348 isfound = (GetNxpNumValue(NAME_NXP_I2C_FRAGMENTATION_ENABLED,
2349 (void*)&i2c_status, sizeof(i2c_status)));
2350 status = phNxpNciHal_send_ext_cmd(sizeof(get_i2c_fragmentation_cmd),
2351 get_i2c_fragmentation_cmd);
2352 if (status != NFCSTATUS_SUCCESS) {
2353 NXPLOG_NCIHAL_E("unable to retrieve get_i2c_fragmentation_cmd");
2354 } else {
2355 if (nxpncihal_ctrl.p_rx_data[8] == 0x10) {
2356 config_i2c_vlaue = 0x01;
2357 phNxpNciHal_notify_i2c_fragmentation();
2358 phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
2359 } else if (nxpncihal_ctrl.p_rx_data[8] == 0x00) {
2360 config_i2c_vlaue = 0x00;
2361 }
2362 if (config_i2c_vlaue == i2c_status) {
2363 NXPLOG_NCIHAL_E("i2c_fragmentation_status existing");
2364 } else {
2365 if (i2c_status == 0x01) {
2366 /* NXP I2C fragmenation enabled*/
2367 status =
2368 phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd),
2369 fragmentation_enable_config_cmd);
2370 if (status != NFCSTATUS_SUCCESS) {
2371 NXPLOG_NCIHAL_E("NXP fragmentation enable failed");
2372 }
2373 } else if (i2c_status == 0x00 || config_i2c_vlaue == 0xff) {
2374 fragmentation_enable_config_cmd[7] = 0x00;
2375 /* NXP I2C fragmentation disabled*/
2376 status =
2377 phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd),
2378 fragmentation_enable_config_cmd);
2379 if (status != NFCSTATUS_SUCCESS) {
2380 NXPLOG_NCIHAL_E("NXP fragmentation disable failed");
2381 }
2382 }
2383 status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
2384 if (status != NFCSTATUS_SUCCESS) {
2385 NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
2386 }
2387 status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
2388 if (status != NFCSTATUS_SUCCESS) {
2389 NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
2390 } else if (i2c_status == 0x01) {
2391 phNxpNciHal_notify_i2c_fragmentation();
2392 phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
2393 }
2394 }
2395 }
2396 }
2397 /******************************************************************************
2398 * Function phNxpNciHal_check_factory_reset
2399 *
2400 * Description This function is called at init time to check
2401 * the presence of ese related info. If file are not
2402 * present set the SWP_INT_SESSION_ID_CFG to FF to
2403 * force the NFCEE to re-run its initialization sequence.
2404 *
2405 * Returns void.
2406 *
2407 ******************************************************************************/
phNxpNciHal_check_factory_reset(void)2408 static void phNxpNciHal_check_factory_reset(void) {
2409 struct stat st;
2410 int ret = 0;
2411 NFCSTATUS status = NFCSTATUS_FAILED;
2412 const char config_eseinfo_path[] = "/data/nfc/nfaStorage.bin1";
2413 static uint8_t reset_ese_session_identity_set[] = {
2414 0x20, 0x02, 0x17, 0x02, 0xA0, 0xEA, 0x08, 0xFF, 0xFF,
2415 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xEB, 0x08,
2416 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2417 #ifdef PN547C2_FACTORY_RESET_DEBUG
2418 static uint8_t reset_ese_session_identity[] = {0x20, 0x03, 0x05, 0x02,
2419 0xA0, 0xEA, 0xA0, 0xEB};
2420 #endif
2421 if (stat(config_eseinfo_path, &st) == -1) {
2422 NXPLOG_NCIHAL_D("%s file not present = %s", __func__, config_eseinfo_path);
2423 ret = -1;
2424 } else {
2425 ret = 0;
2426 }
2427
2428 if (ret == -1) {
2429 #ifdef PN547C2_FACTORY_RESET_DEBUG
2430 /* NXP ACT Proprietary Ext */
2431 status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity),
2432 reset_ese_session_identity);
2433 if (status != NFCSTATUS_SUCCESS) {
2434 NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed");
2435 }
2436 #endif
2437 status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity_set),
2438 reset_ese_session_identity_set);
2439 if (status != NFCSTATUS_SUCCESS) {
2440 NXPLOG_NCIHAL_E("NXP reset_ese_session_identity_set command failed");
2441 }
2442 #ifdef PN547C2_FACTORY_RESET_DEBUG
2443 /* NXP ACT Proprietary Ext */
2444 status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity),
2445 reset_ese_session_identity);
2446 if (status != NFCSTATUS_SUCCESS) {
2447 NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed");
2448 }
2449 #endif
2450 }
2451 }
2452
2453 /******************************************************************************
2454 * Function phNxpNciHal_print_res_status
2455 *
2456 * Description This function is called to process the response status
2457 * and print the status byte.
2458 *
2459 * Returns void.
2460 *
2461 ******************************************************************************/
phNxpNciHal_print_res_status(uint8_t * p_rx_data,uint16_t * p_len)2462 static void phNxpNciHal_print_res_status(uint8_t* p_rx_data, uint16_t* p_len) {
2463 static uint8_t response_buf[][30] = {"STATUS_OK",
2464 "STATUS_REJECTED",
2465 "STATUS_RF_FRAME_CORRUPTED",
2466 "STATUS_FAILED",
2467 "STATUS_NOT_INITIALIZED",
2468 "STATUS_SYNTAX_ERROR",
2469 "STATUS_SEMANTIC_ERROR",
2470 "RFU",
2471 "RFU",
2472 "STATUS_INVALID_PARAM",
2473 "STATUS_MESSAGE_SIZE_EXCEEDED",
2474 "STATUS_UNDEFINED"};
2475 int status_byte;
2476 if (p_rx_data[0] == 0x40 && (p_rx_data[1] == 0x02 || p_rx_data[1] == 0x03)) {
2477 if (p_rx_data[2] && p_rx_data[3] <= 10) {
2478 status_byte = p_rx_data[CORE_RES_STATUS_BYTE];
2479 NXPLOG_NCIHAL_D("%s: response status =%s", __func__,
2480 response_buf[status_byte]);
2481 } else {
2482 NXPLOG_NCIHAL_D("%s: response status =%s", __func__, response_buf[11]);
2483 }
2484 if (phNxpNciClock.isClockSet) {
2485 int i;
2486 for (i = 0; i < *p_len; i++) {
2487 phNxpNciClock.p_rx_data[i] = p_rx_data[i];
2488 }
2489 }
2490
2491 else if (phNxpNciRfSet.isGetRfSetting) {
2492 int i;
2493 for (i = 0; i < *p_len; i++) {
2494 phNxpNciRfSet.p_rx_data[i] = p_rx_data[i];
2495 // NXPLOG_NCIHAL_D("%s: response status =0x%x",__func__,p_rx_data[i]);
2496 }
2497 } else if (phNxpNciMwEepromArea.isGetEepromArea) {
2498 int i;
2499 for (i = 8; i < *p_len; i++) {
2500 phNxpNciMwEepromArea.p_rx_data[i - 8] = p_rx_data[i];
2501 }
2502 }
2503 }
2504
2505 if (p_rx_data[2] && (config_access == true)) {
2506 if (p_rx_data[3] != NFCSTATUS_SUCCESS) {
2507 NXPLOG_NCIHAL_W("Invalid Data from config file . Aborting..");
2508 phNxpNciHal_close();
2509 }
2510 }
2511 }
2512
2513 #if (NFC_NXP_CHIP_TYPE == PN548C2)
phNxpNciHal_core_reset_recovery()2514 NFCSTATUS phNxpNciHal_core_reset_recovery() {
2515 NFCSTATUS status = NFCSTATUS_FAILED;
2516
2517 uint8_t buffer[260];
2518 long bufflen = 260;
2519
2520 /*NCI_INIT_CMD*/
2521 static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
2522 /*NCI_RESET_CMD*/
2523 static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01,
2524 0x00}; // keep configuration
2525
2526 /* reset config cache */
2527 uint8_t retry_core_init_cnt = 0;
2528
2529 if (discovery_cmd_len == 0) {
2530 goto FAILURE;
2531 }
2532 NXPLOG_NCIHAL_D("%s: recovery", __func__);
2533
2534 retry_core_init:
2535 if (retry_core_init_cnt > 3) {
2536 goto FAILURE;
2537 }
2538
2539 status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
2540 if (status != NFCSTATUS_SUCCESS) {
2541 NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
2542 goto FAILURE;
2543 }
2544 status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
2545 if ((status != NFCSTATUS_SUCCESS) &&
2546 (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT)) {
2547 retry_core_init_cnt++;
2548 goto retry_core_init;
2549 } else if (status != NFCSTATUS_SUCCESS) {
2550 NXPLOG_NCIHAL_D("NCI_CORE_RESET: Failed");
2551 retry_core_init_cnt++;
2552 goto retry_core_init;
2553 }
2554 status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
2555 if (status != NFCSTATUS_SUCCESS) {
2556 NXPLOG_NCIHAL_D("NCI_CORE_INIT : Failed");
2557 retry_core_init_cnt++;
2558 goto retry_core_init;
2559 }
2560
2561 status = phNxpNciHal_send_ext_cmd(discovery_cmd_len, discovery_cmd);
2562 if (status != NFCSTATUS_SUCCESS) {
2563 NXPLOG_NCIHAL_D("RF_DISCOVERY : Failed");
2564 retry_core_init_cnt++;
2565 goto retry_core_init;
2566 }
2567
2568 return NFCSTATUS_SUCCESS;
2569 FAILURE:
2570 abort();
2571 }
2572
phNxpNciHal_discovery_cmd_ext(uint8_t * p_cmd_data,uint16_t cmd_len)2573 void phNxpNciHal_discovery_cmd_ext(uint8_t* p_cmd_data, uint16_t cmd_len) {
2574 NXPLOG_NCIHAL_D("phNxpNciHal_discovery_cmd_ext");
2575 if (cmd_len > 0 && cmd_len <= sizeof(discovery_cmd)) {
2576 memcpy(discovery_cmd, p_cmd_data, cmd_len);
2577 discovery_cmd_len = cmd_len;
2578 }
2579 }
2580 #endif
2581