1 /******************************************************************************
2  *
3  *  Copyright 2018 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 #define LOG_TAG "NxpEseHal"
26 #include <log/log.h>
27 
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <stdlib.h>
31 #include <sys/ioctl.h>
32 #include <unistd.h>
33 
34 #include <ese_config.h>
35 #include <hardware/nfc.h>
36 #include <phEseStatus.h>
37 #include <phNxpEsePal.h>
38 #include <phNxpEsePal_spi.h>
39 #include <string.h>
40 #include "NfcAdaptation.h"
41 #include "hal_nxpese.h"
42 #include "phNxpEse_Api.h"
43 
44 #define MAX_RETRY_CNT 10
45 #define HAL_NFC_SPI_DWP_SYNC 21
46 #define RF_ON 1
47 
48 extern int omapi_status;
49 extern bool ese_debug_enabled;
50 
51 static int rf_status;
52 unsigned long int configNum1, configNum2;
53 // Default max retry count for SPI CLT write blocked in secs
54 static const uint8_t DEFAULT_MAX_SPI_WRITE_RETRY_COUNT_RF_ON = 10;
55 static const uint8_t MAX_SPI_WRITE_RETRY_COUNT_HW_ERR = 3;
56 /*******************************************************************************
57 **
58 ** Function         phPalEse_spi_close
59 **
60 ** Description      Closes PN547 device
61 **
62 ** Parameters       pDevHandle - device handle
63 **
64 ** Returns          None
65 **
66 *******************************************************************************/
phPalEse_spi_close(void * pDevHandle)67 void phPalEse_spi_close(void* pDevHandle) {
68   ese_nxp_IoctlInOutData_t inpOutData;
69   static uint8_t cmd_omapi_concurrent[] = {0x2F, 0x01, 0x01, 0x00};
70   int retval;
71   ALOGD_IF(ese_debug_enabled, "halimpl close enter.");
72 
73   NfcAdaptation& pNfcAdapt = NfcAdaptation::GetInstance();
74   pNfcAdapt.Initialize();
75   // nxpesehal_ctrl.p_ese_stack_cback = p_cback;
76   // nxpesehal_ctrl.p_ese_stack_data_cback = p_data_cback;
77   memset(&inpOutData, 0x00, sizeof(ese_nxp_IoctlInOutData_t));
78   inpOutData.inp.data.nxpCmd.cmd_len = sizeof(cmd_omapi_concurrent);
79   inpOutData.inp.data_source = 1;
80   memcpy(inpOutData.inp.data.nxpCmd.p_cmd, cmd_omapi_concurrent,
81          sizeof(cmd_omapi_concurrent));
82   retval = pNfcAdapt.HalIoctl(HAL_NFC_SPI_DWP_SYNC, &inpOutData);
83   ALOGD_IF(ese_debug_enabled, "_spi_close() status %x", retval);
84 
85   if (NULL != pDevHandle) {
86     close((intptr_t)pDevHandle);
87   }
88   ALOGD_IF(ese_debug_enabled, "halimpl close exit.");
89   return;
90 }
phNxpEse_spiIoctl(uint64_t ioctlType,void * p_data)91 ESESTATUS phNxpEse_spiIoctl(uint64_t ioctlType, void* p_data) {
92   if (!p_data) {
93     ALOGD_IF(ese_debug_enabled, "%s:p_data is null ioctltyp: %ld", __FUNCTION__,
94              (long)ioctlType);
95     return ESESTATUS_FAILED;
96   }
97   ese_nxp_IoctlInOutData_t* inpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
98   rf_status = inpOutData->inp.data.nxpCmd.p_cmd[0];
99   if (rf_status == 1) {
100     ALOGD_IF(ese_debug_enabled,
101              "******************RF IS ON*************************************");
102   } else {
103     ALOGD_IF(
104         ese_debug_enabled,
105         "******************RF IS OFF*************************************");
106   }
107   return ESESTATUS_SUCCESS;
108 }
109 
110 /*******************************************************************************
111 **
112 ** Function         phPalEse_spi_open_and_configure
113 **
114 ** Description      Open and configure pn547 device
115 **
116 ** Parameters       pConfig     - hardware information
117 **                  pLinkHandle - device handle
118 **
119 ** Returns          ESE status:
120 **                  ESESTATUS_SUCCESS            - open_and_configure operation
121 *success
122 **                  ESESTATUS_INVALID_DEVICE     - device open operation failure
123 **
124 *******************************************************************************/
phPalEse_spi_open_and_configure(pphPalEse_Config_t pConfig)125 ESESTATUS phPalEse_spi_open_and_configure(pphPalEse_Config_t pConfig) {
126   int nHandle;
127   int retryCnt = 0, nfc_access_retryCnt = 0;
128   int retval;
129   ese_nxp_IoctlInOutData_t inpOutData;
130   NfcAdaptation& pNfcAdapt = NfcAdaptation::GetInstance();
131   pNfcAdapt.Initialize();
132   static uint8_t cmd_omapi_concurrent[] = {0x2F, 0x01, 0x01, 0x01};
133 
134   if (EseConfig::hasKey(NAME_NXP_SOF_WRITE)) {
135     configNum1 = EseConfig::getUnsigned(NAME_NXP_SOF_WRITE);
136     ALOGD_IF(ese_debug_enabled, "NXP_SOF_WRITE value from config file = %ld",
137              configNum1);
138   }
139 
140   if (EseConfig::hasKey(NAME_NXP_SPI_WRITE_TIMEOUT)) {
141     configNum2 = EseConfig::getUnsigned(NAME_NXP_SPI_WRITE_TIMEOUT);
142     ALOGD_IF(ese_debug_enabled,
143              "NXP_SPI_WRITE_TIMEOUT value from config file = %ld", configNum2);
144   }
145   ALOGD_IF(ese_debug_enabled, "halimpl open enter.");
146   memset(&inpOutData, 0x00, sizeof(ese_nxp_IoctlInOutData_t));
147   inpOutData.inp.data.nxpCmd.cmd_len = sizeof(cmd_omapi_concurrent);
148   inpOutData.inp.data_source = 1;
149   memcpy(inpOutData.inp.data.nxpCmd.p_cmd, cmd_omapi_concurrent,
150          sizeof(cmd_omapi_concurrent));
151 
152 retry_nfc_access:
153   omapi_status = ESESTATUS_FAILED;
154   retval = pNfcAdapt.HalIoctl(HAL_NFC_SPI_DWP_SYNC, &inpOutData);
155   if (omapi_status != 0) {
156     ALOGD_IF(ese_debug_enabled, "omapi_status return failed.");
157     nfc_access_retryCnt++;
158     phPalEse_sleep(2000000);
159     if (nfc_access_retryCnt < 5) goto retry_nfc_access;
160     return ESESTATUS_FAILED;
161   }
162 
163   ALOGD_IF(ese_debug_enabled, "Opening port=%s\n", pConfig->pDevName);
164 /* open port */
165 
166 retry:
167   nHandle = open((char const*)pConfig->pDevName, O_RDWR);
168   if (nHandle < 0) {
169     ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
170     if (errno == -EBUSY || errno == EBUSY) {
171       retryCnt++;
172       ALOGE("Retry open eSE driver, retry cnt : %d", retryCnt);
173       if (retryCnt < MAX_RETRY_CNT) {
174         phPalEse_sleep(1000000);
175         goto retry;
176       }
177     }
178     ALOGE("_spi_open() Failed: retval %x", nHandle);
179     pConfig->pDevHandle = NULL;
180     return ESESTATUS_INVALID_DEVICE;
181   }
182   ALOGD_IF(ese_debug_enabled, "eSE driver opened :: fd = [%d]", nHandle);
183   pConfig->pDevHandle = (void*)((intptr_t)nHandle);
184   return ESESTATUS_SUCCESS;
185 }
186 
187 /*******************************************************************************
188 **
189 ** Function         phPalEse_spi_read
190 **
191 ** Description      Reads requested number of bytes from pn547 device into given
192 *buffer
193 **
194 ** Parameters       pDevHandle       - valid device handle
195 **                  pBuffer          - buffer for read data
196 **                  nNbBytesToRead   - number of bytes requested to be read
197 **
198 ** Returns          numRead   - number of successfully read bytes
199 **                  -1        - read operation failure
200 **
201 *******************************************************************************/
phPalEse_spi_read(void * pDevHandle,uint8_t * pBuffer,int nNbBytesToRead)202 int phPalEse_spi_read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead) {
203   int ret = -1;
204   ALOGD_IF(ese_debug_enabled, "%s Read Requested %d bytes", __FUNCTION__,
205            nNbBytesToRead);
206   ret = read((intptr_t)pDevHandle, (void*)pBuffer, (nNbBytesToRead));
207   ALOGD_IF(ese_debug_enabled, "Read Returned = %d", ret);
208   return ret;
209 }
210 
211 /*******************************************************************************
212 **
213 ** Function         phPalEse_spi_write
214 **
215 ** Description      Writes requested number of bytes from given buffer into
216 *pn547 device
217 **
218 ** Parameters       pDevHandle       - valid device handle
219 **                  pBuffer          - buffer for read data
220 **                  nNbBytesToWrite  - number of bytes requested to be written
221 **
222 ** Returns          numWrote   - number of successfully written bytes
223 **                  -1         - write operation failure
224 **
225 *******************************************************************************/
phPalEse_spi_write(void * pDevHandle,uint8_t * pBuffer,int nNbBytesToWrite)226 int phPalEse_spi_write(void* pDevHandle, uint8_t* pBuffer,
227                        int nNbBytesToWrite) {
228   int ret = -1;
229   int numWrote = 0;
230   unsigned long int retryCount = 0;
231   if (NULL == pDevHandle) {
232     return -1;
233   }
234 
235   if (configNum1 == 1) {
236     /* Appending SOF for SPI write */
237     pBuffer[0] = SEND_PACKET_SOF;
238   } else {
239     /* Do Nothing */
240   }
241 
242   unsigned int maxRetryCount = 0, retryDelay = 0;
243   while (numWrote < nNbBytesToWrite) {
244     // usleep(5000);
245     if (rf_status != RF_ON) {
246       ret = write((intptr_t)pDevHandle, pBuffer + numWrote,
247                   nNbBytesToWrite - numWrote);
248     } else {
249       ret = -1;
250     }
251     if (ret > 0) {
252       numWrote += ret;
253     } else if (ret == 0) {
254       ALOGE("_spi_write() EOF");
255       return -1;
256     } else {
257       ALOGE("_spi_write() errno : %x", errno);
258 
259       if (rf_status == RF_ON) {
260         maxRetryCount = (configNum2 > 0)
261                             ? configNum2
262                             : DEFAULT_MAX_SPI_WRITE_RETRY_COUNT_RF_ON;
263         retryDelay = 1000 * WRITE_WAKE_UP_DELAY;
264         ALOGD_IF(ese_debug_enabled, "spi_Write failed as RF is ON.");
265       } else {
266         maxRetryCount = MAX_SPI_WRITE_RETRY_COUNT_HW_ERR;
267         retryDelay = WRITE_WAKE_UP_DELAY;
268         ALOGD_IF(ese_debug_enabled, "spi_write failed");
269       }
270 
271       if (retryCount < maxRetryCount) {
272         retryCount++;
273         /*wait for eSE wake up*/
274         phPalEse_sleep(retryDelay);
275         ALOGE("_spi_write() failed. Going to retry, counter:%ld !", retryCount);
276         continue;
277       }
278       return -1;
279     }
280   }
281   return numWrote;
282 }
283 
284 /*******************************************************************************
285 **
286 ** Function         phPalEse_spi_ioctl
287 **
288 ** Description      Exposed ioctl by p61 spi driver
289 **
290 ** Parameters       pDevHandle     - valid device handle
291 **                  level          - reset level
292 **
293 ** Returns           0   - ioctl operation success
294 **                  -1   - ioctl operation failure
295 **
296 *******************************************************************************/
phPalEse_spi_ioctl(phPalEse_ControlCode_t eControlCode,void * pDevHandle,long level)297 ESESTATUS phPalEse_spi_ioctl(phPalEse_ControlCode_t eControlCode,
298                              void* pDevHandle, long level) {
299   ESESTATUS ret = ESESTATUS_IOCTL_FAILED;
300   ALOGD_IF(ese_debug_enabled, "phPalEse_spi_ioctl(), ioctl %x , level %lx",
301            eControlCode, level);
302   ese_nxp_IoctlInOutData_t inpOutData;
303   inpOutData.inp.level = level;
304   NfcAdaptation& pNfcAdapt = NfcAdaptation::GetInstance();
305   if (NULL == pDevHandle) {
306     return ESESTATUS_IOCTL_FAILED;
307   }
308   switch (eControlCode) {
309     // Nfc Driver communication part
310     case phPalEse_e_ChipRst:
311       ret = pNfcAdapt.HalIoctl(HAL_NFC_SET_SPM_PWR, &inpOutData);
312       break;
313 
314     case phPalEse_e_SetPowerScheme:
315       // ret = sendIoctlData(p, HAL_NFC_SET_POWER_SCHEME, &inpOutData);
316       ret = ESESTATUS_SUCCESS;
317       break;
318 
319     case phPalEse_e_GetSPMStatus:
320       // ret = sendIoctlData(p, HAL_NFC_GET_SPM_STATUS, &inpOutData);
321       ret = ESESTATUS_SUCCESS;
322       break;
323 
324     case phPalEse_e_GetEseAccess:
325       // ret = sendIoctlData(p, HAL_NFC_GET_ESE_ACCESS, &inpOutData);
326       ret = ESESTATUS_SUCCESS;
327       break;
328 #ifdef NXP_ESE_JCOP_DWNLD_PROTECTION
329     case phPalEse_e_SetJcopDwnldState:
330       // ret = sendIoctlData(p, HAL_NFC_SET_DWNLD_STATUS, &inpOutData);
331       ret = ESESTATUS_SUCCESS;
332       break;
333 #endif
334     case phPalEse_e_DisablePwrCntrl:
335       ret = pNfcAdapt.HalIoctl(HAL_NFC_INHIBIT_PWR_CNTRL, &inpOutData);
336       break;
337     default:
338       ret = ESESTATUS_IOCTL_FAILED;
339       break;
340   }
341   return ret;
342 }
343