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