NFC: driver: Add NFC secure zone status query in driver
Implemented secure zone status query calls in NFC driver Change-Id: If41681ec14dbc53401182667df1256d5818f8576
This commit is contained in:
@@ -5,6 +5,11 @@ DLKM_DIR := $(TOP)/device/qcom/common/dlkm
|
|||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS=$(PWD)/$(call intermediates-dir-for,DLKM,sec-module-symvers)/Module.symvers
|
||||||
|
|
||||||
|
LOCAL_REQUIRED_MODULES := sec-module-symvers
|
||||||
|
LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,sec-module-symvers)/Module.symvers
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_MODULE := nxp-nci.ko
|
LOCAL_MODULE := nxp-nci.ko
|
||||||
|
3
Kbuild
3
Kbuild
@@ -6,6 +6,9 @@ LINUXINCLUDE += -I$(NFC_ROOT)/include/uapi/linux/nfc
|
|||||||
|
|
||||||
LINUXINCLUDE += -include $(NFC_ROOT)/config/gki_nfc_conf.h
|
LINUXINCLUDE += -include $(NFC_ROOT)/config/gki_nfc_conf.h
|
||||||
|
|
||||||
|
LINUXINCLUDE += -I$(NFC_ROOT)/../../../qcom/opensource/securemsm-kernel/smcinvoke/
|
||||||
|
LINUXINCLUDE += -I$(NFC_ROOT)/../../../qcom/opensource/securemsm-kernel/linux/
|
||||||
|
|
||||||
obj-$(CONFIG_NXP_NFC_I2C) += nxp-nci.o
|
obj-$(CONFIG_NXP_NFC_I2C) += nxp-nci.o
|
||||||
|
|
||||||
#source files
|
#source files
|
||||||
|
104
nfc/common.c
104
nfc/common.c
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
static int secure_zone = 1;
|
|
||||||
|
|
||||||
int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs,
|
int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs,
|
||||||
uint8_t interface)
|
uint8_t interface)
|
||||||
@@ -131,14 +130,15 @@ int get_valid_gpio(int gpio)
|
|||||||
void gpio_set_ven(struct nfc_dev *nfc_dev, int value)
|
void gpio_set_ven(struct nfc_dev *nfc_dev, int value)
|
||||||
{
|
{
|
||||||
struct platform_gpio *nfc_gpio = &nfc_dev->configs.gpio;
|
struct platform_gpio *nfc_gpio = &nfc_dev->configs.gpio;
|
||||||
|
if(!nfc_dev->secure_zone) {
|
||||||
|
if (gpio_get_value(nfc_gpio->ven) != value) {
|
||||||
|
pr_debug("%s: value %d\n", __func__, value);
|
||||||
|
|
||||||
if (gpio_get_value(nfc_gpio->ven) != value) {
|
gpio_set_value(nfc_gpio->ven, value);
|
||||||
pr_debug("%s: value %d\n", __func__, value);
|
/* hardware dependent delay */
|
||||||
|
usleep_range(NFC_GPIO_SET_WAIT_TIME_US,
|
||||||
gpio_set_value(nfc_gpio->ven, value);
|
NFC_GPIO_SET_WAIT_TIME_US + 100);
|
||||||
/* hardware dependent delay */
|
}
|
||||||
usleep_range(NFC_GPIO_SET_WAIT_TIME_US,
|
|
||||||
NFC_GPIO_SET_WAIT_TIME_US + 100);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,9 +407,12 @@ long nfc_dev_compat_ioctl(struct file *pfile, unsigned int cmd,
|
|||||||
int nfc_post_init(struct nfc_dev *nfc_dev)
|
int nfc_post_init(struct nfc_dev *nfc_dev)
|
||||||
{
|
{
|
||||||
int ret=0;
|
int ret=0;
|
||||||
|
static int post_init_success;
|
||||||
struct platform_configs nfc_configs;
|
struct platform_configs nfc_configs;
|
||||||
struct platform_gpio *nfc_gpio;
|
struct platform_gpio *nfc_gpio;
|
||||||
|
|
||||||
|
if(post_init_success)
|
||||||
|
return 0;
|
||||||
if (!nfc_dev)
|
if (!nfc_dev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
@@ -449,12 +452,79 @@ int nfc_post_init(struct nfc_dev *nfc_dev)
|
|||||||
/*Initialising sempahore to disbale NFC Ven GPIO only after eSE is power off flag is set */
|
/*Initialising sempahore to disbale NFC Ven GPIO only after eSE is power off flag is set */
|
||||||
sema_init(&sem_eSE_pwr_off,0);
|
sema_init(&sem_eSE_pwr_off,0);
|
||||||
|
|
||||||
|
post_init_success = 1;
|
||||||
pr_info("%s success\n", __func__);
|
pr_info("%s success\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nfc_hw_secure_check() - Checks the NFC secure zone status
|
||||||
|
*
|
||||||
|
* Queries the TZ secure libraries if NFC is in secure zone statue or not.
|
||||||
|
*
|
||||||
|
* Return: 0 if FEATURE_NOT_SUPPORTED/PERIPHERAL_NOT_FOUND/state is 2 and
|
||||||
|
* return 1(non-secure) otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool nfc_hw_secure_check(void)
|
||||||
|
{
|
||||||
|
struct Object client_env;
|
||||||
|
struct Object app_object;
|
||||||
|
u32 wifi_uid = HW_NFC_UID;
|
||||||
|
union ObjectArg obj_arg[2] = {{{0, 0}}};
|
||||||
|
int ret;
|
||||||
|
bool retstat = 1;
|
||||||
|
u8 state = 0;
|
||||||
|
|
||||||
|
/* get rootObj */
|
||||||
|
ret = get_client_env_object(&client_env);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("Failed to get client_env_object, ret: %d\n", ret);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = IClientEnv_open(client_env, HW_STATE_UID, &app_object);
|
||||||
|
if (ret) {
|
||||||
|
pr_debug("Failed to get app_object, ret: %d\n", ret);
|
||||||
|
if (ret == FEATURE_NOT_SUPPORTED) {
|
||||||
|
retstat = 0; /* Do not Assert */
|
||||||
|
pr_debug("Secure HW feature not supported\n");
|
||||||
|
}
|
||||||
|
goto exit_release_clientenv;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj_arg[0].b = (struct ObjectBuf) {&wifi_uid, sizeof(u32)};
|
||||||
|
obj_arg[1].b = (struct ObjectBuf) {&state, sizeof(u8)};
|
||||||
|
ret = Object_invoke(app_object, HW_OP_GET_STATE, obj_arg,
|
||||||
|
ObjectCounts_pack(1, 1, 0, 0));
|
||||||
|
|
||||||
|
pr_info("SMC invoke ret: %d state: %d\n", ret, state);
|
||||||
|
if (ret) {
|
||||||
|
if (ret == PERIPHERAL_NOT_FOUND) {
|
||||||
|
retstat = 0; /* Do not Assert */
|
||||||
|
pr_debug("Secure HW mode is not updated. Peripheral not found\n");
|
||||||
|
}
|
||||||
|
goto exit_release_app_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state == 1) {
|
||||||
|
/*Secure Zone*/
|
||||||
|
retstat = 1;
|
||||||
|
} else {
|
||||||
|
/*Non-Secure Zone*/
|
||||||
|
retstat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_release_app_obj:
|
||||||
|
Object_release(app_object);
|
||||||
|
exit_release_clientenv:
|
||||||
|
Object_release(client_env);
|
||||||
|
|
||||||
|
return retstat;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nfc_dynamic_protection_ioctl() - dynamic protection control
|
* nfc_dynamic_protection_ioctl() - dynamic protection control
|
||||||
* @nfc_dev: nfc device data structure
|
* @nfc_dev: nfc device data structure
|
||||||
@@ -491,7 +561,7 @@ int nfc_dynamic_protection_ioctl(struct nfc_dev *nfc_dev, unsigned long sec_zone
|
|||||||
}
|
}
|
||||||
ret = nfc_ioctl_power_states(nfc_dev, 0);
|
ret = nfc_ioctl_power_states(nfc_dev, 0);
|
||||||
/*set driver as secure zone, such that no ioctl calls are allowed*/
|
/*set driver as secure zone, such that no ioctl calls are allowed*/
|
||||||
secure_zone=1;
|
nfc_dev->secure_zone = true;
|
||||||
pr_info("Driver Secure flag set successful\n");
|
pr_info("Driver Secure flag set successful\n");
|
||||||
} else {
|
} else {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@@ -499,7 +569,7 @@ int nfc_dynamic_protection_ioctl(struct nfc_dev *nfc_dev, unsigned long sec_zone
|
|||||||
}
|
}
|
||||||
else if(sec_zone_trans == 0) {
|
else if(sec_zone_trans == 0) {
|
||||||
chk_eSE_pwr_off = 0;
|
chk_eSE_pwr_off = 0;
|
||||||
secure_zone=0;
|
nfc_dev->secure_zone = false;
|
||||||
|
|
||||||
if(init_flag) {
|
if(init_flag) {
|
||||||
/*Initialize once,only during the first non-secure entry*/
|
/*Initialize once,only during the first non-secure entry*/
|
||||||
@@ -508,7 +578,8 @@ int nfc_dynamic_protection_ioctl(struct nfc_dev *nfc_dev, unsigned long sec_zone
|
|||||||
init_flag=0;
|
init_flag=0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = nfc_ioctl_power_states(nfc_dev, 1);
|
if(!gpio_get_value(nfc_gpio->ven))
|
||||||
|
ret = nfc_ioctl_power_states(nfc_dev, 1);
|
||||||
}
|
}
|
||||||
pr_info("Func Driver Secure flag clear successful\n");
|
pr_info("Func Driver Secure flag clear successful\n");
|
||||||
} else {
|
} else {
|
||||||
@@ -541,7 +612,7 @@ long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/*Avoiding ioctl call in secure zone*/
|
/*Avoiding ioctl call in secure zone*/
|
||||||
if(secure_zone) {
|
if(nfc_dev->secure_zone) {
|
||||||
if(cmd!=NFC_SECURE_ZONE) {
|
if(cmd!=NFC_SECURE_ZONE) {
|
||||||
pr_debug("nfc_dev_ioctl failed\n");
|
pr_debug("nfc_dev_ioctl failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -665,10 +736,11 @@ int nfc_dev_close(struct inode *inode, struct file *filp)
|
|||||||
int validate_nfc_state_nci(struct nfc_dev *nfc_dev)
|
int validate_nfc_state_nci(struct nfc_dev *nfc_dev)
|
||||||
{
|
{
|
||||||
struct platform_gpio *nfc_gpio = &nfc_dev->configs.gpio;
|
struct platform_gpio *nfc_gpio = &nfc_dev->configs.gpio;
|
||||||
|
if(!nfc_dev->secure_zone) {
|
||||||
if (!gpio_get_value(nfc_gpio->ven)) {
|
if (!gpio_get_value(nfc_gpio->ven)) {
|
||||||
pr_err("%s: ven low - nfcc powered off\n", __func__);
|
pr_err("%s: ven low - nfcc powered off\n", __func__);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (get_valid_gpio(nfc_gpio->dwl_req) == 1) {
|
if (get_valid_gpio(nfc_gpio->dwl_req) == 1) {
|
||||||
pr_err("%s: fw download in-progress\n", __func__);
|
pr_err("%s: fw download in-progress\n", __func__);
|
||||||
|
17
nfc/common.h
17
nfc/common.h
@@ -33,6 +33,11 @@
|
|||||||
#include "i2c_drv.h"
|
#include "i2c_drv.h"
|
||||||
#include "ese_cold_reset.h"
|
#include "ese_cold_reset.h"
|
||||||
|
|
||||||
|
/*secure library headers*/
|
||||||
|
#include "smcinvoke.h"
|
||||||
|
#include "smcinvoke_object.h"
|
||||||
|
#include "IClientEnv.h"
|
||||||
|
|
||||||
/* Max device count for this driver */
|
/* Max device count for this driver */
|
||||||
#define DEV_COUNT 1
|
#define DEV_COUNT 1
|
||||||
/* i2c device class */
|
/* i2c device class */
|
||||||
@@ -115,6 +120,13 @@
|
|||||||
#define NFC_VDDIO_MAX 1950000 //in uV
|
#define NFC_VDDIO_MAX 1950000 //in uV
|
||||||
#define NFC_CURRENT_MAX 157000 //in uA
|
#define NFC_CURRENT_MAX 157000 //in uA
|
||||||
|
|
||||||
|
//NFC ID for registration with secure libraries
|
||||||
|
#define HW_STATE_UID 0x108
|
||||||
|
#define HW_OP_GET_STATE 1
|
||||||
|
#define HW_NFC_UID 0x506
|
||||||
|
#define FEATURE_NOT_SUPPORTED 12
|
||||||
|
#define PERIPHERAL_NOT_FOUND 10
|
||||||
|
|
||||||
|
|
||||||
#define NUM_OF_IPC_LOG_PAGES (2)
|
#define NUM_OF_IPC_LOG_PAGES (2)
|
||||||
#define PKT_MAX_LEN (4) // no of max bytes to print for cmd/resp
|
#define PKT_MAX_LEN (4) // no of max bytes to print for cmd/resp
|
||||||
@@ -135,6 +147,7 @@ do { \
|
|||||||
static struct semaphore sem_eSE_pwr_off;
|
static struct semaphore sem_eSE_pwr_off;
|
||||||
static chk_eSE_pwr_off;
|
static chk_eSE_pwr_off;
|
||||||
|
|
||||||
|
|
||||||
enum ese_ioctl_request {
|
enum ese_ioctl_request {
|
||||||
/* eSE POWER ON */
|
/* eSE POWER ON */
|
||||||
ESE_POWER_ON = 0,
|
ESE_POWER_ON = 0,
|
||||||
@@ -262,6 +275,9 @@ struct nfc_dev {
|
|||||||
|
|
||||||
union nqx_uinfo nqx_info;
|
union nqx_uinfo nqx_info;
|
||||||
|
|
||||||
|
/*secure zone state*/
|
||||||
|
bool secure_zone;
|
||||||
|
|
||||||
/* CLK control */
|
/* CLK control */
|
||||||
bool clk_run;
|
bool clk_run;
|
||||||
struct clk *s_clk;
|
struct clk *s_clk;
|
||||||
@@ -305,4 +321,5 @@ int nfc_clock_select(struct nfc_dev *nfc_dev);
|
|||||||
int nfc_clock_deselect(struct nfc_dev *nfc_dev);
|
int nfc_clock_deselect(struct nfc_dev *nfc_dev);
|
||||||
int nfc_post_init(struct nfc_dev *nfc_dev);
|
int nfc_post_init(struct nfc_dev *nfc_dev);
|
||||||
int nfc_dynamic_protection_ioctl(struct nfc_dev *nfc_dev, unsigned long sec_zone_trans);
|
int nfc_dynamic_protection_ioctl(struct nfc_dev *nfc_dev, unsigned long sec_zone_trans);
|
||||||
|
bool nfc_hw_secure_check(void);
|
||||||
#endif /* _COMMON_H_ */
|
#endif /* _COMMON_H_ */
|
||||||
|
@@ -156,10 +156,12 @@ int i2c_read(struct nfc_dev *nfc_dev, char *buf, size_t count, int timeout)
|
|||||||
|
|
||||||
if (gpio_get_value(nfc_gpio->irq))
|
if (gpio_get_value(nfc_gpio->irq))
|
||||||
break;
|
break;
|
||||||
if (!gpio_get_value(nfc_gpio->ven)) {
|
if(!nfc_dev->secure_zone) {
|
||||||
pr_info("%s: releasing read\n", __func__);
|
if (!gpio_get_value(nfc_gpio->ven)) {
|
||||||
ret = -EIO;
|
pr_info("%s: releasing read\n", __func__);
|
||||||
goto err;
|
ret = -EIO;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* NFC service wanted to close the driver so,
|
* NFC service wanted to close the driver so,
|
||||||
@@ -413,6 +415,15 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|||||||
goto err_ldo_config_failed;
|
goto err_ldo_config_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*Check NFC Secure Zone status*/
|
||||||
|
if(!nfc_hw_secure_check()) {
|
||||||
|
nfc_post_init(nfc_dev);
|
||||||
|
nfc_dev->secure_zone = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nfc_dev->secure_zone = true;
|
||||||
|
pr_info("%s:nfc_dev->secure_zone = %s", __func__, nfc_dev->secure_zone ? "true" : "false");
|
||||||
|
|
||||||
if(nfc_dev->configs.clk_pin_voting)
|
if(nfc_dev->configs.clk_pin_voting)
|
||||||
nfc_dev->clk_run = false;
|
nfc_dev->clk_run = false;
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user