1 /******************************************************************************
2 *
3 * Copyright 2018-2019,2022 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 #define LOG_TAG "NxpEseHal"
19 #include "phNxpEse_Spm.h"
20
21 #include <errno.h>
22 #include <ese_logs.h>
23 #include <fcntl.h>
24 #include <log/log.h>
25 #include <phNxpEsePal.h>
26 #include <phNxpEse_Internal.h>
27 #include <sys/ioctl.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31
32 #include "phNxpEseFeatures.h"
33
34 /*********************** Global Variables *************************************/
35
36 static void* pEseDeviceHandle = NULL;
37 #define MAX_ESE_ACCESS_TIME_OUT_MS 2000 /*2 seconds*/
38
39 /**
40 * \addtogroup SPI_Power_Management
41 *
42 * @{ */
43 /******************************************************************************
44 \section Introduction Introduction
45
46 * This module provide power request to Pn54x nfc-i2c driver, it checks if
47 * wired access is already granted. It should have access to pn54x drive.
48 * Below are the apis provided by the SPM module.
49 ******************************************************************************/
50 /******************************************************************************
51 * Function phNxpEse_SPM_Init
52 *
53 * Description This function opens the nfc i2c driver to manage power
54 * and synchronization for ese secure element.
55 *
56 * Returns On Success ESESTATUS_SUCCESS else proper error code
57 *
58 ******************************************************************************/
phNxpEse_SPM_Init(void * pDevHandle)59 ESESTATUS phNxpEse_SPM_Init(void* pDevHandle) {
60 ESESTATUS status = ESESTATUS_SUCCESS;
61 pEseDeviceHandle = pDevHandle;
62 if (NULL == pEseDeviceHandle) {
63 NXP_LOG_ESE_E("%s : failed, device handle is null", __FUNCTION__);
64 status = ESESTATUS_FAILED;
65 }
66 NXP_LOG_ESE_D("%s : exit status = %d", __FUNCTION__, status);
67
68 return status;
69 }
70
71 /******************************************************************************
72 * Function phNxpEse_SPM_DeInit
73 *
74 * Description This function closes the nfc i2c driver node.
75 *
76 * Returns Always returns ESESTATUS_SUCCESS
77 *
78 ******************************************************************************/
phNxpEse_SPM_DeInit(void)79 ESESTATUS phNxpEse_SPM_DeInit(void) {
80 pEseDeviceHandle = NULL;
81 return ESESTATUS_SUCCESS;
82 }
83
84 /******************************************************************************
85 * Function phNxpEse_SPM_ConfigPwr
86 *
87 * Description This function request to the nfc i2c driver
88 * to enable/disable power to ese. This api should be called
89 *before
90 * sending any apdu to ese/once apdu exchange is done.
91 *
92 * Returns On Success ESESTATUS_SUCCESS else proper error code
93 *
94 ******************************************************************************/
phNxpEse_SPM_ConfigPwr(spm_power_t arg)95 ESESTATUS phNxpEse_SPM_ConfigPwr(spm_power_t arg) {
96 int32_t ret = -1;
97 ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
98 spm_state_t current_spm_state = SPM_STATE_INVALID;
99 if (GET_CHIP_OS_VERSION() > OS_VERSION_4_0) {
100 /*None of the IOCTLs valid except SPM_RECOVERY_RESET*/
101 if (arg != SPM_RECOVERY_RESET) {
102 return ESESTATUS_SUCCESS;
103 }
104 }
105 ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, arg);
106 switch (arg) {
107 case SPM_POWER_DISABLE: {
108 if (ret < 0) {
109 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
110 wSpmStatus = ESESTATUS_FAILED;
111 } else {
112 if (phNxpEse_SPM_RelAccess() != ESESTATUS_SUCCESS) {
113 NXP_LOG_ESE_E(" %s phNxpEse_SPM_RelAccess : failed \n", __FUNCTION__);
114 }
115 }
116 } break;
117 case SPM_POWER_ENABLE: {
118 if (ret < 0) {
119 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
120 if (errno == -EBUSY) {
121 wSpmStatus = phNxpEse_SPM_GetState(¤t_spm_state);
122 if (wSpmStatus != ESESTATUS_SUCCESS) {
123 NXP_LOG_ESE_E(" %s : phNxpEse_SPM_GetPwrState Failed",
124 __FUNCTION__);
125 if (phNxpEse_SPM_RelAccess() != ESESTATUS_SUCCESS) {
126 NXP_LOG_ESE_E(" %s phNxpEse_SPM_RelAccess : failed \n",
127 __FUNCTION__);
128 }
129 return wSpmStatus;
130 } else {
131 if (current_spm_state & SPM_STATE_DWNLD) {
132 wSpmStatus = ESESTATUS_DWNLD_BUSY;
133 } else {
134 wSpmStatus = ESESTATUS_BUSY;
135 }
136 }
137 } else {
138 wSpmStatus = ESESTATUS_FAILED;
139 }
140 if (wSpmStatus != ESESTATUS_SUCCESS) {
141 if (phNxpEse_SPM_RelAccess() != ESESTATUS_SUCCESS) {
142 NXP_LOG_ESE_E(" %s phNxpEse_SPM_RelAccess : failed \n",
143 __FUNCTION__);
144 }
145 }
146 }
147 } break;
148 case SPM_POWER_RESET: {
149 if (ret < 0) {
150 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
151 if (errno == -EBUSY) {
152 wSpmStatus = phNxpEse_SPM_GetState(¤t_spm_state);
153 if (wSpmStatus != ESESTATUS_SUCCESS) {
154 NXP_LOG_ESE_E(" %s : phNxpEse_SPM_GetPwrState Failed",
155 __FUNCTION__);
156 return wSpmStatus;
157 } else {
158 if (current_spm_state & SPM_STATE_DWNLD) {
159 wSpmStatus = ESESTATUS_DWNLD_BUSY;
160 } else {
161 wSpmStatus = ESESTATUS_BUSY;
162 }
163 }
164 } else {
165 wSpmStatus = ESESTATUS_FAILED;
166 }
167 }
168 } break;
169 case SPM_POWER_PRIO_ENABLE: {
170 if (ret < 0) {
171 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
172 if (errno == -EBUSY) {
173 wSpmStatus = phNxpEse_SPM_GetState(¤t_spm_state);
174 if (wSpmStatus != ESESTATUS_SUCCESS) {
175 NXP_LOG_ESE_E(" %s : phNxpEse_SPM_GetPwrState Failed",
176 __FUNCTION__);
177 return wSpmStatus;
178 } else {
179 if (current_spm_state & SPM_STATE_DWNLD) {
180 wSpmStatus = ESESTATUS_DWNLD_BUSY;
181 } else {
182 wSpmStatus = ESESTATUS_BUSY;
183 }
184 }
185
186 } else {
187 wSpmStatus = ESESTATUS_FAILED;
188 }
189 }
190 } break;
191 case SPM_POWER_PRIO_DISABLE: {
192 if (ret < 0) {
193 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
194 wSpmStatus = ESESTATUS_FAILED;
195 }
196 } break;
197 case SPM_RECOVERY_RESET: {
198 } break;
199 }
200 return wSpmStatus;
201 }
202
203 /******************************************************************************
204 * Function phNxpEse_SPM_EnablePwr
205 *
206 * Description This function request to the nfc i2c driver
207 * to enable power to ese. This api should be called before
208 * sending any apdu to ese.
209 *
210 * Returns On Success ESESTATUS_SUCCESS else proper error code
211 *
212 ******************************************************************************/
phNxpEse_SPM_EnablePwr(void)213 ESESTATUS phNxpEse_SPM_EnablePwr(void) {
214 int32_t ret = -1;
215 ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
216 spm_state_t current_spm_state = SPM_STATE_INVALID;
217 NXP_LOG_ESE_D("%s : phNxpEse_SPM_EnablePwr is set to = 0x%d", __FUNCTION__,
218 0);
219 ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 0);
220 if (ret < 0) {
221 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
222 if (errno == -EBUSY) {
223 wSpmStatus = phNxpEse_SPM_GetState(¤t_spm_state);
224 if (wSpmStatus != ESESTATUS_SUCCESS) {
225 NXP_LOG_ESE_E(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
226 return wSpmStatus;
227 } else {
228 if (current_spm_state == SPM_STATE_DWNLD) {
229 wSpmStatus = ESESTATUS_DWNLD_BUSY;
230 } else {
231 wSpmStatus = ESESTATUS_BUSY;
232 }
233 }
234
235 } else {
236 wSpmStatus = ESESTATUS_FAILED;
237 }
238 }
239
240 return wSpmStatus;
241 }
242
243 /******************************************************************************
244 * Function phNxpEse_SPM_DisablePwr
245 *
246 * Description This function request to the nfc i2c driver
247 * to disable power to ese. This api should be called
248 * once apdu exchange is done.
249 *
250 * Returns On Success ESESTATUS_SUCCESS else proper error code
251 *
252 ******************************************************************************/
phNxpEse_SPM_DisablePwr(void)253 ESESTATUS phNxpEse_SPM_DisablePwr(void) {
254 int32_t ret = -1;
255 ESESTATUS status = ESESTATUS_SUCCESS;
256 NXP_LOG_ESE_D("%s : phNxpEse_SPM_DisablePwr is set to = 0x%d", __FUNCTION__,
257 1);
258 ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 1);
259 if (ret < 0) {
260 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
261 status = ESESTATUS_FAILED;
262 }
263
264 return status;
265 }
266 /******************************************************************************
267 * Function phNxpEse_SPM_SetPwrScheme
268 *
269 * Description This function request to the nfc i2c driver
270 * to set the chip type and power scheme.
271 *
272 * Returns On Success ESESTATUS_SUCCESS else proper error code
273 *
274 ******************************************************************************/
phNxpEse_SPM_SetPwrScheme(long arg)275 ESESTATUS phNxpEse_SPM_SetPwrScheme(long arg) {
276 int32_t ret = -1;
277 ESESTATUS status = ESESTATUS_SUCCESS;
278
279 NXP_LOG_ESE_D("%s : Power scheme is set to = 0x%ld", __FUNCTION__, arg);
280 ret = phPalEse_ioctl(phPalEse_e_SetPowerScheme, pEseDeviceHandle, arg);
281 if (ret < 0) {
282 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
283 status = ESESTATUS_FAILED;
284 }
285
286 return status;
287 }
288
289 /******************************************************************************
290 * Function phNxpEseP61_SPM_EnableDisablePwrCntrl
291 *
292 * Description This function request to the nfc i2c driver
293 * to set the chip type and power scheme.
294 *
295 * Returns On Success ESESTATUS_SUCCESS else proper error code
296 *
297 ******************************************************************************/
phNxpEse_SPM_DisablePwrControl(unsigned long arg)298 ESESTATUS phNxpEse_SPM_DisablePwrControl(unsigned long arg) {
299 int32_t ret = -1;
300 ESESTATUS status = ESESTATUS_SUCCESS;
301
302 NXP_LOG_ESE_D("%s : Inhibit power control is set to = 0x%ld", __FUNCTION__,
303 arg);
304 ret = phPalEse_ioctl(phPalEse_e_DisablePwrCntrl, pEseDeviceHandle, arg);
305 if (ret < 0) {
306 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
307 status = ESESTATUS_FAILED;
308 }
309
310 return status;
311 }
312
313 /******************************************************************************
314 * Function phNxpEse_SPM_GetState
315 *
316 * Description This function gets the current power state of ESE
317 *
318 * Returns On Success ESESTATUS_SUCCESS else proper error code
319 *
320 ******************************************************************************/
phNxpEse_SPM_GetState(spm_state_t * current_state)321 ESESTATUS phNxpEse_SPM_GetState(spm_state_t* current_state) {
322 int32_t ret = -1;
323 ESESTATUS status = ESESTATUS_SUCCESS;
324 spm_state_t ese_current_state = SPM_STATE_INVALID;
325
326 if (current_state == NULL) {
327 NXP_LOG_ESE_E("%s : failed Invalid argument", __FUNCTION__);
328 return ESESTATUS_FAILED;
329 }
330 ret = phPalEse_ioctl(phPalEse_e_GetSPMStatus, pEseDeviceHandle,
331 (unsigned long)&ese_current_state);
332 if (ret < 0) {
333 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
334 status = ESESTATUS_FAILED;
335 } else {
336 *current_state = ese_current_state; /* Current ESE state */
337 }
338
339 return status;
340 }
341
342 /******************************************************************************
343 * Function phNxpEse_SPM_SetJcopDwnldState
344 *
345 * Description This function is used to set the JCOP OS download state
346 *
347 * Returns On Success ESESTATUS_SUCCESS else proper error code
348 *
349 ******************************************************************************/
phNxpEse_SPM_SetJcopDwnldState(long arg)350 ESESTATUS phNxpEse_SPM_SetJcopDwnldState(long arg) {
351 int ret = -1;
352 ESESTATUS status = ESESTATUS_SUCCESS;
353
354 NXP_LOG_ESE_D("%s :phNxpEse_SPM_SetJcopDwnldState = 0x%ld", __FUNCTION__,
355 arg);
356 ret = phPalEse_ioctl(phPalEse_e_SetJcopDwnldState, pEseDeviceHandle, arg);
357 if (ret < 0) {
358 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
359 status = ESESTATUS_FAILED;
360 }
361
362 return status;
363 }
364
365 /******************************************************************************
366 * Function phNxpEse_SPM_SetEseClientUpdateState
367 *
368 * Description This function is used to set the ese Update state
369 *
370 * Returns On Success ESESTATUS_SUCCESS else proper error code
371 *
372 ******************************************************************************/
phNxpEse_SPM_SetEseClientUpdateState(long arg)373 ESESTATUS phNxpEse_SPM_SetEseClientUpdateState(long arg) {
374 int ret = -1;
375 ESESTATUS status = ESESTATUS_SUCCESS;
376
377 NXP_LOG_ESE_D("%s :phNxpEse_SPM_SetEseClientUpdateState = 0x%ld",
378 __FUNCTION__, arg);
379 ret = phPalEse_ioctl(phPalEse_e_SetClientUpdateState, pEseDeviceHandle, arg);
380 if (ret < 0) {
381 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
382 status = ESESTATUS_FAILED;
383 }
384
385 return status;
386 }
387
388 /******************************************************************************
389 * Function phNxpEse_SPM_ResetPwr
390 *
391 * Description This function request to the nfc i2c driver
392 * to reset ese.
393 *
394 * Returns On Success ESESTATUS_SUCCESS else proper error code
395 *
396 ******************************************************************************/
phNxpEse_SPM_ResetPwr(void)397 ESESTATUS phNxpEse_SPM_ResetPwr(void) {
398 int32_t ret = -1;
399 ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
400 spm_state_t current_spm_state = SPM_STATE_INVALID;
401
402 /* reset the ese */
403 ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 2);
404 if (ret < 0) {
405 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
406 if (errno == -EBUSY || errno == EBUSY) {
407 wSpmStatus = phNxpEse_SPM_GetState(¤t_spm_state);
408 if (wSpmStatus != ESESTATUS_SUCCESS) {
409 NXP_LOG_ESE_E(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
410 return wSpmStatus;
411 } else {
412 if (current_spm_state == SPM_STATE_DWNLD) {
413 wSpmStatus = ESESTATUS_DWNLD_BUSY;
414 } else {
415 wSpmStatus = ESESTATUS_BUSY;
416 }
417 }
418
419 } else {
420 wSpmStatus = ESESTATUS_FAILED;
421 }
422 }
423
424 return wSpmStatus;
425 }
426
427 /*******************************************************************************
428 **
429 ** Function phTmlEse_get_ese_access
430 **
431 ** Description
432 **
433 ** Parameters timeout - timeout to wait for ese access
434 **
435 ** Returns success or failure
436 **
437 *******************************************************************************/
phNxpEse_SPM_GetAccess(long timeout)438 ESESTATUS phNxpEse_SPM_GetAccess(long timeout) {
439 ESESTATUS status = ESESTATUS_SUCCESS;
440 NXP_LOG_ESE_D("phTmlEse_get_ese_access(), timeout %ld", timeout);
441 #if ((NFC_NXP_ESE_VER == JCOP_VER_3_1) || (NFC_NXP_ESE_VER == JCOP_VER_3_2))
442 int ret = -1;
443
444 ret = phPalEse_ioctl(phPalEse_e_GetEseAccess, pEseDeviceHandle, timeout);
445 if (ret < 0) {
446 if (ret == -EBUSY)
447 status = ESESTATUS_BUSY;
448 else
449 status = ESESTATUS_FAILED;
450 }
451 NXP_LOG_ESE_D("phTmlEse_get_ese_access(), exit %d", status);
452 #endif
453 return status;
454 }
455 /*******************************************************************************
456 **
457 ** Function phNxpEse_SPM_RelAccess
458 **
459 ** Description
460 **
461 ** Parameters timeout - Releases the ese access
462 **
463 ** Returns success or failure
464 **
465 *******************************************************************************/
phNxpEse_SPM_RelAccess(void)466 ESESTATUS phNxpEse_SPM_RelAccess(void) {
467 ESESTATUS status = ESESTATUS_SUCCESS;
468 #if ((NFC_NXP_ESE_VER == JCOP_VER_3_1) || (NFC_NXP_ESE_VER == JCOP_VER_3_2))
469 int ret = -1;
470 NXP_LOG_ESE_D("phNxpEse_SPM_RelAccess(): enter");
471
472 ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 5);
473 if (ret < 0) {
474 status = ESESTATUS_FAILED;
475 }
476 NXP_LOG_ESE_D("phNxpEse_SPM_RelAccess(): exit %d", status);
477 #endif
478 return status;
479 }
480 /** @} */
481