xref: /openbmc/linux/drivers/nfc/nfcsim.c (revision a20eefae)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * NFC hardware simulation driver
4  * Copyright (c) 2013, Intel Corporation.
5  */
6 
7 #include <linux/device.h>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/ctype.h>
11 #include <linux/debugfs.h>
12 #include <linux/nfc.h>
13 #include <net/nfc/nfc.h>
14 #include <net/nfc/digital.h>
15 
16 #define NFCSIM_ERR(d, fmt, args...) nfc_err(&d->nfc_digital_dev->nfc_dev->dev, \
17 					    "%s: " fmt, __func__, ## args)
18 
19 #define NFCSIM_DBG(d, fmt, args...) dev_dbg(&d->nfc_digital_dev->nfc_dev->dev, \
20 					    "%s: " fmt, __func__, ## args)
21 
22 #define NFCSIM_VERSION "0.2"
23 
24 #define NFCSIM_MODE_NONE	0
25 #define NFCSIM_MODE_INITIATOR	1
26 #define NFCSIM_MODE_TARGET	2
27 
28 #define NFCSIM_CAPABILITIES (NFC_DIGITAL_DRV_CAPS_IN_CRC   | \
29 			     NFC_DIGITAL_DRV_CAPS_TG_CRC)
30 
31 struct nfcsim {
32 	struct nfc_digital_dev *nfc_digital_dev;
33 
34 	struct work_struct recv_work;
35 	struct delayed_work send_work;
36 
37 	struct nfcsim_link *link_in;
38 	struct nfcsim_link *link_out;
39 
40 	bool up;
41 	u8 mode;
42 	u8 rf_tech;
43 
44 	u16 recv_timeout;
45 
46 	nfc_digital_cmd_complete_t cb;
47 	void *arg;
48 
49 	u8 dropframe;
50 };
51 
52 struct nfcsim_link {
53 	struct mutex lock;
54 
55 	u8 rf_tech;
56 	u8 mode;
57 
58 	u8 shutdown;
59 
60 	struct sk_buff *skb;
61 	wait_queue_head_t recv_wait;
62 	u8 cond;
63 };
64 
65 static struct nfcsim_link *nfcsim_link_new(void)
66 {
67 	struct nfcsim_link *link;
68 
69 	link = kzalloc(sizeof(struct nfcsim_link), GFP_KERNEL);
70 	if (!link)
71 		return NULL;
72 
73 	mutex_init(&link->lock);
74 	init_waitqueue_head(&link->recv_wait);
75 
76 	return link;
77 }
78 
79 static void nfcsim_link_free(struct nfcsim_link *link)
80 {
81 	dev_kfree_skb(link->skb);
82 	kfree(link);
83 }
84 
85 static void nfcsim_link_recv_wake(struct nfcsim_link *link)
86 {
87 	link->cond = 1;
88 	wake_up_interruptible(&link->recv_wait);
89 }
90 
91 static void nfcsim_link_set_skb(struct nfcsim_link *link, struct sk_buff *skb,
92 				u8 rf_tech, u8 mode)
93 {
94 	mutex_lock(&link->lock);
95 
96 	dev_kfree_skb(link->skb);
97 	link->skb = skb;
98 	link->rf_tech = rf_tech;
99 	link->mode = mode;
100 
101 	mutex_unlock(&link->lock);
102 }
103 
104 static void nfcsim_link_recv_cancel(struct nfcsim_link *link)
105 {
106 	mutex_lock(&link->lock);
107 
108 	link->mode = NFCSIM_MODE_NONE;
109 
110 	mutex_unlock(&link->lock);
111 
112 	nfcsim_link_recv_wake(link);
113 }
114 
115 static void nfcsim_link_shutdown(struct nfcsim_link *link)
116 {
117 	mutex_lock(&link->lock);
118 
119 	link->shutdown = 1;
120 	link->mode = NFCSIM_MODE_NONE;
121 
122 	mutex_unlock(&link->lock);
123 
124 	nfcsim_link_recv_wake(link);
125 }
126 
127 static struct sk_buff *nfcsim_link_recv_skb(struct nfcsim_link *link,
128 					    int timeout, u8 rf_tech, u8 mode)
129 {
130 	int rc;
131 	struct sk_buff *skb;
132 
133 	rc = wait_event_interruptible_timeout(link->recv_wait,
134 					      link->cond,
135 					      msecs_to_jiffies(timeout));
136 
137 	mutex_lock(&link->lock);
138 
139 	skb = link->skb;
140 	link->skb = NULL;
141 
142 	if (!rc) {
143 		rc = -ETIMEDOUT;
144 		goto done;
145 	}
146 
147 	if (!skb || link->rf_tech != rf_tech || link->mode == mode) {
148 		rc = -EINVAL;
149 		goto done;
150 	}
151 
152 	if (link->shutdown) {
153 		rc = -ENODEV;
154 		goto done;
155 	}
156 
157 done:
158 	mutex_unlock(&link->lock);
159 
160 	if (rc < 0) {
161 		dev_kfree_skb(skb);
162 		skb = ERR_PTR(rc);
163 	}
164 
165 	link->cond = 0;
166 
167 	return skb;
168 }
169 
170 static void nfcsim_send_wq(struct work_struct *work)
171 {
172 	struct nfcsim *dev = container_of(work, struct nfcsim, send_work.work);
173 
174 	/*
175 	 * To effectively send data, the device just wake up its link_out which
176 	 * is the link_in of the peer device. The exchanged skb has already been
177 	 * stored in the dev->link_out through nfcsim_link_set_skb().
178 	 */
179 	nfcsim_link_recv_wake(dev->link_out);
180 }
181 
182 static void nfcsim_recv_wq(struct work_struct *work)
183 {
184 	struct nfcsim *dev = container_of(work, struct nfcsim, recv_work);
185 	struct sk_buff *skb;
186 
187 	skb = nfcsim_link_recv_skb(dev->link_in, dev->recv_timeout,
188 				   dev->rf_tech, dev->mode);
189 
190 	if (!dev->up) {
191 		NFCSIM_ERR(dev, "Device is down\n");
192 
193 		if (!IS_ERR(skb))
194 			dev_kfree_skb(skb);
195 
196 		skb = ERR_PTR(-ENODEV);
197 	}
198 
199 	dev->cb(dev->nfc_digital_dev, dev->arg, skb);
200 }
201 
202 static int nfcsim_send(struct nfc_digital_dev *ddev, struct sk_buff *skb,
203 		       u16 timeout, nfc_digital_cmd_complete_t cb, void *arg)
204 {
205 	struct nfcsim *dev = nfc_digital_get_drvdata(ddev);
206 	u8 delay;
207 
208 	if (!dev->up) {
209 		NFCSIM_ERR(dev, "Device is down\n");
210 		return -ENODEV;
211 	}
212 
213 	dev->recv_timeout = timeout;
214 	dev->cb = cb;
215 	dev->arg = arg;
216 
217 	schedule_work(&dev->recv_work);
218 
219 	if (dev->dropframe) {
220 		NFCSIM_DBG(dev, "dropping frame (out of %d)\n", dev->dropframe);
221 		dev_kfree_skb(skb);
222 		dev->dropframe--;
223 
224 		return 0;
225 	}
226 
227 	if (skb) {
228 		nfcsim_link_set_skb(dev->link_out, skb, dev->rf_tech,
229 				    dev->mode);
230 
231 		/* Add random delay (between 3 and 10 ms) before sending data */
232 		get_random_bytes(&delay, 1);
233 		delay = 3 + (delay & 0x07);
234 
235 		schedule_delayed_work(&dev->send_work, msecs_to_jiffies(delay));
236 	}
237 
238 	return 0;
239 }
240 
241 static void nfcsim_abort_cmd(struct nfc_digital_dev *ddev)
242 {
243 	struct nfcsim *dev = nfc_digital_get_drvdata(ddev);
244 
245 	nfcsim_link_recv_cancel(dev->link_in);
246 }
247 
248 static int nfcsim_switch_rf(struct nfc_digital_dev *ddev, bool on)
249 {
250 	struct nfcsim *dev = nfc_digital_get_drvdata(ddev);
251 
252 	dev->up = on;
253 
254 	return 0;
255 }
256 
257 static int nfcsim_in_configure_hw(struct nfc_digital_dev *ddev,
258 					  int type, int param)
259 {
260 	struct nfcsim *dev = nfc_digital_get_drvdata(ddev);
261 
262 	switch (type) {
263 	case NFC_DIGITAL_CONFIG_RF_TECH:
264 		dev->up = true;
265 		dev->mode = NFCSIM_MODE_INITIATOR;
266 		dev->rf_tech = param;
267 		break;
268 
269 	case NFC_DIGITAL_CONFIG_FRAMING:
270 		break;
271 
272 	default:
273 		NFCSIM_ERR(dev, "Invalid configuration type: %d\n", type);
274 		return -EINVAL;
275 	}
276 
277 	return 0;
278 }
279 
280 static int nfcsim_in_send_cmd(struct nfc_digital_dev *ddev,
281 			       struct sk_buff *skb, u16 timeout,
282 			       nfc_digital_cmd_complete_t cb, void *arg)
283 {
284 	return nfcsim_send(ddev, skb, timeout, cb, arg);
285 }
286 
287 static int nfcsim_tg_configure_hw(struct nfc_digital_dev *ddev,
288 					  int type, int param)
289 {
290 	struct nfcsim *dev = nfc_digital_get_drvdata(ddev);
291 
292 	switch (type) {
293 	case NFC_DIGITAL_CONFIG_RF_TECH:
294 		dev->up = true;
295 		dev->mode = NFCSIM_MODE_TARGET;
296 		dev->rf_tech = param;
297 		break;
298 
299 	case NFC_DIGITAL_CONFIG_FRAMING:
300 		break;
301 
302 	default:
303 		NFCSIM_ERR(dev, "Invalid configuration type: %d\n", type);
304 		return -EINVAL;
305 	}
306 
307 	return 0;
308 }
309 
310 static int nfcsim_tg_send_cmd(struct nfc_digital_dev *ddev,
311 			       struct sk_buff *skb, u16 timeout,
312 			       nfc_digital_cmd_complete_t cb, void *arg)
313 {
314 	return nfcsim_send(ddev, skb, timeout, cb, arg);
315 }
316 
317 static int nfcsim_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
318 			    nfc_digital_cmd_complete_t cb, void *arg)
319 {
320 	return nfcsim_send(ddev, NULL, timeout, cb, arg);
321 }
322 
323 static struct nfc_digital_ops nfcsim_digital_ops = {
324 	.in_configure_hw = nfcsim_in_configure_hw,
325 	.in_send_cmd = nfcsim_in_send_cmd,
326 
327 	.tg_listen = nfcsim_tg_listen,
328 	.tg_configure_hw = nfcsim_tg_configure_hw,
329 	.tg_send_cmd = nfcsim_tg_send_cmd,
330 
331 	.abort_cmd = nfcsim_abort_cmd,
332 	.switch_rf = nfcsim_switch_rf,
333 };
334 
335 static struct dentry *nfcsim_debugfs_root;
336 
337 static void nfcsim_debugfs_init(void)
338 {
339 	nfcsim_debugfs_root = debugfs_create_dir("nfcsim", NULL);
340 
341 	if (!nfcsim_debugfs_root)
342 		pr_err("Could not create debugfs entry\n");
343 
344 }
345 
346 static void nfcsim_debugfs_remove(void)
347 {
348 	debugfs_remove_recursive(nfcsim_debugfs_root);
349 }
350 
351 static void nfcsim_debugfs_init_dev(struct nfcsim *dev)
352 {
353 	struct dentry *dev_dir;
354 	char devname[5]; /* nfcX\0 */
355 	u32 idx;
356 	int n;
357 
358 	if (!nfcsim_debugfs_root) {
359 		NFCSIM_ERR(dev, "nfcsim debugfs not initialized\n");
360 		return;
361 	}
362 
363 	idx = dev->nfc_digital_dev->nfc_dev->idx;
364 	n = snprintf(devname, sizeof(devname), "nfc%d", idx);
365 	if (n >= sizeof(devname)) {
366 		NFCSIM_ERR(dev, "Could not compute dev name for dev %d\n", idx);
367 		return;
368 	}
369 
370 	dev_dir = debugfs_create_dir(devname, nfcsim_debugfs_root);
371 	if (!dev_dir) {
372 		NFCSIM_ERR(dev, "Could not create debugfs entries for nfc%d\n",
373 			   idx);
374 		return;
375 	}
376 
377 	debugfs_create_u8("dropframe", 0664, dev_dir, &dev->dropframe);
378 }
379 
380 static struct nfcsim *nfcsim_device_new(struct nfcsim_link *link_in,
381 					struct nfcsim_link *link_out)
382 {
383 	struct nfcsim *dev;
384 	int rc;
385 
386 	dev = kzalloc(sizeof(struct nfcsim), GFP_KERNEL);
387 	if (!dev)
388 		return ERR_PTR(-ENOMEM);
389 
390 	INIT_DELAYED_WORK(&dev->send_work, nfcsim_send_wq);
391 	INIT_WORK(&dev->recv_work, nfcsim_recv_wq);
392 
393 	dev->nfc_digital_dev =
394 			nfc_digital_allocate_device(&nfcsim_digital_ops,
395 						    NFC_PROTO_NFC_DEP_MASK,
396 						    NFCSIM_CAPABILITIES,
397 						    0, 0);
398 	if (!dev->nfc_digital_dev) {
399 		kfree(dev);
400 		return ERR_PTR(-ENOMEM);
401 	}
402 
403 	nfc_digital_set_drvdata(dev->nfc_digital_dev, dev);
404 
405 	dev->link_in = link_in;
406 	dev->link_out = link_out;
407 
408 	rc = nfc_digital_register_device(dev->nfc_digital_dev);
409 	if (rc) {
410 		pr_err("Could not register digital device (%d)\n", rc);
411 		nfc_digital_free_device(dev->nfc_digital_dev);
412 		kfree(dev);
413 
414 		return ERR_PTR(rc);
415 	}
416 
417 	nfcsim_debugfs_init_dev(dev);
418 
419 	return dev;
420 }
421 
422 static void nfcsim_device_free(struct nfcsim *dev)
423 {
424 	nfc_digital_unregister_device(dev->nfc_digital_dev);
425 
426 	dev->up = false;
427 
428 	nfcsim_link_shutdown(dev->link_in);
429 
430 	cancel_delayed_work_sync(&dev->send_work);
431 	cancel_work_sync(&dev->recv_work);
432 
433 	nfc_digital_free_device(dev->nfc_digital_dev);
434 
435 	kfree(dev);
436 }
437 
438 static struct nfcsim *dev0;
439 static struct nfcsim *dev1;
440 
441 static int __init nfcsim_init(void)
442 {
443 	struct nfcsim_link *link0, *link1;
444 	int rc;
445 
446 	link0 = nfcsim_link_new();
447 	link1 = nfcsim_link_new();
448 	if (!link0 || !link1) {
449 		rc = -ENOMEM;
450 		goto exit_err;
451 	}
452 
453 	nfcsim_debugfs_init();
454 
455 	dev0 = nfcsim_device_new(link0, link1);
456 	if (IS_ERR(dev0)) {
457 		rc = PTR_ERR(dev0);
458 		goto exit_err;
459 	}
460 
461 	dev1 = nfcsim_device_new(link1, link0);
462 	if (IS_ERR(dev1)) {
463 		nfcsim_device_free(dev0);
464 
465 		rc = PTR_ERR(dev1);
466 		goto exit_err;
467 	}
468 
469 	pr_info("nfcsim " NFCSIM_VERSION " initialized\n");
470 
471 	return 0;
472 
473 exit_err:
474 	pr_err("Failed to initialize nfcsim driver (%d)\n", rc);
475 
476 	if (link0)
477 		nfcsim_link_free(link0);
478 	if (link1)
479 		nfcsim_link_free(link1);
480 
481 	return rc;
482 }
483 
484 static void __exit nfcsim_exit(void)
485 {
486 	struct nfcsim_link *link0, *link1;
487 
488 	link0 = dev0->link_in;
489 	link1 = dev0->link_out;
490 
491 	nfcsim_device_free(dev0);
492 	nfcsim_device_free(dev1);
493 
494 	nfcsim_link_free(link0);
495 	nfcsim_link_free(link1);
496 
497 	nfcsim_debugfs_remove();
498 }
499 
500 module_init(nfcsim_init);
501 module_exit(nfcsim_exit);
502 
503 MODULE_DESCRIPTION("NFCSim driver ver " NFCSIM_VERSION);
504 MODULE_VERSION(NFCSIM_VERSION);
505 MODULE_LICENSE("GPL");
506