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