• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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