xref: /openbmc/linux/drivers/nfc/nfcsim.c (revision 7cbe0ff3e475b7268ad9b55057048b2299fd60e0)
1*7cbe0ff3SThierry Escande /*
2*7cbe0ff3SThierry Escande  * NFC hardware simulation driver
3*7cbe0ff3SThierry Escande  * Copyright (c) 2013, Intel Corporation.
4*7cbe0ff3SThierry Escande  *
5*7cbe0ff3SThierry Escande  * This program is free software; you can redistribute it and/or modify it
6*7cbe0ff3SThierry Escande  * under the terms and conditions of the GNU General Public License,
7*7cbe0ff3SThierry Escande  * version 2, as published by the Free Software Foundation.
8*7cbe0ff3SThierry Escande  *
9*7cbe0ff3SThierry Escande  * This program is distributed in the hope it will be useful, but WITHOUT
10*7cbe0ff3SThierry Escande  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11*7cbe0ff3SThierry Escande  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12*7cbe0ff3SThierry Escande  * more details.
13*7cbe0ff3SThierry Escande  *
14*7cbe0ff3SThierry Escande  */
15*7cbe0ff3SThierry Escande 
16*7cbe0ff3SThierry Escande #include <linux/device.h>
17*7cbe0ff3SThierry Escande #include <linux/kernel.h>
18*7cbe0ff3SThierry Escande #include <linux/module.h>
19*7cbe0ff3SThierry Escande #include <linux/nfc.h>
20*7cbe0ff3SThierry Escande #include <net/nfc/nfc.h>
21*7cbe0ff3SThierry Escande 
22*7cbe0ff3SThierry Escande #define DEV_ERR(_dev, fmt, args...) nfc_dev_err(&_dev->nfc_dev->dev, \
23*7cbe0ff3SThierry Escande 						"%s: " fmt, __func__, ## args)
24*7cbe0ff3SThierry Escande 
25*7cbe0ff3SThierry Escande #define DEV_DBG(_dev, fmt, args...) nfc_dev_dbg(&_dev->nfc_dev->dev, \
26*7cbe0ff3SThierry Escande 						"%s: " fmt, __func__, ## args)
27*7cbe0ff3SThierry Escande 
28*7cbe0ff3SThierry Escande #define NFCSIM_VERSION "0.1"
29*7cbe0ff3SThierry Escande 
30*7cbe0ff3SThierry Escande #define NFCSIM_POLL_NONE	0
31*7cbe0ff3SThierry Escande #define NFCSIM_POLL_INITIATOR	1
32*7cbe0ff3SThierry Escande #define NFCSIM_POLL_TARGET	2
33*7cbe0ff3SThierry Escande #define NFCSIM_POLL_DUAL	(NFCSIM_POLL_INITIATOR | NFCSIM_POLL_TARGET)
34*7cbe0ff3SThierry Escande 
35*7cbe0ff3SThierry Escande struct nfcsim {
36*7cbe0ff3SThierry Escande 	struct nfc_dev *nfc_dev;
37*7cbe0ff3SThierry Escande 
38*7cbe0ff3SThierry Escande 	struct mutex lock;
39*7cbe0ff3SThierry Escande 
40*7cbe0ff3SThierry Escande 	struct delayed_work recv_work;
41*7cbe0ff3SThierry Escande 
42*7cbe0ff3SThierry Escande 	struct sk_buff *clone_skb;
43*7cbe0ff3SThierry Escande 
44*7cbe0ff3SThierry Escande 	struct delayed_work poll_work;
45*7cbe0ff3SThierry Escande 	u8 polling_mode;
46*7cbe0ff3SThierry Escande 	u8 curr_polling_mode;
47*7cbe0ff3SThierry Escande 
48*7cbe0ff3SThierry Escande 	u8 shutting_down;
49*7cbe0ff3SThierry Escande 
50*7cbe0ff3SThierry Escande 	u8 up;
51*7cbe0ff3SThierry Escande 
52*7cbe0ff3SThierry Escande 	u8 initiator;
53*7cbe0ff3SThierry Escande 
54*7cbe0ff3SThierry Escande 	data_exchange_cb_t cb;
55*7cbe0ff3SThierry Escande 	void *cb_context;
56*7cbe0ff3SThierry Escande 
57*7cbe0ff3SThierry Escande 	struct nfcsim *peer_dev;
58*7cbe0ff3SThierry Escande };
59*7cbe0ff3SThierry Escande 
60*7cbe0ff3SThierry Escande static struct nfcsim *dev0;
61*7cbe0ff3SThierry Escande static struct nfcsim *dev1;
62*7cbe0ff3SThierry Escande 
63*7cbe0ff3SThierry Escande struct workqueue_struct *wq;
64*7cbe0ff3SThierry Escande 
65*7cbe0ff3SThierry Escande static void nfcsim_cleanup_dev(struct nfcsim *dev, u8 shutdown)
66*7cbe0ff3SThierry Escande {
67*7cbe0ff3SThierry Escande 	DEV_DBG(dev, "shutdown=%d", shutdown);
68*7cbe0ff3SThierry Escande 
69*7cbe0ff3SThierry Escande 	mutex_lock(&dev->lock);
70*7cbe0ff3SThierry Escande 
71*7cbe0ff3SThierry Escande 	dev->polling_mode = NFCSIM_POLL_NONE;
72*7cbe0ff3SThierry Escande 	dev->shutting_down = shutdown;
73*7cbe0ff3SThierry Escande 	dev->cb = NULL;
74*7cbe0ff3SThierry Escande 	dev_kfree_skb(dev->clone_skb);
75*7cbe0ff3SThierry Escande 	dev->clone_skb = NULL;
76*7cbe0ff3SThierry Escande 
77*7cbe0ff3SThierry Escande 	mutex_unlock(&dev->lock);
78*7cbe0ff3SThierry Escande 
79*7cbe0ff3SThierry Escande 	cancel_delayed_work_sync(&dev->poll_work);
80*7cbe0ff3SThierry Escande 	cancel_delayed_work_sync(&dev->recv_work);
81*7cbe0ff3SThierry Escande }
82*7cbe0ff3SThierry Escande 
83*7cbe0ff3SThierry Escande static int nfcsim_target_found(struct nfcsim *dev)
84*7cbe0ff3SThierry Escande {
85*7cbe0ff3SThierry Escande 	struct nfc_target nfc_tgt;
86*7cbe0ff3SThierry Escande 
87*7cbe0ff3SThierry Escande 	DEV_DBG(dev, "");
88*7cbe0ff3SThierry Escande 
89*7cbe0ff3SThierry Escande 	memset(&nfc_tgt, 0, sizeof(struct nfc_target));
90*7cbe0ff3SThierry Escande 
91*7cbe0ff3SThierry Escande 	nfc_tgt.supported_protocols = NFC_PROTO_NFC_DEP_MASK;
92*7cbe0ff3SThierry Escande 	nfc_targets_found(dev->nfc_dev, &nfc_tgt, 1);
93*7cbe0ff3SThierry Escande 
94*7cbe0ff3SThierry Escande 	return 0;
95*7cbe0ff3SThierry Escande }
96*7cbe0ff3SThierry Escande 
97*7cbe0ff3SThierry Escande static int nfcsim_dev_up(struct nfc_dev *nfc_dev)
98*7cbe0ff3SThierry Escande {
99*7cbe0ff3SThierry Escande 	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
100*7cbe0ff3SThierry Escande 
101*7cbe0ff3SThierry Escande 	DEV_DBG(dev, "");
102*7cbe0ff3SThierry Escande 
103*7cbe0ff3SThierry Escande 	mutex_lock(&dev->lock);
104*7cbe0ff3SThierry Escande 
105*7cbe0ff3SThierry Escande 	dev->up = 1;
106*7cbe0ff3SThierry Escande 
107*7cbe0ff3SThierry Escande 	mutex_unlock(&dev->lock);
108*7cbe0ff3SThierry Escande 
109*7cbe0ff3SThierry Escande 	return 0;
110*7cbe0ff3SThierry Escande }
111*7cbe0ff3SThierry Escande 
112*7cbe0ff3SThierry Escande static int nfcsim_dev_down(struct nfc_dev *nfc_dev)
113*7cbe0ff3SThierry Escande {
114*7cbe0ff3SThierry Escande 	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
115*7cbe0ff3SThierry Escande 
116*7cbe0ff3SThierry Escande 	DEV_DBG(dev, "");
117*7cbe0ff3SThierry Escande 
118*7cbe0ff3SThierry Escande 	mutex_lock(&dev->lock);
119*7cbe0ff3SThierry Escande 
120*7cbe0ff3SThierry Escande 	dev->up = 0;
121*7cbe0ff3SThierry Escande 
122*7cbe0ff3SThierry Escande 	mutex_unlock(&dev->lock);
123*7cbe0ff3SThierry Escande 
124*7cbe0ff3SThierry Escande 	return 0;
125*7cbe0ff3SThierry Escande }
126*7cbe0ff3SThierry Escande 
127*7cbe0ff3SThierry Escande static int nfcsim_dep_link_up(struct nfc_dev *nfc_dev,
128*7cbe0ff3SThierry Escande 			      struct nfc_target *target,
129*7cbe0ff3SThierry Escande 			      u8 comm_mode, u8 *gb, size_t gb_len)
130*7cbe0ff3SThierry Escande {
131*7cbe0ff3SThierry Escande 	int rc;
132*7cbe0ff3SThierry Escande 	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
133*7cbe0ff3SThierry Escande 	struct nfcsim *peer = dev->peer_dev;
134*7cbe0ff3SThierry Escande 	u8 *remote_gb;
135*7cbe0ff3SThierry Escande 	size_t remote_gb_len;
136*7cbe0ff3SThierry Escande 
137*7cbe0ff3SThierry Escande 	DEV_DBG(dev, "target_idx: %d, comm_mode: %d\n", target->idx, comm_mode);
138*7cbe0ff3SThierry Escande 
139*7cbe0ff3SThierry Escande 	mutex_lock(&peer->lock);
140*7cbe0ff3SThierry Escande 
141*7cbe0ff3SThierry Escande 	nfc_tm_activated(peer->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
142*7cbe0ff3SThierry Escande 			 NFC_COMM_ACTIVE, gb, gb_len);
143*7cbe0ff3SThierry Escande 
144*7cbe0ff3SThierry Escande 	remote_gb = nfc_get_local_general_bytes(peer->nfc_dev, &remote_gb_len);
145*7cbe0ff3SThierry Escande 	if (!remote_gb) {
146*7cbe0ff3SThierry Escande 		DEV_ERR(peer, "Can't get remote general bytes");
147*7cbe0ff3SThierry Escande 
148*7cbe0ff3SThierry Escande 		mutex_unlock(&peer->lock);
149*7cbe0ff3SThierry Escande 		return -EINVAL;
150*7cbe0ff3SThierry Escande 	}
151*7cbe0ff3SThierry Escande 
152*7cbe0ff3SThierry Escande 	mutex_unlock(&peer->lock);
153*7cbe0ff3SThierry Escande 
154*7cbe0ff3SThierry Escande 	mutex_lock(&dev->lock);
155*7cbe0ff3SThierry Escande 
156*7cbe0ff3SThierry Escande 	rc = nfc_set_remote_general_bytes(nfc_dev, remote_gb, remote_gb_len);
157*7cbe0ff3SThierry Escande 	if (rc) {
158*7cbe0ff3SThierry Escande 		DEV_ERR(dev, "Can't set remote general bytes");
159*7cbe0ff3SThierry Escande 		mutex_unlock(&dev->lock);
160*7cbe0ff3SThierry Escande 		return rc;
161*7cbe0ff3SThierry Escande 	}
162*7cbe0ff3SThierry Escande 
163*7cbe0ff3SThierry Escande 	rc = nfc_dep_link_is_up(nfc_dev, target->idx, NFC_COMM_ACTIVE,
164*7cbe0ff3SThierry Escande 				NFC_RF_INITIATOR);
165*7cbe0ff3SThierry Escande 
166*7cbe0ff3SThierry Escande 	mutex_unlock(&dev->lock);
167*7cbe0ff3SThierry Escande 
168*7cbe0ff3SThierry Escande 	return rc;
169*7cbe0ff3SThierry Escande }
170*7cbe0ff3SThierry Escande 
171*7cbe0ff3SThierry Escande static int nfcsim_dep_link_down(struct nfc_dev *nfc_dev)
172*7cbe0ff3SThierry Escande {
173*7cbe0ff3SThierry Escande 	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
174*7cbe0ff3SThierry Escande 
175*7cbe0ff3SThierry Escande 	DEV_DBG(dev, "");
176*7cbe0ff3SThierry Escande 
177*7cbe0ff3SThierry Escande 	nfcsim_cleanup_dev(dev, 0);
178*7cbe0ff3SThierry Escande 
179*7cbe0ff3SThierry Escande 	return 0;
180*7cbe0ff3SThierry Escande }
181*7cbe0ff3SThierry Escande 
182*7cbe0ff3SThierry Escande static int nfcsim_start_poll(struct nfc_dev *nfc_dev,
183*7cbe0ff3SThierry Escande 			     u32 im_protocols, u32 tm_protocols)
184*7cbe0ff3SThierry Escande {
185*7cbe0ff3SThierry Escande 	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
186*7cbe0ff3SThierry Escande 	int rc;
187*7cbe0ff3SThierry Escande 
188*7cbe0ff3SThierry Escande 	mutex_lock(&dev->lock);
189*7cbe0ff3SThierry Escande 
190*7cbe0ff3SThierry Escande 	if (dev->polling_mode != NFCSIM_POLL_NONE) {
191*7cbe0ff3SThierry Escande 		DEV_ERR(dev, "Already in polling mode");
192*7cbe0ff3SThierry Escande 		rc = -EBUSY;
193*7cbe0ff3SThierry Escande 		goto exit;
194*7cbe0ff3SThierry Escande 	}
195*7cbe0ff3SThierry Escande 
196*7cbe0ff3SThierry Escande 	if (im_protocols & NFC_PROTO_NFC_DEP_MASK)
197*7cbe0ff3SThierry Escande 		dev->polling_mode |= NFCSIM_POLL_INITIATOR;
198*7cbe0ff3SThierry Escande 
199*7cbe0ff3SThierry Escande 	if (tm_protocols & NFC_PROTO_NFC_DEP_MASK)
200*7cbe0ff3SThierry Escande 		dev->polling_mode |= NFCSIM_POLL_TARGET;
201*7cbe0ff3SThierry Escande 
202*7cbe0ff3SThierry Escande 	if (dev->polling_mode == NFCSIM_POLL_NONE) {
203*7cbe0ff3SThierry Escande 		DEV_ERR(dev, "Unsupported polling mode");
204*7cbe0ff3SThierry Escande 		rc = -EINVAL;
205*7cbe0ff3SThierry Escande 		goto exit;
206*7cbe0ff3SThierry Escande 	}
207*7cbe0ff3SThierry Escande 
208*7cbe0ff3SThierry Escande 	dev->initiator = 0;
209*7cbe0ff3SThierry Escande 	dev->curr_polling_mode = NFCSIM_POLL_NONE;
210*7cbe0ff3SThierry Escande 
211*7cbe0ff3SThierry Escande 	queue_delayed_work(wq, &dev->poll_work, 0);
212*7cbe0ff3SThierry Escande 
213*7cbe0ff3SThierry Escande 	DEV_DBG(dev, "Start polling: im: 0x%X, tm: 0x%X", im_protocols,
214*7cbe0ff3SThierry Escande 		tm_protocols);
215*7cbe0ff3SThierry Escande 
216*7cbe0ff3SThierry Escande 	rc = 0;
217*7cbe0ff3SThierry Escande exit:
218*7cbe0ff3SThierry Escande 	mutex_unlock(&dev->lock);
219*7cbe0ff3SThierry Escande 
220*7cbe0ff3SThierry Escande 	return rc;
221*7cbe0ff3SThierry Escande }
222*7cbe0ff3SThierry Escande 
223*7cbe0ff3SThierry Escande static void nfcsim_stop_poll(struct nfc_dev *nfc_dev)
224*7cbe0ff3SThierry Escande {
225*7cbe0ff3SThierry Escande 	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
226*7cbe0ff3SThierry Escande 
227*7cbe0ff3SThierry Escande 	DEV_DBG(dev, "Stop poll");
228*7cbe0ff3SThierry Escande 
229*7cbe0ff3SThierry Escande 	mutex_lock(&dev->lock);
230*7cbe0ff3SThierry Escande 
231*7cbe0ff3SThierry Escande 	dev->polling_mode = NFCSIM_POLL_NONE;
232*7cbe0ff3SThierry Escande 
233*7cbe0ff3SThierry Escande 	mutex_unlock(&dev->lock);
234*7cbe0ff3SThierry Escande 
235*7cbe0ff3SThierry Escande 	cancel_delayed_work_sync(&dev->poll_work);
236*7cbe0ff3SThierry Escande }
237*7cbe0ff3SThierry Escande 
238*7cbe0ff3SThierry Escande static int nfcsim_activate_target(struct nfc_dev *nfc_dev,
239*7cbe0ff3SThierry Escande 				  struct nfc_target *target, u32 protocol)
240*7cbe0ff3SThierry Escande {
241*7cbe0ff3SThierry Escande 	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
242*7cbe0ff3SThierry Escande 
243*7cbe0ff3SThierry Escande 	DEV_DBG(dev, "");
244*7cbe0ff3SThierry Escande 
245*7cbe0ff3SThierry Escande 	return -ENOTSUPP;
246*7cbe0ff3SThierry Escande }
247*7cbe0ff3SThierry Escande 
248*7cbe0ff3SThierry Escande static void nfcsim_deactivate_target(struct nfc_dev *nfc_dev,
249*7cbe0ff3SThierry Escande 				     struct nfc_target *target)
250*7cbe0ff3SThierry Escande {
251*7cbe0ff3SThierry Escande 	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
252*7cbe0ff3SThierry Escande 
253*7cbe0ff3SThierry Escande 	DEV_DBG(dev, "");
254*7cbe0ff3SThierry Escande }
255*7cbe0ff3SThierry Escande 
256*7cbe0ff3SThierry Escande static void nfcsim_wq_recv(struct work_struct *work)
257*7cbe0ff3SThierry Escande {
258*7cbe0ff3SThierry Escande 	struct nfcsim *dev = container_of(work, struct nfcsim,
259*7cbe0ff3SThierry Escande 					  recv_work.work);
260*7cbe0ff3SThierry Escande 
261*7cbe0ff3SThierry Escande 	mutex_lock(&dev->lock);
262*7cbe0ff3SThierry Escande 
263*7cbe0ff3SThierry Escande 	if (dev->shutting_down || !dev->up || !dev->clone_skb) {
264*7cbe0ff3SThierry Escande 		dev_kfree_skb(dev->clone_skb);
265*7cbe0ff3SThierry Escande 		goto exit;
266*7cbe0ff3SThierry Escande 	}
267*7cbe0ff3SThierry Escande 
268*7cbe0ff3SThierry Escande 	if (dev->initiator) {
269*7cbe0ff3SThierry Escande 		if (!dev->cb) {
270*7cbe0ff3SThierry Escande 			DEV_ERR(dev, "Null recv callback");
271*7cbe0ff3SThierry Escande 			dev_kfree_skb(dev->clone_skb);
272*7cbe0ff3SThierry Escande 			goto exit;
273*7cbe0ff3SThierry Escande 		}
274*7cbe0ff3SThierry Escande 
275*7cbe0ff3SThierry Escande 		dev->cb(dev->cb_context, dev->clone_skb, 0);
276*7cbe0ff3SThierry Escande 		dev->cb = NULL;
277*7cbe0ff3SThierry Escande 	} else {
278*7cbe0ff3SThierry Escande 		nfc_tm_data_received(dev->nfc_dev, dev->clone_skb);
279*7cbe0ff3SThierry Escande 	}
280*7cbe0ff3SThierry Escande 
281*7cbe0ff3SThierry Escande exit:
282*7cbe0ff3SThierry Escande 	dev->clone_skb = NULL;
283*7cbe0ff3SThierry Escande 
284*7cbe0ff3SThierry Escande 	mutex_unlock(&dev->lock);
285*7cbe0ff3SThierry Escande }
286*7cbe0ff3SThierry Escande 
287*7cbe0ff3SThierry Escande static int nfcsim_tx(struct nfc_dev *nfc_dev, struct nfc_target *target,
288*7cbe0ff3SThierry Escande 		     struct sk_buff *skb, data_exchange_cb_t cb,
289*7cbe0ff3SThierry Escande 		     void *cb_context)
290*7cbe0ff3SThierry Escande {
291*7cbe0ff3SThierry Escande 	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
292*7cbe0ff3SThierry Escande 	struct nfcsim *peer = dev->peer_dev;
293*7cbe0ff3SThierry Escande 	int err;
294*7cbe0ff3SThierry Escande 
295*7cbe0ff3SThierry Escande 	mutex_lock(&dev->lock);
296*7cbe0ff3SThierry Escande 
297*7cbe0ff3SThierry Escande 	if (dev->shutting_down || !dev->up) {
298*7cbe0ff3SThierry Escande 		mutex_unlock(&dev->lock);
299*7cbe0ff3SThierry Escande 		err = -ENODEV;
300*7cbe0ff3SThierry Escande 		goto exit;
301*7cbe0ff3SThierry Escande 	}
302*7cbe0ff3SThierry Escande 
303*7cbe0ff3SThierry Escande 	dev->cb = cb;
304*7cbe0ff3SThierry Escande 	dev->cb_context = cb_context;
305*7cbe0ff3SThierry Escande 
306*7cbe0ff3SThierry Escande 	mutex_unlock(&dev->lock);
307*7cbe0ff3SThierry Escande 
308*7cbe0ff3SThierry Escande 	mutex_lock(&peer->lock);
309*7cbe0ff3SThierry Escande 
310*7cbe0ff3SThierry Escande 	peer->clone_skb = skb_clone(skb, GFP_KERNEL);
311*7cbe0ff3SThierry Escande 
312*7cbe0ff3SThierry Escande 	if (!peer->clone_skb) {
313*7cbe0ff3SThierry Escande 		DEV_ERR(dev, "skb_clone failed");
314*7cbe0ff3SThierry Escande 		mutex_unlock(&peer->lock);
315*7cbe0ff3SThierry Escande 		err = -ENOMEM;
316*7cbe0ff3SThierry Escande 		goto exit;
317*7cbe0ff3SThierry Escande 	}
318*7cbe0ff3SThierry Escande 
319*7cbe0ff3SThierry Escande 	/* This simulates an arbitrary transmission delay between the 2 devices.
320*7cbe0ff3SThierry Escande 	 * If packet transmission occurs immediately between them, we have a
321*7cbe0ff3SThierry Escande 	 * non-stop flow of several tens of thousands SYMM packets per second
322*7cbe0ff3SThierry Escande 	 * and a burning cpu.
323*7cbe0ff3SThierry Escande 	 *
324*7cbe0ff3SThierry Escande 	 * TODO: Add support for a sysfs entry to control this delay.
325*7cbe0ff3SThierry Escande 	 */
326*7cbe0ff3SThierry Escande 	queue_delayed_work(wq, &peer->recv_work, msecs_to_jiffies(5));
327*7cbe0ff3SThierry Escande 
328*7cbe0ff3SThierry Escande 	mutex_unlock(&peer->lock);
329*7cbe0ff3SThierry Escande 
330*7cbe0ff3SThierry Escande 	err = 0;
331*7cbe0ff3SThierry Escande exit:
332*7cbe0ff3SThierry Escande 	dev_kfree_skb(skb);
333*7cbe0ff3SThierry Escande 
334*7cbe0ff3SThierry Escande 	return err;
335*7cbe0ff3SThierry Escande }
336*7cbe0ff3SThierry Escande 
337*7cbe0ff3SThierry Escande static int nfcsim_im_transceive(struct nfc_dev *nfc_dev,
338*7cbe0ff3SThierry Escande 				struct nfc_target *target, struct sk_buff *skb,
339*7cbe0ff3SThierry Escande 				data_exchange_cb_t cb, void *cb_context)
340*7cbe0ff3SThierry Escande {
341*7cbe0ff3SThierry Escande 	return nfcsim_tx(nfc_dev, target, skb, cb, cb_context);
342*7cbe0ff3SThierry Escande }
343*7cbe0ff3SThierry Escande 
344*7cbe0ff3SThierry Escande static int nfcsim_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
345*7cbe0ff3SThierry Escande {
346*7cbe0ff3SThierry Escande 	return nfcsim_tx(nfc_dev, NULL, skb, NULL, NULL);
347*7cbe0ff3SThierry Escande }
348*7cbe0ff3SThierry Escande 
349*7cbe0ff3SThierry Escande static struct nfc_ops nfcsim_nfc_ops = {
350*7cbe0ff3SThierry Escande 	.dev_up = nfcsim_dev_up,
351*7cbe0ff3SThierry Escande 	.dev_down = nfcsim_dev_down,
352*7cbe0ff3SThierry Escande 	.dep_link_up = nfcsim_dep_link_up,
353*7cbe0ff3SThierry Escande 	.dep_link_down = nfcsim_dep_link_down,
354*7cbe0ff3SThierry Escande 	.start_poll = nfcsim_start_poll,
355*7cbe0ff3SThierry Escande 	.stop_poll = nfcsim_stop_poll,
356*7cbe0ff3SThierry Escande 	.activate_target = nfcsim_activate_target,
357*7cbe0ff3SThierry Escande 	.deactivate_target = nfcsim_deactivate_target,
358*7cbe0ff3SThierry Escande 	.im_transceive = nfcsim_im_transceive,
359*7cbe0ff3SThierry Escande 	.tm_send = nfcsim_tm_send,
360*7cbe0ff3SThierry Escande };
361*7cbe0ff3SThierry Escande 
362*7cbe0ff3SThierry Escande static void nfcsim_set_polling_mode(struct nfcsim *dev)
363*7cbe0ff3SThierry Escande {
364*7cbe0ff3SThierry Escande 	if (dev->polling_mode == NFCSIM_POLL_NONE) {
365*7cbe0ff3SThierry Escande 		dev->curr_polling_mode = NFCSIM_POLL_NONE;
366*7cbe0ff3SThierry Escande 		return;
367*7cbe0ff3SThierry Escande 	}
368*7cbe0ff3SThierry Escande 
369*7cbe0ff3SThierry Escande 	if (dev->curr_polling_mode == NFCSIM_POLL_NONE) {
370*7cbe0ff3SThierry Escande 		if (dev->polling_mode & NFCSIM_POLL_INITIATOR)
371*7cbe0ff3SThierry Escande 			dev->curr_polling_mode = NFCSIM_POLL_INITIATOR;
372*7cbe0ff3SThierry Escande 		else
373*7cbe0ff3SThierry Escande 			dev->curr_polling_mode = NFCSIM_POLL_TARGET;
374*7cbe0ff3SThierry Escande 
375*7cbe0ff3SThierry Escande 		return;
376*7cbe0ff3SThierry Escande 	}
377*7cbe0ff3SThierry Escande 
378*7cbe0ff3SThierry Escande 	if (dev->polling_mode == NFCSIM_POLL_DUAL) {
379*7cbe0ff3SThierry Escande 		if (dev->curr_polling_mode == NFCSIM_POLL_TARGET)
380*7cbe0ff3SThierry Escande 			dev->curr_polling_mode = NFCSIM_POLL_INITIATOR;
381*7cbe0ff3SThierry Escande 		else
382*7cbe0ff3SThierry Escande 			dev->curr_polling_mode = NFCSIM_POLL_TARGET;
383*7cbe0ff3SThierry Escande 	}
384*7cbe0ff3SThierry Escande }
385*7cbe0ff3SThierry Escande 
386*7cbe0ff3SThierry Escande static void nfcsim_wq_poll(struct work_struct *work)
387*7cbe0ff3SThierry Escande {
388*7cbe0ff3SThierry Escande 	struct nfcsim *dev = container_of(work, struct nfcsim, poll_work.work);
389*7cbe0ff3SThierry Escande 	struct nfcsim *peer = dev->peer_dev;
390*7cbe0ff3SThierry Escande 
391*7cbe0ff3SThierry Escande 	/* These work items run on an ordered workqueue and are therefore
392*7cbe0ff3SThierry Escande 	 * serialized. So we can take both mutexes without being dead locked.
393*7cbe0ff3SThierry Escande 	 */
394*7cbe0ff3SThierry Escande 	mutex_lock(&dev->lock);
395*7cbe0ff3SThierry Escande 	mutex_lock(&peer->lock);
396*7cbe0ff3SThierry Escande 
397*7cbe0ff3SThierry Escande 	nfcsim_set_polling_mode(dev);
398*7cbe0ff3SThierry Escande 
399*7cbe0ff3SThierry Escande 	if (dev->curr_polling_mode == NFCSIM_POLL_NONE) {
400*7cbe0ff3SThierry Escande 		DEV_DBG(dev, "Not polling");
401*7cbe0ff3SThierry Escande 		goto unlock;
402*7cbe0ff3SThierry Escande 	}
403*7cbe0ff3SThierry Escande 
404*7cbe0ff3SThierry Escande 	DEV_DBG(dev, "Polling as %s",
405*7cbe0ff3SThierry Escande 		dev->curr_polling_mode == NFCSIM_POLL_INITIATOR ?
406*7cbe0ff3SThierry Escande 		"initiator" : "target");
407*7cbe0ff3SThierry Escande 
408*7cbe0ff3SThierry Escande 	if (dev->curr_polling_mode == NFCSIM_POLL_TARGET)
409*7cbe0ff3SThierry Escande 		goto sched_work;
410*7cbe0ff3SThierry Escande 
411*7cbe0ff3SThierry Escande 	if (peer->curr_polling_mode == NFCSIM_POLL_TARGET) {
412*7cbe0ff3SThierry Escande 		peer->polling_mode = NFCSIM_POLL_NONE;
413*7cbe0ff3SThierry Escande 		dev->polling_mode = NFCSIM_POLL_NONE;
414*7cbe0ff3SThierry Escande 
415*7cbe0ff3SThierry Escande 		dev->initiator = 1;
416*7cbe0ff3SThierry Escande 
417*7cbe0ff3SThierry Escande 		nfcsim_target_found(dev);
418*7cbe0ff3SThierry Escande 
419*7cbe0ff3SThierry Escande 		goto unlock;
420*7cbe0ff3SThierry Escande 	}
421*7cbe0ff3SThierry Escande 
422*7cbe0ff3SThierry Escande sched_work:
423*7cbe0ff3SThierry Escande 	/* This defines the delay for an initiator to check if the other device
424*7cbe0ff3SThierry Escande 	 * is polling in target mode.
425*7cbe0ff3SThierry Escande 	 * If the device starts in dual mode polling, it switches between
426*7cbe0ff3SThierry Escande 	 * initiator and target at every round.
427*7cbe0ff3SThierry Escande 	 * Because the wq is ordered and only 1 work item is executed at a time,
428*7cbe0ff3SThierry Escande 	 * we'll always have one device polling as initiator and the other as
429*7cbe0ff3SThierry Escande 	 * target at some point, even if both are started in dual mode.
430*7cbe0ff3SThierry Escande 	 */
431*7cbe0ff3SThierry Escande 	queue_delayed_work(wq, &dev->poll_work, msecs_to_jiffies(200));
432*7cbe0ff3SThierry Escande 
433*7cbe0ff3SThierry Escande unlock:
434*7cbe0ff3SThierry Escande 	mutex_unlock(&peer->lock);
435*7cbe0ff3SThierry Escande 	mutex_unlock(&dev->lock);
436*7cbe0ff3SThierry Escande }
437*7cbe0ff3SThierry Escande 
438*7cbe0ff3SThierry Escande static struct nfcsim *nfcsim_init_dev(void)
439*7cbe0ff3SThierry Escande {
440*7cbe0ff3SThierry Escande 	struct nfcsim *dev;
441*7cbe0ff3SThierry Escande 	int rc = -ENOMEM;
442*7cbe0ff3SThierry Escande 
443*7cbe0ff3SThierry Escande 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
444*7cbe0ff3SThierry Escande 	if (dev == NULL)
445*7cbe0ff3SThierry Escande 		return ERR_PTR(-ENOMEM);
446*7cbe0ff3SThierry Escande 
447*7cbe0ff3SThierry Escande 	mutex_init(&dev->lock);
448*7cbe0ff3SThierry Escande 
449*7cbe0ff3SThierry Escande 	INIT_DELAYED_WORK(&dev->recv_work, nfcsim_wq_recv);
450*7cbe0ff3SThierry Escande 	INIT_DELAYED_WORK(&dev->poll_work, nfcsim_wq_poll);
451*7cbe0ff3SThierry Escande 
452*7cbe0ff3SThierry Escande 	dev->nfc_dev = nfc_allocate_device(&nfcsim_nfc_ops,
453*7cbe0ff3SThierry Escande 					   NFC_PROTO_NFC_DEP_MASK,
454*7cbe0ff3SThierry Escande 					   0, 0);
455*7cbe0ff3SThierry Escande 	if (!dev->nfc_dev)
456*7cbe0ff3SThierry Escande 		goto error;
457*7cbe0ff3SThierry Escande 
458*7cbe0ff3SThierry Escande 	nfc_set_drvdata(dev->nfc_dev, dev);
459*7cbe0ff3SThierry Escande 
460*7cbe0ff3SThierry Escande 	rc = nfc_register_device(dev->nfc_dev);
461*7cbe0ff3SThierry Escande 	if (rc)
462*7cbe0ff3SThierry Escande 		goto free_nfc_dev;
463*7cbe0ff3SThierry Escande 
464*7cbe0ff3SThierry Escande 	return dev;
465*7cbe0ff3SThierry Escande 
466*7cbe0ff3SThierry Escande free_nfc_dev:
467*7cbe0ff3SThierry Escande 	nfc_free_device(dev->nfc_dev);
468*7cbe0ff3SThierry Escande 
469*7cbe0ff3SThierry Escande error:
470*7cbe0ff3SThierry Escande 	kfree(dev);
471*7cbe0ff3SThierry Escande 
472*7cbe0ff3SThierry Escande 	return ERR_PTR(rc);
473*7cbe0ff3SThierry Escande }
474*7cbe0ff3SThierry Escande 
475*7cbe0ff3SThierry Escande static void nfcsim_free_device(struct nfcsim *dev)
476*7cbe0ff3SThierry Escande {
477*7cbe0ff3SThierry Escande 	nfc_unregister_device(dev->nfc_dev);
478*7cbe0ff3SThierry Escande 
479*7cbe0ff3SThierry Escande 	nfc_free_device(dev->nfc_dev);
480*7cbe0ff3SThierry Escande 
481*7cbe0ff3SThierry Escande 	kfree(dev);
482*7cbe0ff3SThierry Escande }
483*7cbe0ff3SThierry Escande 
484*7cbe0ff3SThierry Escande int __init nfcsim_init(void)
485*7cbe0ff3SThierry Escande {
486*7cbe0ff3SThierry Escande 	int rc;
487*7cbe0ff3SThierry Escande 
488*7cbe0ff3SThierry Escande 	/* We need an ordered wq to ensure that poll_work items are executed
489*7cbe0ff3SThierry Escande 	 * one at a time.
490*7cbe0ff3SThierry Escande 	 */
491*7cbe0ff3SThierry Escande 	wq = alloc_ordered_workqueue("nfcsim", 0);
492*7cbe0ff3SThierry Escande 	if (!wq) {
493*7cbe0ff3SThierry Escande 		rc = -ENOMEM;
494*7cbe0ff3SThierry Escande 		goto exit;
495*7cbe0ff3SThierry Escande 	}
496*7cbe0ff3SThierry Escande 
497*7cbe0ff3SThierry Escande 	dev0 = nfcsim_init_dev();
498*7cbe0ff3SThierry Escande 	if (IS_ERR(dev0)) {
499*7cbe0ff3SThierry Escande 		rc = PTR_ERR(dev0);
500*7cbe0ff3SThierry Escande 		goto exit;
501*7cbe0ff3SThierry Escande 	}
502*7cbe0ff3SThierry Escande 
503*7cbe0ff3SThierry Escande 	dev1 = nfcsim_init_dev();
504*7cbe0ff3SThierry Escande 	if (IS_ERR(dev1)) {
505*7cbe0ff3SThierry Escande 		kfree(dev0);
506*7cbe0ff3SThierry Escande 
507*7cbe0ff3SThierry Escande 		rc = PTR_ERR(dev1);
508*7cbe0ff3SThierry Escande 		goto exit;
509*7cbe0ff3SThierry Escande 	}
510*7cbe0ff3SThierry Escande 
511*7cbe0ff3SThierry Escande 	dev0->peer_dev = dev1;
512*7cbe0ff3SThierry Escande 	dev1->peer_dev = dev0;
513*7cbe0ff3SThierry Escande 
514*7cbe0ff3SThierry Escande 	pr_debug("NFCsim " NFCSIM_VERSION " initialized\n");
515*7cbe0ff3SThierry Escande 
516*7cbe0ff3SThierry Escande 	rc = 0;
517*7cbe0ff3SThierry Escande exit:
518*7cbe0ff3SThierry Escande 	if (rc)
519*7cbe0ff3SThierry Escande 		pr_err("Failed to initialize nfcsim driver (%d)\n",
520*7cbe0ff3SThierry Escande 		       rc);
521*7cbe0ff3SThierry Escande 
522*7cbe0ff3SThierry Escande 	return rc;
523*7cbe0ff3SThierry Escande }
524*7cbe0ff3SThierry Escande 
525*7cbe0ff3SThierry Escande void __exit nfcsim_exit(void)
526*7cbe0ff3SThierry Escande {
527*7cbe0ff3SThierry Escande 	nfcsim_cleanup_dev(dev0, 1);
528*7cbe0ff3SThierry Escande 	nfcsim_cleanup_dev(dev1, 1);
529*7cbe0ff3SThierry Escande 
530*7cbe0ff3SThierry Escande 	nfcsim_free_device(dev0);
531*7cbe0ff3SThierry Escande 	nfcsim_free_device(dev1);
532*7cbe0ff3SThierry Escande 
533*7cbe0ff3SThierry Escande 	destroy_workqueue(wq);
534*7cbe0ff3SThierry Escande }
535*7cbe0ff3SThierry Escande 
536*7cbe0ff3SThierry Escande module_init(nfcsim_init);
537*7cbe0ff3SThierry Escande module_exit(nfcsim_exit);
538*7cbe0ff3SThierry Escande 
539*7cbe0ff3SThierry Escande MODULE_DESCRIPTION("NFCSim driver ver " NFCSIM_VERSION);
540*7cbe0ff3SThierry Escande MODULE_VERSION(NFCSIM_VERSION);
541*7cbe0ff3SThierry Escande MODULE_LICENSE("GPL");
542