]> git.ipfire.org Git - thirdparty/linux.git/blame - net/nfc/nci/core.c
treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 234
[thirdparty/linux.git] / net / nfc / nci / core.c
CommitLineData
caab277b 1// SPDX-License-Identifier: GPL-2.0-only
6a2968aa
IE
2/*
3 * The NFC Controller Interface is the communication protocol between an
4 * NFC Controller (NFCC) and a Device Host (DH).
5 *
6 * Copyright (C) 2011 Texas Instruments, Inc.
772dccf4 7 * Copyright (C) 2014 Marvell International Ltd.
6a2968aa
IE
8 *
9 * Written by Ilan Elias <ilane@ti.com>
10 *
11 * Acknowledgements:
12 * This file is based on hci_core.c, which was written
13 * by Maxim Krasnyansky.
6a2968aa
IE
14 */
15
52858b51 16#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
ed1e0ad8 17
8a70e7f8 18#include <linux/module.h>
b6355e97 19#include <linux/kernel.h>
6a2968aa
IE
20#include <linux/types.h>
21#include <linux/workqueue.h>
22#include <linux/completion.h>
bc3b2d7f 23#include <linux/export.h>
6a2968aa
IE
24#include <linux/sched.h>
25#include <linux/bitops.h>
26#include <linux/skbuff.h>
27
28#include "../nfc.h"
29#include <net/nfc/nci.h>
30#include <net/nfc/nci_core.h>
31#include <linux/nfc.h>
32
b16ae716
CR
33struct core_conn_create_data {
34 int length;
35 struct nci_core_conn_create_cmd *cmd;
36};
37
6a2968aa
IE
38static void nci_cmd_work(struct work_struct *work);
39static void nci_rx_work(struct work_struct *work);
40static void nci_tx_work(struct work_struct *work);
41
4aeee687
CR
42struct nci_conn_info *nci_get_conn_info_by_conn_id(struct nci_dev *ndev,
43 int conn_id)
44{
45 struct nci_conn_info *conn_info;
46
47 list_for_each_entry(conn_info, &ndev->conn_info_list, list) {
48 if (conn_info->conn_id == conn_id)
49 return conn_info;
50 }
51
52 return NULL;
53}
54
9b8d1a4c
CR
55int nci_get_conn_info_by_dest_type_params(struct nci_dev *ndev, u8 dest_type,
56 struct dest_spec_params *params)
85b9ce9a
RD
57{
58 struct nci_conn_info *conn_info;
59
60 list_for_each_entry(conn_info, &ndev->conn_info_list, list) {
9b8d1a4c
CR
61 if (conn_info->dest_type == dest_type) {
62 if (!params)
63 return conn_info->conn_id;
03036184
GS
64
65 if (params->id == conn_info->dest_params->id &&
66 params->protocol == conn_info->dest_params->protocol)
67 return conn_info->conn_id;
9b8d1a4c 68 }
85b9ce9a
RD
69 }
70
71 return -EINVAL;
72}
9b8d1a4c 73EXPORT_SYMBOL(nci_get_conn_info_by_dest_type_params);
85b9ce9a 74
6a2968aa
IE
75/* ---- NCI requests ---- */
76
77void nci_req_complete(struct nci_dev *ndev, int result)
78{
79 if (ndev->req_status == NCI_REQ_PEND) {
80 ndev->req_result = result;
81 ndev->req_status = NCI_REQ_DONE;
82 complete(&ndev->req_completion);
83 }
84}
2df7f8c6 85EXPORT_SYMBOL(nci_req_complete);
6a2968aa
IE
86
87static void nci_req_cancel(struct nci_dev *ndev, int err)
88{
89 if (ndev->req_status == NCI_REQ_PEND) {
90 ndev->req_result = err;
91 ndev->req_status = NCI_REQ_CANCELED;
92 complete(&ndev->req_completion);
93 }
94}
95
96/* Execute request and wait for completion. */
97static int __nci_request(struct nci_dev *ndev,
eb9bc6e9
SO
98 void (*req)(struct nci_dev *ndev, unsigned long opt),
99 unsigned long opt, __u32 timeout)
6a2968aa
IE
100{
101 int rc = 0;
f8c141c3 102 long completion_rc;
6a2968aa
IE
103
104 ndev->req_status = NCI_REQ_PEND;
105
9bec44bf 106 reinit_completion(&ndev->req_completion);
6a2968aa 107 req(ndev, opt);
eb9bc6e9
SO
108 completion_rc =
109 wait_for_completion_interruptible_timeout(&ndev->req_completion,
110 timeout);
6a2968aa 111
20c239c1 112 pr_debug("wait_for_completion return %ld\n", completion_rc);
6a2968aa
IE
113
114 if (completion_rc > 0) {
115 switch (ndev->req_status) {
116 case NCI_REQ_DONE:
117 rc = nci_to_errno(ndev->req_result);
118 break;
119
120 case NCI_REQ_CANCELED:
121 rc = -ndev->req_result;
122 break;
123
124 default:
125 rc = -ETIMEDOUT;
126 break;
127 }
128 } else {
ed1e0ad8
JP
129 pr_err("wait_for_completion_interruptible_timeout failed %ld\n",
130 completion_rc);
6a2968aa
IE
131
132 rc = ((completion_rc == 0) ? (-ETIMEDOUT) : (completion_rc));
133 }
134
135 ndev->req_status = ndev->req_result = 0;
136
137 return rc;
138}
139
11f54f22
CR
140inline int nci_request(struct nci_dev *ndev,
141 void (*req)(struct nci_dev *ndev,
142 unsigned long opt),
143 unsigned long opt, __u32 timeout)
6a2968aa
IE
144{
145 int rc;
146
147 if (!test_bit(NCI_UP, &ndev->flags))
148 return -ENETDOWN;
149
150 /* Serialize all requests */
151 mutex_lock(&ndev->req_lock);
152 rc = __nci_request(ndev, req, opt, timeout);
153 mutex_unlock(&ndev->req_lock);
154
155 return rc;
156}
157
158static void nci_reset_req(struct nci_dev *ndev, unsigned long opt)
159{
e8c0dacd
IE
160 struct nci_core_reset_cmd cmd;
161
162 cmd.reset_type = NCI_RESET_TYPE_RESET_CONFIG;
163 nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 1, &cmd);
6a2968aa
IE
164}
165
166static void nci_init_req(struct nci_dev *ndev, unsigned long opt)
167{
168 nci_send_cmd(ndev, NCI_OP_CORE_INIT_CMD, 0, NULL);
169}
170
171static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
172{
2eb1dc10
IE
173 struct nci_rf_disc_map_cmd cmd;
174 struct disc_map_config *cfg = cmd.mapping_configs;
175 __u8 *num = &cmd.num_mapping_configs;
6a2968aa
IE
176 int i;
177
6a2968aa 178 /* set rf mapping configurations */
2eb1dc10 179 *num = 0;
6a2968aa
IE
180
181 /* by default mapping is set to NCI_RF_INTERFACE_FRAME */
182 for (i = 0; i < ndev->num_supported_rf_interfaces; i++) {
183 if (ndev->supported_rf_interfaces[i] ==
eb9bc6e9 184 NCI_RF_INTERFACE_ISO_DEP) {
2eb1dc10 185 cfg[*num].rf_protocol = NCI_RF_PROTOCOL_ISO_DEP;
637d85a7
IE
186 cfg[*num].mode = NCI_DISC_MAP_MODE_POLL |
187 NCI_DISC_MAP_MODE_LISTEN;
188 cfg[*num].rf_interface = NCI_RF_INTERFACE_ISO_DEP;
2eb1dc10 189 (*num)++;
6a2968aa 190 } else if (ndev->supported_rf_interfaces[i] ==
eb9bc6e9 191 NCI_RF_INTERFACE_NFC_DEP) {
2eb1dc10 192 cfg[*num].rf_protocol = NCI_RF_PROTOCOL_NFC_DEP;
637d85a7
IE
193 cfg[*num].mode = NCI_DISC_MAP_MODE_POLL |
194 NCI_DISC_MAP_MODE_LISTEN;
195 cfg[*num].rf_interface = NCI_RF_INTERFACE_NFC_DEP;
2eb1dc10 196 (*num)++;
6a2968aa
IE
197 }
198
2eb1dc10 199 if (*num == NCI_MAX_NUM_MAPPING_CONFIGS)
6a2968aa
IE
200 break;
201 }
202
203 nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_MAP_CMD,
eb9bc6e9 204 (1 + ((*num) * sizeof(struct disc_map_config))), &cmd);
6a2968aa
IE
205}
206
7e035230
IE
207struct nci_set_config_param {
208 __u8 id;
209 size_t len;
210 __u8 *val;
211};
212
213static void nci_set_config_req(struct nci_dev *ndev, unsigned long opt)
214{
215 struct nci_set_config_param *param = (struct nci_set_config_param *)opt;
216 struct nci_core_set_config_cmd cmd;
217
218 BUG_ON(param->len > NCI_MAX_PARAM_LEN);
219
220 cmd.num_params = 1;
221 cmd.param.id = param->id;
222 cmd.param.len = param->len;
223 memcpy(cmd.param.val, param->val, param->len);
224
225 nci_send_cmd(ndev, NCI_OP_CORE_SET_CONFIG_CMD, (3 + param->len), &cmd);
226}
227
772dccf4
JL
228struct nci_rf_discover_param {
229 __u32 im_protocols;
230 __u32 tm_protocols;
231};
232
6a2968aa
IE
233static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt)
234{
772dccf4
JL
235 struct nci_rf_discover_param *param =
236 (struct nci_rf_discover_param *)opt;
6a2968aa 237 struct nci_rf_disc_cmd cmd;
6a2968aa
IE
238
239 cmd.num_disc_configs = 0;
240
241 if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
772dccf4
JL
242 (param->im_protocols & NFC_PROTO_JEWEL_MASK ||
243 param->im_protocols & NFC_PROTO_MIFARE_MASK ||
244 param->im_protocols & NFC_PROTO_ISO14443_MASK ||
245 param->im_protocols & NFC_PROTO_NFC_DEP_MASK)) {
637d85a7 246 cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
eb9bc6e9 247 NCI_NFC_A_PASSIVE_POLL_MODE;
6a2968aa
IE
248 cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
249 cmd.num_disc_configs++;
250 }
251
252 if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
772dccf4 253 (param->im_protocols & NFC_PROTO_ISO14443_B_MASK)) {
637d85a7 254 cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
eb9bc6e9 255 NCI_NFC_B_PASSIVE_POLL_MODE;
6a2968aa
IE
256 cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
257 cmd.num_disc_configs++;
258 }
259
260 if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
772dccf4
JL
261 (param->im_protocols & NFC_PROTO_FELICA_MASK ||
262 param->im_protocols & NFC_PROTO_NFC_DEP_MASK)) {
637d85a7 263 cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
eb9bc6e9 264 NCI_NFC_F_PASSIVE_POLL_MODE;
6a2968aa
IE
265 cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
266 cmd.num_disc_configs++;
267 }
268
cfdbeeaf 269 if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
772dccf4 270 (param->im_protocols & NFC_PROTO_ISO15693_MASK)) {
cfdbeeaf
VC
271 cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
272 NCI_NFC_V_PASSIVE_POLL_MODE;
273 cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
274 cmd.num_disc_configs++;
275 }
276
772dccf4
JL
277 if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS - 1) &&
278 (param->tm_protocols & NFC_PROTO_NFC_DEP_MASK)) {
279 cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
280 NCI_NFC_A_PASSIVE_LISTEN_MODE;
281 cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
282 cmd.num_disc_configs++;
283 cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
284 NCI_NFC_F_PASSIVE_LISTEN_MODE;
285 cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
286 cmd.num_disc_configs++;
287 }
288
6a2968aa 289 nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_CMD,
eb9bc6e9
SO
290 (1 + (cmd.num_disc_configs * sizeof(struct disc_config))),
291 &cmd);
6a2968aa
IE
292}
293
019c4fba
IE
294struct nci_rf_discover_select_param {
295 __u8 rf_discovery_id;
296 __u8 rf_protocol;
297};
298
299static void nci_rf_discover_select_req(struct nci_dev *ndev, unsigned long opt)
300{
301 struct nci_rf_discover_select_param *param =
eb9bc6e9 302 (struct nci_rf_discover_select_param *)opt;
019c4fba
IE
303 struct nci_rf_discover_select_cmd cmd;
304
305 cmd.rf_discovery_id = param->rf_discovery_id;
306 cmd.rf_protocol = param->rf_protocol;
307
308 switch (cmd.rf_protocol) {
309 case NCI_RF_PROTOCOL_ISO_DEP:
310 cmd.rf_interface = NCI_RF_INTERFACE_ISO_DEP;
311 break;
312
313 case NCI_RF_PROTOCOL_NFC_DEP:
314 cmd.rf_interface = NCI_RF_INTERFACE_NFC_DEP;
315 break;
316
317 default:
318 cmd.rf_interface = NCI_RF_INTERFACE_FRAME;
319 break;
320 }
321
322 nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_SELECT_CMD,
eb9bc6e9 323 sizeof(struct nci_rf_discover_select_cmd), &cmd);
019c4fba
IE
324}
325
6a2968aa
IE
326static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt)
327{
328 struct nci_rf_deactivate_cmd cmd;
329
9295b5b5 330 cmd.type = opt;
6a2968aa
IE
331
332 nci_send_cmd(ndev, NCI_OP_RF_DEACTIVATE_CMD,
eb9bc6e9 333 sizeof(struct nci_rf_deactivate_cmd), &cmd);
6a2968aa
IE
334}
335
7bc4824e 336struct nci_cmd_param {
759afb8d
CR
337 __u16 opcode;
338 size_t len;
339 __u8 *payload;
340};
341
7bc4824e 342static void nci_generic_req(struct nci_dev *ndev, unsigned long opt)
759afb8d 343{
7bc4824e
RD
344 struct nci_cmd_param *param =
345 (struct nci_cmd_param *)opt;
759afb8d
CR
346
347 nci_send_cmd(ndev, param->opcode, param->len, param->payload);
348}
349
350int nci_prop_cmd(struct nci_dev *ndev, __u8 oid, size_t len, __u8 *payload)
351{
7bc4824e 352 struct nci_cmd_param param;
759afb8d
CR
353
354 param.opcode = nci_opcode_pack(NCI_GID_PROPRIETARY, oid);
355 param.len = len;
356 param.payload = payload;
357
7bc4824e 358 return __nci_request(ndev, nci_generic_req, (unsigned long)&param,
759afb8d
CR
359 msecs_to_jiffies(NCI_CMD_TIMEOUT));
360}
361EXPORT_SYMBOL(nci_prop_cmd);
362
7bc4824e
RD
363int nci_core_cmd(struct nci_dev *ndev, __u16 opcode, size_t len, __u8 *payload)
364{
365 struct nci_cmd_param param;
366
367 param.opcode = opcode;
368 param.len = len;
369 param.payload = payload;
370
371 return __nci_request(ndev, nci_generic_req, (unsigned long)&param,
372 msecs_to_jiffies(NCI_CMD_TIMEOUT));
373}
374EXPORT_SYMBOL(nci_core_cmd);
375
025a0cb8
RB
376int nci_core_reset(struct nci_dev *ndev)
377{
378 return __nci_request(ndev, nci_reset_req, 0,
379 msecs_to_jiffies(NCI_RESET_TIMEOUT));
380}
381EXPORT_SYMBOL(nci_core_reset);
382
383int nci_core_init(struct nci_dev *ndev)
384{
385 return __nci_request(ndev, nci_init_req, 0,
386 msecs_to_jiffies(NCI_INIT_TIMEOUT));
387}
388EXPORT_SYMBOL(nci_core_init);
389
1c53855f
CR
390struct nci_loopback_data {
391 u8 conn_id;
392 struct sk_buff *data;
393};
394
395static void nci_send_data_req(struct nci_dev *ndev, unsigned long opt)
396{
397 struct nci_loopback_data *data = (struct nci_loopback_data *)opt;
398
399 nci_send_data(ndev, data->conn_id, data->data);
400}
401
402static void nci_nfcc_loopback_cb(void *context, struct sk_buff *skb, int err)
403{
404 struct nci_dev *ndev = (struct nci_dev *)context;
405 struct nci_conn_info *conn_info;
406
407 conn_info = nci_get_conn_info_by_conn_id(ndev, ndev->cur_conn_id);
408 if (!conn_info) {
409 nci_req_complete(ndev, NCI_STATUS_REJECTED);
410 return;
411 }
412
413 conn_info->rx_skb = skb;
414
415 nci_req_complete(ndev, NCI_STATUS_OK);
416}
417
418int nci_nfcc_loopback(struct nci_dev *ndev, void *data, size_t data_len,
419 struct sk_buff **resp)
420{
421 int r;
422 struct nci_loopback_data loopback_data;
423 struct nci_conn_info *conn_info;
424 struct sk_buff *skb;
425 int conn_id = nci_get_conn_info_by_dest_type_params(ndev,
426 NCI_DESTINATION_NFCC_LOOPBACK, NULL);
427
428 if (conn_id < 0) {
429 r = nci_core_conn_create(ndev, NCI_DESTINATION_NFCC_LOOPBACK,
430 0, 0, NULL);
431 if (r != NCI_STATUS_OK)
432 return r;
433
434 conn_id = nci_get_conn_info_by_dest_type_params(ndev,
435 NCI_DESTINATION_NFCC_LOOPBACK,
436 NULL);
437 }
438
439 conn_info = nci_get_conn_info_by_conn_id(ndev, conn_id);
440 if (!conn_info)
441 return -EPROTO;
442
443 /* store cb and context to be used on receiving data */
444 conn_info->data_exchange_cb = nci_nfcc_loopback_cb;
445 conn_info->data_exchange_cb_context = ndev;
446
447 skb = nci_skb_alloc(ndev, NCI_DATA_HDR_SIZE + data_len, GFP_KERNEL);
448 if (!skb)
449 return -ENOMEM;
450
451 skb_reserve(skb, NCI_DATA_HDR_SIZE);
59ae1d12 452 skb_put_data(skb, data, data_len);
1c53855f
CR
453
454 loopback_data.conn_id = conn_id;
455 loopback_data.data = skb;
456
457 ndev->cur_conn_id = conn_id;
458 r = nci_request(ndev, nci_send_data_req, (unsigned long)&loopback_data,
459 msecs_to_jiffies(NCI_DATA_TIMEOUT));
460 if (r == NCI_STATUS_OK && resp)
461 *resp = conn_info->rx_skb;
462
463 return r;
464}
465EXPORT_SYMBOL(nci_nfcc_loopback);
466
6a2968aa
IE
467static int nci_open_device(struct nci_dev *ndev)
468{
469 int rc = 0;
470
471 mutex_lock(&ndev->req_lock);
472
473 if (test_bit(NCI_UP, &ndev->flags)) {
474 rc = -EALREADY;
475 goto done;
476 }
477
478 if (ndev->ops->open(ndev)) {
479 rc = -EIO;
480 goto done;
481 }
482
483 atomic_set(&ndev->cmd_cnt, 1);
484
485 set_bit(NCI_INIT, &ndev->flags);
486
c39daeee
CR
487 if (ndev->ops->init)
488 rc = ndev->ops->init(ndev);
489
490 if (!rc) {
491 rc = __nci_request(ndev, nci_reset_req, 0,
492 msecs_to_jiffies(NCI_RESET_TIMEOUT));
493 }
6a2968aa 494
81859ab8
CR
495 if (!rc && ndev->ops->setup) {
496 rc = ndev->ops->setup(ndev);
497 }
86e8586e 498
6a2968aa
IE
499 if (!rc) {
500 rc = __nci_request(ndev, nci_init_req, 0,
eb9bc6e9 501 msecs_to_jiffies(NCI_INIT_TIMEOUT));
6a2968aa
IE
502 }
503
e4dbd625 504 if (!rc && ndev->ops->post_setup)
fdf79bd4 505 rc = ndev->ops->post_setup(ndev);
fdf79bd4 506
6a2968aa
IE
507 if (!rc) {
508 rc = __nci_request(ndev, nci_init_complete_req, 0,
eb9bc6e9 509 msecs_to_jiffies(NCI_INIT_TIMEOUT));
6a2968aa
IE
510 }
511
512 clear_bit(NCI_INIT, &ndev->flags);
513
514 if (!rc) {
515 set_bit(NCI_UP, &ndev->flags);
019c4fba 516 nci_clear_target_list(ndev);
8939e47f 517 atomic_set(&ndev->state, NCI_IDLE);
6a2968aa
IE
518 } else {
519 /* Init failed, cleanup */
520 skb_queue_purge(&ndev->cmd_q);
521 skb_queue_purge(&ndev->rx_q);
522 skb_queue_purge(&ndev->tx_q);
523
524 ndev->ops->close(ndev);
525 ndev->flags = 0;
526 }
527
528done:
529 mutex_unlock(&ndev->req_lock);
530 return rc;
531}
532
533static int nci_close_device(struct nci_dev *ndev)
534{
535 nci_req_cancel(ndev, ENODEV);
536 mutex_lock(&ndev->req_lock);
537
538 if (!test_and_clear_bit(NCI_UP, &ndev->flags)) {
539 del_timer_sync(&ndev->cmd_timer);
c4bf98b2 540 del_timer_sync(&ndev->data_timer);
6a2968aa
IE
541 mutex_unlock(&ndev->req_lock);
542 return 0;
543 }
544
545 /* Drop RX and TX queues */
546 skb_queue_purge(&ndev->rx_q);
547 skb_queue_purge(&ndev->tx_q);
548
549 /* Flush RX and TX wq */
550 flush_workqueue(ndev->rx_wq);
551 flush_workqueue(ndev->tx_wq);
552
553 /* Reset device */
554 skb_queue_purge(&ndev->cmd_q);
555 atomic_set(&ndev->cmd_cnt, 1);
556
557 set_bit(NCI_INIT, &ndev->flags);
558 __nci_request(ndev, nci_reset_req, 0,
eb9bc6e9 559 msecs_to_jiffies(NCI_RESET_TIMEOUT));
0e70cba7
CR
560
561 /* After this point our queues are empty
562 * and no works are scheduled.
563 */
564 ndev->ops->close(ndev);
565
6a2968aa
IE
566 clear_bit(NCI_INIT, &ndev->flags);
567
fa9be5f0
AK
568 del_timer_sync(&ndev->cmd_timer);
569
6a2968aa
IE
570 /* Flush cmd wq */
571 flush_workqueue(ndev->cmd_wq);
572
6a2968aa
IE
573 /* Clear flags */
574 ndev->flags = 0;
575
576 mutex_unlock(&ndev->req_lock);
577
578 return 0;
579}
580
581/* NCI command timer function */
e99e88a9 582static void nci_cmd_timer(struct timer_list *t)
6a2968aa 583{
e99e88a9 584 struct nci_dev *ndev = from_timer(ndev, t, cmd_timer);
6a2968aa 585
6a2968aa
IE
586 atomic_set(&ndev->cmd_cnt, 1);
587 queue_work(ndev->cmd_wq, &ndev->cmd_work);
588}
589
c4bf98b2 590/* NCI data exchange timer function */
e99e88a9 591static void nci_data_timer(struct timer_list *t)
c4bf98b2 592{
e99e88a9 593 struct nci_dev *ndev = from_timer(ndev, t, data_timer);
c4bf98b2
IE
594
595 set_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
596 queue_work(ndev->rx_wq, &ndev->rx_work);
597}
598
6a2968aa
IE
599static int nci_dev_up(struct nfc_dev *nfc_dev)
600{
601 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
602
6a2968aa
IE
603 return nci_open_device(ndev);
604}
605
606static int nci_dev_down(struct nfc_dev *nfc_dev)
607{
608 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
609
6a2968aa
IE
610 return nci_close_device(ndev);
611}
612
22c15bf3
AK
613int nci_set_config(struct nci_dev *ndev, __u8 id, size_t len, __u8 *val)
614{
615 struct nci_set_config_param param;
616
617 if (!val || !len)
618 return 0;
619
620 param.id = id;
621 param.len = len;
622 param.val = val;
623
624 return __nci_request(ndev, nci_set_config_req, (unsigned long)&param,
625 msecs_to_jiffies(NCI_SET_CONFIG_TIMEOUT));
626}
627EXPORT_SYMBOL(nci_set_config);
628
af9c8aa6
CR
629static void nci_nfcee_discover_req(struct nci_dev *ndev, unsigned long opt)
630{
631 struct nci_nfcee_discover_cmd cmd;
632 __u8 action = opt;
633
634 cmd.discovery_action = action;
635
636 nci_send_cmd(ndev, NCI_OP_NFCEE_DISCOVER_CMD, 1, &cmd);
637}
638
639int nci_nfcee_discover(struct nci_dev *ndev, u8 action)
640{
21d19f87 641 return __nci_request(ndev, nci_nfcee_discover_req, action,
af9c8aa6
CR
642 msecs_to_jiffies(NCI_CMD_TIMEOUT));
643}
644EXPORT_SYMBOL(nci_nfcee_discover);
645
f7f793f3
CR
646static void nci_nfcee_mode_set_req(struct nci_dev *ndev, unsigned long opt)
647{
648 struct nci_nfcee_mode_set_cmd *cmd =
649 (struct nci_nfcee_mode_set_cmd *)opt;
650
651 nci_send_cmd(ndev, NCI_OP_NFCEE_MODE_SET_CMD,
652 sizeof(struct nci_nfcee_mode_set_cmd), cmd);
653}
654
655int nci_nfcee_mode_set(struct nci_dev *ndev, u8 nfcee_id, u8 nfcee_mode)
656{
657 struct nci_nfcee_mode_set_cmd cmd;
658
659 cmd.nfcee_id = nfcee_id;
660 cmd.nfcee_mode = nfcee_mode;
661
21d19f87
SO
662 return __nci_request(ndev, nci_nfcee_mode_set_req,
663 (unsigned long)&cmd,
664 msecs_to_jiffies(NCI_CMD_TIMEOUT));
f7f793f3
CR
665}
666EXPORT_SYMBOL(nci_nfcee_mode_set);
667
736bb957
CR
668static void nci_core_conn_create_req(struct nci_dev *ndev, unsigned long opt)
669{
b16ae716
CR
670 struct core_conn_create_data *data =
671 (struct core_conn_create_data *)opt;
672
673 nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD, data->length, data->cmd);
736bb957
CR
674}
675
b16ae716
CR
676int nci_core_conn_create(struct nci_dev *ndev, u8 destination_type,
677 u8 number_destination_params,
678 size_t params_len,
736bb957
CR
679 struct core_conn_create_dest_spec_params *params)
680{
b16ae716
CR
681 int r;
682 struct nci_core_conn_create_cmd *cmd;
683 struct core_conn_create_data data;
684
685 data.length = params_len + sizeof(struct nci_core_conn_create_cmd);
686 cmd = kzalloc(data.length, GFP_KERNEL);
687 if (!cmd)
688 return -ENOMEM;
689
690 cmd->destination_type = destination_type;
691 cmd->number_destination_params = number_destination_params;
b16ae716
CR
692
693 data.cmd = cmd;
caa575a8 694
18836029
CR
695 if (params) {
696 memcpy(cmd->params, params, params_len);
697 if (params->length > 0)
9b8d1a4c
CR
698 memcpy(&ndev->cur_params,
699 &params->value[DEST_SPEC_PARAMS_ID_INDEX],
700 sizeof(struct dest_spec_params));
18836029 701 else
9b8d1a4c 702 ndev->cur_params.id = 0;
18836029 703 } else {
9b8d1a4c 704 ndev->cur_params.id = 0;
18836029 705 }
9b8d1a4c 706 ndev->cur_dest_type = destination_type;
b16ae716 707
18836029 708 r = __nci_request(ndev, nci_core_conn_create_req, (unsigned long)&data,
b16ae716
CR
709 msecs_to_jiffies(NCI_CMD_TIMEOUT));
710 kfree(cmd);
711 return r;
736bb957
CR
712}
713EXPORT_SYMBOL(nci_core_conn_create);
714
715static void nci_core_conn_close_req(struct nci_dev *ndev, unsigned long opt)
716{
717 __u8 conn_id = opt;
718
719 nci_send_cmd(ndev, NCI_OP_CORE_CONN_CLOSE_CMD, 1, &conn_id);
720}
721
722int nci_core_conn_close(struct nci_dev *ndev, u8 conn_id)
723{
de5ea851 724 ndev->cur_conn_id = conn_id;
21d19f87
SO
725 return __nci_request(ndev, nci_core_conn_close_req, conn_id,
726 msecs_to_jiffies(NCI_CMD_TIMEOUT));
736bb957
CR
727}
728EXPORT_SYMBOL(nci_core_conn_close);
729
7e035230
IE
730static int nci_set_local_general_bytes(struct nfc_dev *nfc_dev)
731{
732 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
733 struct nci_set_config_param param;
529ee066 734 int rc;
7e035230
IE
735
736 param.val = nfc_get_local_general_bytes(nfc_dev, &param.len);
737 if ((param.val == NULL) || (param.len == 0))
f9fc36f4 738 return 0;
7e035230 739
460d8f97 740 if (param.len > NFC_MAX_GT_LEN)
7e035230
IE
741 return -EINVAL;
742
7e035230 743 param.id = NCI_PN_ATR_REQ_GEN_BYTES;
7e035230 744
529ee066
JL
745 rc = nci_request(ndev, nci_set_config_req, (unsigned long)&param,
746 msecs_to_jiffies(NCI_SET_CONFIG_TIMEOUT));
747 if (rc)
748 return rc;
749
750 param.id = NCI_LN_ATR_RES_GEN_BYTES;
751
f9fc36f4
SJ
752 return nci_request(ndev, nci_set_config_req, (unsigned long)&param,
753 msecs_to_jiffies(NCI_SET_CONFIG_TIMEOUT));
7e035230
IE
754}
755
90d78c13
JL
756static int nci_set_listen_parameters(struct nfc_dev *nfc_dev)
757{
758 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
759 int rc;
760 __u8 val;
761
762 val = NCI_LA_SEL_INFO_NFC_DEP_MASK;
763
764 rc = nci_set_config(ndev, NCI_LA_SEL_INFO, 1, &val);
765 if (rc)
766 return rc;
767
768 val = NCI_LF_PROTOCOL_TYPE_NFC_DEP_MASK;
769
770 rc = nci_set_config(ndev, NCI_LF_PROTOCOL_TYPE, 1, &val);
771 if (rc)
772 return rc;
773
774 val = NCI_LF_CON_BITR_F_212 | NCI_LF_CON_BITR_F_424;
775
776 return nci_set_config(ndev, NCI_LF_CON_BITR_F, 1, &val);
777}
778
fe7c5800
SO
779static int nci_start_poll(struct nfc_dev *nfc_dev,
780 __u32 im_protocols, __u32 tm_protocols)
6a2968aa
IE
781{
782 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
772dccf4 783 struct nci_rf_discover_param param;
6a2968aa
IE
784 int rc;
785
019c4fba 786 if ((atomic_read(&ndev->state) == NCI_DISCOVERY) ||
eb9bc6e9 787 (atomic_read(&ndev->state) == NCI_W4_ALL_DISCOVERIES)) {
ed1e0ad8 788 pr_err("unable to start poll, since poll is already active\n");
6a2968aa
IE
789 return -EBUSY;
790 }
791
de054799 792 if (ndev->target_active_prot) {
ed1e0ad8 793 pr_err("there is an active target\n");
de054799
IE
794 return -EBUSY;
795 }
796
019c4fba 797 if ((atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) ||
eb9bc6e9 798 (atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) {
019c4fba 799 pr_debug("target active or w4 select, implicitly deactivate\n");
6a2968aa 800
9295b5b5
CR
801 rc = nci_request(ndev, nci_rf_deactivate_req,
802 NCI_DEACTIVATE_TYPE_IDLE_MODE,
eb9bc6e9 803 msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
6a2968aa
IE
804 if (rc)
805 return -EBUSY;
806 }
807
529ee066 808 if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) {
7e035230
IE
809 rc = nci_set_local_general_bytes(nfc_dev);
810 if (rc) {
811 pr_err("failed to set local general bytes\n");
812 return rc;
813 }
814 }
815
90d78c13
JL
816 if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) {
817 rc = nci_set_listen_parameters(nfc_dev);
818 if (rc)
819 pr_err("failed to set listen parameters\n");
820 }
821
772dccf4
JL
822 param.im_protocols = im_protocols;
823 param.tm_protocols = tm_protocols;
824 rc = nci_request(ndev, nci_rf_discover_req, (unsigned long)&param,
eb9bc6e9 825 msecs_to_jiffies(NCI_RF_DISC_TIMEOUT));
6a2968aa
IE
826
827 if (!rc)
fe7c5800 828 ndev->poll_prots = im_protocols;
6a2968aa
IE
829
830 return rc;
831}
832
833static void nci_stop_poll(struct nfc_dev *nfc_dev)
834{
835 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
836
019c4fba 837 if ((atomic_read(&ndev->state) != NCI_DISCOVERY) &&
eb9bc6e9 838 (atomic_read(&ndev->state) != NCI_W4_ALL_DISCOVERIES)) {
ed1e0ad8 839 pr_err("unable to stop poll, since poll is not active\n");
6a2968aa
IE
840 return;
841 }
842
9295b5b5 843 nci_request(ndev, nci_rf_deactivate_req, NCI_DEACTIVATE_TYPE_IDLE_MODE,
eb9bc6e9 844 msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
6a2968aa
IE
845}
846
90099433
EL
847static int nci_activate_target(struct nfc_dev *nfc_dev,
848 struct nfc_target *target, __u32 protocol)
6a2968aa
IE
849{
850 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
019c4fba 851 struct nci_rf_discover_select_param param;
90099433 852 struct nfc_target *nci_target = NULL;
019c4fba
IE
853 int i;
854 int rc = 0;
6a2968aa 855
90099433 856 pr_debug("target_idx %d, protocol 0x%x\n", target->idx, protocol);
6a2968aa 857
019c4fba 858 if ((atomic_read(&ndev->state) != NCI_W4_HOST_SELECT) &&
eb9bc6e9 859 (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
ed1e0ad8 860 pr_err("there is no available target to activate\n");
6a2968aa
IE
861 return -EINVAL;
862 }
863
864 if (ndev->target_active_prot) {
ed1e0ad8 865 pr_err("there is already an active target\n");
6a2968aa
IE
866 return -EBUSY;
867 }
868
019c4fba 869 for (i = 0; i < ndev->n_targets; i++) {
90099433
EL
870 if (ndev->targets[i].idx == target->idx) {
871 nci_target = &ndev->targets[i];
019c4fba
IE
872 break;
873 }
874 }
875
90099433 876 if (!nci_target) {
019c4fba
IE
877 pr_err("unable to find the selected target\n");
878 return -EINVAL;
879 }
880
90099433 881 if (!(nci_target->supported_protocols & (1 << protocol))) {
ed1e0ad8
JP
882 pr_err("target does not support the requested protocol 0x%x\n",
883 protocol);
6a2968aa
IE
884 return -EINVAL;
885 }
886
019c4fba 887 if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) {
90099433 888 param.rf_discovery_id = nci_target->logical_idx;
019c4fba
IE
889
890 if (protocol == NFC_PROTO_JEWEL)
891 param.rf_protocol = NCI_RF_PROTOCOL_T1T;
892 else if (protocol == NFC_PROTO_MIFARE)
893 param.rf_protocol = NCI_RF_PROTOCOL_T2T;
894 else if (protocol == NFC_PROTO_FELICA)
895 param.rf_protocol = NCI_RF_PROTOCOL_T3T;
01d719a2
SO
896 else if (protocol == NFC_PROTO_ISO14443 ||
897 protocol == NFC_PROTO_ISO14443_B)
019c4fba
IE
898 param.rf_protocol = NCI_RF_PROTOCOL_ISO_DEP;
899 else
900 param.rf_protocol = NCI_RF_PROTOCOL_NFC_DEP;
901
902 rc = nci_request(ndev, nci_rf_discover_select_req,
eb9bc6e9
SO
903 (unsigned long)&param,
904 msecs_to_jiffies(NCI_RF_DISC_SELECT_TIMEOUT));
019c4fba 905 }
6a2968aa 906
019c4fba
IE
907 if (!rc)
908 ndev->target_active_prot = protocol;
909
910 return rc;
6a2968aa
IE
911}
912
90099433 913static void nci_deactivate_target(struct nfc_dev *nfc_dev,
96d4581f
CR
914 struct nfc_target *target,
915 __u8 mode)
6a2968aa
IE
916{
917 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
96d4581f 918 u8 nci_mode = NCI_DEACTIVATE_TYPE_IDLE_MODE;
6a2968aa 919
767f19ae 920 pr_debug("entry\n");
6a2968aa
IE
921
922 if (!ndev->target_active_prot) {
ed1e0ad8 923 pr_err("unable to deactivate target, no active target\n");
6a2968aa
IE
924 return;
925 }
926
927 ndev->target_active_prot = 0;
928
96d4581f
CR
929 switch (mode) {
930 case NFC_TARGET_MODE_SLEEP:
931 nci_mode = NCI_DEACTIVATE_TYPE_SLEEP_MODE;
932 break;
933 }
934
8939e47f 935 if (atomic_read(&ndev->state) == NCI_POLL_ACTIVE) {
96d4581f 936 nci_request(ndev, nci_rf_deactivate_req, nci_mode,
eb9bc6e9 937 msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
6a2968aa
IE
938 }
939}
940
767f19ae
IE
941static int nci_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
942 __u8 comm_mode, __u8 *gb, size_t gb_len)
943{
944 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
945 int rc;
946
947 pr_debug("target_idx %d, comm_mode %d\n", target->idx, comm_mode);
948
949 rc = nci_activate_target(nfc_dev, target, NFC_PROTO_NFC_DEP);
950 if (rc)
951 return rc;
952
953 rc = nfc_set_remote_general_bytes(nfc_dev, ndev->remote_gb,
954 ndev->remote_gb_len);
955 if (!rc)
956 rc = nfc_dep_link_is_up(nfc_dev, target->idx, NFC_COMM_PASSIVE,
957 NFC_RF_INITIATOR);
958
959 return rc;
960}
961
962static int nci_dep_link_down(struct nfc_dev *nfc_dev)
963{
d7979e13
JL
964 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
965 int rc;
966
767f19ae
IE
967 pr_debug("entry\n");
968
d7979e13 969 if (nfc_dev->rf_mode == NFC_RF_INITIATOR) {
96d4581f 970 nci_deactivate_target(nfc_dev, NULL, NCI_DEACTIVATE_TYPE_IDLE_MODE);
d7979e13
JL
971 } else {
972 if (atomic_read(&ndev->state) == NCI_LISTEN_ACTIVE ||
973 atomic_read(&ndev->state) == NCI_DISCOVERY) {
974 nci_request(ndev, nci_rf_deactivate_req, 0,
975 msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
976 }
977
978 rc = nfc_tm_deactivated(nfc_dev);
979 if (rc)
980 pr_err("error when signaling tm deactivation\n");
981 }
767f19ae
IE
982
983 return 0;
984}
985
986
be9ae4ce
SO
987static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
988 struct sk_buff *skb,
989 data_exchange_cb_t cb, void *cb_context)
6a2968aa
IE
990{
991 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
38f04c6b 992 int rc;
4aeee687
CR
993 struct nci_conn_info *conn_info;
994
12bdf27d 995 conn_info = ndev->rf_conn_info;
4aeee687
CR
996 if (!conn_info)
997 return -EPROTO;
6a2968aa 998
90099433 999 pr_debug("target_idx %d, len %d\n", target->idx, skb->len);
6a2968aa
IE
1000
1001 if (!ndev->target_active_prot) {
ed1e0ad8 1002 pr_err("unable to exchange data, no active target\n");
6a2968aa
IE
1003 return -EINVAL;
1004 }
1005
38f04c6b
IE
1006 if (test_and_set_bit(NCI_DATA_EXCHANGE, &ndev->flags))
1007 return -EBUSY;
1008
6a2968aa 1009 /* store cb and context to be used on receiving data */
4aeee687
CR
1010 conn_info->data_exchange_cb = cb;
1011 conn_info->data_exchange_cb_context = cb_context;
6a2968aa 1012
e8c0dacd 1013 rc = nci_send_data(ndev, NCI_STATIC_RF_CONN_ID, skb);
38f04c6b
IE
1014 if (rc)
1015 clear_bit(NCI_DATA_EXCHANGE, &ndev->flags);
1016
1017 return rc;
6a2968aa
IE
1018}
1019
485f442f
JL
1020static int nci_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
1021{
1022 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
1023 int rc;
1024
1025 rc = nci_send_data(ndev, NCI_STATIC_RF_CONN_ID, skb);
1026 if (rc)
1027 pr_err("unable to send data\n");
1028
1029 return rc;
1030}
1031
0a946301
SO
1032static int nci_enable_se(struct nfc_dev *nfc_dev, u32 se_idx)
1033{
93bca2bf
CR
1034 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
1035
1036 if (ndev->ops->enable_se)
1037 return ndev->ops->enable_se(ndev, se_idx);
1038
0a946301
SO
1039 return 0;
1040}
1041
1042static int nci_disable_se(struct nfc_dev *nfc_dev, u32 se_idx)
1043{
e9ef9431
CR
1044 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
1045
1046 if (ndev->ops->disable_se)
1047 return ndev->ops->disable_se(ndev, se_idx);
1048
0a946301
SO
1049 return 0;
1050}
1051
1052static int nci_discover_se(struct nfc_dev *nfc_dev)
1053{
fa00e8fe 1054 int r;
ba4db551
CR
1055 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
1056
fa00e8fe
CR
1057 if (ndev->ops->discover_se) {
1058 r = nci_nfcee_discover(ndev, NCI_NFCEE_DISCOVERY_ACTION_ENABLE);
1059 if (r != NCI_STATUS_OK)
1060 return -EPROTO;
1061
ba4db551 1062 return ndev->ops->discover_se(ndev);
fa00e8fe 1063 }
ba4db551 1064
0a946301
SO
1065 return 0;
1066}
1067
a688bf55
CR
1068static int nci_se_io(struct nfc_dev *nfc_dev, u32 se_idx,
1069 u8 *apdu, size_t apdu_length,
1070 se_io_cb_t cb, void *cb_context)
1071{
1072 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
1073
1074 if (ndev->ops->se_io)
1075 return ndev->ops->se_io(ndev, se_idx, apdu,
1076 apdu_length, cb, cb_context);
1077
1078 return 0;
1079}
1080
25af01ed
CP
1081static int nci_fw_download(struct nfc_dev *nfc_dev, const char *firmware_name)
1082{
1083 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
1084
1085 if (!ndev->ops->fw_download)
1086 return -ENOTSUPP;
1087
1088 return ndev->ops->fw_download(ndev, firmware_name);
1089}
1090
6a2968aa
IE
1091static struct nfc_ops nci_nfc_ops = {
1092 .dev_up = nci_dev_up,
1093 .dev_down = nci_dev_down,
1094 .start_poll = nci_start_poll,
1095 .stop_poll = nci_stop_poll,
767f19ae
IE
1096 .dep_link_up = nci_dep_link_up,
1097 .dep_link_down = nci_dep_link_down,
6a2968aa
IE
1098 .activate_target = nci_activate_target,
1099 .deactivate_target = nci_deactivate_target,
be9ae4ce 1100 .im_transceive = nci_transceive,
485f442f 1101 .tm_send = nci_tm_send,
0a946301
SO
1102 .enable_se = nci_enable_se,
1103 .disable_se = nci_disable_se,
1104 .discover_se = nci_discover_se,
a688bf55 1105 .se_io = nci_se_io,
25af01ed 1106 .fw_download = nci_fw_download,
6a2968aa
IE
1107};
1108
1109/* ---- Interface to NCI drivers ---- */
6a2968aa
IE
1110/**
1111 * nci_allocate_device - allocate a new nci device
1112 *
1113 * @ops: device operations
1114 * @supported_protocols: NFC protocols supported by the device
1115 */
1116struct nci_dev *nci_allocate_device(struct nci_ops *ops,
eb9bc6e9
SO
1117 __u32 supported_protocols,
1118 int tx_headroom, int tx_tailroom)
6a2968aa 1119{
8ebafde0 1120 struct nci_dev *ndev;
6a2968aa 1121
24bf3304 1122 pr_debug("supported_protocols 0x%x\n", supported_protocols);
6a2968aa
IE
1123
1124 if (!ops->open || !ops->close || !ops->send)
8ebafde0 1125 return NULL;
6a2968aa
IE
1126
1127 if (!supported_protocols)
8ebafde0 1128 return NULL;
6a2968aa
IE
1129
1130 ndev = kzalloc(sizeof(struct nci_dev), GFP_KERNEL);
1131 if (!ndev)
8ebafde0 1132 return NULL;
6a2968aa
IE
1133
1134 ndev->ops = ops;
b6355e97
SO
1135
1136 if (ops->n_prop_ops > NCI_MAX_PROPRIETARY_CMD) {
1137 pr_err("Too many proprietary commands: %zd\n",
1138 ops->n_prop_ops);
1139 ops->prop_ops = NULL;
1140 ops->n_prop_ops = 0;
1141 }
1142
6a2968aa
IE
1143 ndev->tx_headroom = tx_headroom;
1144 ndev->tx_tailroom = tx_tailroom;
9bec44bf 1145 init_completion(&ndev->req_completion);
6a2968aa
IE
1146
1147 ndev->nfc_dev = nfc_allocate_device(&nci_nfc_ops,
eb9bc6e9
SO
1148 supported_protocols,
1149 tx_headroom + NCI_DATA_HDR_SIZE,
1150 tx_tailroom);
6a2968aa 1151 if (!ndev->nfc_dev)
11f54f22
CR
1152 goto free_nci;
1153
1154 ndev->hci_dev = nci_hci_allocate(ndev);
1155 if (!ndev->hci_dev)
1156 goto free_nfc;
6a2968aa
IE
1157
1158 nfc_set_drvdata(ndev->nfc_dev, ndev);
1159
8ebafde0 1160 return ndev;
6a2968aa 1161
11f54f22 1162free_nfc:
20777bc5 1163 nfc_free_device(ndev->nfc_dev);
11f54f22 1164free_nci:
6a2968aa 1165 kfree(ndev);
8ebafde0 1166 return NULL;
6a2968aa
IE
1167}
1168EXPORT_SYMBOL(nci_allocate_device);
1169
1170/**
1171 * nci_free_device - deallocate nci device
1172 *
1173 * @ndev: The nci device to deallocate
1174 */
1175void nci_free_device(struct nci_dev *ndev)
1176{
6a2968aa
IE
1177 nfc_free_device(ndev->nfc_dev);
1178 kfree(ndev);
1179}
1180EXPORT_SYMBOL(nci_free_device);
1181
1182/**
1183 * nci_register_device - register a nci device in the nfc subsystem
1184 *
1185 * @dev: The nci device to register
1186 */
1187int nci_register_device(struct nci_dev *ndev)
1188{
1189 int rc;
1190 struct device *dev = &ndev->nfc_dev->dev;
1191 char name[32];
1192
6a2968aa
IE
1193 ndev->flags = 0;
1194
1195 INIT_WORK(&ndev->cmd_work, nci_cmd_work);
1196 snprintf(name, sizeof(name), "%s_nci_cmd_wq", dev_name(dev));
1197 ndev->cmd_wq = create_singlethread_workqueue(name);
1198 if (!ndev->cmd_wq) {
1199 rc = -ENOMEM;
3c1c0f5d 1200 goto exit;
6a2968aa
IE
1201 }
1202
1203 INIT_WORK(&ndev->rx_work, nci_rx_work);
1204 snprintf(name, sizeof(name), "%s_nci_rx_wq", dev_name(dev));
1205 ndev->rx_wq = create_singlethread_workqueue(name);
1206 if (!ndev->rx_wq) {
1207 rc = -ENOMEM;
1208 goto destroy_cmd_wq_exit;
1209 }
1210
1211 INIT_WORK(&ndev->tx_work, nci_tx_work);
1212 snprintf(name, sizeof(name), "%s_nci_tx_wq", dev_name(dev));
1213 ndev->tx_wq = create_singlethread_workqueue(name);
1214 if (!ndev->tx_wq) {
1215 rc = -ENOMEM;
1216 goto destroy_rx_wq_exit;
1217 }
1218
1219 skb_queue_head_init(&ndev->cmd_q);
1220 skb_queue_head_init(&ndev->rx_q);
1221 skb_queue_head_init(&ndev->tx_q);
1222
e99e88a9
KC
1223 timer_setup(&ndev->cmd_timer, nci_cmd_timer, 0);
1224 timer_setup(&ndev->data_timer, nci_data_timer, 0);
6a2968aa
IE
1225
1226 mutex_init(&ndev->req_lock);
4aeee687 1227 INIT_LIST_HEAD(&ndev->conn_info_list);
6a2968aa 1228
3c1c0f5d
VC
1229 rc = nfc_register_device(ndev->nfc_dev);
1230 if (rc)
1231 goto destroy_rx_wq_exit;
1232
6a2968aa
IE
1233 goto exit;
1234
1235destroy_rx_wq_exit:
1236 destroy_workqueue(ndev->rx_wq);
1237
1238destroy_cmd_wq_exit:
1239 destroy_workqueue(ndev->cmd_wq);
1240
6a2968aa
IE
1241exit:
1242 return rc;
1243}
1244EXPORT_SYMBOL(nci_register_device);
1245
1246/**
1247 * nci_unregister_device - unregister a nci device in the nfc subsystem
1248 *
1249 * @dev: The nci device to unregister
1250 */
1251void nci_unregister_device(struct nci_dev *ndev)
1252{
4aeee687
CR
1253 struct nci_conn_info *conn_info, *n;
1254
6a2968aa
IE
1255 nci_close_device(ndev);
1256
1257 destroy_workqueue(ndev->cmd_wq);
1258 destroy_workqueue(ndev->rx_wq);
1259 destroy_workqueue(ndev->tx_wq);
1260
4aeee687
CR
1261 list_for_each_entry_safe(conn_info, n, &ndev->conn_info_list, list) {
1262 list_del(&conn_info->list);
1263 /* conn_info is allocated with devm_kzalloc */
1264 }
1265
6a2968aa
IE
1266 nfc_unregister_device(ndev->nfc_dev);
1267}
1268EXPORT_SYMBOL(nci_unregister_device);
1269
1270/**
1271 * nci_recv_frame - receive frame from NCI drivers
1272 *
1095e69f 1273 * @ndev: The nci device
6a2968aa
IE
1274 * @skb: The sk_buff to receive
1275 */
1095e69f 1276int nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb)
6a2968aa 1277{
24bf3304 1278 pr_debug("len %d\n", skb->len);
6a2968aa 1279
874934f4
SJ
1280 if (!ndev || (!test_bit(NCI_UP, &ndev->flags) &&
1281 !test_bit(NCI_INIT, &ndev->flags))) {
6a2968aa
IE
1282 kfree_skb(skb);
1283 return -ENXIO;
1284 }
1285
1286 /* Queue frame for rx worker thread */
1287 skb_queue_tail(&ndev->rx_q, skb);
1288 queue_work(ndev->rx_wq, &ndev->rx_work);
1289
1290 return 0;
1291}
1292EXPORT_SYMBOL(nci_recv_frame);
1293
e5629d29 1294int nci_send_frame(struct nci_dev *ndev, struct sk_buff *skb)
6a2968aa 1295{
24bf3304 1296 pr_debug("len %d\n", skb->len);
6a2968aa
IE
1297
1298 if (!ndev) {
1299 kfree_skb(skb);
1300 return -ENODEV;
1301 }
1302
1303 /* Get rid of skb owner, prior to sending to the driver. */
1304 skb_orphan(skb);
1305
05158296
HT
1306 /* Send copy to sniffer */
1307 nfc_send_to_raw_sock(ndev->nfc_dev, skb,
1308 RAW_PAYLOAD_NCI, NFC_DIRECTION_TX);
1309
1095e69f 1310 return ndev->ops->send(ndev, skb);
6a2968aa 1311}
e5629d29 1312EXPORT_SYMBOL(nci_send_frame);
6a2968aa
IE
1313
1314/* Send NCI command */
1315int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload)
1316{
1317 struct nci_ctrl_hdr *hdr;
1318 struct sk_buff *skb;
1319
24bf3304 1320 pr_debug("opcode 0x%x, plen %d\n", opcode, plen);
6a2968aa
IE
1321
1322 skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + plen), GFP_KERNEL);
1323 if (!skb) {
ed1e0ad8 1324 pr_err("no memory for command\n");
6a2968aa
IE
1325 return -ENOMEM;
1326 }
1327
4df864c1 1328 hdr = skb_put(skb, NCI_CTRL_HDR_SIZE);
6a2968aa
IE
1329 hdr->gid = nci_opcode_gid(opcode);
1330 hdr->oid = nci_opcode_oid(opcode);
1331 hdr->plen = plen;
1332
1333 nci_mt_set((__u8 *)hdr, NCI_MT_CMD_PKT);
1334 nci_pbf_set((__u8 *)hdr, NCI_PBF_LAST);
1335
1336 if (plen)
59ae1d12 1337 skb_put_data(skb, payload, plen);
6a2968aa 1338
6a2968aa
IE
1339 skb_queue_tail(&ndev->cmd_q, skb);
1340 queue_work(ndev->cmd_wq, &ndev->cmd_work);
1341
1342 return 0;
1343}
e5629d29 1344EXPORT_SYMBOL(nci_send_cmd);
6a2968aa 1345
b6355e97 1346/* Proprietary commands API */
22e4bd09
RD
1347static struct nci_driver_ops *ops_cmd_lookup(struct nci_driver_ops *ops,
1348 size_t n_ops,
1349 __u16 opcode)
b6355e97
SO
1350{
1351 size_t i;
22e4bd09 1352 struct nci_driver_ops *op;
b6355e97 1353
0a97a3cb 1354 if (!ops || !n_ops)
b6355e97
SO
1355 return NULL;
1356
0a97a3cb
RD
1357 for (i = 0; i < n_ops; i++) {
1358 op = &ops[i];
1359 if (op->opcode == opcode)
1360 return op;
b6355e97
SO
1361 }
1362
1363 return NULL;
1364}
1365
0a97a3cb 1366static int nci_op_rsp_packet(struct nci_dev *ndev, __u16 rsp_opcode,
22e4bd09 1367 struct sk_buff *skb, struct nci_driver_ops *ops,
0a97a3cb 1368 size_t n_ops)
b6355e97 1369{
22e4bd09 1370 struct nci_driver_ops *op;
b6355e97 1371
0a97a3cb
RD
1372 op = ops_cmd_lookup(ops, n_ops, rsp_opcode);
1373 if (!op || !op->rsp)
b6355e97
SO
1374 return -ENOTSUPP;
1375
0a97a3cb 1376 return op->rsp(ndev, skb);
b6355e97
SO
1377}
1378
0a97a3cb 1379static int nci_op_ntf_packet(struct nci_dev *ndev, __u16 ntf_opcode,
22e4bd09 1380 struct sk_buff *skb, struct nci_driver_ops *ops,
0a97a3cb 1381 size_t n_ops)
b6355e97 1382{
22e4bd09 1383 struct nci_driver_ops *op;
b6355e97 1384
0a97a3cb
RD
1385 op = ops_cmd_lookup(ops, n_ops, ntf_opcode);
1386 if (!op || !op->ntf)
b6355e97
SO
1387 return -ENOTSUPP;
1388
0a97a3cb
RD
1389 return op->ntf(ndev, skb);
1390}
1391
f1163174
RD
1392int nci_prop_rsp_packet(struct nci_dev *ndev, __u16 opcode,
1393 struct sk_buff *skb)
0a97a3cb
RD
1394{
1395 return nci_op_rsp_packet(ndev, opcode, skb, ndev->ops->prop_ops,
1396 ndev->ops->n_prop_ops);
1397}
1398
f1163174
RD
1399int nci_prop_ntf_packet(struct nci_dev *ndev, __u16 opcode,
1400 struct sk_buff *skb)
0a97a3cb
RD
1401{
1402 return nci_op_ntf_packet(ndev, opcode, skb, ndev->ops->prop_ops,
1403 ndev->ops->n_prop_ops);
1404}
1405
f1163174
RD
1406int nci_core_rsp_packet(struct nci_dev *ndev, __u16 opcode,
1407 struct sk_buff *skb)
0a97a3cb
RD
1408{
1409 return nci_op_rsp_packet(ndev, opcode, skb, ndev->ops->core_ops,
1410 ndev->ops->n_core_ops);
1411}
1412
f1163174
RD
1413int nci_core_ntf_packet(struct nci_dev *ndev, __u16 opcode,
1414 struct sk_buff *skb)
0a97a3cb
RD
1415{
1416 return nci_op_ntf_packet(ndev, opcode, skb, ndev->ops->core_ops,
1417 ndev->ops->n_core_ops);
b6355e97
SO
1418}
1419
6a2968aa
IE
1420/* ---- NCI TX Data worker thread ---- */
1421
1422static void nci_tx_work(struct work_struct *work)
1423{
1424 struct nci_dev *ndev = container_of(work, struct nci_dev, tx_work);
4aeee687 1425 struct nci_conn_info *conn_info;
6a2968aa
IE
1426 struct sk_buff *skb;
1427
4aeee687
CR
1428 conn_info = nci_get_conn_info_by_conn_id(ndev, ndev->cur_conn_id);
1429 if (!conn_info)
1430 return;
1431
1432 pr_debug("credits_cnt %d\n", atomic_read(&conn_info->credits_cnt));
6a2968aa
IE
1433
1434 /* Send queued tx data */
4aeee687 1435 while (atomic_read(&conn_info->credits_cnt)) {
6a2968aa
IE
1436 skb = skb_dequeue(&ndev->tx_q);
1437 if (!skb)
1438 return;
1439
db98c829 1440 /* Check if data flow control is used */
4aeee687 1441 if (atomic_read(&conn_info->credits_cnt) !=
eb9bc6e9 1442 NCI_DATA_FLOW_CONTROL_NOT_USED)
4aeee687 1443 atomic_dec(&conn_info->credits_cnt);
6a2968aa 1444
20c239c1
JP
1445 pr_debug("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d\n",
1446 nci_pbf(skb->data),
1447 nci_conn_id(skb->data),
1448 nci_plen(skb->data));
6a2968aa 1449
1095e69f 1450 nci_send_frame(ndev, skb);
c4bf98b2
IE
1451
1452 mod_timer(&ndev->data_timer,
eb9bc6e9 1453 jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT));
6a2968aa
IE
1454 }
1455}
1456
1457/* ----- NCI RX worker thread (data & control) ----- */
1458
1459static void nci_rx_work(struct work_struct *work)
1460{
1461 struct nci_dev *ndev = container_of(work, struct nci_dev, rx_work);
1462 struct sk_buff *skb;
1463
1464 while ((skb = skb_dequeue(&ndev->rx_q))) {
05158296
HT
1465
1466 /* Send copy to sniffer */
1467 nfc_send_to_raw_sock(ndev->nfc_dev, skb,
1468 RAW_PAYLOAD_NCI, NFC_DIRECTION_RX);
1469
6a2968aa
IE
1470 /* Process frame */
1471 switch (nci_mt(skb->data)) {
1472 case NCI_MT_RSP_PKT:
1473 nci_rsp_packet(ndev, skb);
1474 break;
1475
1476 case NCI_MT_NTF_PKT:
1477 nci_ntf_packet(ndev, skb);
1478 break;
1479
1480 case NCI_MT_DATA_PKT:
1481 nci_rx_data_packet(ndev, skb);
1482 break;
1483
1484 default:
ed1e0ad8 1485 pr_err("unknown MT 0x%x\n", nci_mt(skb->data));
6a2968aa
IE
1486 kfree_skb(skb);
1487 break;
1488 }
1489 }
c4bf98b2
IE
1490
1491 /* check if a data exchange timout has occurred */
1492 if (test_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags)) {
1493 /* complete the data exchange transaction, if exists */
1494 if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
4aeee687
CR
1495 nci_data_exchange_complete(ndev, NULL,
1496 ndev->cur_conn_id,
1497 -ETIMEDOUT);
c4bf98b2
IE
1498
1499 clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
1500 }
6a2968aa
IE
1501}
1502
1503/* ----- NCI TX CMD worker thread ----- */
1504
1505static void nci_cmd_work(struct work_struct *work)
1506{
1507 struct nci_dev *ndev = container_of(work, struct nci_dev, cmd_work);
1508 struct sk_buff *skb;
1509
24bf3304 1510 pr_debug("cmd_cnt %d\n", atomic_read(&ndev->cmd_cnt));
6a2968aa
IE
1511
1512 /* Send queued command */
1513 if (atomic_read(&ndev->cmd_cnt)) {
1514 skb = skb_dequeue(&ndev->cmd_q);
1515 if (!skb)
1516 return;
1517
1518 atomic_dec(&ndev->cmd_cnt);
1519
20c239c1
JP
1520 pr_debug("NCI TX: MT=cmd, PBF=%d, GID=0x%x, OID=0x%x, plen=%d\n",
1521 nci_pbf(skb->data),
1522 nci_opcode_gid(nci_opcode(skb->data)),
1523 nci_opcode_oid(nci_opcode(skb->data)),
1524 nci_plen(skb->data));
6a2968aa 1525
1095e69f 1526 nci_send_frame(ndev, skb);
6a2968aa
IE
1527
1528 mod_timer(&ndev->cmd_timer,
eb9bc6e9 1529 jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT));
6a2968aa
IE
1530 }
1531}
8a70e7f8
DJ
1532
1533MODULE_LICENSE("GPL");