From e1da0efa2ee71df957b280bcfa41f82ce6986a1d Mon Sep 17 00:00:00 2001 From: Eric Lapuyade Date: Tue, 10 Apr 2012 19:43:05 +0200 Subject: NFC: Export target lost function NFC drivers will call this routine when they detect that a tag leaves the RF field. This will eventually lead to the corresponding netlink event to be sent. Signed-off-by: Eric Lapuyade Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- include/net/nfc/nfc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/net/nfc') diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index bac070bf3514..57ea09533ae1 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -181,6 +181,7 @@ int nfc_set_remote_general_bytes(struct nfc_dev *dev, int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, int ntargets); +int nfc_target_lost(struct nfc_dev *dev, u32 target_idx); int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, u8 comm_mode, u8 rf_mode); -- cgit v1.2.3 From 8b8d2e08bf0d50193931afd27482a59376b66b2b Mon Sep 17 00:00:00 2001 From: Eric Lapuyade Date: Tue, 10 Apr 2012 19:43:06 +0200 Subject: NFC: HCI support This is an implementation of ETSI TS 102 622 specification. Many NFC chipsets use HCI as the host <-> target protocol on top of a serial link like i2c. Signed-off-by: Eric Lapuyade Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- include/net/nfc/hci.h | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/net/nfc/nfc.h | 1 + 2 files changed, 199 insertions(+) create mode 100644 include/net/nfc/hci.h (limited to 'include/net/nfc') diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h new file mode 100644 index 000000000000..aca65a5a9d0d --- /dev/null +++ b/include/net/nfc/hci.h @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __NET_HCI_H +#define __NET_HCI_H + +#include + +#include + +struct nfc_hci_dev; + +struct nfc_hci_ops { + int (*open) (struct nfc_hci_dev *hdev); + void (*close) (struct nfc_hci_dev *hdev); + int (*hci_ready) (struct nfc_hci_dev *hdev); + int (*xmit) (struct nfc_hci_dev *hdev, struct sk_buff *skb); + int (*start_poll) (struct nfc_hci_dev *hdev, u32 protocols); + int (*target_from_gate) (struct nfc_hci_dev *hdev, u8 gate, + struct nfc_target *target); + int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate, + struct nfc_target *target); + int (*data_exchange) (struct nfc_hci_dev *hdev, + struct nfc_target *target, + struct sk_buff *skb, struct sk_buff **res_skb); +}; + +#define NFC_HCI_MAX_CUSTOM_GATES 15 +struct nfc_hci_init_data { + u8 gate_count; + u8 gates[NFC_HCI_MAX_CUSTOM_GATES]; + char session_id[9]; +}; + +typedef int (*xmit) (struct sk_buff *skb, void *cb_data); + +#define NFC_HCI_MAX_GATES 256 + +struct nfc_hci_dev { + struct nfc_dev *ndev; + + u32 max_data_link_payload; + + struct mutex msg_tx_mutex; + + struct list_head msg_tx_queue; + + struct workqueue_struct *msg_tx_wq; + struct work_struct msg_tx_work; + + struct timer_list cmd_timer; + struct hci_msg *cmd_pending_msg; + + struct sk_buff_head rx_hcp_frags; + + struct workqueue_struct *msg_rx_wq; + struct work_struct msg_rx_work; + + struct sk_buff_head msg_rx_queue; + + struct nfc_hci_ops *ops; + + struct nfc_hci_init_data init_data; + + void *clientdata; + + u8 gate2pipe[NFC_HCI_MAX_GATES]; + + bool poll_started; + struct nfc_target *targets; + int target_count; + + u8 sw_romlib; + u8 sw_patch; + u8 sw_flashlib_major; + u8 sw_flashlib_minor; + + u8 hw_derivative; + u8 hw_version; + u8 hw_mpw; + u8 hw_software; + u8 hw_bsid; +}; + +/* hci device allocation */ +struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops, + struct nfc_hci_init_data *init_data, + u32 protocols, + int tx_headroom, + int tx_tailroom, + int max_link_payload); +void nfc_hci_free_device(struct nfc_hci_dev *hdev); + +int nfc_hci_register_device(struct nfc_hci_dev *hdev); +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); + +/* Host IDs */ +#define NFC_HCI_HOST_CONTROLLER_ID 0x00 +#define NFC_HCI_TERMINAL_HOST_ID 0x01 +#define NFC_HCI_UICC_HOST_ID 0x02 + +/* Host Controller Gates and registry indexes */ +#define NFC_HCI_ADMIN_GATE 0x00 +#define NFC_HCI_ADMIN_SESSION_IDENTITY 0x01 +#define NFC_HCI_ADMIN_MAX_PIPE 0x02 +#define NFC_HCI_ADMIN_WHITELIST 0x03 +#define NFC_HCI_ADMIN_HOST_LIST 0x04 + +#define NFC_HCI_LOOPBACK_GATE 0x04 + +#define NFC_HCI_ID_MGMT_GATE 0x05 +#define NFC_HCI_ID_MGMT_VERSION_SW 0x01 +#define NFC_HCI_ID_MGMT_VERSION_HW 0x03 +#define NFC_HCI_ID_MGMT_VENDOR_NAME 0x04 +#define NFC_HCI_ID_MGMT_MODEL_ID 0x05 +#define NFC_HCI_ID_MGMT_HCI_VERSION 0x02 +#define NFC_HCI_ID_MGMT_GATES_LIST 0x06 + +#define NFC_HCI_LINK_MGMT_GATE 0x06 +#define NFC_HCI_LINK_MGMT_REC_ERROR 0x01 + +#define NFC_HCI_RF_READER_B_GATE 0x11 +#define NFC_HCI_RF_READER_B_PUPI 0x03 +#define NFC_HCI_RF_READER_B_APPLICATION_DATA 0x04 +#define NFC_HCI_RF_READER_B_AFI 0x02 +#define NFC_HCI_RF_READER_B_HIGHER_LAYER_RESPONSE 0x01 +#define NFC_HCI_RF_READER_B_HIGHER_LAYER_DATA 0x05 + +#define NFC_HCI_RF_READER_A_GATE 0x13 +#define NFC_HCI_RF_READER_A_UID 0x02 +#define NFC_HCI_RF_READER_A_ATQA 0x04 +#define NFC_HCI_RF_READER_A_APPLICATION_DATA 0x05 +#define NFC_HCI_RF_READER_A_SAK 0x03 +#define NFC_HCI_RF_READER_A_FWI_SFGT 0x06 +#define NFC_HCI_RF_READER_A_DATARATE_MAX 0x01 + +#define NFC_HCI_TYPE_A_SEL_PROT(x) (((x) & 0x60) >> 5) +#define NFC_HCI_TYPE_A_SEL_PROT_MIFARE 0 +#define NFC_HCI_TYPE_A_SEL_PROT_ISO14443 1 +#define NFC_HCI_TYPE_A_SEL_PROT_DEP 2 +#define NFC_HCI_TYPE_A_SEL_PROT_ISO14443_DEP 3 + +/* Generic events */ +#define NFC_HCI_EVT_HCI_END_OF_OPERATION 0x01 +#define NFC_HCI_EVT_POST_DATA 0x02 +#define NFC_HCI_EVT_HOT_PLUG 0x03 + +/* Reader RF gates events */ +#define NFC_HCI_EVT_READER_REQUESTED 0x10 +#define NFC_HCI_EVT_END_OPERATION 0x11 + +/* Reader Application gate events */ +#define NFC_HCI_EVT_TARGET_DISCOVERED 0x10 + +/* receiving messages from lower layer */ +void nfc_hci_resp_received(struct nfc_hci_dev *hdev, u8 result, + struct sk_buff *skb); +void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, + struct sk_buff *skb); +void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, + struct sk_buff *skb); +void nfc_hci_recv_frame(struct nfc_hci_dev *hdev, struct sk_buff *skb); + +/* connecting to gates and sending hci instructions */ +int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate); +int nfc_hci_disconnect_gate(struct nfc_hci_dev *hdev, u8 gate); +int nfc_hci_disconnect_all_gates(struct nfc_hci_dev *hdev); +int nfc_hci_get_param(struct nfc_hci_dev *hdev, u8 gate, u8 idx, + struct sk_buff **skb); +int nfc_hci_set_param(struct nfc_hci_dev *hdev, u8 gate, u8 idx, + const u8 *param, size_t param_len); +int nfc_hci_send_cmd(struct nfc_hci_dev *hdev, u8 gate, u8 cmd, + const u8 *param, size_t param_len, struct sk_buff **skb); +int nfc_hci_send_response(struct nfc_hci_dev *hdev, u8 gate, u8 response, + const u8 *param, size_t param_len); +int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event, + const u8 *param, size_t param_len); + +#endif /* __NET_HCI_H */ diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 57ea09533ae1..431a6c59b418 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -78,6 +78,7 @@ struct nfc_target { u8 sensb_res[NFC_SENSB_RES_MAXSIZE]; u8 sensf_res_len; u8 sensf_res[NFC_SENSF_RES_MAXSIZE]; + u8 hci_reader_gate; }; struct nfc_genl_data { -- cgit v1.2.3 From eb738fe535ae8e44402c372ecc1321eee0552a09 Mon Sep 17 00:00:00 2001 From: Eric Lapuyade Date: Tue, 10 Apr 2012 19:43:07 +0200 Subject: NFC: SHDLC implementation Most NFC HCI chipsets actually use a simplified HDLC link layer to carry HCI payloads. This implementation registers itself as an HCI device on behalf of the NFC driver. Signed-off-by: Eric Lapuyade Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- include/net/nfc/shdlc.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 include/net/nfc/shdlc.h (limited to 'include/net/nfc') diff --git a/include/net/nfc/shdlc.h b/include/net/nfc/shdlc.h new file mode 100644 index 000000000000..1071987d0408 --- /dev/null +++ b/include/net/nfc/shdlc.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __NFC_SHDLC_H +#define __NFC_SHDLC_H + +struct nfc_shdlc; + +struct nfc_shdlc_ops { + int (*open) (struct nfc_shdlc *shdlc); + void (*close) (struct nfc_shdlc *shdlc); + int (*hci_ready) (struct nfc_shdlc *shdlc); + int (*xmit) (struct nfc_shdlc *shdlc, struct sk_buff *skb); + int (*start_poll) (struct nfc_shdlc *shdlc, u32 protocols); + int (*target_from_gate) (struct nfc_shdlc *shdlc, u8 gate, + struct nfc_target *target); + int (*complete_target_discovered) (struct nfc_shdlc *shdlc, u8 gate, + struct nfc_target *target); + int (*data_exchange) (struct nfc_shdlc *shdlc, + struct nfc_target *target, + struct sk_buff *skb, struct sk_buff **res_skb); +}; + +enum shdlc_state { + SHDLC_DISCONNECTED = 0, + SHDLC_CONNECTING = 1, + SHDLC_NEGOCIATING = 2, + SHDLC_CONNECTED = 3 +}; + +struct nfc_shdlc { + struct mutex state_mutex; + enum shdlc_state state; + int hard_fault; + + struct nfc_hci_dev *hdev; + + wait_queue_head_t *connect_wq; + int connect_tries; + int connect_result; + struct timer_list connect_timer;/* aka T3 in spec 10.6.1 */ + + u8 w; /* window size */ + bool srej_support; + + struct timer_list t1_timer; /* send ack timeout */ + bool t1_active; + + struct timer_list t2_timer; /* guard/retransmit timeout */ + bool t2_active; + + int ns; /* next seq num for send */ + int nr; /* next expected seq num for receive */ + int dnr; /* oldest sent unacked seq num */ + + struct sk_buff_head rcv_q; + + struct sk_buff_head send_q; + bool rnr; /* other side is not ready to receive */ + + struct sk_buff_head ack_pending_q; + + struct workqueue_struct *sm_wq; + struct work_struct sm_work; + + struct nfc_shdlc_ops *ops; + + int client_headroom; + int client_tailroom; + + void *clientdata; +}; + +void nfc_shdlc_recv_frame(struct nfc_shdlc *shdlc, struct sk_buff *skb); + +struct nfc_shdlc *nfc_shdlc_allocate(struct nfc_shdlc_ops *ops, + struct nfc_hci_init_data *init_data, + u32 protocols, + int tx_headroom, int tx_tailroom, + int max_link_payload, const char *devname); + +void nfc_shdlc_free(struct nfc_shdlc *shdlc); + +void nfc_shdlc_set_clientdata(struct nfc_shdlc *shdlc, void *clientdata); +void *nfc_shdlc_get_clientdata(struct nfc_shdlc *shdlc); +struct nfc_hci_dev *nfc_shdlc_get_hci_dev(struct nfc_shdlc *shdlc); + +#endif /* __NFC_SHDLC_H */ -- cgit v1.2.3 From c4fbb6515a4dcec83d340247639b5644c4745528 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 10 Apr 2012 19:43:09 +0200 Subject: NFC: The core part should generate the target index The target index can be used by userspace to uniquely identify a target and thus should be kept unique, per NFC adapter. Moreover, some protocols do not provide a logical index when discovering new targets, so we have to generate one for them. For NCI or pn533 to fetch their logical index, we added a logical_idx field to the target structure. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- include/net/nfc/nfc.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/net/nfc') diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 431a6c59b418..45f05634315b 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -79,6 +79,7 @@ struct nfc_target { u8 sensf_res_len; u8 sensf_res[NFC_SENSF_RES_MAXSIZE]; u8 hci_reader_gate; + u8 logical_idx; }; struct nfc_genl_data { @@ -88,6 +89,7 @@ struct nfc_genl_data { struct nfc_dev { unsigned idx; + unsigned target_idx; struct nfc_target *targets; int n_targets; int targets_generation; -- cgit v1.2.3 From 01ae0eea9bed132a9c4a2c207dbf8e05b0051071 Mon Sep 17 00:00:00 2001 From: Eric Lapuyade Date: Tue, 10 Apr 2012 19:43:10 +0200 Subject: NFC: Fix next target_idx type and rename for clarity Signed-off-by: Eric Lapuyade Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- include/net/nfc/nfc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net/nfc') diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 45f05634315b..f4f6950a8b05 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -89,7 +89,7 @@ struct nfc_genl_data { struct nfc_dev { unsigned idx; - unsigned target_idx; + u32 target_next_idx; struct nfc_target *targets; int n_targets; int targets_generation; -- cgit v1.2.3 From 144612cacc0b5c230f0b3aebc3a3a53854c332ee Mon Sep 17 00:00:00 2001 From: Eric Lapuyade Date: Tue, 10 Apr 2012 19:43:11 +0200 Subject: NFC: Changed target activated state logic Signed-off-by: Eric Lapuyade Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- include/net/nfc/nfc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/net/nfc') diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index f4f6950a8b05..7273ff169bb8 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -66,6 +66,7 @@ struct nfc_ops { #define NFC_TARGET_IDX_ANY -1 #define NFC_MAX_GT_LEN 48 +#define NFC_TARGET_IDX_NONE 0xffffffff struct nfc_target { u32 idx; @@ -97,7 +98,7 @@ struct nfc_dev { struct device dev; bool dev_up; bool polling; - bool remote_activated; + u32 activated_target_idx; bool dep_link_up; u32 dep_rf_mode; struct nfc_genl_data genl_data; -- cgit v1.2.3 From c8d56ae78653c02fc6e6f304a18f860302481c2d Mon Sep 17 00:00:00 2001 From: Eric Lapuyade Date: Tue, 10 Apr 2012 19:43:12 +0200 Subject: NFC: Add Core support to generate tag lost event Some HW/drivers get notifications when a tag moves out of the radio field. This notification is now forwarded to user space through netlink. Signed-off-by: Eric Lapuyade Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- include/net/nfc/nfc.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/net/nfc') diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 7273ff169bb8..313d00fac276 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -62,6 +62,7 @@ struct nfc_ops { int (*data_exchange)(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context); + int (*check_presence)(struct nfc_dev *dev, u32 target_idx); }; #define NFC_TARGET_IDX_ANY -1 @@ -107,6 +108,10 @@ struct nfc_dev { int tx_headroom; int tx_tailroom; + struct timer_list check_pres_timer; + struct workqueue_struct *check_pres_wq; + struct work_struct check_pres_work; + struct nfc_ops *ops; }; #define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev) -- cgit v1.2.3