aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Escande <thierry.escande@linux.intel.com>2013-09-19 11:55:25 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2013-09-24 19:35:42 -0400
commit4b10884eb428c243ae2070a539612e645f3d9b93 (patch)
tree1b80e5d3561f3cfd3d3a9cee926423f4de241fdc
parentcec4b8edc9c139ef658e2a26aa38a2a4b768aec6 (diff)
NFC: Digital Protocol stack implementation
This is the initial commit of the NFC Digital Protocol stack implementation. It offers an interface for devices that don't have an embedded NFC Digital protocol stack. The driver instantiates the digital stack by calling nfc_digital_allocate_device(). Within the nfc_digital_ops structure, the driver specifies a set of function pointers for driver operations. These functions must be implemented by the driver and are: 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. 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. Then the driver registers itself against the digital stack by using nfc_digital_register_device() which in turn registers the digital stack against the NFC core layer. The digital stack implements common NFC operations like dev_up(), dev_down(), start_poll(), stop_poll(), etc. This patch is only a skeleton and NFC operations are just stubs. Signed-off-by: Thierry Escande <thierry.escande@linux.intel.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--include/net/nfc/digital.h199
-rw-r--r--net/nfc/Kconfig12
-rw-r--r--net/nfc/Makefile2
-rw-r--r--net/nfc/digital.h27
-rw-r--r--net/nfc/digital_core.c151
5 files changed, 391 insertions, 0 deletions
diff --git a/include/net/nfc/digital.h b/include/net/nfc/digital.h
new file mode 100644
index 000000000000..8e16b6e0265a
--- /dev/null
+++ b/include/net/nfc/digital.h
@@ -0,0 +1,199 @@
1/*
2 * NFC Digital Protocol stack
3 * Copyright (c) 2013, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 */
15
16#ifndef __NFC_DIGITAL_H
17#define __NFC_DIGITAL_H
18
19#include <linux/skbuff.h>
20#include <net/nfc/nfc.h>
21
22/**
23 * Configuration types for in_configure_hw and tg_configure_hw.
24 */
25enum {
26 NFC_DIGITAL_CONFIG_RF_TECH = 0,
27 NFC_DIGITAL_CONFIG_FRAMING,
28};
29
30/**
31 * RF technology values passed as param argument to in_configure_hw and
32 * tg_configure_hw for NFC_DIGITAL_CONFIG_RF_TECH configuration type.
33 */
34enum {
35 NFC_DIGITAL_RF_TECH_106A = 0,
36 NFC_DIGITAL_RF_TECH_212F,
37 NFC_DIGITAL_RF_TECH_424F,
38
39 NFC_DIGITAL_RF_TECH_LAST,
40};
41
42/**
43 * Framing configuration passed as param argument to in_configure_hw and
44 * tg_configure_hw for NFC_DIGITAL_CONFIG_FRAMING configuration type.
45 */
46enum {
47 NFC_DIGITAL_FRAMING_NFCA_SHORT = 0,
48 NFC_DIGITAL_FRAMING_NFCA_STANDARD,
49 NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A,
50
51 NFC_DIGITAL_FRAMING_NFCA_T1T,
52 NFC_DIGITAL_FRAMING_NFCA_T2T,
53 NFC_DIGITAL_FRAMING_NFCA_NFC_DEP,
54
55 NFC_DIGITAL_FRAMING_NFCF,
56 NFC_DIGITAL_FRAMING_NFCF_T3T,
57 NFC_DIGITAL_FRAMING_NFCF_NFC_DEP,
58 NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED,
59
60 NFC_DIGITAL_FRAMING_LAST,
61};
62
63#define DIGITAL_MDAA_NFCID1_SIZE 3
64
65struct digital_tg_mdaa_params {
66 u16 sens_res;
67 u8 nfcid1[DIGITAL_MDAA_NFCID1_SIZE];
68 u8 sel_res;
69
70 u8 nfcid2[NFC_NFCID2_MAXSIZE];
71 u16 sc;
72};
73
74struct nfc_digital_dev;
75
76/**
77 * nfc_digital_cmd_complete_t - Definition of command result callback
78 *
79 * @ddev: nfc_digital_device ref
80 * @arg: user data
81 * @resp: response data
82 *
83 * resp pointer can be an error code and will be checked with IS_ERR() macro.
84 * The callback is responsible for freeing resp sk_buff.
85 */
86typedef void (*nfc_digital_cmd_complete_t)(struct nfc_digital_dev *ddev,
87 void *arg, struct sk_buff *resp);
88
89/**
90 * Device side NFC Digital operations
91 *
92 * Initiator mode:
93 * @in_configure_hw: Hardware configuration for RF technology and communication
94 * framing in initiator mode. This is a synchronous function.
95 * @in_send_cmd: Initiator mode data exchange using RF technology and framing
96 * previously set with in_configure_hw. The peer response is returned
97 * through callback cb. If an io error occurs or the peer didn't reply
98 * within the specified timeout (ms), the error code is passed back through
99 * the resp pointer. This is an asynchronous function.
100 *
101 * Target mode: Only NFC-DEP protocol is supported in target mode.
102 * @tg_configure_hw: Hardware configuration for RF technology and communication
103 * framing in target mode. This is a synchronous function.
104 * @tg_send_cmd: Target mode data exchange using RF technology and framing
105 * previously set with tg_configure_hw. The peer next command is returned
106 * through callback cb. If an io error occurs or the peer didn't reply
107 * within the specified timeout (ms), the error code is passed back through
108 * the resp pointer. This is an asynchronous function.
109 * @tg_listen: Put the device in listen mode waiting for data from the peer
110 * device. This is an asynchronous function.
111 * @tg_listen_mdaa: If supported, put the device in automatic listen mode with
112 * mode detection and automatic anti-collision. In this mode, the device
113 * automatically detects the RF technology and executes the anti-collision
114 * detection using the command responses specified in mdaa_params. The
115 * mdaa_params structure contains SENS_RES, NFCID1, and SEL_RES for 106A RF
116 * tech. NFCID2 and system code (sc) for 212F and 424F. The driver returns
117 * the NFC-DEP ATR_REQ command through cb. The digital stack deducts the RF
118 * tech by analyzing the SoD of the frame containing the ATR_REQ command.
119 * This is an asynchronous function.
120 *
121 * @switch_rf: Turns device radio on or off. The stack does not call explicitly
122 * switch_rf to turn the radio on. A call to in|tg_configure_hw must turn
123 * the device radio on.
124 * @abort_cmd: Discard the last sent command.
125 */
126struct nfc_digital_ops {
127 int (*in_configure_hw)(struct nfc_digital_dev *ddev, int type,
128 int param);
129 int (*in_send_cmd)(struct nfc_digital_dev *ddev, struct sk_buff *skb,
130 u16 timeout, nfc_digital_cmd_complete_t cb,
131 void *arg);
132
133 int (*tg_configure_hw)(struct nfc_digital_dev *ddev, int type,
134 int param);
135 int (*tg_send_cmd)(struct nfc_digital_dev *ddev, struct sk_buff *skb,
136 u16 timeout, nfc_digital_cmd_complete_t cb,
137 void *arg);
138 int (*tg_listen)(struct nfc_digital_dev *ddev, u16 timeout,
139 nfc_digital_cmd_complete_t cb, void *arg);
140 int (*tg_listen_mdaa)(struct nfc_digital_dev *ddev,
141 struct digital_tg_mdaa_params *mdaa_params,
142 u16 timeout, nfc_digital_cmd_complete_t cb,
143 void *arg);
144
145 int (*switch_rf)(struct nfc_digital_dev *ddev, bool on);
146 void (*abort_cmd)(struct nfc_digital_dev *ddev);
147};
148
149/**
150 * Driver capabilities - bit mask made of the following values
151 *
152 * @NFC_DIGITAL_DRV_CAPS_IN_CRC: The driver handles CRC calculation in initiator
153 * mode.
154 * @NFC_DIGITAL_DRV_CAPS_TG_CRC: The driver handles CRC calculation in target
155 * mode.
156 */
157#define NFC_DIGITAL_DRV_CAPS_IN_CRC 0x0001
158#define NFC_DIGITAL_DRV_CAPS_TG_CRC 0x0002
159
160struct nfc_digital_dev {
161 struct nfc_dev *nfc_dev;
162 struct nfc_digital_ops *ops;
163
164 u32 protocols;
165
166 int tx_headroom;
167 int tx_tailroom;
168
169 u32 driver_capabilities;
170 void *driver_data;
171};
172
173struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops,
174 __u32 supported_protocols,
175 __u32 driver_capabilities,
176 int tx_headroom,
177 int tx_tailroom);
178void nfc_digital_free_device(struct nfc_digital_dev *ndev);
179int nfc_digital_register_device(struct nfc_digital_dev *ndev);
180void nfc_digital_unregister_device(struct nfc_digital_dev *ndev);
181
182static inline void nfc_digital_set_parent_dev(struct nfc_digital_dev *ndev,
183 struct device *dev)
184{
185 nfc_set_parent_dev(ndev->nfc_dev, dev);
186}
187
188static inline void nfc_digital_set_drvdata(struct nfc_digital_dev *dev,
189 void *data)
190{
191 dev->driver_data = data;
192}
193
194static inline void *nfc_digital_get_drvdata(struct nfc_digital_dev *dev)
195{
196 return dev->driver_data;
197}
198
199#endif /* __NFC_DIGITAL_H */
diff --git a/net/nfc/Kconfig b/net/nfc/Kconfig
index 5948b2fc72f6..13e1237e1ea1 100644
--- a/net/nfc/Kconfig
+++ b/net/nfc/Kconfig
@@ -14,6 +14,18 @@ menuconfig NFC
14 To compile this support as a module, choose M here: the module will 14 To compile this support as a module, choose M here: the module will
15 be called nfc. 15 be called nfc.
16 16
17config NFC_DIGITAL
18 depends on NFC
19 tristate "NFC Digital Protocol stack support"
20 default n
21 help
22 Say Y if you want to build NFC digital protocol stack support.
23 This is needed by NFC chipsets whose firmware only implement
24 the NFC analog layer.
25
26 To compile this support as a module, choose M here: the module will
27 be called nfc_digital.
28
17source "net/nfc/nci/Kconfig" 29source "net/nfc/nci/Kconfig"
18source "net/nfc/hci/Kconfig" 30source "net/nfc/hci/Kconfig"
19 31
diff --git a/net/nfc/Makefile b/net/nfc/Makefile
index a76f4533cb6c..8e0cabd85e99 100644
--- a/net/nfc/Makefile
+++ b/net/nfc/Makefile
@@ -5,7 +5,9 @@
5obj-$(CONFIG_NFC) += nfc.o 5obj-$(CONFIG_NFC) += nfc.o
6obj-$(CONFIG_NFC_NCI) += nci/ 6obj-$(CONFIG_NFC_NCI) += nci/
7obj-$(CONFIG_NFC_HCI) += hci/ 7obj-$(CONFIG_NFC_HCI) += hci/
8obj-$(CONFIG_NFC_DIGITAL) += nfc_digital.o
8 9
9nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \ 10nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \
10 llcp_sock.o 11 llcp_sock.o
11 12
13nfc_digital-objs := digital_core.o
diff --git a/net/nfc/digital.h b/net/nfc/digital.h
new file mode 100644
index 000000000000..8d91ed820912
--- /dev/null
+++ b/net/nfc/digital.h
@@ -0,0 +1,27 @@
1/*
2 * NFC Digital Protocol stack
3 * Copyright (c) 2013, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 */
15
16#ifndef __DIGITAL_H
17#define __DIGITAL_H
18
19#include <net/nfc/nfc.h>
20#include <net/nfc/digital.h>
21
22#define PR_DBG(fmt, ...) pr_debug("%s: " fmt "\n", __func__, ##__VA_ARGS__)
23#define PR_ERR(fmt, ...) pr_err("%s: " fmt "\n", __func__, ##__VA_ARGS__)
24#define PROTOCOL_ERR(req) pr_err("%s:%d: NFC Digital Protocol error: %s\n", \
25 __func__, __LINE__, req)
26
27#endif /* __DIGITAL_H */
diff --git a/net/nfc/digital_core.c b/net/nfc/digital_core.c
new file mode 100644
index 000000000000..471188a0d2e0
--- /dev/null
+++ b/net/nfc/digital_core.c
@@ -0,0 +1,151 @@
1/*
2 * NFC Digital Protocol stack
3 * Copyright (c) 2013, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 */
15
16#include <linux/module.h>
17
18#include "digital.h"
19
20static int digital_start_poll(struct nfc_dev *nfc_dev, __u32 im_protocols,
21 __u32 tm_protocols)
22{
23 return -EOPNOTSUPP;
24}
25
26static void digital_stop_poll(struct nfc_dev *nfc_dev)
27{
28}
29
30static int digital_dev_up(struct nfc_dev *nfc_dev)
31{
32 return -EOPNOTSUPP;
33}
34
35static int digital_dev_down(struct nfc_dev *nfc_dev)
36{
37 return -EOPNOTSUPP;
38}
39
40static int digital_dep_link_up(struct nfc_dev *nfc_dev,
41 struct nfc_target *target,
42 __u8 comm_mode, __u8 *gb, size_t gb_len)
43{
44 return -EOPNOTSUPP;
45}
46
47static int digital_dep_link_down(struct nfc_dev *nfc_dev)
48{
49 return -EOPNOTSUPP;
50}
51
52static int digital_activate_target(struct nfc_dev *nfc_dev,
53 struct nfc_target *target, __u32 protocol)
54{
55 return -EOPNOTSUPP;
56}
57
58static void digital_deactivate_target(struct nfc_dev *nfc_dev,
59 struct nfc_target *target)
60{
61}
62
63static int digital_tg_send(struct nfc_dev *dev, struct sk_buff *skb)
64{
65 return -EOPNOTSUPP;
66}
67
68static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target,
69 struct sk_buff *skb, data_exchange_cb_t cb,
70 void *cb_context)
71{
72 return -EOPNOTSUPP;
73}
74
75static struct nfc_ops digital_nfc_ops = {
76 .dev_up = digital_dev_up,
77 .dev_down = digital_dev_down,
78 .start_poll = digital_start_poll,
79 .stop_poll = digital_stop_poll,
80 .dep_link_up = digital_dep_link_up,
81 .dep_link_down = digital_dep_link_down,
82 .activate_target = digital_activate_target,
83 .deactivate_target = digital_deactivate_target,
84 .tm_send = digital_tg_send,
85 .im_transceive = digital_in_send,
86};
87
88struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops,
89 __u32 supported_protocols,
90 __u32 driver_capabilities,
91 int tx_headroom, int tx_tailroom)
92{
93 struct nfc_digital_dev *ddev;
94
95 if (!ops->in_configure_hw || !ops->in_send_cmd || !ops->tg_listen ||
96 !ops->tg_configure_hw || !ops->tg_send_cmd || !ops->abort_cmd ||
97 !ops->switch_rf)
98 return NULL;
99
100 ddev = kzalloc(sizeof(struct nfc_digital_dev), GFP_KERNEL);
101 if (!ddev) {
102 PR_ERR("kzalloc failed");
103 return NULL;
104 }
105
106 ddev->driver_capabilities = driver_capabilities;
107 ddev->ops = ops;
108
109 ddev->tx_headroom = tx_headroom;
110 ddev->tx_tailroom = tx_tailroom;
111
112 ddev->nfc_dev = nfc_allocate_device(&digital_nfc_ops, ddev->protocols,
113 ddev->tx_headroom,
114 ddev->tx_tailroom);
115 if (!ddev->nfc_dev) {
116 PR_ERR("nfc_allocate_device failed");
117 goto free_dev;
118 }
119
120 nfc_set_drvdata(ddev->nfc_dev, ddev);
121
122 return ddev;
123
124free_dev:
125 kfree(ddev);
126
127 return NULL;
128}
129EXPORT_SYMBOL(nfc_digital_allocate_device);
130
131void nfc_digital_free_device(struct nfc_digital_dev *ddev)
132{
133 nfc_free_device(ddev->nfc_dev);
134
135 kfree(ddev);
136}
137EXPORT_SYMBOL(nfc_digital_free_device);
138
139int nfc_digital_register_device(struct nfc_digital_dev *ddev)
140{
141 return nfc_register_device(ddev->nfc_dev);
142}
143EXPORT_SYMBOL(nfc_digital_register_device);
144
145void nfc_digital_unregister_device(struct nfc_digital_dev *ddev)
146{
147 nfc_unregister_device(ddev->nfc_dev);
148}
149EXPORT_SYMBOL(nfc_digital_unregister_device);
150
151MODULE_LICENSE("GPL");