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(&current_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(&current_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(&current_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