Home | History | Annotate | Download | only in spm
      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 #define LOG_TAG "NxpEseHal"
     19 #include <log/log.h>
     20 
     21 #include <errno.h>
     22 #include <fcntl.h>
     23 #include <phNxpEsePal.h>
     24 #include <phNxpEse_Internal.h>
     25 #include <sys/ioctl.h>
     26 #include <sys/stat.h>
     27 #include <sys/types.h>
     28 #include <unistd.h>
     29 #include "phNxpEseFeatures.h"
     30 #include "phNxpEse_Spm.h"
     31 
     32 /*********************** Global Variables *************************************/
     33 extern bool ese_debug_enabled;
     34 
     35 static void* pEseDeviceHandle = NULL;
     36 #define MAX_ESE_ACCESS_TIME_OUT_MS 2000 /*2 seconds*/
     37 
     38 /**
     39  * \addtogroup SPI_Power_Management
     40  *
     41  * @{ */
     42 /******************************************************************************
     43 \section Introduction Introduction
     44 
     45  * This module provide power request to Pn54x nfc-i2c driver, it cheks if
     46  * wired access is already granted. It should have access to pn54x drive.
     47  * Below are the apis provided by the SPM module.
     48  ******************************************************************************/
     49 /******************************************************************************
     50  * Function         phNxpEse_SPM_Init
     51  *
     52  * Description      This function opens the nfc i2c driver to manage power
     53  *                  and synchronization for ese secure element.
     54  *
     55  * Returns          On Success ESESTATUS_SUCCESS else proper error code
     56  *
     57  ******************************************************************************/
     58 ESESTATUS phNxpEse_SPM_Init(void* pDevHandle) {
     59   ESESTATUS status = ESESTATUS_SUCCESS;
     60   pEseDeviceHandle = pDevHandle;
     61   if (NULL == pEseDeviceHandle) {
     62     ALOGE("%s : failed, device handle is null", __FUNCTION__);
     63     status = ESESTATUS_FAILED;
     64   }
     65   ALOGD_IF(ese_debug_enabled, "%s : exit status = %d", __FUNCTION__, status);
     66 
     67   return status;
     68 }
     69 
     70 /******************************************************************************
     71  * Function         phNxpEse_SPM_DeInit
     72  *
     73  * Description      This function closes the nfc i2c driver node.
     74  *
     75  * Returns          Always returns ESESTATUS_SUCCESS
     76  *
     77  ******************************************************************************/
     78 ESESTATUS phNxpEse_SPM_DeInit(void) {
     79   pEseDeviceHandle = NULL;
     80   return ESESTATUS_SUCCESS;
     81 }
     82 
     83 /******************************************************************************
     84  * Function         phNxpEse_SPM_ConfigPwr
     85  *
     86  * Description      This function request to the nfc i2c driver
     87  *                  to enable/disable power to ese. This api should be called
     88  *before
     89  *                  sending any apdu to ese/once apdu exchange is done.
     90  *
     91  * Returns          On Success ESESTATUS_SUCCESS else proper error code
     92  *
     93  ******************************************************************************/
     94 ESESTATUS phNxpEse_SPM_ConfigPwr(spm_power_t arg) {
     95   int32_t ret = -1;
     96   ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
     97   spm_state_t current_spm_state = SPM_STATE_INVALID;
     98 
     99   ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, arg);
    100   switch (arg) {
    101     case SPM_POWER_DISABLE: {
    102       if (ret < 0) {
    103         ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
    104         wSpmStatus = ESESTATUS_FAILED;
    105       }
    106     } break;
    107     case SPM_POWER_ENABLE: {
    108       if (ret < 0) {
    109         ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
    110         if (errno == -EBUSY) {
    111           wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
    112           if (wSpmStatus != ESESTATUS_SUCCESS) {
    113             ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
    114             return wSpmStatus;
    115           } else {
    116             if (current_spm_state & SPM_STATE_DWNLD) {
    117               wSpmStatus = ESESTATUS_DWNLD_BUSY;
    118             } else {
    119               wSpmStatus = ESESTATUS_BUSY;
    120             }
    121           }
    122 
    123         } else {
    124           wSpmStatus = ESESTATUS_FAILED;
    125         }
    126       }
    127     } break;
    128     case SPM_POWER_RESET: {
    129       if (ret < 0) {
    130         ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
    131         if (errno == -EBUSY) {
    132           wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
    133           if (wSpmStatus != ESESTATUS_SUCCESS) {
    134             ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
    135             return wSpmStatus;
    136           } else {
    137             if (current_spm_state & SPM_STATE_DWNLD) {
    138               wSpmStatus = ESESTATUS_DWNLD_BUSY;
    139             } else {
    140               wSpmStatus = ESESTATUS_BUSY;
    141             }
    142           }
    143         } else {
    144           wSpmStatus = ESESTATUS_FAILED;
    145         }
    146       }
    147     } break;
    148     case SPM_POWER_PRIO_ENABLE: {
    149       if (ret < 0) {
    150         ALOGE("%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             ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
    155             return wSpmStatus;
    156           } else {
    157             if (current_spm_state & SPM_STATE_DWNLD) {
    158               wSpmStatus = ESESTATUS_DWNLD_BUSY;
    159             } else {
    160               wSpmStatus = ESESTATUS_BUSY;
    161             }
    162           }
    163 
    164         } else {
    165           wSpmStatus = ESESTATUS_FAILED;
    166         }
    167       }
    168     } break;
    169     case SPM_POWER_PRIO_DISABLE: {
    170       if (ret < 0) {
    171         ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
    172         wSpmStatus = ESESTATUS_FAILED;
    173       }
    174     } break;
    175   }
    176   return wSpmStatus;
    177 }
    178 
    179 /******************************************************************************
    180  * Function         phNxpEse_SPM_EnablePwr
    181  *
    182  * Description      This function request to the nfc i2c driver
    183  *                  to enable power to ese. This api should be called before
    184  *                  sending any apdu to ese.
    185  *
    186  * Returns          On Success ESESTATUS_SUCCESS else proper error code
    187  *
    188  ******************************************************************************/
    189 ESESTATUS phNxpEse_SPM_EnablePwr(void) {
    190   int32_t ret = -1;
    191   ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
    192   spm_state_t current_spm_state = SPM_STATE_INVALID;
    193   ALOGD_IF(ese_debug_enabled, "%s : phNxpEse_SPM_EnablePwr is set to  = 0x%d",
    194            __FUNCTION__, 0);
    195   ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 0);
    196   if (ret < 0) {
    197     ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
    198     if (errno == -EBUSY) {
    199       wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
    200       if (wSpmStatus != ESESTATUS_SUCCESS) {
    201         ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
    202         return wSpmStatus;
    203       } else {
    204         if (current_spm_state == SPM_STATE_DWNLD) {
    205           wSpmStatus = ESESTATUS_DWNLD_BUSY;
    206         } else {
    207           wSpmStatus = ESESTATUS_BUSY;
    208         }
    209       }
    210 
    211     } else {
    212       wSpmStatus = ESESTATUS_FAILED;
    213     }
    214   }
    215 
    216   return wSpmStatus;
    217 }
    218 
    219 /******************************************************************************
    220  * Function         phNxpEse_SPM_DisablePwr
    221  *
    222  * Description      This function request to the nfc i2c driver
    223  *                  to disable power to ese. This api should be called
    224  *                  once apdu exchange is done.
    225  *
    226  * Returns          On Success ESESTATUS_SUCCESS else proper error code
    227  *
    228  ******************************************************************************/
    229 ESESTATUS phNxpEse_SPM_DisablePwr(void) {
    230   int32_t ret = -1;
    231   ESESTATUS status = ESESTATUS_SUCCESS;
    232   ALOGD_IF(ese_debug_enabled, "%s : phNxpEse_SPM_DisablePwr is set to  = 0x%d",
    233            __FUNCTION__, 1);
    234   ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 1);
    235   if (ret < 0) {
    236     ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
    237     status = ESESTATUS_FAILED;
    238   }
    239 
    240   return status;
    241 }
    242 /******************************************************************************
    243  * Function         phNxpEse_SPM_SetPwrScheme
    244  *
    245  * Description      This function request to the nfc i2c driver
    246  *                  to set the chip type and power scheme.
    247  *
    248  * Returns          On Success ESESTATUS_SUCCESS else proper error code
    249  *
    250  ******************************************************************************/
    251 ESESTATUS phNxpEse_SPM_SetPwrScheme(long arg) {
    252   int32_t ret = -1;
    253   ESESTATUS status = ESESTATUS_SUCCESS;
    254 
    255   ALOGD_IF(ese_debug_enabled, "%s : Power scheme is set to  = 0x%ld",
    256            __FUNCTION__, arg);
    257   ret = phPalEse_ioctl(phPalEse_e_SetPowerScheme, pEseDeviceHandle, arg);
    258   if (ret < 0) {
    259     ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
    260     status = ESESTATUS_FAILED;
    261   }
    262 
    263   return status;
    264 }
    265 
    266 /******************************************************************************
    267  * Function         phNxpEseP61_SPM_EnableDisablePwrCntrl
    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  ******************************************************************************/
    275 ESESTATUS phNxpEse_SPM_DisablePwrControl(unsigned long arg) {
    276   int32_t ret = -1;
    277   ESESTATUS status = ESESTATUS_SUCCESS;
    278 
    279   ALOGD_IF(ese_debug_enabled, "%s : Inhibit power control is set to  = 0x%ld",
    280            __FUNCTION__, arg);
    281   ret = phPalEse_ioctl(phPalEse_e_DisablePwrCntrl, pEseDeviceHandle, arg);
    282   if (ret < 0) {
    283     ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
    284     status = ESESTATUS_FAILED;
    285   }
    286 
    287   return status;
    288 }
    289 
    290 /******************************************************************************
    291  * Function         phNxpEse_SPM_GetState
    292  *
    293  * Description      This function gets the current power state of ESE
    294  *
    295  * Returns          On Success ESESTATUS_SUCCESS else proper error code
    296  *
    297  ******************************************************************************/
    298 ESESTATUS phNxpEse_SPM_GetState(spm_state_t* current_state) {
    299   int32_t ret = -1;
    300   ESESTATUS status = ESESTATUS_SUCCESS;
    301   spm_state_t ese_current_state;
    302 
    303   if (current_state == NULL) {
    304     ALOGE("%s : failed Invalid argument", __FUNCTION__);
    305     return ESESTATUS_FAILED;
    306   }
    307   ret = phPalEse_ioctl(phPalEse_e_GetSPMStatus, pEseDeviceHandle,
    308                        (unsigned long)&ese_current_state);
    309   if (ret < 0) {
    310     ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
    311     status = ESESTATUS_FAILED;
    312   } else {
    313     *current_state = ese_current_state; /* Current ESE state */
    314   }
    315 
    316   return status;
    317 }
    318 #ifdef NXP_ESE_JCOP_DWNLD_PROTECTION
    319 /******************************************************************************
    320  * Function         phNxpEse_SPM_SetJcopDwnldState
    321  *
    322  * Description      This function is used to set the JCOP OS download state
    323  *
    324  * Returns          On Success ESESTATUS_SUCCESS else proper error code
    325  *
    326  ******************************************************************************/
    327 ESESTATUS phNxpEse_SPM_SetJcopDwnldState(long arg) {
    328   int ret = -1;
    329   ESESTATUS status = ESESTATUS_SUCCESS;
    330 
    331   ALOGD_IF(ese_debug_enabled, "%s :phNxpEse_SPM_SetJcopDwnldState  = 0x%ld",
    332            __FUNCTION__, arg);
    333   ret = phPalEse_ioctl(phPalEse_e_SetJcopDwnldState, pEseDeviceHandle, arg);
    334   if (ret < 0) {
    335     ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
    336     status = ESESTATUS_FAILED;
    337   }
    338 
    339   return status;
    340 }
    341 #endif