blob: 99b06a16b8086c5906ea3429e73dad69dec549c8 [file] [log] [blame]
David Brazdil0f672f62019-12-10 10:32:29 +00001// SPDX-License-Identifier: GPL-2.0-or-later
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002/*
3 * Copyright (C) 2011 Instituto Nokia de Tecnologia
4 *
5 * Authors:
6 * Lauro Ramos Venancio <lauro.venancio@openbossa.org>
7 * Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
8 *
9 * Vendor commands implementation based on net/wireless/nl80211.c
10 * which is:
11 *
12 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
13 * Copyright 2013-2014 Intel Mobile Communications GmbH
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000014 */
15
16#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
17
18#include <net/genetlink.h>
19#include <linux/nfc.h>
20#include <linux/slab.h>
21
22#include "nfc.h"
23#include "llcp.h"
24
25static const struct genl_multicast_group nfc_genl_mcgrps[] = {
26 { .name = NFC_GENL_MCAST_EVENT_NAME, },
27};
28
29static struct genl_family nfc_genl_family;
30static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
31 [NFC_ATTR_DEVICE_INDEX] = { .type = NLA_U32 },
32 [NFC_ATTR_DEVICE_NAME] = { .type = NLA_STRING,
33 .len = NFC_DEVICE_NAME_MAXSIZE },
34 [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 },
Olivier Deprez0e641232021-09-23 10:07:05 +020035 [NFC_ATTR_TARGET_INDEX] = { .type = NLA_U32 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000036 [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 },
37 [NFC_ATTR_RF_MODE] = { .type = NLA_U8 },
38 [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 },
39 [NFC_ATTR_IM_PROTOCOLS] = { .type = NLA_U32 },
40 [NFC_ATTR_TM_PROTOCOLS] = { .type = NLA_U32 },
41 [NFC_ATTR_LLC_PARAM_LTO] = { .type = NLA_U8 },
42 [NFC_ATTR_LLC_PARAM_RW] = { .type = NLA_U8 },
43 [NFC_ATTR_LLC_PARAM_MIUX] = { .type = NLA_U16 },
44 [NFC_ATTR_LLC_SDP] = { .type = NLA_NESTED },
45 [NFC_ATTR_FIRMWARE_NAME] = { .type = NLA_STRING,
46 .len = NFC_FIRMWARE_NAME_MAXSIZE },
Olivier Deprez0e641232021-09-23 10:07:05 +020047 [NFC_ATTR_SE_INDEX] = { .type = NLA_U32 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000048 [NFC_ATTR_SE_APDU] = { .type = NLA_BINARY },
Olivier Deprez0e641232021-09-23 10:07:05 +020049 [NFC_ATTR_VENDOR_ID] = { .type = NLA_U32 },
50 [NFC_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000051 [NFC_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
52
53};
54
55static const struct nla_policy nfc_sdp_genl_policy[NFC_SDP_ATTR_MAX + 1] = {
56 [NFC_SDP_ATTR_URI] = { .type = NLA_STRING,
57 .len = U8_MAX - 4 },
58 [NFC_SDP_ATTR_SAP] = { .type = NLA_U8 },
59};
60
61static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
62 struct netlink_callback *cb, int flags)
63{
64 void *hdr;
65
66 hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
67 &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
68 if (!hdr)
69 return -EMSGSIZE;
70
71 genl_dump_check_consistent(cb, hdr);
72
73 if (nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target->idx) ||
74 nla_put_u32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols) ||
75 nla_put_u16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res) ||
76 nla_put_u8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res))
77 goto nla_put_failure;
78 if (target->nfcid1_len > 0 &&
79 nla_put(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
80 target->nfcid1))
81 goto nla_put_failure;
82 if (target->sensb_res_len > 0 &&
83 nla_put(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
84 target->sensb_res))
85 goto nla_put_failure;
86 if (target->sensf_res_len > 0 &&
87 nla_put(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
88 target->sensf_res))
89 goto nla_put_failure;
90
91 if (target->is_iso15693) {
92 if (nla_put_u8(msg, NFC_ATTR_TARGET_ISO15693_DSFID,
93 target->iso15693_dsfid) ||
94 nla_put(msg, NFC_ATTR_TARGET_ISO15693_UID,
95 sizeof(target->iso15693_uid), target->iso15693_uid))
96 goto nla_put_failure;
97 }
98
99 genlmsg_end(msg, hdr);
100 return 0;
101
102nla_put_failure:
103 genlmsg_cancel(msg, hdr);
104 return -EMSGSIZE;
105}
106
107static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
108{
109 struct nlattr **attrbuf = genl_family_attrbuf(&nfc_genl_family);
110 struct nfc_dev *dev;
111 int rc;
112 u32 idx;
113
David Brazdil0f672f62019-12-10 10:32:29 +0000114 rc = nlmsg_parse_deprecated(cb->nlh,
115 GENL_HDRLEN + nfc_genl_family.hdrsize,
116 attrbuf, nfc_genl_family.maxattr,
117 nfc_genl_policy, NULL);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000118 if (rc < 0)
119 return ERR_PTR(rc);
120
121 if (!attrbuf[NFC_ATTR_DEVICE_INDEX])
122 return ERR_PTR(-EINVAL);
123
124 idx = nla_get_u32(attrbuf[NFC_ATTR_DEVICE_INDEX]);
125
126 dev = nfc_get_device(idx);
127 if (!dev)
128 return ERR_PTR(-ENODEV);
129
130 return dev;
131}
132
133static int nfc_genl_dump_targets(struct sk_buff *skb,
134 struct netlink_callback *cb)
135{
136 int i = cb->args[0];
137 struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
138 int rc;
139
140 if (!dev) {
141 dev = __get_device_from_cb(cb);
142 if (IS_ERR(dev))
143 return PTR_ERR(dev);
144
145 cb->args[1] = (long) dev;
146 }
147
148 device_lock(&dev->dev);
149
150 cb->seq = dev->targets_generation;
151
152 while (i < dev->n_targets) {
153 rc = nfc_genl_send_target(skb, &dev->targets[i], cb,
154 NLM_F_MULTI);
155 if (rc < 0)
156 break;
157
158 i++;
159 }
160
161 device_unlock(&dev->dev);
162
163 cb->args[0] = i;
164
165 return skb->len;
166}
167
168static int nfc_genl_dump_targets_done(struct netlink_callback *cb)
169{
170 struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
171
172 if (dev)
173 nfc_put_device(dev);
174
175 return 0;
176}
177
178int nfc_genl_targets_found(struct nfc_dev *dev)
179{
180 struct sk_buff *msg;
181 void *hdr;
182
183 dev->genl_data.poll_req_portid = 0;
184
185 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
186 if (!msg)
187 return -ENOMEM;
188
189 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
190 NFC_EVENT_TARGETS_FOUND);
191 if (!hdr)
192 goto free_msg;
193
194 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
195 goto nla_put_failure;
196
197 genlmsg_end(msg, hdr);
198
199 return genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
200
201nla_put_failure:
202free_msg:
203 nlmsg_free(msg);
204 return -EMSGSIZE;
205}
206
207int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx)
208{
209 struct sk_buff *msg;
210 void *hdr;
211
212 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
213 if (!msg)
214 return -ENOMEM;
215
216 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
217 NFC_EVENT_TARGET_LOST);
218 if (!hdr)
219 goto free_msg;
220
221 if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
222 nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
223 goto nla_put_failure;
224
225 genlmsg_end(msg, hdr);
226
227 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
228
229 return 0;
230
231nla_put_failure:
232free_msg:
233 nlmsg_free(msg);
234 return -EMSGSIZE;
235}
236
237int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol)
238{
239 struct sk_buff *msg;
240 void *hdr;
241
242 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
243 if (!msg)
244 return -ENOMEM;
245
246 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
247 NFC_EVENT_TM_ACTIVATED);
248 if (!hdr)
249 goto free_msg;
250
251 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
252 goto nla_put_failure;
253 if (nla_put_u32(msg, NFC_ATTR_TM_PROTOCOLS, protocol))
254 goto nla_put_failure;
255
256 genlmsg_end(msg, hdr);
257
258 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
259
260 return 0;
261
262nla_put_failure:
263free_msg:
264 nlmsg_free(msg);
265 return -EMSGSIZE;
266}
267
268int nfc_genl_tm_deactivated(struct nfc_dev *dev)
269{
270 struct sk_buff *msg;
271 void *hdr;
272
273 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
274 if (!msg)
275 return -ENOMEM;
276
277 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
278 NFC_EVENT_TM_DEACTIVATED);
279 if (!hdr)
280 goto free_msg;
281
282 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
283 goto nla_put_failure;
284
285 genlmsg_end(msg, hdr);
286
287 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
288
289 return 0;
290
291nla_put_failure:
292free_msg:
293 nlmsg_free(msg);
294 return -EMSGSIZE;
295}
296
297static int nfc_genl_setup_device_added(struct nfc_dev *dev, struct sk_buff *msg)
298{
299 if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
300 nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
301 nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
302 nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) ||
303 nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode))
304 return -1;
305 return 0;
306}
307
308int nfc_genl_device_added(struct nfc_dev *dev)
309{
310 struct sk_buff *msg;
311 void *hdr;
312
313 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
314 if (!msg)
315 return -ENOMEM;
316
317 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
318 NFC_EVENT_DEVICE_ADDED);
319 if (!hdr)
320 goto free_msg;
321
322 if (nfc_genl_setup_device_added(dev, msg))
323 goto nla_put_failure;
324
325 genlmsg_end(msg, hdr);
326
327 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
328
329 return 0;
330
331nla_put_failure:
332free_msg:
333 nlmsg_free(msg);
334 return -EMSGSIZE;
335}
336
337int nfc_genl_device_removed(struct nfc_dev *dev)
338{
339 struct sk_buff *msg;
340 void *hdr;
341
342 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
343 if (!msg)
344 return -ENOMEM;
345
346 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
347 NFC_EVENT_DEVICE_REMOVED);
348 if (!hdr)
349 goto free_msg;
350
351 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
352 goto nla_put_failure;
353
354 genlmsg_end(msg, hdr);
355
356 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
357
358 return 0;
359
360nla_put_failure:
361free_msg:
362 nlmsg_free(msg);
363 return -EMSGSIZE;
364}
365
366int nfc_genl_llc_send_sdres(struct nfc_dev *dev, struct hlist_head *sdres_list)
367{
368 struct sk_buff *msg;
369 struct nlattr *sdp_attr, *uri_attr;
370 struct nfc_llcp_sdp_tlv *sdres;
371 struct hlist_node *n;
372 void *hdr;
373 int rc = -EMSGSIZE;
374 int i;
375
376 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
377 if (!msg)
378 return -ENOMEM;
379
380 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
381 NFC_EVENT_LLC_SDRES);
382 if (!hdr)
383 goto free_msg;
384
385 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
386 goto nla_put_failure;
387
David Brazdil0f672f62019-12-10 10:32:29 +0000388 sdp_attr = nla_nest_start_noflag(msg, NFC_ATTR_LLC_SDP);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000389 if (sdp_attr == NULL) {
390 rc = -ENOMEM;
391 goto nla_put_failure;
392 }
393
394 i = 1;
395 hlist_for_each_entry_safe(sdres, n, sdres_list, node) {
396 pr_debug("uri: %s, sap: %d\n", sdres->uri, sdres->sap);
397
David Brazdil0f672f62019-12-10 10:32:29 +0000398 uri_attr = nla_nest_start_noflag(msg, i++);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000399 if (uri_attr == NULL) {
400 rc = -ENOMEM;
401 goto nla_put_failure;
402 }
403
404 if (nla_put_u8(msg, NFC_SDP_ATTR_SAP, sdres->sap))
405 goto nla_put_failure;
406
407 if (nla_put_string(msg, NFC_SDP_ATTR_URI, sdres->uri))
408 goto nla_put_failure;
409
410 nla_nest_end(msg, uri_attr);
411
412 hlist_del(&sdres->node);
413
414 nfc_llcp_free_sdp_tlv(sdres);
415 }
416
417 nla_nest_end(msg, sdp_attr);
418
419 genlmsg_end(msg, hdr);
420
421 return genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
422
423nla_put_failure:
424free_msg:
425 nlmsg_free(msg);
426
427 nfc_llcp_free_sdp_tlv_list(sdres_list);
428
429 return rc;
430}
431
432int nfc_genl_se_added(struct nfc_dev *dev, u32 se_idx, u16 type)
433{
434 struct sk_buff *msg;
435 void *hdr;
436
437 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
438 if (!msg)
439 return -ENOMEM;
440
441 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
442 NFC_EVENT_SE_ADDED);
443 if (!hdr)
444 goto free_msg;
445
446 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
447 nla_put_u32(msg, NFC_ATTR_SE_INDEX, se_idx) ||
448 nla_put_u8(msg, NFC_ATTR_SE_TYPE, type))
449 goto nla_put_failure;
450
451 genlmsg_end(msg, hdr);
452
453 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
454
455 return 0;
456
457nla_put_failure:
458free_msg:
459 nlmsg_free(msg);
460 return -EMSGSIZE;
461}
462
463int nfc_genl_se_removed(struct nfc_dev *dev, u32 se_idx)
464{
465 struct sk_buff *msg;
466 void *hdr;
467
468 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
469 if (!msg)
470 return -ENOMEM;
471
472 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
473 NFC_EVENT_SE_REMOVED);
474 if (!hdr)
475 goto free_msg;
476
477 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
478 nla_put_u32(msg, NFC_ATTR_SE_INDEX, se_idx))
479 goto nla_put_failure;
480
481 genlmsg_end(msg, hdr);
482
483 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
484
485 return 0;
486
487nla_put_failure:
488free_msg:
489 nlmsg_free(msg);
490 return -EMSGSIZE;
491}
492
493int nfc_genl_se_transaction(struct nfc_dev *dev, u8 se_idx,
494 struct nfc_evt_transaction *evt_transaction)
495{
496 struct nfc_se *se;
497 struct sk_buff *msg;
498 void *hdr;
499
500 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
501 if (!msg)
502 return -ENOMEM;
503
504 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
505 NFC_EVENT_SE_TRANSACTION);
506 if (!hdr)
507 goto free_msg;
508
509 se = nfc_find_se(dev, se_idx);
510 if (!se)
511 goto free_msg;
512
513 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
514 nla_put_u32(msg, NFC_ATTR_SE_INDEX, se_idx) ||
515 nla_put_u8(msg, NFC_ATTR_SE_TYPE, se->type) ||
516 nla_put(msg, NFC_ATTR_SE_AID, evt_transaction->aid_len,
517 evt_transaction->aid) ||
518 nla_put(msg, NFC_ATTR_SE_PARAMS, evt_transaction->params_len,
519 evt_transaction->params))
520 goto nla_put_failure;
521
522 /* evt_transaction is no more used */
523 devm_kfree(&dev->dev, evt_transaction);
524
525 genlmsg_end(msg, hdr);
526
527 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
528
529 return 0;
530
531nla_put_failure:
532free_msg:
533 /* evt_transaction is no more used */
534 devm_kfree(&dev->dev, evt_transaction);
535 nlmsg_free(msg);
536 return -EMSGSIZE;
537}
538
539int nfc_genl_se_connectivity(struct nfc_dev *dev, u8 se_idx)
540{
541 struct nfc_se *se;
542 struct sk_buff *msg;
543 void *hdr;
544
545 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
546 if (!msg)
547 return -ENOMEM;
548
549 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
550 NFC_EVENT_SE_CONNECTIVITY);
551 if (!hdr)
552 goto free_msg;
553
554 se = nfc_find_se(dev, se_idx);
555 if (!se)
556 goto free_msg;
557
558 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
559 nla_put_u32(msg, NFC_ATTR_SE_INDEX, se_idx) ||
560 nla_put_u8(msg, NFC_ATTR_SE_TYPE, se->type))
561 goto nla_put_failure;
562
563 genlmsg_end(msg, hdr);
564
565 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
566
567 return 0;
568
569nla_put_failure:
570free_msg:
571 nlmsg_free(msg);
572 return -EMSGSIZE;
573}
574
575static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
576 u32 portid, u32 seq,
577 struct netlink_callback *cb,
578 int flags)
579{
580 void *hdr;
581
582 hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, flags,
583 NFC_CMD_GET_DEVICE);
584 if (!hdr)
585 return -EMSGSIZE;
586
587 if (cb)
588 genl_dump_check_consistent(cb, hdr);
589
590 if (nfc_genl_setup_device_added(dev, msg))
591 goto nla_put_failure;
592
593 genlmsg_end(msg, hdr);
594 return 0;
595
596nla_put_failure:
597 genlmsg_cancel(msg, hdr);
598 return -EMSGSIZE;
599}
600
601static int nfc_genl_dump_devices(struct sk_buff *skb,
602 struct netlink_callback *cb)
603{
604 struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
605 struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
606 bool first_call = false;
607
608 if (!iter) {
609 first_call = true;
610 iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL);
611 if (!iter)
612 return -ENOMEM;
613 cb->args[0] = (long) iter;
614 }
615
616 mutex_lock(&nfc_devlist_mutex);
617
618 cb->seq = nfc_devlist_generation;
619
620 if (first_call) {
621 nfc_device_iter_init(iter);
622 dev = nfc_device_iter_next(iter);
623 }
624
625 while (dev) {
626 int rc;
627
628 rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).portid,
629 cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
630 if (rc < 0)
631 break;
632
633 dev = nfc_device_iter_next(iter);
634 }
635
636 mutex_unlock(&nfc_devlist_mutex);
637
638 cb->args[1] = (long) dev;
639
640 return skb->len;
641}
642
643static int nfc_genl_dump_devices_done(struct netlink_callback *cb)
644{
645 struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
646
647 nfc_device_iter_exit(iter);
648 kfree(iter);
649
650 return 0;
651}
652
653int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
654 u8 comm_mode, u8 rf_mode)
655{
656 struct sk_buff *msg;
657 void *hdr;
658
659 pr_debug("DEP link is up\n");
660
661 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
662 if (!msg)
663 return -ENOMEM;
664
665 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, NFC_CMD_DEP_LINK_UP);
666 if (!hdr)
667 goto free_msg;
668
669 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
670 goto nla_put_failure;
671 if (rf_mode == NFC_RF_INITIATOR &&
672 nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
673 goto nla_put_failure;
674 if (nla_put_u8(msg, NFC_ATTR_COMM_MODE, comm_mode) ||
675 nla_put_u8(msg, NFC_ATTR_RF_MODE, rf_mode))
676 goto nla_put_failure;
677
678 genlmsg_end(msg, hdr);
679
680 dev->dep_link_up = true;
681
682 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
683
684 return 0;
685
686nla_put_failure:
687free_msg:
688 nlmsg_free(msg);
689 return -EMSGSIZE;
690}
691
692int nfc_genl_dep_link_down_event(struct nfc_dev *dev)
693{
694 struct sk_buff *msg;
695 void *hdr;
696
697 pr_debug("DEP link is down\n");
698
699 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
700 if (!msg)
701 return -ENOMEM;
702
703 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
704 NFC_CMD_DEP_LINK_DOWN);
705 if (!hdr)
706 goto free_msg;
707
708 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
709 goto nla_put_failure;
710
711 genlmsg_end(msg, hdr);
712
713 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC);
714
715 return 0;
716
717nla_put_failure:
718free_msg:
719 nlmsg_free(msg);
720 return -EMSGSIZE;
721}
722
723static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
724{
725 struct sk_buff *msg;
726 struct nfc_dev *dev;
727 u32 idx;
728 int rc = -ENOBUFS;
729
730 if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
731 return -EINVAL;
732
733 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
734
735 dev = nfc_get_device(idx);
736 if (!dev)
737 return -ENODEV;
738
739 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
740 if (!msg) {
741 rc = -ENOMEM;
742 goto out_putdev;
743 }
744
745 rc = nfc_genl_send_device(msg, dev, info->snd_portid, info->snd_seq,
746 NULL, 0);
747 if (rc < 0)
748 goto out_free;
749
750 nfc_put_device(dev);
751
752 return genlmsg_reply(msg, info);
753
754out_free:
755 nlmsg_free(msg);
756out_putdev:
757 nfc_put_device(dev);
758 return rc;
759}
760
761static int nfc_genl_dev_up(struct sk_buff *skb, struct genl_info *info)
762{
763 struct nfc_dev *dev;
764 int rc;
765 u32 idx;
766
767 if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
768 return -EINVAL;
769
770 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
771
772 dev = nfc_get_device(idx);
773 if (!dev)
774 return -ENODEV;
775
776 rc = nfc_dev_up(dev);
777
778 nfc_put_device(dev);
779 return rc;
780}
781
782static int nfc_genl_dev_down(struct sk_buff *skb, struct genl_info *info)
783{
784 struct nfc_dev *dev;
785 int rc;
786 u32 idx;
787
788 if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
789 return -EINVAL;
790
791 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
792
793 dev = nfc_get_device(idx);
794 if (!dev)
795 return -ENODEV;
796
797 rc = nfc_dev_down(dev);
798
799 nfc_put_device(dev);
800 return rc;
801}
802
803static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
804{
805 struct nfc_dev *dev;
806 int rc;
807 u32 idx;
808 u32 im_protocols = 0, tm_protocols = 0;
809
810 pr_debug("Poll start\n");
811
812 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
813 ((!info->attrs[NFC_ATTR_IM_PROTOCOLS] &&
814 !info->attrs[NFC_ATTR_PROTOCOLS]) &&
815 !info->attrs[NFC_ATTR_TM_PROTOCOLS]))
816 return -EINVAL;
817
818 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
819
820 if (info->attrs[NFC_ATTR_TM_PROTOCOLS])
821 tm_protocols = nla_get_u32(info->attrs[NFC_ATTR_TM_PROTOCOLS]);
822
823 if (info->attrs[NFC_ATTR_IM_PROTOCOLS])
824 im_protocols = nla_get_u32(info->attrs[NFC_ATTR_IM_PROTOCOLS]);
825 else if (info->attrs[NFC_ATTR_PROTOCOLS])
826 im_protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]);
827
828 dev = nfc_get_device(idx);
829 if (!dev)
830 return -ENODEV;
831
832 mutex_lock(&dev->genl_data.genl_data_mutex);
833
834 rc = nfc_start_poll(dev, im_protocols, tm_protocols);
835 if (!rc)
836 dev->genl_data.poll_req_portid = info->snd_portid;
837
838 mutex_unlock(&dev->genl_data.genl_data_mutex);
839
840 nfc_put_device(dev);
841 return rc;
842}
843
844static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info)
845{
846 struct nfc_dev *dev;
847 int rc;
848 u32 idx;
849
850 if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
851 return -EINVAL;
852
853 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
854
855 dev = nfc_get_device(idx);
856 if (!dev)
857 return -ENODEV;
858
859 device_lock(&dev->dev);
860
861 if (!dev->polling) {
862 device_unlock(&dev->dev);
Olivier Deprez0e641232021-09-23 10:07:05 +0200863 nfc_put_device(dev);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000864 return -EINVAL;
865 }
866
867 device_unlock(&dev->dev);
868
869 mutex_lock(&dev->genl_data.genl_data_mutex);
870
871 if (dev->genl_data.poll_req_portid != info->snd_portid) {
872 rc = -EBUSY;
873 goto out;
874 }
875
876 rc = nfc_stop_poll(dev);
877 dev->genl_data.poll_req_portid = 0;
878
879out:
880 mutex_unlock(&dev->genl_data.genl_data_mutex);
881 nfc_put_device(dev);
882 return rc;
883}
884
885static int nfc_genl_activate_target(struct sk_buff *skb, struct genl_info *info)
886{
887 struct nfc_dev *dev;
888 u32 device_idx, target_idx, protocol;
889 int rc;
890
891 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
892 !info->attrs[NFC_ATTR_TARGET_INDEX] ||
893 !info->attrs[NFC_ATTR_PROTOCOLS])
894 return -EINVAL;
895
896 device_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
897
898 dev = nfc_get_device(device_idx);
899 if (!dev)
900 return -ENODEV;
901
902 target_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
903 protocol = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]);
904
905 nfc_deactivate_target(dev, target_idx, NFC_TARGET_MODE_SLEEP);
906 rc = nfc_activate_target(dev, target_idx, protocol);
907
908 nfc_put_device(dev);
909 return rc;
910}
911
912static int nfc_genl_deactivate_target(struct sk_buff *skb,
913 struct genl_info *info)
914{
915 struct nfc_dev *dev;
916 u32 device_idx, target_idx;
917 int rc;
918
David Brazdil0f672f62019-12-10 10:32:29 +0000919 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
920 !info->attrs[NFC_ATTR_TARGET_INDEX])
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000921 return -EINVAL;
922
923 device_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
924
925 dev = nfc_get_device(device_idx);
926 if (!dev)
927 return -ENODEV;
928
929 target_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
930
931 rc = nfc_deactivate_target(dev, target_idx, NFC_TARGET_MODE_SLEEP);
932
933 nfc_put_device(dev);
934 return rc;
935}
936
937static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
938{
939 struct nfc_dev *dev;
940 int rc, tgt_idx;
941 u32 idx;
942 u8 comm;
943
944 pr_debug("DEP link up\n");
945
946 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
947 !info->attrs[NFC_ATTR_COMM_MODE])
948 return -EINVAL;
949
950 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
951 if (!info->attrs[NFC_ATTR_TARGET_INDEX])
952 tgt_idx = NFC_TARGET_IDX_ANY;
953 else
954 tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
955
956 comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]);
957
958 if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE)
959 return -EINVAL;
960
961 dev = nfc_get_device(idx);
962 if (!dev)
963 return -ENODEV;
964
965 rc = nfc_dep_link_up(dev, tgt_idx, comm);
966
967 nfc_put_device(dev);
968
969 return rc;
970}
971
972static int nfc_genl_dep_link_down(struct sk_buff *skb, struct genl_info *info)
973{
974 struct nfc_dev *dev;
975 int rc;
976 u32 idx;
977
David Brazdil0f672f62019-12-10 10:32:29 +0000978 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
979 !info->attrs[NFC_ATTR_TARGET_INDEX])
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000980 return -EINVAL;
981
982 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
983
984 dev = nfc_get_device(idx);
985 if (!dev)
986 return -ENODEV;
987
988 rc = nfc_dep_link_down(dev);
989
990 nfc_put_device(dev);
991 return rc;
992}
993
994static int nfc_genl_send_params(struct sk_buff *msg,
995 struct nfc_llcp_local *local,
996 u32 portid, u32 seq)
997{
998 void *hdr;
999
1000 hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, 0,
1001 NFC_CMD_LLC_GET_PARAMS);
1002 if (!hdr)
1003 return -EMSGSIZE;
1004
1005 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, local->dev->idx) ||
1006 nla_put_u8(msg, NFC_ATTR_LLC_PARAM_LTO, local->lto) ||
1007 nla_put_u8(msg, NFC_ATTR_LLC_PARAM_RW, local->rw) ||
1008 nla_put_u16(msg, NFC_ATTR_LLC_PARAM_MIUX, be16_to_cpu(local->miux)))
1009 goto nla_put_failure;
1010
1011 genlmsg_end(msg, hdr);
1012 return 0;
1013
1014nla_put_failure:
1015 genlmsg_cancel(msg, hdr);
1016 return -EMSGSIZE;
1017}
1018
1019static int nfc_genl_llc_get_params(struct sk_buff *skb, struct genl_info *info)
1020{
1021 struct nfc_dev *dev;
1022 struct nfc_llcp_local *local;
1023 int rc = 0;
1024 struct sk_buff *msg = NULL;
1025 u32 idx;
1026
David Brazdil0f672f62019-12-10 10:32:29 +00001027 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
1028 !info->attrs[NFC_ATTR_FIRMWARE_NAME])
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001029 return -EINVAL;
1030
1031 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
1032
1033 dev = nfc_get_device(idx);
1034 if (!dev)
1035 return -ENODEV;
1036
1037 device_lock(&dev->dev);
1038
1039 local = nfc_llcp_find_local(dev);
1040 if (!local) {
1041 rc = -ENODEV;
1042 goto exit;
1043 }
1044
1045 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1046 if (!msg) {
1047 rc = -ENOMEM;
1048 goto exit;
1049 }
1050
1051 rc = nfc_genl_send_params(msg, local, info->snd_portid, info->snd_seq);
1052
1053exit:
1054 device_unlock(&dev->dev);
1055
1056 nfc_put_device(dev);
1057
1058 if (rc < 0) {
1059 if (msg)
1060 nlmsg_free(msg);
1061
1062 return rc;
1063 }
1064
1065 return genlmsg_reply(msg, info);
1066}
1067
1068static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info)
1069{
1070 struct nfc_dev *dev;
1071 struct nfc_llcp_local *local;
1072 u8 rw = 0;
1073 u16 miux = 0;
1074 u32 idx;
1075 int rc = 0;
1076
1077 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
1078 (!info->attrs[NFC_ATTR_LLC_PARAM_LTO] &&
1079 !info->attrs[NFC_ATTR_LLC_PARAM_RW] &&
1080 !info->attrs[NFC_ATTR_LLC_PARAM_MIUX]))
1081 return -EINVAL;
1082
1083 if (info->attrs[NFC_ATTR_LLC_PARAM_RW]) {
1084 rw = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_RW]);
1085
1086 if (rw > LLCP_MAX_RW)
1087 return -EINVAL;
1088 }
1089
1090 if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX]) {
1091 miux = nla_get_u16(info->attrs[NFC_ATTR_LLC_PARAM_MIUX]);
1092
1093 if (miux > LLCP_MAX_MIUX)
1094 return -EINVAL;
1095 }
1096
1097 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
1098
1099 dev = nfc_get_device(idx);
1100 if (!dev)
1101 return -ENODEV;
1102
1103 device_lock(&dev->dev);
1104
1105 local = nfc_llcp_find_local(dev);
1106 if (!local) {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001107 rc = -ENODEV;
1108 goto exit;
1109 }
1110
1111 if (info->attrs[NFC_ATTR_LLC_PARAM_LTO]) {
1112 if (dev->dep_link_up) {
1113 rc = -EINPROGRESS;
1114 goto exit;
1115 }
1116
1117 local->lto = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_LTO]);
1118 }
1119
1120 if (info->attrs[NFC_ATTR_LLC_PARAM_RW])
1121 local->rw = rw;
1122
1123 if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX])
1124 local->miux = cpu_to_be16(miux);
1125
1126exit:
1127 device_unlock(&dev->dev);
1128
1129 nfc_put_device(dev);
1130
1131 return rc;
1132}
1133
1134static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
1135{
1136 struct nfc_dev *dev;
1137 struct nfc_llcp_local *local;
1138 struct nlattr *attr, *sdp_attrs[NFC_SDP_ATTR_MAX+1];
1139 u32 idx;
1140 u8 tid;
1141 char *uri;
1142 int rc = 0, rem;
1143 size_t uri_len, tlvs_len;
1144 struct hlist_head sdreq_list;
1145 struct nfc_llcp_sdp_tlv *sdreq;
1146
1147 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
1148 !info->attrs[NFC_ATTR_LLC_SDP])
1149 return -EINVAL;
1150
1151 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
1152
1153 dev = nfc_get_device(idx);
1154 if (!dev)
1155 return -ENODEV;
1156
1157 device_lock(&dev->dev);
1158
1159 if (dev->dep_link_up == false) {
1160 rc = -ENOLINK;
1161 goto exit;
1162 }
1163
1164 local = nfc_llcp_find_local(dev);
1165 if (!local) {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001166 rc = -ENODEV;
1167 goto exit;
1168 }
1169
1170 INIT_HLIST_HEAD(&sdreq_list);
1171
1172 tlvs_len = 0;
1173
1174 nla_for_each_nested(attr, info->attrs[NFC_ATTR_LLC_SDP], rem) {
David Brazdil0f672f62019-12-10 10:32:29 +00001175 rc = nla_parse_nested_deprecated(sdp_attrs, NFC_SDP_ATTR_MAX,
1176 attr, nfc_sdp_genl_policy,
1177 info->extack);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001178
1179 if (rc != 0) {
1180 rc = -EINVAL;
1181 goto exit;
1182 }
1183
1184 if (!sdp_attrs[NFC_SDP_ATTR_URI])
1185 continue;
1186
1187 uri_len = nla_len(sdp_attrs[NFC_SDP_ATTR_URI]);
1188 if (uri_len == 0)
1189 continue;
1190
1191 uri = nla_data(sdp_attrs[NFC_SDP_ATTR_URI]);
1192 if (uri == NULL || *uri == 0)
1193 continue;
1194
1195 tid = local->sdreq_next_tid++;
1196
1197 sdreq = nfc_llcp_build_sdreq_tlv(tid, uri, uri_len);
1198 if (sdreq == NULL) {
1199 rc = -ENOMEM;
1200 goto exit;
1201 }
1202
1203 tlvs_len += sdreq->tlv_len;
1204
1205 hlist_add_head(&sdreq->node, &sdreq_list);
1206 }
1207
1208 if (hlist_empty(&sdreq_list)) {
1209 rc = -EINVAL;
1210 goto exit;
1211 }
1212
1213 rc = nfc_llcp_send_snl_sdreq(local, &sdreq_list, tlvs_len);
1214exit:
1215 device_unlock(&dev->dev);
1216
1217 nfc_put_device(dev);
1218
1219 return rc;
1220}
1221
1222static int nfc_genl_fw_download(struct sk_buff *skb, struct genl_info *info)
1223{
1224 struct nfc_dev *dev;
1225 int rc;
1226 u32 idx;
1227 char firmware_name[NFC_FIRMWARE_NAME_MAXSIZE + 1];
1228
Olivier Deprez0e641232021-09-23 10:07:05 +02001229 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || !info->attrs[NFC_ATTR_FIRMWARE_NAME])
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001230 return -EINVAL;
1231
1232 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
1233
1234 dev = nfc_get_device(idx);
1235 if (!dev)
1236 return -ENODEV;
1237
1238 nla_strlcpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
1239 sizeof(firmware_name));
1240
1241 rc = nfc_fw_download(dev, firmware_name);
1242
1243 nfc_put_device(dev);
1244 return rc;
1245}
1246
1247int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name,
1248 u32 result)
1249{
1250 struct sk_buff *msg;
1251 void *hdr;
1252
1253 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1254 if (!msg)
1255 return -ENOMEM;
1256
1257 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
1258 NFC_CMD_FW_DOWNLOAD);
1259 if (!hdr)
1260 goto free_msg;
1261
1262 if (nla_put_string(msg, NFC_ATTR_FIRMWARE_NAME, firmware_name) ||
1263 nla_put_u32(msg, NFC_ATTR_FIRMWARE_DOWNLOAD_STATUS, result) ||
1264 nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
1265 goto nla_put_failure;
1266
1267 genlmsg_end(msg, hdr);
1268
1269 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
1270
1271 return 0;
1272
1273nla_put_failure:
1274free_msg:
1275 nlmsg_free(msg);
1276 return -EMSGSIZE;
1277}
1278
1279static int nfc_genl_enable_se(struct sk_buff *skb, struct genl_info *info)
1280{
1281 struct nfc_dev *dev;
1282 int rc;
1283 u32 idx, se_idx;
1284
1285 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
1286 !info->attrs[NFC_ATTR_SE_INDEX])
1287 return -EINVAL;
1288
1289 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
1290 se_idx = nla_get_u32(info->attrs[NFC_ATTR_SE_INDEX]);
1291
1292 dev = nfc_get_device(idx);
1293 if (!dev)
1294 return -ENODEV;
1295
1296 rc = nfc_enable_se(dev, se_idx);
1297
1298 nfc_put_device(dev);
1299 return rc;
1300}
1301
1302static int nfc_genl_disable_se(struct sk_buff *skb, struct genl_info *info)
1303{
1304 struct nfc_dev *dev;
1305 int rc;
1306 u32 idx, se_idx;
1307
1308 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
1309 !info->attrs[NFC_ATTR_SE_INDEX])
1310 return -EINVAL;
1311
1312 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
1313 se_idx = nla_get_u32(info->attrs[NFC_ATTR_SE_INDEX]);
1314
1315 dev = nfc_get_device(idx);
1316 if (!dev)
1317 return -ENODEV;
1318
1319 rc = nfc_disable_se(dev, se_idx);
1320
1321 nfc_put_device(dev);
1322 return rc;
1323}
1324
1325static int nfc_genl_send_se(struct sk_buff *msg, struct nfc_dev *dev,
1326 u32 portid, u32 seq,
1327 struct netlink_callback *cb,
1328 int flags)
1329{
1330 void *hdr;
1331 struct nfc_se *se, *n;
1332
1333 list_for_each_entry_safe(se, n, &dev->secure_elements, list) {
1334 hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, flags,
1335 NFC_CMD_GET_SE);
1336 if (!hdr)
1337 goto nla_put_failure;
1338
1339 if (cb)
1340 genl_dump_check_consistent(cb, hdr);
1341
1342 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
1343 nla_put_u32(msg, NFC_ATTR_SE_INDEX, se->idx) ||
1344 nla_put_u8(msg, NFC_ATTR_SE_TYPE, se->type))
1345 goto nla_put_failure;
1346
1347 genlmsg_end(msg, hdr);
1348 }
1349
1350 return 0;
1351
1352nla_put_failure:
1353 genlmsg_cancel(msg, hdr);
1354 return -EMSGSIZE;
1355}
1356
1357static int nfc_genl_dump_ses(struct sk_buff *skb,
1358 struct netlink_callback *cb)
1359{
1360 struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
1361 struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
1362 bool first_call = false;
1363
1364 if (!iter) {
1365 first_call = true;
1366 iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL);
1367 if (!iter)
1368 return -ENOMEM;
1369 cb->args[0] = (long) iter;
1370 }
1371
1372 mutex_lock(&nfc_devlist_mutex);
1373
1374 cb->seq = nfc_devlist_generation;
1375
1376 if (first_call) {
1377 nfc_device_iter_init(iter);
1378 dev = nfc_device_iter_next(iter);
1379 }
1380
1381 while (dev) {
1382 int rc;
1383
1384 rc = nfc_genl_send_se(skb, dev, NETLINK_CB(cb->skb).portid,
1385 cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
1386 if (rc < 0)
1387 break;
1388
1389 dev = nfc_device_iter_next(iter);
1390 }
1391
1392 mutex_unlock(&nfc_devlist_mutex);
1393
1394 cb->args[1] = (long) dev;
1395
1396 return skb->len;
1397}
1398
1399static int nfc_genl_dump_ses_done(struct netlink_callback *cb)
1400{
1401 struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
1402
1403 nfc_device_iter_exit(iter);
1404 kfree(iter);
1405
1406 return 0;
1407}
1408
1409static int nfc_se_io(struct nfc_dev *dev, u32 se_idx,
1410 u8 *apdu, size_t apdu_length,
1411 se_io_cb_t cb, void *cb_context)
1412{
1413 struct nfc_se *se;
1414 int rc;
1415
1416 pr_debug("%s se index %d\n", dev_name(&dev->dev), se_idx);
1417
1418 device_lock(&dev->dev);
1419
1420 if (!device_is_registered(&dev->dev)) {
1421 rc = -ENODEV;
1422 goto error;
1423 }
1424
1425 if (!dev->dev_up) {
1426 rc = -ENODEV;
1427 goto error;
1428 }
1429
1430 if (!dev->ops->se_io) {
1431 rc = -EOPNOTSUPP;
1432 goto error;
1433 }
1434
1435 se = nfc_find_se(dev, se_idx);
1436 if (!se) {
1437 rc = -EINVAL;
1438 goto error;
1439 }
1440
1441 if (se->state != NFC_SE_ENABLED) {
1442 rc = -ENODEV;
1443 goto error;
1444 }
1445
1446 rc = dev->ops->se_io(dev, se_idx, apdu,
1447 apdu_length, cb, cb_context);
1448
1449error:
1450 device_unlock(&dev->dev);
1451 return rc;
1452}
1453
1454struct se_io_ctx {
1455 u32 dev_idx;
1456 u32 se_idx;
1457};
1458
1459static void se_io_cb(void *context, u8 *apdu, size_t apdu_len, int err)
1460{
1461 struct se_io_ctx *ctx = context;
1462 struct sk_buff *msg;
1463 void *hdr;
1464
1465 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1466 if (!msg) {
1467 kfree(ctx);
1468 return;
1469 }
1470
1471 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
1472 NFC_CMD_SE_IO);
1473 if (!hdr)
1474 goto free_msg;
1475
1476 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, ctx->dev_idx) ||
1477 nla_put_u32(msg, NFC_ATTR_SE_INDEX, ctx->se_idx) ||
1478 nla_put(msg, NFC_ATTR_SE_APDU, apdu_len, apdu))
1479 goto nla_put_failure;
1480
1481 genlmsg_end(msg, hdr);
1482
1483 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
1484
1485 kfree(ctx);
1486
1487 return;
1488
1489nla_put_failure:
1490free_msg:
1491 nlmsg_free(msg);
1492 kfree(ctx);
1493
1494 return;
1495}
1496
1497static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
1498{
1499 struct nfc_dev *dev;
1500 struct se_io_ctx *ctx;
1501 u32 dev_idx, se_idx;
1502 u8 *apdu;
1503 size_t apdu_len;
1504
1505 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
1506 !info->attrs[NFC_ATTR_SE_INDEX] ||
1507 !info->attrs[NFC_ATTR_SE_APDU])
1508 return -EINVAL;
1509
1510 dev_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
1511 se_idx = nla_get_u32(info->attrs[NFC_ATTR_SE_INDEX]);
1512
1513 dev = nfc_get_device(dev_idx);
1514 if (!dev)
1515 return -ENODEV;
1516
1517 if (!dev->ops || !dev->ops->se_io)
1518 return -ENOTSUPP;
1519
1520 apdu_len = nla_len(info->attrs[NFC_ATTR_SE_APDU]);
1521 if (apdu_len == 0)
1522 return -EINVAL;
1523
1524 apdu = nla_data(info->attrs[NFC_ATTR_SE_APDU]);
1525 if (!apdu)
1526 return -EINVAL;
1527
1528 ctx = kzalloc(sizeof(struct se_io_ctx), GFP_KERNEL);
1529 if (!ctx)
1530 return -ENOMEM;
1531
1532 ctx->dev_idx = dev_idx;
1533 ctx->se_idx = se_idx;
1534
1535 return nfc_se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
1536}
1537
1538static int nfc_genl_vendor_cmd(struct sk_buff *skb,
1539 struct genl_info *info)
1540{
1541 struct nfc_dev *dev;
1542 struct nfc_vendor_cmd *cmd;
1543 u32 dev_idx, vid, subcmd;
1544 u8 *data;
1545 size_t data_len;
1546 int i, err;
1547
1548 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
1549 !info->attrs[NFC_ATTR_VENDOR_ID] ||
1550 !info->attrs[NFC_ATTR_VENDOR_SUBCMD])
1551 return -EINVAL;
1552
1553 dev_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
1554 vid = nla_get_u32(info->attrs[NFC_ATTR_VENDOR_ID]);
1555 subcmd = nla_get_u32(info->attrs[NFC_ATTR_VENDOR_SUBCMD]);
1556
1557 dev = nfc_get_device(dev_idx);
1558 if (!dev || !dev->vendor_cmds || !dev->n_vendor_cmds)
1559 return -ENODEV;
1560
1561 if (info->attrs[NFC_ATTR_VENDOR_DATA]) {
1562 data = nla_data(info->attrs[NFC_ATTR_VENDOR_DATA]);
1563 data_len = nla_len(info->attrs[NFC_ATTR_VENDOR_DATA]);
1564 if (data_len == 0)
1565 return -EINVAL;
1566 } else {
1567 data = NULL;
1568 data_len = 0;
1569 }
1570
1571 for (i = 0; i < dev->n_vendor_cmds; i++) {
1572 cmd = &dev->vendor_cmds[i];
1573
1574 if (cmd->vendor_id != vid || cmd->subcmd != subcmd)
1575 continue;
1576
1577 dev->cur_cmd_info = info;
1578 err = cmd->doit(dev, data, data_len);
1579 dev->cur_cmd_info = NULL;
1580 return err;
1581 }
1582
1583 return -EOPNOTSUPP;
1584}
1585
1586/* message building helper */
1587static inline void *nfc_hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
1588 int flags, u8 cmd)
1589{
1590 /* since there is no private header just add the generic one */
1591 return genlmsg_put(skb, portid, seq, &nfc_genl_family, flags, cmd);
1592}
1593
1594static struct sk_buff *
1595__nfc_alloc_vendor_cmd_skb(struct nfc_dev *dev, int approxlen,
1596 u32 portid, u32 seq,
1597 enum nfc_attrs attr,
1598 u32 oui, u32 subcmd, gfp_t gfp)
1599{
1600 struct sk_buff *skb;
1601 void *hdr;
1602
1603 skb = nlmsg_new(approxlen + 100, gfp);
1604 if (!skb)
1605 return NULL;
1606
1607 hdr = nfc_hdr_put(skb, portid, seq, 0, NFC_CMD_VENDOR);
1608 if (!hdr) {
1609 kfree_skb(skb);
1610 return NULL;
1611 }
1612
1613 if (nla_put_u32(skb, NFC_ATTR_DEVICE_INDEX, dev->idx))
1614 goto nla_put_failure;
1615 if (nla_put_u32(skb, NFC_ATTR_VENDOR_ID, oui))
1616 goto nla_put_failure;
1617 if (nla_put_u32(skb, NFC_ATTR_VENDOR_SUBCMD, subcmd))
1618 goto nla_put_failure;
1619
1620 ((void **)skb->cb)[0] = dev;
1621 ((void **)skb->cb)[1] = hdr;
1622
1623 return skb;
1624
1625nla_put_failure:
1626 kfree_skb(skb);
1627 return NULL;
1628}
1629
1630struct sk_buff *__nfc_alloc_vendor_cmd_reply_skb(struct nfc_dev *dev,
1631 enum nfc_attrs attr,
1632 u32 oui, u32 subcmd,
1633 int approxlen)
1634{
1635 if (WARN_ON(!dev->cur_cmd_info))
1636 return NULL;
1637
1638 return __nfc_alloc_vendor_cmd_skb(dev, approxlen,
1639 dev->cur_cmd_info->snd_portid,
1640 dev->cur_cmd_info->snd_seq, attr,
1641 oui, subcmd, GFP_KERNEL);
1642}
1643EXPORT_SYMBOL(__nfc_alloc_vendor_cmd_reply_skb);
1644
1645int nfc_vendor_cmd_reply(struct sk_buff *skb)
1646{
1647 struct nfc_dev *dev = ((void **)skb->cb)[0];
1648 void *hdr = ((void **)skb->cb)[1];
1649
1650 /* clear CB data for netlink core to own from now on */
1651 memset(skb->cb, 0, sizeof(skb->cb));
1652
1653 if (WARN_ON(!dev->cur_cmd_info)) {
1654 kfree_skb(skb);
1655 return -EINVAL;
1656 }
1657
1658 genlmsg_end(skb, hdr);
1659 return genlmsg_reply(skb, dev->cur_cmd_info);
1660}
1661EXPORT_SYMBOL(nfc_vendor_cmd_reply);
1662
1663static const struct genl_ops nfc_genl_ops[] = {
1664 {
1665 .cmd = NFC_CMD_GET_DEVICE,
David Brazdil0f672f62019-12-10 10:32:29 +00001666 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001667 .doit = nfc_genl_get_device,
1668 .dumpit = nfc_genl_dump_devices,
1669 .done = nfc_genl_dump_devices_done,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001670 },
1671 {
1672 .cmd = NFC_CMD_DEV_UP,
David Brazdil0f672f62019-12-10 10:32:29 +00001673 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001674 .doit = nfc_genl_dev_up,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001675 },
1676 {
1677 .cmd = NFC_CMD_DEV_DOWN,
David Brazdil0f672f62019-12-10 10:32:29 +00001678 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001679 .doit = nfc_genl_dev_down,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001680 },
1681 {
1682 .cmd = NFC_CMD_START_POLL,
David Brazdil0f672f62019-12-10 10:32:29 +00001683 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001684 .doit = nfc_genl_start_poll,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001685 },
1686 {
1687 .cmd = NFC_CMD_STOP_POLL,
David Brazdil0f672f62019-12-10 10:32:29 +00001688 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001689 .doit = nfc_genl_stop_poll,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001690 },
1691 {
1692 .cmd = NFC_CMD_DEP_LINK_UP,
David Brazdil0f672f62019-12-10 10:32:29 +00001693 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001694 .doit = nfc_genl_dep_link_up,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001695 },
1696 {
1697 .cmd = NFC_CMD_DEP_LINK_DOWN,
David Brazdil0f672f62019-12-10 10:32:29 +00001698 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001699 .doit = nfc_genl_dep_link_down,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001700 },
1701 {
1702 .cmd = NFC_CMD_GET_TARGET,
David Brazdil0f672f62019-12-10 10:32:29 +00001703 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001704 .dumpit = nfc_genl_dump_targets,
1705 .done = nfc_genl_dump_targets_done,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001706 },
1707 {
1708 .cmd = NFC_CMD_LLC_GET_PARAMS,
David Brazdil0f672f62019-12-10 10:32:29 +00001709 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001710 .doit = nfc_genl_llc_get_params,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001711 },
1712 {
1713 .cmd = NFC_CMD_LLC_SET_PARAMS,
David Brazdil0f672f62019-12-10 10:32:29 +00001714 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001715 .doit = nfc_genl_llc_set_params,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001716 },
1717 {
1718 .cmd = NFC_CMD_LLC_SDREQ,
David Brazdil0f672f62019-12-10 10:32:29 +00001719 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001720 .doit = nfc_genl_llc_sdreq,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001721 },
1722 {
1723 .cmd = NFC_CMD_FW_DOWNLOAD,
David Brazdil0f672f62019-12-10 10:32:29 +00001724 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001725 .doit = nfc_genl_fw_download,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001726 },
1727 {
1728 .cmd = NFC_CMD_ENABLE_SE,
David Brazdil0f672f62019-12-10 10:32:29 +00001729 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001730 .doit = nfc_genl_enable_se,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001731 },
1732 {
1733 .cmd = NFC_CMD_DISABLE_SE,
David Brazdil0f672f62019-12-10 10:32:29 +00001734 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001735 .doit = nfc_genl_disable_se,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001736 },
1737 {
1738 .cmd = NFC_CMD_GET_SE,
David Brazdil0f672f62019-12-10 10:32:29 +00001739 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001740 .dumpit = nfc_genl_dump_ses,
1741 .done = nfc_genl_dump_ses_done,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001742 },
1743 {
1744 .cmd = NFC_CMD_SE_IO,
David Brazdil0f672f62019-12-10 10:32:29 +00001745 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001746 .doit = nfc_genl_se_io,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001747 },
1748 {
1749 .cmd = NFC_CMD_ACTIVATE_TARGET,
David Brazdil0f672f62019-12-10 10:32:29 +00001750 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001751 .doit = nfc_genl_activate_target,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001752 },
1753 {
1754 .cmd = NFC_CMD_VENDOR,
David Brazdil0f672f62019-12-10 10:32:29 +00001755 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001756 .doit = nfc_genl_vendor_cmd,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001757 },
1758 {
1759 .cmd = NFC_CMD_DEACTIVATE_TARGET,
David Brazdil0f672f62019-12-10 10:32:29 +00001760 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001761 .doit = nfc_genl_deactivate_target,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001762 },
1763};
1764
1765static struct genl_family nfc_genl_family __ro_after_init = {
1766 .hdrsize = 0,
1767 .name = NFC_GENL_NAME,
1768 .version = NFC_GENL_VERSION,
1769 .maxattr = NFC_ATTR_MAX,
David Brazdil0f672f62019-12-10 10:32:29 +00001770 .policy = nfc_genl_policy,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001771 .module = THIS_MODULE,
1772 .ops = nfc_genl_ops,
1773 .n_ops = ARRAY_SIZE(nfc_genl_ops),
1774 .mcgrps = nfc_genl_mcgrps,
1775 .n_mcgrps = ARRAY_SIZE(nfc_genl_mcgrps),
1776};
1777
1778
1779struct urelease_work {
1780 struct work_struct w;
1781 u32 portid;
1782};
1783
1784static void nfc_urelease_event_work(struct work_struct *work)
1785{
1786 struct urelease_work *w = container_of(work, struct urelease_work, w);
1787 struct class_dev_iter iter;
1788 struct nfc_dev *dev;
1789
1790 pr_debug("portid %d\n", w->portid);
1791
1792 mutex_lock(&nfc_devlist_mutex);
1793
1794 nfc_device_iter_init(&iter);
1795 dev = nfc_device_iter_next(&iter);
1796
1797 while (dev) {
1798 mutex_lock(&dev->genl_data.genl_data_mutex);
1799
1800 if (dev->genl_data.poll_req_portid == w->portid) {
1801 nfc_stop_poll(dev);
1802 dev->genl_data.poll_req_portid = 0;
1803 }
1804
1805 mutex_unlock(&dev->genl_data.genl_data_mutex);
1806
1807 dev = nfc_device_iter_next(&iter);
1808 }
1809
1810 nfc_device_iter_exit(&iter);
1811
1812 mutex_unlock(&nfc_devlist_mutex);
1813
1814 kfree(w);
1815}
1816
1817static int nfc_genl_rcv_nl_event(struct notifier_block *this,
1818 unsigned long event, void *ptr)
1819{
1820 struct netlink_notify *n = ptr;
1821 struct urelease_work *w;
1822
1823 if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
1824 goto out;
1825
1826 pr_debug("NETLINK_URELEASE event from id %d\n", n->portid);
1827
1828 w = kmalloc(sizeof(*w), GFP_ATOMIC);
1829 if (w) {
1830 INIT_WORK((struct work_struct *) w, nfc_urelease_event_work);
1831 w->portid = n->portid;
1832 schedule_work((struct work_struct *) w);
1833 }
1834
1835out:
1836 return NOTIFY_DONE;
1837}
1838
1839void nfc_genl_data_init(struct nfc_genl_data *genl_data)
1840{
1841 genl_data->poll_req_portid = 0;
1842 mutex_init(&genl_data->genl_data_mutex);
1843}
1844
1845void nfc_genl_data_exit(struct nfc_genl_data *genl_data)
1846{
1847 mutex_destroy(&genl_data->genl_data_mutex);
1848}
1849
1850static struct notifier_block nl_notifier = {
1851 .notifier_call = nfc_genl_rcv_nl_event,
1852};
1853
1854/**
1855 * nfc_genl_init() - Initialize netlink interface
1856 *
1857 * This initialization function registers the nfc netlink family.
1858 */
1859int __init nfc_genl_init(void)
1860{
1861 int rc;
1862
1863 rc = genl_register_family(&nfc_genl_family);
1864 if (rc)
1865 return rc;
1866
1867 netlink_register_notifier(&nl_notifier);
1868
1869 return 0;
1870}
1871
1872/**
1873 * nfc_genl_exit() - Deinitialize netlink interface
1874 *
1875 * This exit function unregisters the nfc netlink family.
1876 */
1877void nfc_genl_exit(void)
1878{
1879 netlink_unregister_notifier(&nl_notifier);
1880 genl_unregister_family(&nfc_genl_family);
1881}