1 /******************************************************************************
2 *
3 * Copyright 2018-2019, 2022-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 #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_SetPwrScheme
205 *
206 * Description This function request to the nfc i2c driver
207 * to set the chip type and power scheme.
208 *
209 * Returns On Success ESESTATUS_SUCCESS else proper error code
210 *
211 ******************************************************************************/
phNxpEse_SPM_SetPwrScheme(long arg)212 ESESTATUS phNxpEse_SPM_SetPwrScheme(long arg) {
213 int32_t ret = -1;
214 ESESTATUS status = ESESTATUS_SUCCESS;
215
216 NXP_LOG_ESE_D("%s : Power scheme is set to = 0x%ld", __FUNCTION__, arg);
217 ret = phPalEse_ioctl(phPalEse_e_SetPowerScheme, pEseDeviceHandle, arg);
218 if (ret < 0) {
219 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
220 status = ESESTATUS_FAILED;
221 }
222
223 return status;
224 }
225
226 /******************************************************************************
227 * Function phNxpEseP61_SPM_EnableDisablePwrCntrl
228 *
229 * Description This function request to the nfc i2c driver
230 * to set the chip type and power scheme.
231 *
232 * Returns On Success ESESTATUS_SUCCESS else proper error code
233 *
234 ******************************************************************************/
phNxpEse_SPM_DisablePwrControl(unsigned long arg)235 ESESTATUS phNxpEse_SPM_DisablePwrControl(unsigned long arg) {
236 int32_t ret = -1;
237 ESESTATUS status = ESESTATUS_SUCCESS;
238
239 NXP_LOG_ESE_D("%s : Inhibit power control is set to = 0x%ld", __FUNCTION__,
240 arg);
241 ret = phPalEse_ioctl(phPalEse_e_DisablePwrCntrl, pEseDeviceHandle, arg);
242 if (ret < 0) {
243 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
244 status = ESESTATUS_FAILED;
245 }
246
247 return status;
248 }
249
250 /******************************************************************************
251 * Function phNxpEse_SPM_GetState
252 *
253 * Description This function gets the current power state of ESE
254 *
255 * Returns On Success ESESTATUS_SUCCESS else proper error code
256 *
257 ******************************************************************************/
phNxpEse_SPM_GetState(spm_state_t * current_state)258 ESESTATUS phNxpEse_SPM_GetState(spm_state_t* current_state) {
259 int32_t ret = -1;
260 ESESTATUS status = ESESTATUS_SUCCESS;
261 spm_state_t ese_current_state = SPM_STATE_INVALID;
262
263 if (current_state == NULL) {
264 NXP_LOG_ESE_E("%s : failed Invalid argument", __FUNCTION__);
265 return ESESTATUS_FAILED;
266 }
267 ret = phPalEse_ioctl(phPalEse_e_GetSPMStatus, pEseDeviceHandle,
268 (unsigned long)&ese_current_state);
269 if (ret < 0) {
270 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
271 status = ESESTATUS_FAILED;
272 } else {
273 *current_state = ese_current_state; /* Current ESE state */
274 }
275
276 return status;
277 }
278
279 /******************************************************************************
280 * Function phNxpEse_SPM_SetJcopDwnldState
281 *
282 * Description This function is used to set the JCOP OS download state
283 *
284 * Returns On Success ESESTATUS_SUCCESS else proper error code
285 *
286 ******************************************************************************/
phNxpEse_SPM_SetJcopDwnldState(long arg)287 ESESTATUS phNxpEse_SPM_SetJcopDwnldState(long arg) {
288 int ret = -1;
289 ESESTATUS status = ESESTATUS_SUCCESS;
290
291 NXP_LOG_ESE_D("%s :phNxpEse_SPM_SetJcopDwnldState = 0x%ld", __FUNCTION__,
292 arg);
293 ret = phPalEse_ioctl(phPalEse_e_SetJcopDwnldState, pEseDeviceHandle, arg);
294 if (ret < 0) {
295 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
296 status = ESESTATUS_FAILED;
297 }
298
299 return status;
300 }
301
302 /******************************************************************************
303 * Function phNxpEse_SPM_SetEseClientUpdateState
304 *
305 * Description This function is used to set the ese Update state
306 *
307 * Returns On Success ESESTATUS_SUCCESS else proper error code
308 *
309 ******************************************************************************/
phNxpEse_SPM_SetEseClientUpdateState(long arg)310 ESESTATUS phNxpEse_SPM_SetEseClientUpdateState(long arg) {
311 int ret = -1;
312 ESESTATUS status = ESESTATUS_SUCCESS;
313
314 NXP_LOG_ESE_D("%s :phNxpEse_SPM_SetEseClientUpdateState = 0x%ld",
315 __FUNCTION__, arg);
316 ret = phPalEse_ioctl(phPalEse_e_SetClientUpdateState, pEseDeviceHandle, arg);
317 if (ret < 0) {
318 NXP_LOG_ESE_E("%s : failed errno = 0x%x", __FUNCTION__, errno);
319 status = ESESTATUS_FAILED;
320 }
321
322 return status;
323 }
324
325 /*******************************************************************************
326 **
327 ** Function phNxpEse_SPM_RelAccess
328 **
329 ** Description
330 **
331 ** Parameters timeout - Releases the ese access
332 **
333 ** Returns success or failure
334 **
335 *******************************************************************************/
phNxpEse_SPM_RelAccess(void)336 ESESTATUS phNxpEse_SPM_RelAccess(void) {
337 ESESTATUS status = ESESTATUS_SUCCESS;
338 #if ((NFC_NXP_ESE_VER == JCOP_VER_3_1) || (NFC_NXP_ESE_VER == JCOP_VER_3_2))
339 int ret = -1;
340 NXP_LOG_ESE_D("phNxpEse_SPM_RelAccess(): enter");
341
342 ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 5);
343 if (ret < 0) {
344 status = ESESTATUS_FAILED;
345 }
346 NXP_LOG_ESE_D("phNxpEse_SPM_RelAccess(): exit %d", status);
347 #endif
348 return status;
349 }
350 /** @} */
351