NFC: nci: Support logical connections management
[deliverable/linux.git] / net / nfc / nci / core.c
CommitLineData
6a2968aa
IE
1/*
2 * The NFC Controller Interface is the communication protocol between an
3 * NFC Controller (NFCC) and a Device Host (DH).
4 *
5 * Copyright (C) 2011 Texas Instruments, Inc.
772dccf4 6 * Copyright (C) 2014 Marvell International Ltd.
6a2968aa
IE
7 *
8 * Written by Ilan Elias <ilane@ti.com>
9 *
10 * Acknowledgements:
11 * This file is based on hci_core.c, which was written
12 * by Maxim Krasnyansky.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2
16 * as published by the Free Software Foundation
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
98b32dec 24 * along with this program; if not, see <http://www.gnu.org/licenses/>.
6a2968aa
IE
25 *
26 */
27
52858b51 28#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
ed1e0ad8 29
8a70e7f8 30#include <linux/module.h>
6a2968aa
IE
31#include <linux/types.h>
32#include <linux/workqueue.h>
33#include <linux/completion.h>
bc3b2d7f 34#include <linux/export.h>
6a2968aa
IE
35#include <linux/sched.h>
36#include <linux/bitops.h>
37#include <linux/skbuff.h>
38
39#include "../nfc.h"
40#include <net/nfc/nci.h>
41#include <net/nfc/nci_core.h>
42#include <linux/nfc.h>
43
44static void nci_cmd_work(struct work_struct *work);
45static void nci_rx_work(struct work_struct *work);
46static void nci_tx_work(struct work_struct *work);
47
4aeee687
CR
48struct nci_conn_info *nci_get_conn_info_by_conn_id(struct nci_dev *ndev,
49 int conn_id)
50{
51 struct nci_conn_info *conn_info;
52
53 list_for_each_entry(conn_info, &ndev->conn_info_list, list) {
54 if (conn_info->conn_id == conn_id)
55 return conn_info;
56 }
57
58 return NULL;
59}
60
6a2968aa
IE
61/* ---- NCI requests ---- */
62
63void nci_req_complete(struct nci_dev *ndev, int result)
64{
65 if (ndev->req_status == NCI_REQ_PEND) {
66 ndev->req_result = result;
67 ndev->req_status = NCI_REQ_DONE;
68 complete(&ndev->req_completion);
69 }
70}
71
72static void nci_req_cancel(struct nci_dev *ndev, int err)
73{
74 if (ndev->req_status == NCI_REQ_PEND) {
75 ndev->req_result = err;
76 ndev->req_status = NCI_REQ_CANCELED;
77 complete(&ndev->req_completion);
78 }
79}
80
81/* Execute request and wait for completion. */
82static int __nci_request(struct nci_dev *ndev,
eb9bc6e9
SO
83 void (*req)(struct nci_dev *ndev, unsigned long opt),
84 unsigned long opt, __u32 timeout)
6a2968aa
IE
85{
86 int rc = 0;
f8c141c3 87 long completion_rc;
6a2968aa
IE
88
89 ndev->req_status = NCI_REQ_PEND;
90
9bec44bf 91 reinit_completion(&ndev->req_completion);
6a2968aa 92 req(ndev, opt);
eb9bc6e9
SO
93 completion_rc =
94 wait_for_completion_interruptible_timeout(&ndev->req_completion,
95 timeout);
6a2968aa 96
20c239c1 97 pr_debug("wait_for_completion return %ld\n", completion_rc);
6a2968aa
IE
98
99 if (completion_rc > 0) {
100 switch (ndev->req_status) {
101 case NCI_REQ_DONE:
102 rc = nci_to_errno(ndev->req_result);
103 break;
104
105 case NCI_REQ_CANCELED:
106 rc = -ndev->req_result;
107 break;
108
109 default:
110 rc = -ETIMEDOUT;
111 break;
112 }
113 } else {
ed1e0ad8
JP
114 pr_err("wait_for_completion_interruptible_timeout failed %ld\n",
115 completion_rc);
6a2968aa
IE
116
117 rc = ((completion_rc == 0) ? (-ETIMEDOUT) : (completion_rc));
118 }
119
120 ndev->req_status = ndev->req_result = 0;
121
122 return rc;
123}
124
125static inline int nci_request(struct nci_dev *ndev,
eb9bc6e9
SO
126 void (*req)(struct nci_dev *ndev,
127 unsigned long opt),
128 unsigned long opt, __u32 timeout)
6a2968aa
IE
129{
130 int rc;
131
132 if (!test_bit(NCI_UP, &ndev->flags))
133 return -ENETDOWN;
134
135 /* Serialize all requests */
136 mutex_lock(&ndev->req_lock);
137 rc = __nci_request(ndev, req, opt, timeout);
138 mutex_unlock(&ndev->req_lock);
139
140 return rc;
141}
142
143static void nci_reset_req(struct nci_dev *ndev, unsigned long opt)
144{
e8c0dacd
IE
145 struct nci_core_reset_cmd cmd;
146
147 cmd.reset_type = NCI_RESET_TYPE_RESET_CONFIG;
148 nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 1, &cmd);
6a2968aa
IE
149}
150
151static void nci_init_req(struct nci_dev *ndev, unsigned long opt)
152{
153 nci_send_cmd(ndev, NCI_OP_CORE_INIT_CMD, 0, NULL);
154}
155
156static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
157{
2eb1dc10
IE
158 struct nci_rf_disc_map_cmd cmd;
159 struct disc_map_config *cfg = cmd.mapping_configs;
160 __u8 *num = &cmd.num_mapping_configs;
6a2968aa
IE
161 int i;
162
6a2968aa 163 /* set rf mapping configurations */
2eb1dc10 164 *num = 0;
6a2968aa
IE
165
166 /* by default mapping is set to NCI_RF_INTERFACE_FRAME */
167 for (i = 0; i < ndev->num_supported_rf_interfaces; i++) {
168 if (ndev->supported_rf_interfaces[i] ==
eb9bc6e9 169 NCI_RF_INTERFACE_ISO_DEP) {
2eb1dc10 170 cfg[*num].rf_protocol = NCI_RF_PROTOCOL_ISO_DEP;
637d85a7
IE
171 cfg[*num].mode = NCI_DISC_MAP_MODE_POLL |
172 NCI_DISC_MAP_MODE_LISTEN;
173 cfg[*num].rf_interface = NCI_RF_INTERFACE_ISO_DEP;
2eb1dc10 174 (*num)++;
6a2968aa 175 } else if (ndev->supported_rf_interfaces[i] ==
eb9bc6e9 176 NCI_RF_INTERFACE_NFC_DEP) {
2eb1dc10 177 cfg[*num].rf_protocol = NCI_RF_PROTOCOL_NFC_DEP;
637d85a7
IE
178 cfg[*num].mode = NCI_DISC_MAP_MODE_POLL |
179 NCI_DISC_MAP_MODE_LISTEN;
180 cfg[*num].rf_interface = NCI_RF_INTERFACE_NFC_DEP;
2eb1dc10 181 (*num)++;
6a2968aa
IE
182 }
183
2eb1dc10 184 if (*num == NCI_MAX_NUM_MAPPING_CONFIGS)
6a2968aa
IE
185 break;
186 }
187
188 nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_MAP_CMD,
eb9bc6e9 189 (1 + ((*num) * sizeof(struct disc_map_config))), &cmd);
6a2968aa
IE
190}
191
7e035230
IE
192struct nci_set_config_param {
193 __u8 id;
194 size_t len;
195 __u8 *val;
196};
197
198static void nci_set_config_req(struct nci_dev *ndev, unsigned long opt)
199{
200 struct nci_set_config_param *param = (struct nci_set_config_param *)opt;
201 struct nci_core_set_config_cmd cmd;
202
203 BUG_ON(param->len > NCI_MAX_PARAM_LEN);
204
205 cmd.num_params = 1;
206 cmd.param.id = param->id;
207 cmd.param.len = param->len;
208 memcpy(cmd.param.val, param->val, param->len);
209
210 nci_send_cmd(ndev, NCI_OP_CORE_SET_CONFIG_CMD, (3 + param->len), &cmd);
211}
212
772dccf4
JL
213struct nci_rf_discover_param {
214 __u32 im_protocols;
215 __u32 tm_protocols;
216};
217
6a2968aa
IE
218static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt)
219{
772dccf4
JL
220 struct nci_rf_discover_param *param =
221 (struct nci_rf_discover_param *)opt;
6a2968aa 222 struct nci_rf_disc_cmd cmd;
6a2968aa
IE
223
224 cmd.num_disc_configs = 0;
225
226 if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
772dccf4
JL
227 (param->im_protocols & NFC_PROTO_JEWEL_MASK ||
228 param->im_protocols & NFC_PROTO_MIFARE_MASK ||
229 param->im_protocols & NFC_PROTO_ISO14443_MASK ||
230 param->im_protocols & NFC_PROTO_NFC_DEP_MASK)) {
637d85a7 231 cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
eb9bc6e9 232 NCI_NFC_A_PASSIVE_POLL_MODE;
6a2968aa
IE
233 cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
234 cmd.num_disc_configs++;
235 }
236
237 if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
772dccf4 238 (param->im_protocols & NFC_PROTO_ISO14443_B_MASK)) {
637d85a7 239 cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
eb9bc6e9 240 NCI_NFC_B_PASSIVE_POLL_MODE;
6a2968aa
IE
241 cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
242 cmd.num_disc_configs++;
243 }
244
245 if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
772dccf4
JL
246 (param->im_protocols & NFC_PROTO_FELICA_MASK ||
247 param->im_protocols & NFC_PROTO_NFC_DEP_MASK)) {
637d85a7 248 cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
eb9bc6e9 249 NCI_NFC_F_PASSIVE_POLL_MODE;
6a2968aa
IE
250 cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
251 cmd.num_disc_configs++;
252 }
253
cfdbeeaf 254 if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
772dccf4 255 (param->im_protocols & NFC_PROTO_ISO15693_MASK)) {
cfdbeeaf
VC
256 cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
257 NCI_NFC_V_PASSIVE_POLL_MODE;
258 cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
259 cmd.num_disc_configs++;
260 }
261
772dccf4
JL
262 if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS - 1) &&
263 (param->tm_protocols & NFC_PROTO_NFC_DEP_MASK)) {
264 cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
265 NCI_NFC_A_PASSIVE_LISTEN_MODE;
266 cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
267 cmd.num_disc_configs++;
268 cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
269 NCI_NFC_F_PASSIVE_LISTEN_MODE;
270 cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
271 cmd.num_disc_configs++;
272 }
273
6a2968aa 274 nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_CMD,
eb9bc6e9
SO
275 (1 + (cmd.num_disc_configs * sizeof(struct disc_config))),
276 &cmd);
6a2968aa
IE
277}
278
019c4fba
IE
279struct nci_rf_discover_select_param {
280 __u8 rf_discovery_id;
281 __u8 rf_protocol;
282};
283
284static void nci_rf_discover_select_req(struct nci_dev *ndev, unsigned long opt)
285{
286 struct nci_rf_discover_select_param *param =
eb9bc6e9 287 (struct nci_rf_discover_select_param *)opt;
019c4fba
IE
288 struct nci_rf_discover_select_cmd cmd;
289
290 cmd.rf_discovery_id = param->rf_discovery_id;
291 cmd.rf_protocol = param->rf_protocol;
292
293 switch (cmd.rf_protocol) {
294 case NCI_RF_PROTOCOL_ISO_DEP:
295 cmd.rf_interface = NCI_RF_INTERFACE_ISO_DEP;
296 break;
297
298 case NCI_RF_PROTOCOL_NFC_DEP:
299 cmd.rf_interface = NCI_RF_INTERFACE_NFC_DEP;
300 break;
301
302 default:
303 cmd.rf_interface = NCI_RF_INTERFACE_FRAME;
304 break;
305 }
306
307 nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_SELECT_CMD,
eb9bc6e9 308 sizeof(struct nci_rf_discover_select_cmd), &cmd);
019c4fba
IE
309}
310
6a2968aa
IE
311static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt)
312{
313 struct nci_rf_deactivate_cmd cmd;
314
9295b5b5 315 cmd.type = opt;
6a2968aa
IE
316
317 nci_send_cmd(ndev, NCI_OP_RF_DEACTIVATE_CMD,
eb9bc6e9 318 sizeof(struct nci_rf_deactivate_cmd), &cmd);
6a2968aa
IE
319}
320
321static int nci_open_device(struct nci_dev *ndev)
322{
323 int rc = 0;
324
325 mutex_lock(&ndev->req_lock);
326
327 if (test_bit(NCI_UP, &ndev->flags)) {
328 rc = -EALREADY;
329 goto done;
330 }
331
332 if (ndev->ops->open(ndev)) {
333 rc = -EIO;
334 goto done;
335 }
336
337 atomic_set(&ndev->cmd_cnt, 1);
338
339 set_bit(NCI_INIT, &ndev->flags);
340
341 rc = __nci_request(ndev, nci_reset_req, 0,
eb9bc6e9 342 msecs_to_jiffies(NCI_RESET_TIMEOUT));
6a2968aa 343
44a589ca 344 if (ndev->ops->setup)
86e8586e
AK
345 ndev->ops->setup(ndev);
346
6a2968aa
IE
347 if (!rc) {
348 rc = __nci_request(ndev, nci_init_req, 0,
eb9bc6e9 349 msecs_to_jiffies(NCI_INIT_TIMEOUT));
6a2968aa
IE
350 }
351
352 if (!rc) {
353 rc = __nci_request(ndev, nci_init_complete_req, 0,
eb9bc6e9 354 msecs_to_jiffies(NCI_INIT_TIMEOUT));
6a2968aa
IE
355 }
356
357 clear_bit(NCI_INIT, &ndev->flags);
358
359 if (!rc) {
360 set_bit(NCI_UP, &ndev->flags);
019c4fba 361 nci_clear_target_list(ndev);
8939e47f 362 atomic_set(&ndev->state, NCI_IDLE);
6a2968aa
IE
363 } else {
364 /* Init failed, cleanup */
365 skb_queue_purge(&ndev->cmd_q);
366 skb_queue_purge(&ndev->rx_q);
367 skb_queue_purge(&ndev->tx_q);
368
369 ndev->ops->close(ndev);
370 ndev->flags = 0;
371 }
372
373done:
374 mutex_unlock(&ndev->req_lock);
375 return rc;
376}
377
378static int nci_close_device(struct nci_dev *ndev)
379{
380 nci_req_cancel(ndev, ENODEV);
381 mutex_lock(&ndev->req_lock);
382
383 if (!test_and_clear_bit(NCI_UP, &ndev->flags)) {
384 del_timer_sync(&ndev->cmd_timer);
c4bf98b2 385 del_timer_sync(&ndev->data_timer);
6a2968aa
IE
386 mutex_unlock(&ndev->req_lock);
387 return 0;
388 }
389
390 /* Drop RX and TX queues */
391 skb_queue_purge(&ndev->rx_q);
392 skb_queue_purge(&ndev->tx_q);
393
394 /* Flush RX and TX wq */
395 flush_workqueue(ndev->rx_wq);
396 flush_workqueue(ndev->tx_wq);
397
398 /* Reset device */
399 skb_queue_purge(&ndev->cmd_q);
400 atomic_set(&ndev->cmd_cnt, 1);
401
402 set_bit(NCI_INIT, &ndev->flags);
403 __nci_request(ndev, nci_reset_req, 0,
eb9bc6e9 404 msecs_to_jiffies(NCI_RESET_TIMEOUT));
6a2968aa
IE
405 clear_bit(NCI_INIT, &ndev->flags);
406
fa9be5f0
AK
407 del_timer_sync(&ndev->cmd_timer);
408
6a2968aa
IE
409 /* Flush cmd wq */
410 flush_workqueue(ndev->cmd_wq);
411
412 /* After this point our queues are empty
413 * and no works are scheduled. */
414 ndev->ops->close(ndev);
415
416 /* Clear flags */
417 ndev->flags = 0;
418
419 mutex_unlock(&ndev->req_lock);
420
421 return 0;
422}
423
424/* NCI command timer function */
425static void nci_cmd_timer(unsigned long arg)
426{
427 struct nci_dev *ndev = (void *) arg;
428
6a2968aa
IE
429 atomic_set(&ndev->cmd_cnt, 1);
430 queue_work(ndev->cmd_wq, &ndev->cmd_work);
431}
432
c4bf98b2
IE
433/* NCI data exchange timer function */
434static void nci_data_timer(unsigned long arg)
435{
436 struct nci_dev *ndev = (void *) arg;
437
438 set_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
439 queue_work(ndev->rx_wq, &ndev->rx_work);
440}
441
6a2968aa
IE
442static int nci_dev_up(struct nfc_dev *nfc_dev)
443{
444 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
445
6a2968aa
IE
446 return nci_open_device(ndev);
447}
448
449static int nci_dev_down(struct nfc_dev *nfc_dev)
450{
451 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
452
6a2968aa
IE
453 return nci_close_device(ndev);
454}
455
22c15bf3
AK
456int nci_set_config(struct nci_dev *ndev, __u8 id, size_t len, __u8 *val)
457{
458 struct nci_set_config_param param;
459
460 if (!val || !len)
461 return 0;
462
463 param.id = id;
464 param.len = len;
465 param.val = val;
466
467 return __nci_request(ndev, nci_set_config_req, (unsigned long)&param,
468 msecs_to_jiffies(NCI_SET_CONFIG_TIMEOUT));
469}
470EXPORT_SYMBOL(nci_set_config);
471
af9c8aa6
CR
472static void nci_nfcee_discover_req(struct nci_dev *ndev, unsigned long opt)
473{
474 struct nci_nfcee_discover_cmd cmd;
475 __u8 action = opt;
476
477 cmd.discovery_action = action;
478
479 nci_send_cmd(ndev, NCI_OP_NFCEE_DISCOVER_CMD, 1, &cmd);
480}
481
482int nci_nfcee_discover(struct nci_dev *ndev, u8 action)
483{
484 return nci_request(ndev, nci_nfcee_discover_req, action,
485 msecs_to_jiffies(NCI_CMD_TIMEOUT));
486}
487EXPORT_SYMBOL(nci_nfcee_discover);
488
f7f793f3
CR
489static void nci_nfcee_mode_set_req(struct nci_dev *ndev, unsigned long opt)
490{
491 struct nci_nfcee_mode_set_cmd *cmd =
492 (struct nci_nfcee_mode_set_cmd *)opt;
493
494 nci_send_cmd(ndev, NCI_OP_NFCEE_MODE_SET_CMD,
495 sizeof(struct nci_nfcee_mode_set_cmd), cmd);
496}
497
498int nci_nfcee_mode_set(struct nci_dev *ndev, u8 nfcee_id, u8 nfcee_mode)
499{
500 struct nci_nfcee_mode_set_cmd cmd;
501
502 cmd.nfcee_id = nfcee_id;
503 cmd.nfcee_mode = nfcee_mode;
504
505 return nci_request(ndev, nci_nfcee_mode_set_req, (unsigned long)&cmd,
506 msecs_to_jiffies(NCI_CMD_TIMEOUT));
507}
508EXPORT_SYMBOL(nci_nfcee_mode_set);
509
736bb957
CR
510static void nci_core_conn_create_req(struct nci_dev *ndev, unsigned long opt)
511{
512 struct nci_core_conn_create_cmd cmd;
513 struct core_conn_create_dest_spec_params *params =
514 (struct core_conn_create_dest_spec_params *)opt;
515
516 cmd.destination_type = NCI_DESTINATION_NFCEE;
517 cmd.number_destination_params = 1;
518 memcpy(&cmd.params.type, params,
519 sizeof(struct core_conn_create_dest_spec_params));
520 nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD,
521 sizeof(struct nci_core_conn_create_cmd), &cmd);
522}
523
524int nci_core_conn_create(struct nci_dev *ndev,
525 struct core_conn_create_dest_spec_params *params)
526{
527 ndev->cur_id = params->value.id;
528 return nci_request(ndev, nci_core_conn_create_req,
529 (unsigned long)params,
530 msecs_to_jiffies(NCI_CMD_TIMEOUT));
531}
532EXPORT_SYMBOL(nci_core_conn_create);
533
534static void nci_core_conn_close_req(struct nci_dev *ndev, unsigned long opt)
535{
536 __u8 conn_id = opt;
537
538 nci_send_cmd(ndev, NCI_OP_CORE_CONN_CLOSE_CMD, 1, &conn_id);
539}
540
541int nci_core_conn_close(struct nci_dev *ndev, u8 conn_id)
542{
543 return nci_request(ndev, nci_core_conn_close_req, conn_id,
544 msecs_to_jiffies(NCI_CMD_TIMEOUT));
545}
546EXPORT_SYMBOL(nci_core_conn_close);
547
7e035230
IE
548static int nci_set_local_general_bytes(struct nfc_dev *nfc_dev)
549{
550 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
551 struct nci_set_config_param param;
529ee066 552 int rc;
7e035230
IE
553
554 param.val = nfc_get_local_general_bytes(nfc_dev, &param.len);
555 if ((param.val == NULL) || (param.len == 0))
f9fc36f4 556 return 0;
7e035230 557
460d8f97 558 if (param.len > NFC_MAX_GT_LEN)
7e035230
IE
559 return -EINVAL;
560
7e035230 561 param.id = NCI_PN_ATR_REQ_GEN_BYTES;
7e035230 562
529ee066
JL
563 rc = nci_request(ndev, nci_set_config_req, (unsigned long)&param,
564 msecs_to_jiffies(NCI_SET_CONFIG_TIMEOUT));
565 if (rc)
566 return rc;
567
568 param.id = NCI_LN_ATR_RES_GEN_BYTES;
569
f9fc36f4
SJ
570 return nci_request(ndev, nci_set_config_req, (unsigned long)&param,
571 msecs_to_jiffies(NCI_SET_CONFIG_TIMEOUT));
7e035230
IE
572}
573
90d78c13
JL
574static int nci_set_listen_parameters(struct nfc_dev *nfc_dev)
575{
576 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
577 int rc;
578 __u8 val;
579
580 val = NCI_LA_SEL_INFO_NFC_DEP_MASK;
581
582 rc = nci_set_config(ndev, NCI_LA_SEL_INFO, 1, &val);
583 if (rc)
584 return rc;
585
586 val = NCI_LF_PROTOCOL_TYPE_NFC_DEP_MASK;
587
588 rc = nci_set_config(ndev, NCI_LF_PROTOCOL_TYPE, 1, &val);
589 if (rc)
590 return rc;
591
592 val = NCI_LF_CON_BITR_F_212 | NCI_LF_CON_BITR_F_424;
593
594 return nci_set_config(ndev, NCI_LF_CON_BITR_F, 1, &val);
595}
596
fe7c5800
SO
597static int nci_start_poll(struct nfc_dev *nfc_dev,
598 __u32 im_protocols, __u32 tm_protocols)
6a2968aa
IE
599{
600 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
772dccf4 601 struct nci_rf_discover_param param;
6a2968aa
IE
602 int rc;
603
019c4fba 604 if ((atomic_read(&ndev->state) == NCI_DISCOVERY) ||
eb9bc6e9 605 (atomic_read(&ndev->state) == NCI_W4_ALL_DISCOVERIES)) {
ed1e0ad8 606 pr_err("unable to start poll, since poll is already active\n");
6a2968aa
IE
607 return -EBUSY;
608 }
609
de054799 610 if (ndev->target_active_prot) {
ed1e0ad8 611 pr_err("there is an active target\n");
de054799
IE
612 return -EBUSY;
613 }
614
019c4fba 615 if ((atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) ||
eb9bc6e9 616 (atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) {
019c4fba 617 pr_debug("target active or w4 select, implicitly deactivate\n");
6a2968aa 618
9295b5b5
CR
619 rc = nci_request(ndev, nci_rf_deactivate_req,
620 NCI_DEACTIVATE_TYPE_IDLE_MODE,
eb9bc6e9 621 msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
6a2968aa
IE
622 if (rc)
623 return -EBUSY;
624 }
625
529ee066 626 if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) {
7e035230
IE
627 rc = nci_set_local_general_bytes(nfc_dev);
628 if (rc) {
629 pr_err("failed to set local general bytes\n");
630 return rc;
631 }
632 }
633
90d78c13
JL
634 if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) {
635 rc = nci_set_listen_parameters(nfc_dev);
636 if (rc)
637 pr_err("failed to set listen parameters\n");
638 }
639
772dccf4
JL
640 param.im_protocols = im_protocols;
641 param.tm_protocols = tm_protocols;
642 rc = nci_request(ndev, nci_rf_discover_req, (unsigned long)&param,
eb9bc6e9 643 msecs_to_jiffies(NCI_RF_DISC_TIMEOUT));
6a2968aa
IE
644
645 if (!rc)
fe7c5800 646 ndev->poll_prots = im_protocols;
6a2968aa
IE
647
648 return rc;
649}
650
651static void nci_stop_poll(struct nfc_dev *nfc_dev)
652{
653 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
654
019c4fba 655 if ((atomic_read(&ndev->state) != NCI_DISCOVERY) &&
eb9bc6e9 656 (atomic_read(&ndev->state) != NCI_W4_ALL_DISCOVERIES)) {
ed1e0ad8 657 pr_err("unable to stop poll, since poll is not active\n");
6a2968aa
IE
658 return;
659 }
660
9295b5b5 661 nci_request(ndev, nci_rf_deactivate_req, NCI_DEACTIVATE_TYPE_IDLE_MODE,
eb9bc6e9 662 msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
6a2968aa
IE
663}
664
90099433
EL
665static int nci_activate_target(struct nfc_dev *nfc_dev,
666 struct nfc_target *target, __u32 protocol)
6a2968aa
IE
667{
668 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
019c4fba 669 struct nci_rf_discover_select_param param;
90099433 670 struct nfc_target *nci_target = NULL;
019c4fba
IE
671 int i;
672 int rc = 0;
6a2968aa 673
90099433 674 pr_debug("target_idx %d, protocol 0x%x\n", target->idx, protocol);
6a2968aa 675
019c4fba 676 if ((atomic_read(&ndev->state) != NCI_W4_HOST_SELECT) &&
eb9bc6e9 677 (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
ed1e0ad8 678 pr_err("there is no available target to activate\n");
6a2968aa
IE
679 return -EINVAL;
680 }
681
682 if (ndev->target_active_prot) {
ed1e0ad8 683 pr_err("there is already an active target\n");
6a2968aa
IE
684 return -EBUSY;
685 }
686
019c4fba 687 for (i = 0; i < ndev->n_targets; i++) {
90099433
EL
688 if (ndev->targets[i].idx == target->idx) {
689 nci_target = &ndev->targets[i];
019c4fba
IE
690 break;
691 }
692 }
693
90099433 694 if (!nci_target) {
019c4fba
IE
695 pr_err("unable to find the selected target\n");
696 return -EINVAL;
697 }
698
90099433 699 if (!(nci_target->supported_protocols & (1 << protocol))) {
ed1e0ad8
JP
700 pr_err("target does not support the requested protocol 0x%x\n",
701 protocol);
6a2968aa
IE
702 return -EINVAL;
703 }
704
019c4fba 705 if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) {
90099433 706 param.rf_discovery_id = nci_target->logical_idx;
019c4fba
IE
707
708 if (protocol == NFC_PROTO_JEWEL)
709 param.rf_protocol = NCI_RF_PROTOCOL_T1T;
710 else if (protocol == NFC_PROTO_MIFARE)
711 param.rf_protocol = NCI_RF_PROTOCOL_T2T;
712 else if (protocol == NFC_PROTO_FELICA)
713 param.rf_protocol = NCI_RF_PROTOCOL_T3T;
01d719a2
SO
714 else if (protocol == NFC_PROTO_ISO14443 ||
715 protocol == NFC_PROTO_ISO14443_B)
019c4fba
IE
716 param.rf_protocol = NCI_RF_PROTOCOL_ISO_DEP;
717 else
718 param.rf_protocol = NCI_RF_PROTOCOL_NFC_DEP;
719
720 rc = nci_request(ndev, nci_rf_discover_select_req,
eb9bc6e9
SO
721 (unsigned long)&param,
722 msecs_to_jiffies(NCI_RF_DISC_SELECT_TIMEOUT));
019c4fba 723 }
6a2968aa 724
019c4fba
IE
725 if (!rc)
726 ndev->target_active_prot = protocol;
727
728 return rc;
6a2968aa
IE
729}
730
90099433
EL
731static void nci_deactivate_target(struct nfc_dev *nfc_dev,
732 struct nfc_target *target)
6a2968aa
IE
733{
734 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
735
767f19ae 736 pr_debug("entry\n");
6a2968aa
IE
737
738 if (!ndev->target_active_prot) {
ed1e0ad8 739 pr_err("unable to deactivate target, no active target\n");
6a2968aa
IE
740 return;
741 }
742
743 ndev->target_active_prot = 0;
744
8939e47f 745 if (atomic_read(&ndev->state) == NCI_POLL_ACTIVE) {
9295b5b5
CR
746 nci_request(ndev, nci_rf_deactivate_req,
747 NCI_DEACTIVATE_TYPE_SLEEP_MODE,
eb9bc6e9 748 msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
6a2968aa
IE
749 }
750}
751
767f19ae
IE
752static int nci_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
753 __u8 comm_mode, __u8 *gb, size_t gb_len)
754{
755 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
756 int rc;
757
758 pr_debug("target_idx %d, comm_mode %d\n", target->idx, comm_mode);
759
760 rc = nci_activate_target(nfc_dev, target, NFC_PROTO_NFC_DEP);
761 if (rc)
762 return rc;
763
764 rc = nfc_set_remote_general_bytes(nfc_dev, ndev->remote_gb,
765 ndev->remote_gb_len);
766 if (!rc)
767 rc = nfc_dep_link_is_up(nfc_dev, target->idx, NFC_COMM_PASSIVE,
768 NFC_RF_INITIATOR);
769
770 return rc;
771}
772
773static int nci_dep_link_down(struct nfc_dev *nfc_dev)
774{
d7979e13
JL
775 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
776 int rc;
777
767f19ae
IE
778 pr_debug("entry\n");
779
d7979e13
JL
780 if (nfc_dev->rf_mode == NFC_RF_INITIATOR) {
781 nci_deactivate_target(nfc_dev, NULL);
782 } else {
783 if (atomic_read(&ndev->state) == NCI_LISTEN_ACTIVE ||
784 atomic_read(&ndev->state) == NCI_DISCOVERY) {
785 nci_request(ndev, nci_rf_deactivate_req, 0,
786 msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
787 }
788
789 rc = nfc_tm_deactivated(nfc_dev);
790 if (rc)
791 pr_err("error when signaling tm deactivation\n");
792 }
767f19ae
IE
793
794 return 0;
795}
796
797
be9ae4ce
SO
798static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
799 struct sk_buff *skb,
800 data_exchange_cb_t cb, void *cb_context)
6a2968aa
IE
801{
802 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
38f04c6b 803 int rc;
4aeee687
CR
804 struct nci_conn_info *conn_info;
805
806 conn_info = nci_get_conn_info_by_conn_id(ndev, NCI_STATIC_RF_CONN_ID);
807 if (!conn_info)
808 return -EPROTO;
6a2968aa 809
90099433 810 pr_debug("target_idx %d, len %d\n", target->idx, skb->len);
6a2968aa
IE
811
812 if (!ndev->target_active_prot) {
ed1e0ad8 813 pr_err("unable to exchange data, no active target\n");
6a2968aa
IE
814 return -EINVAL;
815 }
816
38f04c6b
IE
817 if (test_and_set_bit(NCI_DATA_EXCHANGE, &ndev->flags))
818 return -EBUSY;
819
6a2968aa 820 /* store cb and context to be used on receiving data */
4aeee687
CR
821 conn_info->data_exchange_cb = cb;
822 conn_info->data_exchange_cb_context = cb_context;
6a2968aa 823
e8c0dacd 824 rc = nci_send_data(ndev, NCI_STATIC_RF_CONN_ID, skb);
38f04c6b
IE
825 if (rc)
826 clear_bit(NCI_DATA_EXCHANGE, &ndev->flags);
827
828 return rc;
6a2968aa
IE
829}
830
485f442f
JL
831static int nci_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
832{
833 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
834 int rc;
835
836 rc = nci_send_data(ndev, NCI_STATIC_RF_CONN_ID, skb);
837 if (rc)
838 pr_err("unable to send data\n");
839
840 return rc;
841}
842
0a946301
SO
843static int nci_enable_se(struct nfc_dev *nfc_dev, u32 se_idx)
844{
93bca2bf
CR
845 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
846
847 if (ndev->ops->enable_se)
848 return ndev->ops->enable_se(ndev, se_idx);
849
0a946301
SO
850 return 0;
851}
852
853static int nci_disable_se(struct nfc_dev *nfc_dev, u32 se_idx)
854{
e9ef9431
CR
855 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
856
857 if (ndev->ops->disable_se)
858 return ndev->ops->disable_se(ndev, se_idx);
859
0a946301
SO
860 return 0;
861}
862
863static int nci_discover_se(struct nfc_dev *nfc_dev)
864{
ba4db551
CR
865 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
866
867 if (ndev->ops->discover_se)
868 return ndev->ops->discover_se(ndev);
869
0a946301
SO
870 return 0;
871}
872
a688bf55
CR
873static int nci_se_io(struct nfc_dev *nfc_dev, u32 se_idx,
874 u8 *apdu, size_t apdu_length,
875 se_io_cb_t cb, void *cb_context)
876{
877 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
878
879 if (ndev->ops->se_io)
880 return ndev->ops->se_io(ndev, se_idx, apdu,
881 apdu_length, cb, cb_context);
882
883 return 0;
884}
885
6a2968aa
IE
886static struct nfc_ops nci_nfc_ops = {
887 .dev_up = nci_dev_up,
888 .dev_down = nci_dev_down,
889 .start_poll = nci_start_poll,
890 .stop_poll = nci_stop_poll,
767f19ae
IE
891 .dep_link_up = nci_dep_link_up,
892 .dep_link_down = nci_dep_link_down,
6a2968aa
IE
893 .activate_target = nci_activate_target,
894 .deactivate_target = nci_deactivate_target,
be9ae4ce 895 .im_transceive = nci_transceive,
485f442f 896 .tm_send = nci_tm_send,
0a946301
SO
897 .enable_se = nci_enable_se,
898 .disable_se = nci_disable_se,
899 .discover_se = nci_discover_se,
a688bf55 900 .se_io = nci_se_io,
6a2968aa
IE
901};
902
903/* ---- Interface to NCI drivers ---- */
904
905/**
906 * nci_allocate_device - allocate a new nci device
907 *
908 * @ops: device operations
909 * @supported_protocols: NFC protocols supported by the device
910 */
911struct nci_dev *nci_allocate_device(struct nci_ops *ops,
eb9bc6e9
SO
912 __u32 supported_protocols,
913 int tx_headroom, int tx_tailroom)
6a2968aa 914{
8ebafde0 915 struct nci_dev *ndev;
6a2968aa 916
24bf3304 917 pr_debug("supported_protocols 0x%x\n", supported_protocols);
6a2968aa
IE
918
919 if (!ops->open || !ops->close || !ops->send)
8ebafde0 920 return NULL;
6a2968aa
IE
921
922 if (!supported_protocols)
8ebafde0 923 return NULL;
6a2968aa
IE
924
925 ndev = kzalloc(sizeof(struct nci_dev), GFP_KERNEL);
926 if (!ndev)
8ebafde0 927 return NULL;
6a2968aa
IE
928
929 ndev->ops = ops;
930 ndev->tx_headroom = tx_headroom;
931 ndev->tx_tailroom = tx_tailroom;
9bec44bf 932 init_completion(&ndev->req_completion);
6a2968aa
IE
933
934 ndev->nfc_dev = nfc_allocate_device(&nci_nfc_ops,
eb9bc6e9
SO
935 supported_protocols,
936 tx_headroom + NCI_DATA_HDR_SIZE,
937 tx_tailroom);
6a2968aa
IE
938 if (!ndev->nfc_dev)
939 goto free_exit;
940
941 nfc_set_drvdata(ndev->nfc_dev, ndev);
942
8ebafde0 943 return ndev;
6a2968aa
IE
944
945free_exit:
946 kfree(ndev);
8ebafde0 947 return NULL;
6a2968aa
IE
948}
949EXPORT_SYMBOL(nci_allocate_device);
950
951/**
952 * nci_free_device - deallocate nci device
953 *
954 * @ndev: The nci device to deallocate
955 */
956void nci_free_device(struct nci_dev *ndev)
957{
6a2968aa
IE
958 nfc_free_device(ndev->nfc_dev);
959 kfree(ndev);
960}
961EXPORT_SYMBOL(nci_free_device);
962
963/**
964 * nci_register_device - register a nci device in the nfc subsystem
965 *
966 * @dev: The nci device to register
967 */
968int nci_register_device(struct nci_dev *ndev)
969{
970 int rc;
971 struct device *dev = &ndev->nfc_dev->dev;
972 char name[32];
973
6a2968aa
IE
974 ndev->flags = 0;
975
976 INIT_WORK(&ndev->cmd_work, nci_cmd_work);
977 snprintf(name, sizeof(name), "%s_nci_cmd_wq", dev_name(dev));
978 ndev->cmd_wq = create_singlethread_workqueue(name);
979 if (!ndev->cmd_wq) {
980 rc = -ENOMEM;
3c1c0f5d 981 goto exit;
6a2968aa
IE
982 }
983
984 INIT_WORK(&ndev->rx_work, nci_rx_work);
985 snprintf(name, sizeof(name), "%s_nci_rx_wq", dev_name(dev));
986 ndev->rx_wq = create_singlethread_workqueue(name);
987 if (!ndev->rx_wq) {
988 rc = -ENOMEM;
989 goto destroy_cmd_wq_exit;
990 }
991
992 INIT_WORK(&ndev->tx_work, nci_tx_work);
993 snprintf(name, sizeof(name), "%s_nci_tx_wq", dev_name(dev));
994 ndev->tx_wq = create_singlethread_workqueue(name);
995 if (!ndev->tx_wq) {
996 rc = -ENOMEM;
997 goto destroy_rx_wq_exit;
998 }
999
1000 skb_queue_head_init(&ndev->cmd_q);
1001 skb_queue_head_init(&ndev->rx_q);
1002 skb_queue_head_init(&ndev->tx_q);
1003
1004 setup_timer(&ndev->cmd_timer, nci_cmd_timer,
eb9bc6e9 1005 (unsigned long) ndev);
c4bf98b2 1006 setup_timer(&ndev->data_timer, nci_data_timer,
eb9bc6e9 1007 (unsigned long) ndev);
6a2968aa
IE
1008
1009 mutex_init(&ndev->req_lock);
4aeee687 1010 INIT_LIST_HEAD(&ndev->conn_info_list);
6a2968aa 1011
3c1c0f5d
VC
1012 rc = nfc_register_device(ndev->nfc_dev);
1013 if (rc)
1014 goto destroy_rx_wq_exit;
1015
6a2968aa
IE
1016 goto exit;
1017
1018destroy_rx_wq_exit:
1019 destroy_workqueue(ndev->rx_wq);
1020
1021destroy_cmd_wq_exit:
1022 destroy_workqueue(ndev->cmd_wq);
1023
6a2968aa
IE
1024exit:
1025 return rc;
1026}
1027EXPORT_SYMBOL(nci_register_device);
1028
1029/**
1030 * nci_unregister_device - unregister a nci device in the nfc subsystem
1031 *
1032 * @dev: The nci device to unregister
1033 */
1034void nci_unregister_device(struct nci_dev *ndev)
1035{
4aeee687
CR
1036 struct nci_conn_info *conn_info, *n;
1037
6a2968aa
IE
1038 nci_close_device(ndev);
1039
1040 destroy_workqueue(ndev->cmd_wq);
1041 destroy_workqueue(ndev->rx_wq);
1042 destroy_workqueue(ndev->tx_wq);
1043
4aeee687
CR
1044 list_for_each_entry_safe(conn_info, n, &ndev->conn_info_list, list) {
1045 list_del(&conn_info->list);
1046 /* conn_info is allocated with devm_kzalloc */
1047 }
1048
6a2968aa
IE
1049 nfc_unregister_device(ndev->nfc_dev);
1050}
1051EXPORT_SYMBOL(nci_unregister_device);
1052
1053/**
1054 * nci_recv_frame - receive frame from NCI drivers
1055 *
1095e69f 1056 * @ndev: The nci device
6a2968aa
IE
1057 * @skb: The sk_buff to receive
1058 */
1095e69f 1059int nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb)
6a2968aa 1060{
24bf3304 1061 pr_debug("len %d\n", skb->len);
6a2968aa 1062
874934f4
SJ
1063 if (!ndev || (!test_bit(NCI_UP, &ndev->flags) &&
1064 !test_bit(NCI_INIT, &ndev->flags))) {
6a2968aa
IE
1065 kfree_skb(skb);
1066 return -ENXIO;
1067 }
1068
1069 /* Queue frame for rx worker thread */
1070 skb_queue_tail(&ndev->rx_q, skb);
1071 queue_work(ndev->rx_wq, &ndev->rx_work);
1072
1073 return 0;
1074}
1075EXPORT_SYMBOL(nci_recv_frame);
1076
1095e69f 1077static int nci_send_frame(struct nci_dev *ndev, struct sk_buff *skb)
6a2968aa 1078{
24bf3304 1079 pr_debug("len %d\n", skb->len);
6a2968aa
IE
1080
1081 if (!ndev) {
1082 kfree_skb(skb);
1083 return -ENODEV;
1084 }
1085
1086 /* Get rid of skb owner, prior to sending to the driver. */
1087 skb_orphan(skb);
1088
05158296
HT
1089 /* Send copy to sniffer */
1090 nfc_send_to_raw_sock(ndev->nfc_dev, skb,
1091 RAW_PAYLOAD_NCI, NFC_DIRECTION_TX);
1092
1095e69f 1093 return ndev->ops->send(ndev, skb);
6a2968aa
IE
1094}
1095
1096/* Send NCI command */
1097int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload)
1098{
1099 struct nci_ctrl_hdr *hdr;
1100 struct sk_buff *skb;
1101
24bf3304 1102 pr_debug("opcode 0x%x, plen %d\n", opcode, plen);
6a2968aa
IE
1103
1104 skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + plen), GFP_KERNEL);
1105 if (!skb) {
ed1e0ad8 1106 pr_err("no memory for command\n");
6a2968aa
IE
1107 return -ENOMEM;
1108 }
1109
1110 hdr = (struct nci_ctrl_hdr *) skb_put(skb, NCI_CTRL_HDR_SIZE);
1111 hdr->gid = nci_opcode_gid(opcode);
1112 hdr->oid = nci_opcode_oid(opcode);
1113 hdr->plen = plen;
1114
1115 nci_mt_set((__u8 *)hdr, NCI_MT_CMD_PKT);
1116 nci_pbf_set((__u8 *)hdr, NCI_PBF_LAST);
1117
1118 if (plen)
1119 memcpy(skb_put(skb, plen), payload, plen);
1120
6a2968aa
IE
1121 skb_queue_tail(&ndev->cmd_q, skb);
1122 queue_work(ndev->cmd_wq, &ndev->cmd_work);
1123
1124 return 0;
1125}
1126
1127/* ---- NCI TX Data worker thread ---- */
1128
1129static void nci_tx_work(struct work_struct *work)
1130{
1131 struct nci_dev *ndev = container_of(work, struct nci_dev, tx_work);
4aeee687 1132 struct nci_conn_info *conn_info;
6a2968aa
IE
1133 struct sk_buff *skb;
1134
4aeee687
CR
1135 conn_info = nci_get_conn_info_by_conn_id(ndev, ndev->cur_conn_id);
1136 if (!conn_info)
1137 return;
1138
1139 pr_debug("credits_cnt %d\n", atomic_read(&conn_info->credits_cnt));
6a2968aa
IE
1140
1141 /* Send queued tx data */
4aeee687 1142 while (atomic_read(&conn_info->credits_cnt)) {
6a2968aa
IE
1143 skb = skb_dequeue(&ndev->tx_q);
1144 if (!skb)
1145 return;
1146
db98c829 1147 /* Check if data flow control is used */
4aeee687 1148 if (atomic_read(&conn_info->credits_cnt) !=
eb9bc6e9 1149 NCI_DATA_FLOW_CONTROL_NOT_USED)
4aeee687 1150 atomic_dec(&conn_info->credits_cnt);
6a2968aa 1151
20c239c1
JP
1152 pr_debug("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d\n",
1153 nci_pbf(skb->data),
1154 nci_conn_id(skb->data),
1155 nci_plen(skb->data));
6a2968aa 1156
1095e69f 1157 nci_send_frame(ndev, skb);
c4bf98b2
IE
1158
1159 mod_timer(&ndev->data_timer,
eb9bc6e9 1160 jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT));
6a2968aa
IE
1161 }
1162}
1163
1164/* ----- NCI RX worker thread (data & control) ----- */
1165
1166static void nci_rx_work(struct work_struct *work)
1167{
1168 struct nci_dev *ndev = container_of(work, struct nci_dev, rx_work);
1169 struct sk_buff *skb;
1170
1171 while ((skb = skb_dequeue(&ndev->rx_q))) {
05158296
HT
1172
1173 /* Send copy to sniffer */
1174 nfc_send_to_raw_sock(ndev->nfc_dev, skb,
1175 RAW_PAYLOAD_NCI, NFC_DIRECTION_RX);
1176
6a2968aa
IE
1177 /* Process frame */
1178 switch (nci_mt(skb->data)) {
1179 case NCI_MT_RSP_PKT:
1180 nci_rsp_packet(ndev, skb);
1181 break;
1182
1183 case NCI_MT_NTF_PKT:
1184 nci_ntf_packet(ndev, skb);
1185 break;
1186
1187 case NCI_MT_DATA_PKT:
1188 nci_rx_data_packet(ndev, skb);
1189 break;
1190
1191 default:
ed1e0ad8 1192 pr_err("unknown MT 0x%x\n", nci_mt(skb->data));
6a2968aa
IE
1193 kfree_skb(skb);
1194 break;
1195 }
1196 }
c4bf98b2
IE
1197
1198 /* check if a data exchange timout has occurred */
1199 if (test_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags)) {
1200 /* complete the data exchange transaction, if exists */
1201 if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
4aeee687
CR
1202 nci_data_exchange_complete(ndev, NULL,
1203 ndev->cur_conn_id,
1204 -ETIMEDOUT);
c4bf98b2
IE
1205
1206 clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
1207 }
6a2968aa
IE
1208}
1209
1210/* ----- NCI TX CMD worker thread ----- */
1211
1212static void nci_cmd_work(struct work_struct *work)
1213{
1214 struct nci_dev *ndev = container_of(work, struct nci_dev, cmd_work);
1215 struct sk_buff *skb;
1216
24bf3304 1217 pr_debug("cmd_cnt %d\n", atomic_read(&ndev->cmd_cnt));
6a2968aa
IE
1218
1219 /* Send queued command */
1220 if (atomic_read(&ndev->cmd_cnt)) {
1221 skb = skb_dequeue(&ndev->cmd_q);
1222 if (!skb)
1223 return;
1224
1225 atomic_dec(&ndev->cmd_cnt);
1226
20c239c1
JP
1227 pr_debug("NCI TX: MT=cmd, PBF=%d, GID=0x%x, OID=0x%x, plen=%d\n",
1228 nci_pbf(skb->data),
1229 nci_opcode_gid(nci_opcode(skb->data)),
1230 nci_opcode_oid(nci_opcode(skb->data)),
1231 nci_plen(skb->data));
6a2968aa 1232
1095e69f 1233 nci_send_frame(ndev, skb);
6a2968aa
IE
1234
1235 mod_timer(&ndev->cmd_timer,
eb9bc6e9 1236 jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT));
6a2968aa
IE
1237 }
1238}
8a70e7f8
DJ
1239
1240MODULE_LICENSE("GPL");
This page took 0.24459 seconds and 5 git commands to generate.