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