• 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 #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