Commit 390a1bd8 authored by Samuel Ortiz's avatar Samuel Ortiz

NFC: Initial Secure Element API

Each NFC adapter can have several links to different secure elements and
that property needs to be exported by the drivers.
A secure element link can be enabled and disabled, and card emulation will
be handled by the currently active one. Otherwise card emulation will be
host implemented.
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent 2ad554a5
...@@ -542,6 +542,7 @@ static int nfcwilink_probe(struct platform_device *pdev) ...@@ -542,6 +542,7 @@ static int nfcwilink_probe(struct platform_device *pdev)
drv->ndev = nci_allocate_device(&nfcwilink_ops, drv->ndev = nci_allocate_device(&nfcwilink_ops,
protocols, protocols,
NFC_SE_NONE,
NFCWILINK_HDR_LEN, NFCWILINK_HDR_LEN,
0); 0);
if (!drv->ndev) { if (!drv->ndev) {
......
...@@ -2525,6 +2525,7 @@ static int pn533_probe(struct usb_interface *interface, ...@@ -2525,6 +2525,7 @@ static int pn533_probe(struct usb_interface *interface,
dev->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols, dev->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols,
NFC_SE_NONE,
dev->ops->tx_header_len + dev->ops->tx_header_len +
PN533_CMD_DATAEXCH_HEAD_LEN, PN533_CMD_DATAEXCH_HEAD_LEN,
dev->ops->tx_tail_len); dev->ops->tx_tail_len);
......
...@@ -801,7 +801,7 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, ...@@ -801,7 +801,7 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
struct nfc_hci_dev **hdev) struct nfc_hci_dev **hdev)
{ {
struct pn544_hci_info *info; struct pn544_hci_info *info;
u32 protocols; u32 protocols, se;
struct nfc_hci_init_data init_data; struct nfc_hci_init_data init_data;
int r; int r;
...@@ -834,8 +834,10 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, ...@@ -834,8 +834,10 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
NFC_PROTO_ISO14443_B_MASK | NFC_PROTO_ISO14443_B_MASK |
NFC_PROTO_NFC_DEP_MASK; NFC_PROTO_NFC_DEP_MASK;
se = NFC_SE_UICC | NFC_SE_EMBEDDED;
info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, 0, info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, 0,
protocols, llc_name, protocols, se, llc_name,
phy_headroom + PN544_CMDS_HEADROOM, phy_headroom + PN544_CMDS_HEADROOM,
phy_tailroom, phy_payload); phy_tailroom, phy_payload);
if (!info->hdev) { if (!info->hdev) {
......
...@@ -59,6 +59,8 @@ struct nfc_hci_ops { ...@@ -59,6 +59,8 @@ struct nfc_hci_ops {
struct nfc_target *target); struct nfc_target *target);
int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event, int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event,
struct sk_buff *skb); struct sk_buff *skb);
int (*enable_se)(struct nfc_dev *dev, u32 secure_element);
int (*disable_se)(struct nfc_dev *dev, u32 secure_element);
}; };
/* Pipes */ /* Pipes */
...@@ -150,6 +152,7 @@ struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops, ...@@ -150,6 +152,7 @@ struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops,
struct nfc_hci_init_data *init_data, struct nfc_hci_init_data *init_data,
unsigned long quirks, unsigned long quirks,
u32 protocols, u32 protocols,
u32 supported_se,
const char *llc_name, const char *llc_name,
int tx_headroom, int tx_headroom,
int tx_tailroom, int tx_tailroom,
......
...@@ -147,6 +147,7 @@ struct nci_dev { ...@@ -147,6 +147,7 @@ struct nci_dev {
/* ----- NCI Devices ----- */ /* ----- NCI Devices ----- */
struct nci_dev *nci_allocate_device(struct nci_ops *ops, struct nci_dev *nci_allocate_device(struct nci_ops *ops,
__u32 supported_protocols, __u32 supported_protocols,
__u32 supported_se,
int tx_headroom, int tx_headroom,
int tx_tailroom); int tx_tailroom);
void nci_free_device(struct nci_dev *ndev); void nci_free_device(struct nci_dev *ndev);
......
...@@ -68,6 +68,8 @@ struct nfc_ops { ...@@ -68,6 +68,8 @@ struct nfc_ops {
void *cb_context); void *cb_context);
int (*tm_send)(struct nfc_dev *dev, struct sk_buff *skb); int (*tm_send)(struct nfc_dev *dev, struct sk_buff *skb);
int (*check_presence)(struct nfc_dev *dev, struct nfc_target *target); int (*check_presence)(struct nfc_dev *dev, struct nfc_target *target);
int (*enable_se)(struct nfc_dev *dev, u32 secure_element);
int (*disable_se)(struct nfc_dev *dev, u32 secure_element);
}; };
#define NFC_TARGET_IDX_ANY -1 #define NFC_TARGET_IDX_ANY -1
...@@ -109,6 +111,9 @@ struct nfc_dev { ...@@ -109,6 +111,9 @@ struct nfc_dev {
struct nfc_genl_data genl_data; struct nfc_genl_data genl_data;
u32 supported_protocols; u32 supported_protocols;
u32 supported_se;
u32 active_se;
int tx_headroom; int tx_headroom;
int tx_tailroom; int tx_tailroom;
...@@ -125,6 +130,7 @@ extern struct class nfc_class; ...@@ -125,6 +130,7 @@ extern struct class nfc_class;
struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
u32 supported_protocols, u32 supported_protocols,
u32 supported_se,
int tx_headroom, int tx_headroom,
int tx_tailroom); int tx_tailroom);
......
...@@ -67,6 +67,11 @@ ...@@ -67,6 +67,11 @@
* subsequent CONNECT and CC messages. * subsequent CONNECT and CC messages.
* If one of the passed parameters is wrong none is set and -EINVAL is * If one of the passed parameters is wrong none is set and -EINVAL is
* returned. * returned.
* @NFC_CMD_ENABLE_SE: Enable the physical link to a specific secure element.
* Once enabled a secure element will handle card emulation mode, i.e.
* starting a poll from a device which has a secure element enabled means
* we want to do SE based card emulation.
* @NFC_CMD_DISABLE_SE: Disable the physical link to a specific secure element.
*/ */
enum nfc_commands { enum nfc_commands {
NFC_CMD_UNSPEC, NFC_CMD_UNSPEC,
...@@ -86,6 +91,8 @@ enum nfc_commands { ...@@ -86,6 +91,8 @@ enum nfc_commands {
NFC_EVENT_TM_DEACTIVATED, NFC_EVENT_TM_DEACTIVATED,
NFC_CMD_LLC_GET_PARAMS, NFC_CMD_LLC_GET_PARAMS,
NFC_CMD_LLC_SET_PARAMS, NFC_CMD_LLC_SET_PARAMS,
NFC_CMD_ENABLE_SE,
NFC_CMD_DISABLE_SE,
/* private: internal use only */ /* private: internal use only */
__NFC_CMD_AFTER_LAST __NFC_CMD_AFTER_LAST
}; };
...@@ -114,6 +121,7 @@ enum nfc_commands { ...@@ -114,6 +121,7 @@ enum nfc_commands {
* @NFC_ATTR_LLC_PARAM_LTO: Link TimeOut parameter * @NFC_ATTR_LLC_PARAM_LTO: Link TimeOut parameter
* @NFC_ATTR_LLC_PARAM_RW: Receive Window size parameter * @NFC_ATTR_LLC_PARAM_RW: Receive Window size parameter
* @NFC_ATTR_LLC_PARAM_MIUX: MIU eXtension parameter * @NFC_ATTR_LLC_PARAM_MIUX: MIU eXtension parameter
* @NFC_ATTR_SE: Available Secure Elements
*/ */
enum nfc_attrs { enum nfc_attrs {
NFC_ATTR_UNSPEC, NFC_ATTR_UNSPEC,
...@@ -134,6 +142,7 @@ enum nfc_attrs { ...@@ -134,6 +142,7 @@ enum nfc_attrs {
NFC_ATTR_LLC_PARAM_LTO, NFC_ATTR_LLC_PARAM_LTO,
NFC_ATTR_LLC_PARAM_RW, NFC_ATTR_LLC_PARAM_RW,
NFC_ATTR_LLC_PARAM_MIUX, NFC_ATTR_LLC_PARAM_MIUX,
NFC_ATTR_SE,
/* private: internal use only */ /* private: internal use only */
__NFC_ATTR_AFTER_LAST __NFC_ATTR_AFTER_LAST
}; };
...@@ -172,6 +181,11 @@ enum nfc_attrs { ...@@ -172,6 +181,11 @@ enum nfc_attrs {
#define NFC_PROTO_NFC_DEP_MASK (1 << NFC_PROTO_NFC_DEP) #define NFC_PROTO_NFC_DEP_MASK (1 << NFC_PROTO_NFC_DEP)
#define NFC_PROTO_ISO14443_B_MASK (1 << NFC_PROTO_ISO14443_B) #define NFC_PROTO_ISO14443_B_MASK (1 << NFC_PROTO_ISO14443_B)
/* NFC Secure Elements */
#define NFC_SE_NONE 0x0
#define NFC_SE_UICC 0x1
#define NFC_SE_EMBEDDED 0x2
struct sockaddr_nfc { struct sockaddr_nfc {
sa_family_t sa_family; sa_family_t sa_family;
__u32 dev_idx; __u32 dev_idx;
......
...@@ -757,6 +757,7 @@ struct nfc_dev *nfc_get_device(unsigned int idx) ...@@ -757,6 +757,7 @@ struct nfc_dev *nfc_get_device(unsigned int idx)
*/ */
struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
u32 supported_protocols, u32 supported_protocols,
u32 supported_se,
int tx_headroom, int tx_tailroom) int tx_headroom, int tx_tailroom)
{ {
struct nfc_dev *dev; struct nfc_dev *dev;
...@@ -774,6 +775,8 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, ...@@ -774,6 +775,8 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
dev->ops = ops; dev->ops = ops;
dev->supported_protocols = supported_protocols; dev->supported_protocols = supported_protocols;
dev->supported_se = supported_se;
dev->active_se = NFC_SE_NONE;
dev->tx_headroom = tx_headroom; dev->tx_headroom = tx_headroom;
dev->tx_tailroom = tx_tailroom; dev->tx_tailroom = tx_tailroom;
......
...@@ -797,6 +797,7 @@ struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops, ...@@ -797,6 +797,7 @@ struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops,
struct nfc_hci_init_data *init_data, struct nfc_hci_init_data *init_data,
unsigned long quirks, unsigned long quirks,
u32 protocols, u32 protocols,
u32 supported_se,
const char *llc_name, const char *llc_name,
int tx_headroom, int tx_headroom,
int tx_tailroom, int tx_tailroom,
...@@ -822,7 +823,7 @@ struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops, ...@@ -822,7 +823,7 @@ struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops,
return NULL; return NULL;
} }
hdev->ndev = nfc_allocate_device(&hci_nfc_ops, protocols, hdev->ndev = nfc_allocate_device(&hci_nfc_ops, protocols, supported_se,
tx_headroom + HCI_CMDS_HEADROOM, tx_headroom + HCI_CMDS_HEADROOM,
tx_tailroom); tx_tailroom);
if (!hdev->ndev) { if (!hdev->ndev) {
......
...@@ -658,6 +658,7 @@ static struct nfc_ops nci_nfc_ops = { ...@@ -658,6 +658,7 @@ static struct nfc_ops nci_nfc_ops = {
*/ */
struct nci_dev *nci_allocate_device(struct nci_ops *ops, struct nci_dev *nci_allocate_device(struct nci_ops *ops,
__u32 supported_protocols, __u32 supported_protocols,
__u32 supported_se,
int tx_headroom, int tx_tailroom) int tx_headroom, int tx_tailroom)
{ {
struct nci_dev *ndev; struct nci_dev *ndev;
...@@ -680,6 +681,7 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops, ...@@ -680,6 +681,7 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops,
ndev->nfc_dev = nfc_allocate_device(&nci_nfc_ops, ndev->nfc_dev = nfc_allocate_device(&nci_nfc_ops,
supported_protocols, supported_protocols,
supported_se,
tx_headroom + NCI_DATA_HDR_SIZE, tx_headroom + NCI_DATA_HDR_SIZE,
tx_tailroom); tx_tailroom);
if (!ndev->nfc_dev) if (!ndev->nfc_dev)
......
...@@ -366,6 +366,7 @@ static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, ...@@ -366,6 +366,7 @@ static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) || if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) || nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) || nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
nla_put_u32(msg, NFC_ATTR_SE, dev->supported_se) ||
nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) || nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) ||
nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode)) nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode))
goto nla_put_failure; goto nla_put_failure;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment