aboutsummaryrefslogtreecommitdiff
path: root/include/net/nfc
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/nfc')
-rw-r--r--include/net/nfc/digital.h248
-rw-r--r--include/net/nfc/hci.h11
-rw-r--r--include/net/nfc/llc.h4
-rw-r--r--include/net/nfc/nci.h7
-rw-r--r--include/net/nfc/nci_core.h51
-rw-r--r--include/net/nfc/nfc.h35
6 files changed, 298 insertions, 58 deletions
diff --git a/include/net/nfc/digital.h b/include/net/nfc/digital.h
new file mode 100644
index 00000000000..bdf55c3b7a1
--- /dev/null
+++ b/include/net/nfc/digital.h
@@ -0,0 +1,248 @@
+/*
+ * NFC Digital Protocol stack
+ * Copyright (c) 2013, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ */
+
+#ifndef __NFC_DIGITAL_H
+#define __NFC_DIGITAL_H
+
+#include <linux/skbuff.h>
+#include <net/nfc/nfc.h>
+
+/**
+ * Configuration types for in_configure_hw and tg_configure_hw.
+ */
+enum {
+ NFC_DIGITAL_CONFIG_RF_TECH = 0,
+ NFC_DIGITAL_CONFIG_FRAMING,
+};
+
+/**
+ * RF technology values passed as param argument to in_configure_hw and
+ * tg_configure_hw for NFC_DIGITAL_CONFIG_RF_TECH configuration type.
+ */
+enum {
+ NFC_DIGITAL_RF_TECH_106A = 0,
+ NFC_DIGITAL_RF_TECH_212F,
+ NFC_DIGITAL_RF_TECH_424F,
+ NFC_DIGITAL_RF_TECH_ISO15693,
+ NFC_DIGITAL_RF_TECH_106B,
+
+ NFC_DIGITAL_RF_TECH_LAST,
+};
+
+/**
+ * Framing configuration passed as param argument to in_configure_hw and
+ * tg_configure_hw for NFC_DIGITAL_CONFIG_FRAMING configuration type.
+ */
+enum {
+ NFC_DIGITAL_FRAMING_NFCA_SHORT = 0,
+ NFC_DIGITAL_FRAMING_NFCA_STANDARD,
+ NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A,
+
+ NFC_DIGITAL_FRAMING_NFCA_T1T,
+ NFC_DIGITAL_FRAMING_NFCA_T2T,
+ NFC_DIGITAL_FRAMING_NFCA_T4T,
+ NFC_DIGITAL_FRAMING_NFCA_NFC_DEP,
+
+ NFC_DIGITAL_FRAMING_NFCF,
+ NFC_DIGITAL_FRAMING_NFCF_T3T,
+ NFC_DIGITAL_FRAMING_NFCF_NFC_DEP,
+ NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED,
+
+ NFC_DIGITAL_FRAMING_ISO15693_INVENTORY,
+ NFC_DIGITAL_FRAMING_ISO15693_T5T,
+
+ NFC_DIGITAL_FRAMING_NFCB,
+ NFC_DIGITAL_FRAMING_NFCB_T4T,
+
+ NFC_DIGITAL_FRAMING_LAST,
+};
+
+#define DIGITAL_MDAA_NFCID1_SIZE 3
+
+struct digital_tg_mdaa_params {
+ u16 sens_res;
+ u8 nfcid1[DIGITAL_MDAA_NFCID1_SIZE];
+ u8 sel_res;
+
+ u8 nfcid2[NFC_NFCID2_MAXSIZE];
+ u16 sc;
+};
+
+struct nfc_digital_dev;
+
+/**
+ * nfc_digital_cmd_complete_t - Definition of command result callback
+ *
+ * @ddev: nfc_digital_device ref
+ * @arg: user data
+ * @resp: response data
+ *
+ * resp pointer can be an error code and will be checked with IS_ERR() macro.
+ * The callback is responsible for freeing resp sk_buff.
+ */
+typedef void (*nfc_digital_cmd_complete_t)(struct nfc_digital_dev *ddev,
+ void *arg, struct sk_buff *resp);
+
+/**
+ * Device side NFC Digital operations
+ *
+ * Initiator mode:
+ * @in_configure_hw: Hardware configuration for RF technology and communication
+ * framing in initiator mode. This is a synchronous function.
+ * @in_send_cmd: Initiator mode data exchange using RF technology and framing
+ * previously set with in_configure_hw. The peer response is returned
+ * through callback cb. If an io error occurs or the peer didn't reply
+ * within the specified timeout (ms), the error code is passed back through
+ * the resp pointer. This is an asynchronous function.
+ *
+ * Target mode: Only NFC-DEP protocol is supported in target mode.
+ * @tg_configure_hw: Hardware configuration for RF technology and communication
+ * framing in target mode. This is a synchronous function.
+ * @tg_send_cmd: Target mode data exchange using RF technology and framing
+ * previously set with tg_configure_hw. The peer next command is returned
+ * through callback cb. If an io error occurs or the peer didn't reply
+ * within the specified timeout (ms), the error code is passed back through
+ * the resp pointer. This is an asynchronous function.
+ * @tg_listen: Put the device in listen mode waiting for data from the peer
+ * device. This is an asynchronous function.
+ * @tg_listen_mdaa: If supported, put the device in automatic listen mode with
+ * mode detection and automatic anti-collision. In this mode, the device
+ * automatically detects the RF technology and executes the anti-collision
+ * detection using the command responses specified in mdaa_params. The
+ * mdaa_params structure contains SENS_RES, NFCID1, and SEL_RES for 106A RF
+ * tech. NFCID2 and system code (sc) for 212F and 424F. The driver returns
+ * the NFC-DEP ATR_REQ command through cb. The digital stack deducts the RF
+ * tech by analyzing the SoD of the frame containing the ATR_REQ command.
+ * This is an asynchronous function.
+ *
+ * @switch_rf: Turns device radio on or off. The stack does not call explicitly
+ * switch_rf to turn the radio on. A call to in|tg_configure_hw must turn
+ * the device radio on.
+ * @abort_cmd: Discard the last sent command.
+ *
+ * Notes: Asynchronous functions have a timeout parameter. It is the driver
+ * responsibility to call the digital stack back through the
+ * nfc_digital_cmd_complete_t callback when no RF respsonse has been
+ * received within the specified time (in milliseconds). In that case the
+ * driver must set the resp sk_buff to ERR_PTR(-ETIMEDOUT).
+ * Since the digital stack serializes commands to be sent, it's mandatory
+ * for the driver to handle the timeout correctly. Otherwise the stack
+ * would not be able to send new commands, waiting for the reply of the
+ * current one.
+ */
+struct nfc_digital_ops {
+ int (*in_configure_hw)(struct nfc_digital_dev *ddev, int type,
+ int param);
+ int (*in_send_cmd)(struct nfc_digital_dev *ddev, struct sk_buff *skb,
+ u16 timeout, nfc_digital_cmd_complete_t cb,
+ void *arg);
+
+ int (*tg_configure_hw)(struct nfc_digital_dev *ddev, int type,
+ int param);
+ int (*tg_send_cmd)(struct nfc_digital_dev *ddev, struct sk_buff *skb,
+ u16 timeout, nfc_digital_cmd_complete_t cb,
+ void *arg);
+ int (*tg_listen)(struct nfc_digital_dev *ddev, u16 timeout,
+ nfc_digital_cmd_complete_t cb, void *arg);
+ int (*tg_listen_mdaa)(struct nfc_digital_dev *ddev,
+ struct digital_tg_mdaa_params *mdaa_params,
+ u16 timeout, nfc_digital_cmd_complete_t cb,
+ void *arg);
+
+ int (*switch_rf)(struct nfc_digital_dev *ddev, bool on);
+ void (*abort_cmd)(struct nfc_digital_dev *ddev);
+};
+
+#define NFC_DIGITAL_POLL_MODE_COUNT_MAX 6 /* 106A, 212F, and 424F in & tg */
+
+typedef int (*digital_poll_t)(struct nfc_digital_dev *ddev, u8 rf_tech);
+
+struct digital_poll_tech {
+ u8 rf_tech;
+ digital_poll_t poll_func;
+};
+
+/**
+ * Driver capabilities - bit mask made of the following values
+ *
+ * @NFC_DIGITAL_DRV_CAPS_IN_CRC: The driver handles CRC calculation in initiator
+ * mode.
+ * @NFC_DIGITAL_DRV_CAPS_TG_CRC: The driver handles CRC calculation in target
+ * mode.
+ */
+#define NFC_DIGITAL_DRV_CAPS_IN_CRC 0x0001
+#define NFC_DIGITAL_DRV_CAPS_TG_CRC 0x0002
+
+struct nfc_digital_dev {
+ struct nfc_dev *nfc_dev;
+ struct nfc_digital_ops *ops;
+
+ u32 protocols;
+
+ int tx_headroom;
+ int tx_tailroom;
+
+ u32 driver_capabilities;
+ void *driver_data;
+
+ struct digital_poll_tech poll_techs[NFC_DIGITAL_POLL_MODE_COUNT_MAX];
+ u8 poll_tech_count;
+ u8 poll_tech_index;
+ struct mutex poll_lock;
+
+ struct work_struct cmd_work;
+ struct work_struct cmd_complete_work;
+ struct list_head cmd_queue;
+ struct mutex cmd_lock;
+
+ struct work_struct poll_work;
+
+ u8 curr_protocol;
+ u8 curr_rf_tech;
+ u8 curr_nfc_dep_pni;
+
+ u16 target_fsc;
+
+ int (*skb_check_crc)(struct sk_buff *skb);
+ void (*skb_add_crc)(struct sk_buff *skb);
+};
+
+struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops,
+ __u32 supported_protocols,
+ __u32 driver_capabilities,
+ int tx_headroom,
+ int tx_tailroom);
+void nfc_digital_free_device(struct nfc_digital_dev *ndev);
+int nfc_digital_register_device(struct nfc_digital_dev *ndev);
+void nfc_digital_unregister_device(struct nfc_digital_dev *ndev);
+
+static inline void nfc_digital_set_parent_dev(struct nfc_digital_dev *ndev,
+ struct device *dev)
+{
+ nfc_set_parent_dev(ndev->nfc_dev, dev);
+}
+
+static inline void nfc_digital_set_drvdata(struct nfc_digital_dev *dev,
+ void *data)
+{
+ dev->driver_data = data;
+}
+
+static inline void *nfc_digital_get_drvdata(struct nfc_digital_dev *dev)
+{
+ return dev->driver_data;
+}
+
+#endif /* __NFC_DIGITAL_H */
diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h
index b64b7bce4b9..61286db5438 100644
--- a/include/net/nfc/hci.h
+++ b/include/net/nfc/hci.h
@@ -12,9 +12,7 @@
* 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.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __NET_HCI_H
@@ -24,17 +22,12 @@
#include <net/nfc/nfc.h>
-struct nfc_phy_ops {
- int (*write)(void *dev_id, struct sk_buff *skb);
- int (*enable)(void *dev_id);
- void (*disable)(void *dev_id);
-};
-
struct nfc_hci_dev;
struct nfc_hci_ops {
int (*open) (struct nfc_hci_dev *hdev);
void (*close) (struct nfc_hci_dev *hdev);
+ int (*load_session) (struct nfc_hci_dev *hdev);
int (*hci_ready) (struct nfc_hci_dev *hdev);
/*
* xmit must always send the complete buffer before
diff --git a/include/net/nfc/llc.h b/include/net/nfc/llc.h
index 400ab7ae749..c25fbdee0d6 100644
--- a/include/net/nfc/llc.h
+++ b/include/net/nfc/llc.h
@@ -13,9 +13,7 @@
* 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.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __NFC_LLC_H_
diff --git a/include/net/nfc/nci.h b/include/net/nfc/nci.h
index 88785e5c6b2..fbfa4e471ab 100644
--- a/include/net/nfc/nci.h
+++ b/include/net/nfc/nci.h
@@ -20,8 +20,7 @@
* 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
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
@@ -166,6 +165,10 @@
#define NCI_GID_NFCEE_MGMT 0x2
#define NCI_GID_PROPRIETARY 0xf
+/* ----- NCI over SPI head/crc(tail) room needed for outgoing frames ----- */
+#define NCI_SPI_HDR_LEN 4
+#define NCI_SPI_CRC_LEN 2
+
/* ---- NCI Packet structures ---- */
#define NCI_CTRL_HDR_SIZE 3
#define NCI_DATA_HDR_SIZE 3
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h
index 99fc1f3a392..1f9a0f5272f 100644
--- a/include/net/nfc/nci_core.h
+++ b/include/net/nfc/nci_core.h
@@ -21,8 +21,7 @@
* 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
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
@@ -68,6 +67,7 @@ struct nci_ops {
int (*open)(struct nci_dev *ndev);
int (*close)(struct nci_dev *ndev);
int (*send)(struct nci_dev *ndev, struct sk_buff *skb);
+ int (*setup)(struct nci_dev *ndev);
};
#define NCI_MAX_SUPPORTED_RF_INTERFACES 4
@@ -154,6 +154,7 @@ void nci_free_device(struct nci_dev *ndev);
int nci_register_device(struct nci_dev *ndev);
void nci_unregister_device(struct nci_dev *ndev);
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);
static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev,
unsigned int len,
@@ -207,19 +208,9 @@ int nci_to_errno(__u8 code);
#define NCI_SPI_CRC_ENABLED 0x01
/* ----- NCI SPI structures ----- */
-struct nci_spi_dev;
-
-struct nci_spi_ops {
- int (*open)(struct nci_spi_dev *ndev);
- int (*close)(struct nci_spi_dev *ndev);
- void (*assert_int)(struct nci_spi_dev *ndev);
- void (*deassert_int)(struct nci_spi_dev *ndev);
-};
-
-struct nci_spi_dev {
- struct nci_dev *nci_dev;
+struct nci_spi {
+ struct nci_dev *ndev;
struct spi_device *spi;
- struct nci_spi_ops *ops;
unsigned int xfer_udelay; /* microseconds delay between
transactions */
@@ -227,31 +218,15 @@ struct nci_spi_dev {
struct completion req_completion;
u8 req_result;
-
- void *driver_data;
};
-/* ----- NCI SPI Devices ----- */
-struct nci_spi_dev *nci_spi_allocate_device(struct spi_device *spi,
- struct nci_spi_ops *ops,
- u32 supported_protocols,
- u32 supported_se,
- u8 acknowledge_mode,
- unsigned int delay);
-void nci_spi_free_device(struct nci_spi_dev *ndev);
-int nci_spi_register_device(struct nci_spi_dev *ndev);
-void nci_spi_unregister_device(struct nci_spi_dev *ndev);
-int nci_spi_recv_frame(struct nci_spi_dev *ndev);
-
-static inline void nci_spi_set_drvdata(struct nci_spi_dev *ndev,
- void *data)
-{
- ndev->driver_data = data;
-}
-
-static inline void *nci_spi_get_drvdata(struct nci_spi_dev *ndev)
-{
- return ndev->driver_data;
-}
+/* ----- NCI SPI ----- */
+struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi,
+ u8 acknowledge_mode, unsigned int delay,
+ struct nci_dev *ndev);
+int nci_spi_send(struct nci_spi *nspi,
+ struct completion *write_handshake_completion,
+ struct sk_buff *skb);
+struct sk_buff *nci_spi_read(struct nci_spi *nspi);
#endif /* __NCI_CORE_H */
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h
index f68ee68e4e3..6c583e244de 100644
--- a/include/net/nfc/nfc.h
+++ b/include/net/nfc/nfc.h
@@ -16,9 +16,7 @@
* 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.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __NET_NFC_H
@@ -28,9 +26,14 @@
#include <linux/device.h>
#include <linux/skbuff.h>
-#define nfc_dev_info(dev, fmt, arg...) dev_info((dev), "NFC: " fmt "\n", ## arg)
-#define nfc_dev_err(dev, fmt, arg...) dev_err((dev), "NFC: " fmt "\n", ## arg)
-#define nfc_dev_dbg(dev, fmt, arg...) dev_dbg((dev), fmt "\n", ## arg)
+#define nfc_info(dev, fmt, ...) dev_info((dev), "NFC: " fmt, ##__VA_ARGS__)
+#define nfc_err(dev, fmt, ...) dev_err((dev), "NFC: " fmt, ##__VA_ARGS__)
+
+struct nfc_phy_ops {
+ int (*write)(void *dev_id, struct sk_buff *skb);
+ int (*enable)(void *dev_id);
+ void (*disable)(void *dev_id);
+};
struct nfc_dev;
@@ -48,6 +51,8 @@ struct nfc_dev;
typedef void (*data_exchange_cb_t)(void *context, struct sk_buff *skb,
int err);
+typedef void (*se_io_cb_t)(void *context, u8 *apdu, size_t apdu_len, int err);
+
struct nfc_target;
struct nfc_ops {
@@ -74,12 +79,23 @@ struct nfc_ops {
int (*discover_se)(struct nfc_dev *dev);
int (*enable_se)(struct nfc_dev *dev, u32 se_idx);
int (*disable_se)(struct nfc_dev *dev, u32 se_idx);
+ int (*se_io) (struct nfc_dev *dev, u32 se_idx,
+ u8 *apdu, size_t apdu_length,
+ se_io_cb_t cb, void *cb_context);
};
#define NFC_TARGET_IDX_ANY -1
#define NFC_MAX_GT_LEN 48
#define NFC_ATR_RES_GT_OFFSET 15
+/**
+ * struct nfc_target - NFC target descriptiom
+ *
+ * @sens_res: 2 bytes describing the target SENS_RES response, if the target
+ * is a type A one. The %sens_res most significant byte must be byte 2
+ * as described by the NFC Forum digital specification (i.e. the platform
+ * configuration one) while %sens_res least significant byte is byte 1.
+ */
struct nfc_target {
u32 idx;
u32 supported_protocols;
@@ -95,6 +111,9 @@ struct nfc_target {
u8 sensf_res[NFC_SENSF_RES_MAXSIZE];
u8 hci_reader_gate;
u8 logical_idx;
+ u8 is_iso15693;
+ u8 iso15693_dsfid;
+ u8 iso15693_uid[NFC_ISO15693_UID_MAXSIZE];
};
/**
@@ -243,5 +262,9 @@ void nfc_driver_failure(struct nfc_dev *dev, int err);
int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type);
int nfc_remove_se(struct nfc_dev *dev, u32 se_idx);
+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);
#endif /* __NET_NFC_H */