From b6355e972aaab0173ce11a1650e7dba67f820918 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Sat, 6 Jun 2015 13:16:37 +0200 Subject: NFC: nci: Handle proprietary response and notifications Allow for drivers to explicitly define handlers for each proprietary notifications and responses they expect to support. Reviewed-by: Christophe Ricard Signed-off-by: Samuel Ortiz --- include/net/nfc/nci_core.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include/net') diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index d4dcc71..c49688c 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h @@ -66,6 +66,12 @@ enum nci_state { struct nci_dev; +struct nci_prop_ops { + __u16 opcode; + int (*rsp)(struct nci_dev *dev, struct sk_buff *skb); + int (*ntf)(struct nci_dev *dev, struct sk_buff *skb); +}; + struct nci_ops { int (*open)(struct nci_dev *ndev); int (*close)(struct nci_dev *ndev); @@ -84,12 +90,16 @@ struct nci_ops { struct sk_buff *skb); void (*hci_cmd_received)(struct nci_dev *ndev, u8 pipe, u8 cmd, struct sk_buff *skb); + + struct nci_prop_ops *prop_ops; + size_t n_prop_ops; }; #define NCI_MAX_SUPPORTED_RF_INTERFACES 4 #define NCI_MAX_DISCOVERED_TARGETS 10 #define NCI_MAX_NUM_NFCEE 255 #define NCI_MAX_CONN_ID 7 +#define NCI_MAX_PROPRIETARY_CMD 64 struct nci_conn_info { struct list_head list; @@ -320,6 +330,10 @@ static inline void *nci_get_drvdata(struct nci_dev *ndev) void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb); void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb); +int nci_prop_rsp_packet(struct nci_dev *ndev, __u16 opcode, + struct sk_buff *skb); +int nci_prop_ntf_packet(struct nci_dev *ndev, __u16 opcode, + struct sk_buff *skb); void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb); int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload); int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb); -- cgit v1.1 From c39daeee50eb0b95d3b91bda21b77955a459ee5f Mon Sep 17 00:00:00 2001 From: Christophe Ricard Date: Sat, 6 Jun 2015 13:16:40 +0200 Subject: NFC: nci: Add nci init ops for early device initialization Some device may need to execute some proprietary commands in order to "wake-up"; Before the nci state initialization. Signed-off-by: Christophe Ricard Signed-off-by: Samuel Ortiz --- include/net/nfc/nci_core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/net') diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index c49688c..886854a 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h @@ -73,6 +73,7 @@ struct nci_prop_ops { }; struct nci_ops { + int (*init)(struct nci_dev *ndev); int (*open)(struct nci_dev *ndev); int (*close)(struct nci_dev *ndev); int (*send)(struct nci_dev *ndev, struct sk_buff *skb); -- cgit v1.1 From 759afb8d288ffbe9a1cdb20af037b5c072dc38b2 Mon Sep 17 00:00:00 2001 From: Christophe Ricard Date: Sat, 6 Jun 2015 13:16:41 +0200 Subject: NFC: nci: Add nci_prop_cmd allowing to send proprietary nci cmd Handle allowing to send proprietary nci commands anywhere in the nci state machine. Signed-off-by: Christophe Ricard Signed-off-by: Samuel Ortiz --- include/net/nfc/nci_core.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/net') diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index 886854a..98f18a2 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h @@ -275,6 +275,8 @@ int nci_request(struct nci_dev *ndev, void (*req)(struct nci_dev *ndev, unsigned long opt), unsigned long opt, __u32 timeout); +int nci_prop_cmd(struct nci_dev *ndev, __u8 oid, size_t len, __u8 *payload); + int nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb); int nci_set_config(struct nci_dev *ndev, __u8 id, size_t len, __u8 *val); -- cgit v1.1 From 8115dd5905318afcde713726064ec052b7d488cf Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 14 Oct 2014 01:42:23 +0200 Subject: NFC: Introduce vendor commands structures Together with inline routines to associate a vendor commands array with an NFC device. Vendor commands allow vendors to implement their very specific operations from driver code instead of adding new stack ops for non NFC generic commands. Vendors need to select their own unique IDs and use that as a namespace for defining sub commands. Signed-off-by: Samuel Ortiz --- include/net/nfc/hci.h | 7 +++++++ include/net/nfc/nci_core.h | 7 +++++++ include/net/nfc/nfc.h | 22 ++++++++++++++++++++++ 3 files changed, 36 insertions(+) (limited to 'include/net') diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h index 020a814..316694d 100644 --- a/include/net/nfc/hci.h +++ b/include/net/nfc/hci.h @@ -179,6 +179,13 @@ void nfc_hci_unregister_device(struct nfc_hci_dev *hdev); void nfc_hci_set_clientdata(struct nfc_hci_dev *hdev, void *clientdata); void *nfc_hci_get_clientdata(struct nfc_hci_dev *hdev); +static inline int nfc_hci_set_vendor_cmds(struct nfc_hci_dev *hdev, + struct nfc_vendor_cmd *cmds, + int n_cmds) +{ + return nfc_set_vendor_cmds(hdev->ndev, cmds, n_cmds); +} + void nfc_hci_driver_failure(struct nfc_hci_dev *hdev, int err); int nfc_hci_result_to_errno(u8 result); diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index 98f18a2..9d77ed5 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h @@ -331,6 +331,13 @@ static inline void *nci_get_drvdata(struct nci_dev *ndev) return ndev->driver_data; } +static inline int nci_set_vendor_cmds(struct nci_dev *ndev, + struct nfc_vendor_cmd *cmds, + int n_cmds) +{ + return nfc_set_vendor_cmds(ndev->nfc_dev, cmds, n_cmds); +} + void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb); void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb); int nci_prop_rsp_packet(struct nci_dev *ndev, __u16 opcode, diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 7ac029c..f9e58ae 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -165,6 +165,12 @@ struct nfc_genl_data { struct mutex genl_data_mutex; }; +struct nfc_vendor_cmd { + __u32 vendor_id; + __u32 subcmd; + int (*doit)(struct nfc_dev *dev, void *data, size_t data_len); +}; + struct nfc_dev { int idx; u32 target_next_idx; @@ -193,6 +199,9 @@ struct nfc_dev { struct rfkill *rfkill; + struct nfc_vendor_cmd *vendor_cmds; + int n_vendor_cmds; + struct nfc_ops *ops; }; #define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev) @@ -296,4 +305,17 @@ struct nfc_se *nfc_find_se(struct nfc_dev *dev, u32 se_idx); void nfc_send_to_raw_sock(struct nfc_dev *dev, struct sk_buff *skb, u8 payload_type, u8 direction); +static inline int nfc_set_vendor_cmds(struct nfc_dev *dev, + struct nfc_vendor_cmd *cmds, + int n_cmds) +{ + if (dev->vendor_cmds || dev->n_vendor_cmds) + return -EINVAL; + + dev->vendor_cmds = cmds; + dev->n_vendor_cmds = n_cmds; + + return 0; +} + #endif /* __NET_NFC_H */ -- cgit v1.1 From 9961127d4bce6325e9a0b0fb105e0c85a6c62cb7 Mon Sep 17 00:00:00 2001 From: Vincent Cuissard Date: Thu, 11 Jun 2015 11:25:47 +0200 Subject: NFC: nci: add generic uart support Some NFC controller supports UART as host interface. As with SPI, a lot of code can be shared between vendor drivers. This patch add the generic support of UART and provides some extension API for vendor specific needs. This code is strongly inspired by the Bluetooth HCI ldisc implementation. NCI UART vendor drivers will have to register themselves to this layer via nci_uart_register. Underlying tty will have to be configured from user land thanks to an ioctl. Signed-off-by: Vincent Cuissard Signed-off-by: Samuel Ortiz --- include/net/nfc/nci.h | 1 + include/net/nfc/nci_core.h | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) (limited to 'include/net') diff --git a/include/net/nfc/nci.h b/include/net/nfc/nci.h index a2f2f3d..75d2e18 100644 --- a/include/net/nfc/nci.h +++ b/include/net/nfc/nci.h @@ -35,6 +35,7 @@ #define NCI_MAX_NUM_RF_CONFIGS 10 #define NCI_MAX_NUM_CONN 10 #define NCI_MAX_PARAM_LEN 251 +#define NCI_MAX_PACKET_SIZE 258 /* NCI Status Codes */ #define NCI_STATUS_OK 0x00 diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index 9d77ed5..01fc8c5 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -391,4 +392,50 @@ int nci_spi_send(struct nci_spi *nspi, struct sk_buff *skb); struct sk_buff *nci_spi_read(struct nci_spi *nspi); +/* ----- NCI UART ---- */ + +/* Ioctl */ +#define NCIUARTSETDRIVER _IOW('U', 0, char *) + +enum nci_uart_driver { + NCI_UART_DRIVER_MARVELL = 0, + NCI_UART_DRIVER_MAX +}; + +struct nci_uart; + +struct nci_uart_ops { + int (*open)(struct nci_uart *nci_uart); + void (*close)(struct nci_uart *nci_uart); + int (*recv)(struct nci_uart *nci_uart, struct sk_buff *skb); + int (*recv_buf)(struct nci_uart *nci_uart, const u8 *data, char *flags, + int count); + int (*send)(struct nci_uart *nci_uart, struct sk_buff *skb); + void (*tx_start)(struct nci_uart *nci_uart); + void (*tx_done)(struct nci_uart *nci_uart); +}; + +struct nci_uart { + struct module *owner; + struct nci_uart_ops ops; + const char *name; + enum nci_uart_driver driver; + + /* Dynamic data */ + struct nci_dev *ndev; + spinlock_t rx_lock; + struct work_struct write_work; + struct tty_struct *tty; + unsigned long tx_state; + struct sk_buff_head tx_q; + struct sk_buff *tx_skb; + struct sk_buff *rx_skb; + int rx_packet_len; + void *drv_data; +}; + +int nci_uart_register(struct nci_uart *nu); +void nci_uart_unregister(struct nci_uart *nu); +void nci_uart_set_config(struct nci_uart *nu, int baudrate, int flow_ctrl); + #endif /* __NCI_CORE_H */ -- cgit v1.1