1 /******************************************************************************
2 *
3 * Copyright 2018-2020, 2023 NXP
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /*
20 * DAL spi port implementation for linux
21 *
22 * Project: Trusted ESE Linux
23 *
24 */
25
26 #include "EseSpiTransport.h"
27
28 #define LOG_TAG "NxpEseHal"
29 #include <errno.h>
30 #include <ese_config.h>
31 #include <ese_logs.h>
32 #include <fcntl.h>
33 #include <hardware/nfc.h>
34 #include <log/log.h>
35 #include <phEseStatus.h>
36 #include <phNxpEsePal.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/ioctl.h>
40 #include <unistd.h>
41
42 #include "NfcAdaptation.h"
43 #include "hal_nxpese.h"
44 #include "phNxpEse_Api.h"
45
46 #define MAX_RETRY_CNT 10
47 #define HAL_NFC_SPI_DWP_SYNC 21
48 #define USE_COLD_RESET 0x00
49
50 extern int omapi_status;
51
52 static int rf_status;
53 #if (NFC_NXP_ESE_VER == JCOP_VER_5_x)
54 eseIoctlData_t eseioctldata;
55 #endif
56 // Default max retry count for SPI CLT write blocked in secs
57 static unsigned long int gsMaxSpiWriteRetryCnt = 10;
58 #if (NFC_NXP_ESE_VER == JCOP_VER_4_0)
59 static ESESTATUS phNxpEse_spiIoctl_legacy(uint64_t ioctlType, void* p_data);
60 #endif
61
62 /*******************************************************************************
63 **
64 ** Function phPalEse_spi_close
65 **
66 ** Description Closes PN547 device
67 **
68 ** Parameters pDevHandle - device handle
69 **
70 ** Returns None
71 **
72 *******************************************************************************/
Close(void * pDevHandle)73 void EseSpiTransport::Close(void* pDevHandle) {
74 if (NULL != pDevHandle) {
75 close((intptr_t)pDevHandle);
76 }
77 return;
78 }
79
80 #ifdef NXP_BOOTTIME_UPDATE
81 /*******************************************************************************
82 **
83 ** Function phNxpEse_spiIoctl
84 **
85 ** Description Perform cross HAL IOCTL functionality
86 **
87 ** Parameters ioctlType, input data
88 **
89 ** Returns SUCCESS/FAIL
90 **
91 *******************************************************************************/
phNxpEse_spiIoctl(uint64_t ioctlType,void * p_data)92 ESESTATUS phNxpEse_spiIoctl(uint64_t ioctlType, void* p_data) {
93 ESESTATUS status = ESESTATUS_SUCCESS;
94 if (!p_data) {
95 NXP_LOG_ESE_E("halimpl phNxpEse_spiIoctl p_data is null ioctltyp: %ld",
96 (long)ioctlType);
97 return ESESTATUS_FAILED;
98 }
99 #if (NFC_NXP_ESE_VER == JCOP_VER_5_x)
100 ese_nxp_IoctlInOutData_t* inpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
101 switch (ioctlType) {
102 case HAL_ESE_IOCTL_RF_STATUS_UPDATE:
103 rf_status = inpOutData->inp.data.nxpCmd.p_cmd[0];
104 if (rf_status == 1) {
105 NXP_LOG_ESE_D(
106 "******************RF IS ON*************************************");
107 } else {
108 NXP_LOG_ESE_D(
109 "******************RF IS OFF*************************************");
110 }
111 break;
112 default:
113 NXP_LOG_ESE_D("Invalid IOCTL type");
114 break;
115 }
116 #endif
117 #if (NFC_NXP_ESE_VER == JCOP_VER_4_0)
118 status = phNxpEse_spiIoctl_legacy(ioctlType, p_data);
119 #endif
120 return status;
121 }
122 #endif
123
124 #if (NFC_NXP_ESE_VER == JCOP_VER_4_0)
125 /*******************************************************************************
126 **
127 ** Function phNxpEse_spiIoctl_legacy
128 **
129 ** Description Perform cross HAL IOCTL functionality
130 **
131 ** Parameters ioctlType, input data
132 **
133 ** Returns SUCCESS/FAIL
134 **
135 *******************************************************************************/
phNxpEse_spiIoctl_legacy(uint64_t ioctlType,void * p_data)136 static ESESTATUS phNxpEse_spiIoctl_legacy(uint64_t ioctlType, void* p_data) {
137 ese_nxp_IoctlInOutData_t* inpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
138 switch (ioctlType) {
139 case HAL_ESE_IOCTL_RF_STATUS_UPDATE:
140
141 rf_status = inpOutData->inp.data.nxpCmd.p_cmd[0];
142 if (rf_status == 1) {
143 NXP_LOG_ESE_D(
144 "******************RF IS ON*************************************");
145 } else {
146 NXP_LOG_ESE_D(
147 "******************RF IS OFF*************************************");
148 }
149 break;
150 default:
151 NXP_LOG_ESE_D("Invalid IOCTL type");
152 break;
153 }
154 return ESESTATUS_SUCCESS;
155 }
156 #endif
157
158 /*******************************************************************************
159 **
160 ** Function OpenAndConfigure
161 **
162 ** Description Open and configure pn547 device
163 **
164 ** Parameters pConfig - hardware information
165 ** pLinkHandle - device handle
166 **
167 ** Returns ESE status:
168 ** ESESTATUS_SUCCESS - open_and_configure operation
169 *success
170 ** ESESTATUS_INVALID_DEVICE - device open operation failure
171 **
172 *******************************************************************************/
OpenAndConfigure(pphPalEse_Config_t pConfig)173 ESESTATUS EseSpiTransport::OpenAndConfigure(pphPalEse_Config_t pConfig) {
174 int nHandle;
175 int retryCnt = 0;
176 ALOGD("NxpEse EseSpiTransport::OpenAndConfigure 1");
177 if (EseConfig::hasKey(NAME_NXP_SOF_WRITE)) {
178 mConfigSofWrite = EseConfig::getUnsigned(NAME_NXP_SOF_WRITE);
179 NXP_LOG_ESE_D("NXP_SOF_WRITE value from config file = %ld",
180 mConfigSofWrite);
181 }
182 if (EseConfig::hasKey(NAME_NXP_SPI_WRITE_TIMEOUT)) {
183 mConfigSpiWriteTimeout = EseConfig::getUnsigned(NAME_NXP_SPI_WRITE_TIMEOUT);
184 NXP_LOG_ESE_D("NXP_SPI_WRITE_TIMEOUT value from config file = %ld",
185 mConfigSpiWriteTimeout);
186 }
187 /* Read eSE cold reset interface from ese config file */
188 if (EseConfig::hasKey(NAME_NXP_P61_COLD_RESET_INTERFACE)) {
189 mConfigColdResetIntf =
190 EseConfig::getUnsigned(NAME_NXP_P61_COLD_RESET_INTERFACE);
191 NXP_LOG_ESE_D("mConfigColdResetIntf value from config file = %ld",
192 mConfigColdResetIntf);
193 } else {
194 mConfigColdResetIntf = 0x01; /* Default interface is NFC HAL */
195 NXP_LOG_ESE_D("mConfigColdResetIntf: Default value ");
196 }
197 /* Read eSE GPIO reset config */
198 if (EseConfig::hasKey(NAME_NXP_ESE_GPIO_RESET)) {
199 mConfigGpioReset = EseConfig::getUnsigned(NAME_NXP_ESE_GPIO_RESET);
200 NXP_LOG_ESE_D("mConfigGpioReset value from config file = %ld",
201 mConfigGpioReset);
202 } else {
203 mConfigGpioReset = USE_COLD_RESET;
204 NXP_LOG_ESE_D("mConfigGpioReset: Default value ");
205 }
206 NXP_LOG_ESE_D("Opening port=%s\n", pConfig->pDevName);
207 /* open port */
208 retry:
209 nHandle = open((char const*)pConfig->pDevName, O_RDWR);
210 if (nHandle < 0) {
211 NXP_LOG_ESE_E("%s : failed errno = 0x%x, retval %x", __FUNCTION__, errno,
212 nHandle);
213
214 if ((errno == -EBUSY) || (errno == EBUSY)) {
215 if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
216 phPalEse_sleep(100 * 1000); // 100ms delay
217 return ESESTATUS_DRIVER_BUSY;
218 } else {
219 retryCnt++;
220 NXP_LOG_ESE_E("Retry open eSE driver, retry cnt : %d", retryCnt);
221 if (retryCnt < MAX_RETRY_CNT) {
222 phPalEse_sleep(1000000);
223 goto retry;
224 }
225 }
226 }
227 NXP_LOG_ESE_E("_spi_open() Failed: retval %x", nHandle);
228 pConfig->pDevHandle = NULL;
229 return ESESTATUS_INVALID_DEVICE;
230 }
231 NXP_LOG_ESE_D("eSE driver opened :: fd = [%d]", nHandle);
232 pConfig->pDevHandle = (void*)((intptr_t)nHandle);
233 return ESESTATUS_SUCCESS;
234 }
235
236 /*******************************************************************************
237 **
238 ** Function Read
239 **
240 ** Description Reads requested number of bytes from pn547 device into given
241 *buffer
242 **
243 ** Parameters pDevHandle - valid device handle
244 ** pBuffer - buffer for read data
245 ** nNbBytesToRead - number of bytes requested to be read
246 **
247 ** Returns numRead - number of successfully read bytes
248 ** -1 - read operation failure
249 **
250 *******************************************************************************/
Read(void * pDevHandle,uint8_t * pBuffer,int nNbBytesToRead)251 int EseSpiTransport::Read(void* pDevHandle, uint8_t* pBuffer,
252 int nNbBytesToRead) {
253 int ret = -1;
254 ret = read((intptr_t)pDevHandle, (void*)pBuffer, (nNbBytesToRead));
255 return ret;
256 }
257
258 /*******************************************************************************
259 **
260 ** Function Write
261 **
262 ** Description Writes requested number of bytes from given buffer into
263 *pn547 device
264 **
265 ** Parameters pDevHandle - valid device handle
266 ** pBuffer - buffer for read data
267 ** nNbBytesToWrite - number of bytes requested to be written
268 **
269 ** Returns numWrote - number of successfully written bytes
270 ** -1 - write operation failure
271 **
272 *******************************************************************************/
Write(void * pDevHandle,uint8_t * pBuffer,int nNbBytesToWrite)273 int EseSpiTransport::Write(void* pDevHandle, uint8_t* pBuffer,
274 int nNbBytesToWrite) {
275 int ret = -1;
276 int numWrote = 0;
277 unsigned long int retryCount = 0;
278 if (NULL == pDevHandle) {
279 NXP_LOG_ESE_E("phPalEse_spi_write: received pDevHandle=NULL");
280 return -1;
281 }
282 if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
283 if (mConfigSofWrite == 1) {
284 /* Appending SOF for SPI write */
285 pBuffer[0] = SEND_PACKET_SOF;
286 } else {
287 /* Do Nothing */
288 }
289 }
290 NXP_LOG_ESE_D("NXP_SPI_WRITE_TIMEOUT value is... : %ld secs",
291 mConfigSpiWriteTimeout);
292 if (mConfigSpiWriteTimeout > 0) {
293 gsMaxSpiWriteRetryCnt = mConfigSpiWriteTimeout;
294 } else {
295 /* Do Nothing */
296 }
297
298 while (numWrote < nNbBytesToWrite) {
299 // usleep(5000);
300 if (rf_status == 0) {
301 ret = write((intptr_t)pDevHandle, pBuffer + numWrote,
302 nNbBytesToWrite - numWrote);
303 } else {
304 ret = -1;
305 }
306 if (ret > 0) {
307 numWrote += ret;
308 } else if (ret == 0) {
309 NXP_LOG_ESE_E("_spi_write() EOF");
310 return -1;
311 } else {
312 NXP_LOG_ESE_E("_spi_write() errno : %x", errno);
313 NXP_LOG_ESE_D("rf_status value is %d", rf_status);
314 if ((errno == EINTR || errno == EAGAIN || rf_status == 1) &&
315 (retryCount < gsMaxSpiWriteRetryCnt)) {
316 /*Configure retry count or timeout here,now its configured for 2*10
317 * secs*/
318 if (retryCount > gsMaxSpiWriteRetryCnt) {
319 ret = -1;
320 break;
321 }
322
323 retryCount++;
324 /* 5ms delay to give ESE wake up delay */
325 phPalEse_sleep(1000 * (GET_WAKE_UP_DELAY()));
326 NXP_LOG_ESE_E("_spi_write() failed. Going to retry, counter:%ld !",
327 retryCount);
328 continue;
329 }
330 return -1;
331 }
332 }
333 return numWrote;
334 }
335
336 /*******************************************************************************
337 **
338 ** Function Ioctl
339 **
340 ** Description Exposed ioctl by p61 spi driver
341 **
342 ** Parameters pDevHandle - valid device handle
343 ** level - reset level
344 **
345 ** Returns 0 - ioctl operation success
346 ** -1 - ioctl operation failure
347 **
348 *******************************************************************************/
Ioctl(phPalEse_ControlCode_t eControlCode,void * pDevHandle,long level)349 ESESTATUS EseSpiTransport::Ioctl(phPalEse_ControlCode_t eControlCode,
350 void* pDevHandle, long level) {
351 ESESTATUS ret = ESESTATUS_IOCTL_FAILED;
352 int retioctl = 0x00;
353 #if (NFC_NXP_ESE_VER == JCOP_VER_5_x)
354 ese_nxp_IoctlInOutData_t inpOutData;
355 inpOutData.inp.level = level;
356 NfcAdaptation& pNfcAdapt = NfcAdaptation::GetInstance();
357 #endif
358 NXP_LOG_ESE_D("phPalEse_spi_ioctl(), ioctl %x , level %lx", eControlCode,
359 level);
360 if (NULL == pDevHandle) {
361 if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
362 return ESESTATUS_IOCTL_FAILED;
363 }
364 }
365 switch (eControlCode) {
366 case phPalEse_e_ResetDevice:
367 if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
368 ret = ESESTATUS_SUCCESS;
369 } else {
370 ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_PWR, level);
371 }
372 break;
373
374 case phPalEse_e_EnableLog:
375 if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
376 ret = ESESTATUS_SUCCESS;
377 } else {
378 ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_DBG, level);
379 }
380 break;
381
382 case phPalEse_e_EnablePollMode:
383 if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
384 ret = ESESTATUS_SUCCESS;
385 } else {
386 ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_POLL, level);
387 }
388 break;
389 case phPalEse_e_SetSecureMode:
390 ret =
391 (ESESTATUS)ioctl((intptr_t)pDevHandle, ESE_SET_TRUSTED_ACCESS, level);
392 if (0x00 <= ret) {
393 ret = ESESTATUS_SUCCESS;
394 }
395 break;
396 case phPalEse_e_ChipRst:
397 if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
398 if (level == 5) { // SPI driver communication part
399 if (!mConfigColdResetIntf) { // Call the driver IOCTL
400 unsigned int cmd = ESE_PERFORM_COLD_RESET;
401 if ((mConfigGpioReset == 0x01) &&
402 ((GET_CHIP_OS_VERSION() == OS_VERSION_8_9))) {
403 cmd = P61_SET_PWR;
404 }
405 retioctl = ioctl((intptr_t)pDevHandle, cmd, level);
406 if (0x00 <= retioctl) {
407 ret = ESESTATUS_SUCCESS;
408 }
409 } else {
410 if ((NFC_NXP_ESE_VER == JCOP_VER_5_x) &&
411 (GET_CHIP_OS_VERSION() != OS_VERSION_8_9)) {
412 // Nfc Driver communication part
413 pNfcAdapt.Initialize();
414 ret = pNfcAdapt.resetEse(level);
415 } else {
416 NXP_LOG_ESE_E("%s: Not supported", __func__);
417 ret = ESESTATUS_SUCCESS;
418 }
419 }
420 } else {
421 ret = ESESTATUS_SUCCESS;
422 }
423 } else {
424 ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_SPM_PWR, level);
425 }
426 break;
427 case phPalEse_e_ResetProtection:
428 if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
429 retioctl = ioctl((intptr_t)pDevHandle, PERFORM_RESET_PROTECTION, level);
430 if (0x00 <= retioctl) {
431 ret = ESESTATUS_SUCCESS;
432 } else {
433 NXP_LOG_ESE_E("phPalEse_e_ResetProtection ioctl failed status :%x !",
434 retioctl);
435 }
436 }
437 break;
438 case phPalEse_e_EnableThroughputMeasurement:
439 if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
440 ret = ESESTATUS_SUCCESS;
441 } else {
442 ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_THROUGHPUT, level);
443 }
444 break;
445
446 case phPalEse_e_SetPowerScheme:
447 if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
448 ret = ESESTATUS_SUCCESS;
449 } else {
450 ret =
451 (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_POWER_SCHEME, level);
452 }
453 break;
454
455 case phPalEse_e_GetSPMStatus:
456 if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
457 ret = ESESTATUS_SUCCESS;
458 } else {
459 ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_GET_SPM_STATUS, level);
460 }
461 break;
462
463 case phPalEse_e_GetEseAccess:
464 if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
465 ret = ESESTATUS_SUCCESS;
466 } else {
467 ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_GET_ESE_ACCESS, level);
468 }
469 break;
470 case phPalEse_e_SetJcopDwnldState:
471 if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
472 ret = ESESTATUS_SUCCESS;
473 } else {
474 ret =
475 (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_DWNLD_STATUS, level);
476 }
477 break;
478 case phPalEse_e_DisablePwrCntrl:
479 ret = ESESTATUS_SUCCESS;
480 break;
481 default:
482 ret = ESESTATUS_IOCTL_FAILED;
483 break;
484 }
485 NXP_LOG_ESE_D("Exit phPalEse_spi_ioctl : ret = %d errno = %d", ret, errno);
486 return (ESESTATUS)ret;
487 }
488