blob: e6b2df3981b62fd5e88d4e9637c8669bcb153cb4 [file] [log] [blame]
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +02001/*
2 * Copyright (C) 2012 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#define pr_fmt(fmt) "hci: %s: " fmt, __func__
21
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/nfc.h>
26
27#include <net/nfc/nfc.h>
28#include <net/nfc/hci.h>
29
30#include "hci.h"
31
32/* Largest headroom needed for outgoing HCI commands */
33#define HCI_CMDS_HEADROOM 1
34
Eric Lapuyade6c1c5b92012-05-03 15:35:25 +020035static int nfc_hci_result_to_errno(u8 result)
36{
37 switch (result) {
38 case NFC_HCI_ANY_OK:
39 return 0;
40 case NFC_HCI_ANY_E_TIMEOUT:
41 return -ETIME;
42 default:
43 return -1;
44 }
45}
46
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +020047static void nfc_hci_msg_tx_work(struct work_struct *work)
48{
49 struct nfc_hci_dev *hdev = container_of(work, struct nfc_hci_dev,
50 msg_tx_work);
51 struct hci_msg *msg;
52 struct sk_buff *skb;
53 int r = 0;
54
55 mutex_lock(&hdev->msg_tx_mutex);
56
57 if (hdev->cmd_pending_msg) {
58 if (timer_pending(&hdev->cmd_timer) == 0) {
59 if (hdev->cmd_pending_msg->cb)
60 hdev->cmd_pending_msg->cb(hdev,
Eric Lapuyade6c1c5b92012-05-03 15:35:25 +020061 -ETIME,
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +020062 NULL,
63 hdev->
64 cmd_pending_msg->
65 cb_context);
66 kfree(hdev->cmd_pending_msg);
67 hdev->cmd_pending_msg = NULL;
68 } else
69 goto exit;
70 }
71
72next_msg:
73 if (list_empty(&hdev->msg_tx_queue))
74 goto exit;
75
76 msg = list_first_entry(&hdev->msg_tx_queue, struct hci_msg, msg_l);
77 list_del(&msg->msg_l);
78
79 pr_debug("msg_tx_queue has a cmd to send\n");
80 while ((skb = skb_dequeue(&msg->msg_frags)) != NULL) {
81 r = hdev->ops->xmit(hdev, skb);
82 if (r < 0) {
83 kfree_skb(skb);
84 skb_queue_purge(&msg->msg_frags);
85 if (msg->cb)
Eric Lapuyade6c1c5b92012-05-03 15:35:25 +020086 msg->cb(hdev, r, NULL, msg->cb_context);
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +020087 kfree(msg);
88 break;
89 }
90 }
91
92 if (r)
93 goto next_msg;
94
95 if (msg->wait_response == false) {
96 kfree(msg);
97 goto next_msg;
98 }
99
100 hdev->cmd_pending_msg = msg;
101 mod_timer(&hdev->cmd_timer, jiffies +
102 msecs_to_jiffies(hdev->cmd_pending_msg->completion_delay));
103
104exit:
105 mutex_unlock(&hdev->msg_tx_mutex);
106}
107
108static void nfc_hci_msg_rx_work(struct work_struct *work)
109{
110 struct nfc_hci_dev *hdev = container_of(work, struct nfc_hci_dev,
111 msg_rx_work);
112 struct sk_buff *skb;
113 struct hcp_message *message;
114 u8 pipe;
115 u8 type;
116 u8 instruction;
117
118 while ((skb = skb_dequeue(&hdev->msg_rx_queue)) != NULL) {
119 pipe = skb->data[0];
120 skb_pull(skb, NFC_HCI_HCP_PACKET_HEADER_LEN);
121 message = (struct hcp_message *)skb->data;
122 type = HCP_MSG_GET_TYPE(message->header);
123 instruction = HCP_MSG_GET_CMD(message->header);
124 skb_pull(skb, NFC_HCI_HCP_MESSAGE_HEADER_LEN);
125
126 nfc_hci_hcp_message_rx(hdev, pipe, type, instruction, skb);
127 }
128}
129
Eric Lapuyadeccca0d62012-05-03 15:59:37 +0200130static void __nfc_hci_cmd_completion(struct nfc_hci_dev *hdev, int err,
131 struct sk_buff *skb)
132{
133 del_timer_sync(&hdev->cmd_timer);
134
135 if (hdev->cmd_pending_msg->cb)
136 hdev->cmd_pending_msg->cb(hdev, err, skb,
137 hdev->cmd_pending_msg->cb_context);
138 else
139 kfree_skb(skb);
140
141 kfree(hdev->cmd_pending_msg);
142 hdev->cmd_pending_msg = NULL;
143
144 queue_work(hdev->msg_tx_wq, &hdev->msg_tx_work);
145}
146
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200147void nfc_hci_resp_received(struct nfc_hci_dev *hdev, u8 result,
148 struct sk_buff *skb)
149{
150 mutex_lock(&hdev->msg_tx_mutex);
151
152 if (hdev->cmd_pending_msg == NULL) {
153 kfree_skb(skb);
154 goto exit;
155 }
156
Eric Lapuyadeccca0d62012-05-03 15:59:37 +0200157 __nfc_hci_cmd_completion(hdev, nfc_hci_result_to_errno(result), skb);
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200158
159exit:
160 mutex_unlock(&hdev->msg_tx_mutex);
161}
162
163void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
164 struct sk_buff *skb)
165{
166 kfree_skb(skb);
167}
168
169static u32 nfc_hci_sak_to_protocol(u8 sak)
170{
171 switch (NFC_HCI_TYPE_A_SEL_PROT(sak)) {
172 case NFC_HCI_TYPE_A_SEL_PROT_MIFARE:
173 return NFC_PROTO_MIFARE_MASK;
174 case NFC_HCI_TYPE_A_SEL_PROT_ISO14443:
175 return NFC_PROTO_ISO14443_MASK;
176 case NFC_HCI_TYPE_A_SEL_PROT_DEP:
177 return NFC_PROTO_NFC_DEP_MASK;
178 case NFC_HCI_TYPE_A_SEL_PROT_ISO14443_DEP:
179 return NFC_PROTO_ISO14443_MASK | NFC_PROTO_NFC_DEP_MASK;
180 default:
181 return 0xffffffff;
182 }
183}
184
185static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate)
186{
187 struct nfc_target *targets;
188 struct sk_buff *atqa_skb = NULL;
189 struct sk_buff *sak_skb = NULL;
190 int r;
191
192 pr_debug("from gate %d\n", gate);
193
194 targets = kzalloc(sizeof(struct nfc_target), GFP_KERNEL);
195 if (targets == NULL)
196 return -ENOMEM;
197
198 switch (gate) {
199 case NFC_HCI_RF_READER_A_GATE:
200 r = nfc_hci_get_param(hdev, NFC_HCI_RF_READER_A_GATE,
201 NFC_HCI_RF_READER_A_ATQA, &atqa_skb);
202 if (r < 0)
203 goto exit;
204
205 r = nfc_hci_get_param(hdev, NFC_HCI_RF_READER_A_GATE,
206 NFC_HCI_RF_READER_A_SAK, &sak_skb);
207 if (r < 0)
208 goto exit;
209
210 if (atqa_skb->len != 2 || sak_skb->len != 1) {
211 r = -EPROTO;
212 goto exit;
213 }
214
215 targets->supported_protocols =
216 nfc_hci_sak_to_protocol(sak_skb->data[0]);
217 if (targets->supported_protocols == 0xffffffff) {
218 r = -EPROTO;
219 goto exit;
220 }
221
222 targets->sens_res = be16_to_cpu(*(u16 *)atqa_skb->data);
223 targets->sel_res = sak_skb->data[0];
224
225 if (hdev->ops->complete_target_discovered) {
226 r = hdev->ops->complete_target_discovered(hdev, gate,
227 targets);
228 if (r < 0)
229 goto exit;
230 }
231 break;
232 case NFC_HCI_RF_READER_B_GATE:
233 targets->supported_protocols = NFC_PROTO_ISO14443_MASK;
234 break;
235 default:
236 if (hdev->ops->target_from_gate)
237 r = hdev->ops->target_from_gate(hdev, gate, targets);
238 else
239 r = -EPROTO;
240 if (r < 0)
241 goto exit;
242
243 if (hdev->ops->complete_target_discovered) {
244 r = hdev->ops->complete_target_discovered(hdev, gate,
245 targets);
246 if (r < 0)
247 goto exit;
248 }
249 break;
250 }
251
252 targets->hci_reader_gate = gate;
253
254 r = nfc_targets_found(hdev->ndev, targets, 1);
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200255
256exit:
257 kfree(targets);
258 kfree_skb(atqa_skb);
259 kfree_skb(sak_skb);
260
261 return r;
262}
263
264void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event,
265 struct sk_buff *skb)
266{
267 int r = 0;
268
269 switch (event) {
270 case NFC_HCI_EVT_TARGET_DISCOVERED:
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200271 if (skb->len < 1) { /* no status data? */
272 r = -EPROTO;
273 goto exit;
274 }
275
276 if (skb->data[0] == 3) {
277 /* TODO: Multiple targets in field, none activated
278 * poll is supposedly stopped, but there is no
279 * single target to activate, so nothing to report
280 * up.
281 * if we need to restart poll, we must save the
282 * protocols from the initial poll and reuse here.
283 */
284 }
285
286 if (skb->data[0] != 0) {
287 r = -EPROTO;
288 goto exit;
289 }
290
291 r = nfc_hci_target_discovered(hdev,
292 nfc_hci_pipe2gate(hdev, pipe));
293 break;
294 default:
295 /* TODO: Unknown events are hardware specific
296 * pass them to the driver (needs a new hci_ops) */
297 break;
298 }
299
300exit:
301 kfree_skb(skb);
302
303 if (r) {
304 /* TODO: There was an error dispatching the event,
305 * how to propagate up to nfc core?
306 */
307 }
308}
309
310static void nfc_hci_cmd_timeout(unsigned long data)
311{
312 struct nfc_hci_dev *hdev = (struct nfc_hci_dev *)data;
313
314 queue_work(hdev->msg_tx_wq, &hdev->msg_tx_work);
315}
316
317static int hci_dev_connect_gates(struct nfc_hci_dev *hdev, u8 gate_count,
318 u8 gates[])
319{
320 int r;
321 u8 *p = gates;
322 while (gate_count--) {
323 r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID, *p);
324 if (r < 0)
325 return r;
326 p++;
327 }
328
329 return 0;
330}
331
332static int hci_dev_session_init(struct nfc_hci_dev *hdev)
333{
334 struct sk_buff *skb = NULL;
335 int r;
336 u8 hci_gates[] = { /* NFC_HCI_ADMIN_GATE MUST be first */
337 NFC_HCI_ADMIN_GATE, NFC_HCI_LOOPBACK_GATE,
338 NFC_HCI_ID_MGMT_GATE, NFC_HCI_LINK_MGMT_GATE,
339 NFC_HCI_RF_READER_B_GATE, NFC_HCI_RF_READER_A_GATE
340 };
341
342 r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID,
343 NFC_HCI_ADMIN_GATE);
344 if (r < 0)
345 goto exit;
346
347 r = nfc_hci_get_param(hdev, NFC_HCI_ADMIN_GATE,
348 NFC_HCI_ADMIN_SESSION_IDENTITY, &skb);
349 if (r < 0)
350 goto disconnect_all;
351
352 if (skb->len && skb->len == strlen(hdev->init_data.session_id))
353 if (memcmp(hdev->init_data.session_id, skb->data,
354 skb->len) == 0) {
355 /* TODO ELa: restore gate<->pipe table from
356 * some TBD location.
357 * note: it doesn't seem possible to get the chip
358 * currently open gate/pipe table.
359 * It is only possible to obtain the supported
360 * gate list.
361 */
362
363 /* goto exit
364 * For now, always do a full initialization */
365 }
366
367 r = nfc_hci_disconnect_all_gates(hdev);
368 if (r < 0)
369 goto exit;
370
371 r = hci_dev_connect_gates(hdev, sizeof(hci_gates), hci_gates);
372 if (r < 0)
373 goto disconnect_all;
374
375 r = hci_dev_connect_gates(hdev, hdev->init_data.gate_count,
376 hdev->init_data.gates);
377 if (r < 0)
378 goto disconnect_all;
379
380 r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE,
381 NFC_HCI_ADMIN_SESSION_IDENTITY,
382 hdev->init_data.session_id,
383 strlen(hdev->init_data.session_id));
384 if (r == 0)
385 goto exit;
386
387disconnect_all:
388 nfc_hci_disconnect_all_gates(hdev);
389
390exit:
391 if (skb)
392 kfree_skb(skb);
393
394 return r;
395}
396
397static int hci_dev_version(struct nfc_hci_dev *hdev)
398{
399 int r;
400 struct sk_buff *skb;
401
402 r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE,
403 NFC_HCI_ID_MGMT_VERSION_SW, &skb);
404 if (r < 0)
405 return r;
406
407 if (skb->len != 3) {
408 kfree_skb(skb);
409 return -EINVAL;
410 }
411
412 hdev->sw_romlib = (skb->data[0] & 0xf0) >> 4;
413 hdev->sw_patch = skb->data[0] & 0x0f;
414 hdev->sw_flashlib_major = skb->data[1];
415 hdev->sw_flashlib_minor = skb->data[2];
416
417 kfree_skb(skb);
418
419 r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE,
420 NFC_HCI_ID_MGMT_VERSION_HW, &skb);
421 if (r < 0)
422 return r;
423
424 if (skb->len != 3) {
425 kfree_skb(skb);
426 return -EINVAL;
427 }
428
429 hdev->hw_derivative = (skb->data[0] & 0xe0) >> 5;
430 hdev->hw_version = skb->data[0] & 0x1f;
431 hdev->hw_mpw = (skb->data[1] & 0xc0) >> 6;
432 hdev->hw_software = skb->data[1] & 0x3f;
433 hdev->hw_bsid = skb->data[2];
434
435 kfree_skb(skb);
436
437 pr_info("SOFTWARE INFO:\n");
438 pr_info("RomLib : %d\n", hdev->sw_romlib);
439 pr_info("Patch : %d\n", hdev->sw_patch);
440 pr_info("FlashLib Major : %d\n", hdev->sw_flashlib_major);
441 pr_info("FlashLib Minor : %d\n", hdev->sw_flashlib_minor);
442 pr_info("HARDWARE INFO:\n");
443 pr_info("Derivative : %d\n", hdev->hw_derivative);
444 pr_info("HW Version : %d\n", hdev->hw_version);
445 pr_info("#MPW : %d\n", hdev->hw_mpw);
446 pr_info("Software : %d\n", hdev->hw_software);
447 pr_info("BSID Version : %d\n", hdev->hw_bsid);
448
449 return 0;
450}
451
452static int hci_dev_up(struct nfc_dev *nfc_dev)
453{
454 struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
455 int r = 0;
456
457 if (hdev->ops->open) {
458 r = hdev->ops->open(hdev);
459 if (r < 0)
460 return r;
461 }
462
463 r = hci_dev_session_init(hdev);
464 if (r < 0)
465 goto exit;
466
467 r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
468 NFC_HCI_EVT_END_OPERATION, NULL, 0);
469 if (r < 0)
470 goto exit;
471
472 if (hdev->ops->hci_ready) {
473 r = hdev->ops->hci_ready(hdev);
474 if (r < 0)
475 goto exit;
476 }
477
478 r = hci_dev_version(hdev);
479 if (r < 0)
480 goto exit;
481
482exit:
483 if (r < 0)
484 if (hdev->ops->close)
485 hdev->ops->close(hdev);
486 return r;
487}
488
489static int hci_dev_down(struct nfc_dev *nfc_dev)
490{
491 struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
492
493 if (hdev->ops->close)
494 hdev->ops->close(hdev);
495
496 memset(hdev->gate2pipe, NFC_HCI_INVALID_PIPE, sizeof(hdev->gate2pipe));
497
498 return 0;
499}
500
Samuel Ortizfe7c5802012-05-15 15:57:06 +0200501static int hci_start_poll(struct nfc_dev *nfc_dev,
502 u32 im_protocols, u32 tm_protocols)
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200503{
504 struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200505
506 if (hdev->ops->start_poll)
Samuel Ortizfe7c5802012-05-15 15:57:06 +0200507 return hdev->ops->start_poll(hdev, im_protocols, tm_protocols);
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200508 else
Eric Lapuyade03bed292012-05-07 12:31:31 +0200509 return nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200510 NFC_HCI_EVT_READER_REQUESTED, NULL, 0);
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200511}
512
513static void hci_stop_poll(struct nfc_dev *nfc_dev)
514{
515 struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
516
Eric Lapuyade03bed292012-05-07 12:31:31 +0200517 nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
518 NFC_HCI_EVT_END_OPERATION, NULL, 0);
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200519}
520
Eric Lapuyade90099432012-05-07 12:31:13 +0200521static int hci_activate_target(struct nfc_dev *nfc_dev,
522 struct nfc_target *target, u32 protocol)
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200523{
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200524 return 0;
525}
526
Eric Lapuyade90099432012-05-07 12:31:13 +0200527static void hci_deactivate_target(struct nfc_dev *nfc_dev,
528 struct nfc_target *target)
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200529{
530}
531
Samuel Ortizbe9ae4c2012-05-16 15:55:48 +0200532static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
533 struct sk_buff *skb, data_exchange_cb_t cb,
534 void *cb_context)
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200535{
536 struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
537 int r;
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200538 struct sk_buff *res_skb = NULL;
539
Eric Lapuyade90099432012-05-07 12:31:13 +0200540 pr_debug("target_idx=%d\n", target->idx);
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200541
542 switch (target->hci_reader_gate) {
543 case NFC_HCI_RF_READER_A_GATE:
544 case NFC_HCI_RF_READER_B_GATE:
545 if (hdev->ops->data_exchange) {
546 r = hdev->ops->data_exchange(hdev, target, skb,
547 &res_skb);
548 if (r <= 0) /* handled */
549 break;
550 }
551
552 *skb_push(skb, 1) = 0; /* CTR, see spec:10.2.2.1 */
553 r = nfc_hci_send_cmd(hdev, target->hci_reader_gate,
554 NFC_HCI_WR_XCHG_DATA,
555 skb->data, skb->len, &res_skb);
556 /*
557 * TODO: Check RF Error indicator to make sure data is valid.
558 * It seems that HCI cmd can complete without error, but data
559 * can be invalid if an RF error occured? Ignore for now.
560 */
561 if (r == 0)
562 skb_trim(res_skb, res_skb->len - 1); /* RF Err ind */
563 break;
564 default:
565 if (hdev->ops->data_exchange) {
566 r = hdev->ops->data_exchange(hdev, target, skb,
567 &res_skb);
568 if (r == 1)
569 r = -ENOTSUPP;
570 }
571 else
572 r = -ENOTSUPP;
573 }
574
575 kfree_skb(skb);
576
577 cb(cb_context, res_skb, r);
578
579 return 0;
580}
581
Eric Lapuyade1676f752012-05-07 12:31:16 +0200582static int hci_check_presence(struct nfc_dev *nfc_dev,
583 struct nfc_target *target)
584{
585 struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
586
587 if (hdev->ops->check_presence)
588 return hdev->ops->check_presence(hdev, target);
589
590 return 0;
591}
592
H Hartley Sweetenbd007be2012-05-07 12:31:27 +0200593static struct nfc_ops hci_nfc_ops = {
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200594 .dev_up = hci_dev_up,
595 .dev_down = hci_dev_down,
596 .start_poll = hci_start_poll,
597 .stop_poll = hci_stop_poll,
598 .activate_target = hci_activate_target,
599 .deactivate_target = hci_deactivate_target,
Samuel Ortizbe9ae4c2012-05-16 15:55:48 +0200600 .im_transceive = hci_transceive,
Eric Lapuyade1676f752012-05-07 12:31:16 +0200601 .check_presence = hci_check_presence,
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200602};
603
604struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops,
605 struct nfc_hci_init_data *init_data,
606 u32 protocols,
607 int tx_headroom,
608 int tx_tailroom,
609 int max_link_payload)
610{
611 struct nfc_hci_dev *hdev;
612
613 if (ops->xmit == NULL)
614 return NULL;
615
616 if (protocols == 0)
617 return NULL;
618
619 hdev = kzalloc(sizeof(struct nfc_hci_dev), GFP_KERNEL);
620 if (hdev == NULL)
621 return NULL;
622
623 hdev->ndev = nfc_allocate_device(&hci_nfc_ops, protocols,
624 tx_headroom + HCI_CMDS_HEADROOM,
625 tx_tailroom);
626 if (!hdev->ndev) {
627 kfree(hdev);
628 return NULL;
629 }
630
631 hdev->ops = ops;
632 hdev->max_data_link_payload = max_link_payload;
633 hdev->init_data = *init_data;
634
635 nfc_set_drvdata(hdev->ndev, hdev);
636
637 memset(hdev->gate2pipe, NFC_HCI_INVALID_PIPE, sizeof(hdev->gate2pipe));
638
639 return hdev;
640}
641EXPORT_SYMBOL(nfc_hci_allocate_device);
642
643void nfc_hci_free_device(struct nfc_hci_dev *hdev)
644{
645 nfc_free_device(hdev->ndev);
646 kfree(hdev);
647}
648EXPORT_SYMBOL(nfc_hci_free_device);
649
650int nfc_hci_register_device(struct nfc_hci_dev *hdev)
651{
652 struct device *dev = &hdev->ndev->dev;
653 const char *devname = dev_name(dev);
654 char name[32];
655 int r = 0;
656
657 mutex_init(&hdev->msg_tx_mutex);
658
659 INIT_LIST_HEAD(&hdev->msg_tx_queue);
660
661 INIT_WORK(&hdev->msg_tx_work, nfc_hci_msg_tx_work);
662 snprintf(name, sizeof(name), "%s_hci_msg_tx_wq", devname);
663 hdev->msg_tx_wq = alloc_workqueue(name, WQ_NON_REENTRANT | WQ_UNBOUND |
664 WQ_MEM_RECLAIM, 1);
665 if (hdev->msg_tx_wq == NULL) {
666 r = -ENOMEM;
667 goto exit;
668 }
669
670 init_timer(&hdev->cmd_timer);
671 hdev->cmd_timer.data = (unsigned long)hdev;
672 hdev->cmd_timer.function = nfc_hci_cmd_timeout;
673
674 skb_queue_head_init(&hdev->rx_hcp_frags);
675
676 INIT_WORK(&hdev->msg_rx_work, nfc_hci_msg_rx_work);
677 snprintf(name, sizeof(name), "%s_hci_msg_rx_wq", devname);
678 hdev->msg_rx_wq = alloc_workqueue(name, WQ_NON_REENTRANT | WQ_UNBOUND |
679 WQ_MEM_RECLAIM, 1);
680 if (hdev->msg_rx_wq == NULL) {
681 r = -ENOMEM;
682 goto exit;
683 }
684
685 skb_queue_head_init(&hdev->msg_rx_queue);
686
687 r = nfc_register_device(hdev->ndev);
688
689exit:
690 if (r < 0) {
691 if (hdev->msg_tx_wq)
692 destroy_workqueue(hdev->msg_tx_wq);
693 if (hdev->msg_rx_wq)
694 destroy_workqueue(hdev->msg_rx_wq);
695 }
696
697 return r;
698}
699EXPORT_SYMBOL(nfc_hci_register_device);
700
701void nfc_hci_unregister_device(struct nfc_hci_dev *hdev)
702{
703 struct hci_msg *msg;
704
705 skb_queue_purge(&hdev->rx_hcp_frags);
706 skb_queue_purge(&hdev->msg_rx_queue);
707
708 while ((msg = list_first_entry(&hdev->msg_tx_queue, struct hci_msg,
709 msg_l)) != NULL) {
710 list_del(&msg->msg_l);
711 skb_queue_purge(&msg->msg_frags);
712 kfree(msg);
713 }
714
715 del_timer_sync(&hdev->cmd_timer);
716
717 nfc_unregister_device(hdev->ndev);
718
719 destroy_workqueue(hdev->msg_tx_wq);
720
721 destroy_workqueue(hdev->msg_rx_wq);
722}
723EXPORT_SYMBOL(nfc_hci_unregister_device);
724
725void nfc_hci_set_clientdata(struct nfc_hci_dev *hdev, void *clientdata)
726{
727 hdev->clientdata = clientdata;
728}
729EXPORT_SYMBOL(nfc_hci_set_clientdata);
730
731void *nfc_hci_get_clientdata(struct nfc_hci_dev *hdev)
732{
733 return hdev->clientdata;
734}
735EXPORT_SYMBOL(nfc_hci_get_clientdata);
736
Eric Lapuyade72b06f72012-06-11 13:36:52 +0200737static void nfc_hci_failure(struct nfc_hci_dev *hdev, int err)
Eric Lapuyadea9a741a2012-04-30 18:21:51 +0200738{
Eric Lapuyadea070c852012-06-11 15:06:56 +0200739 mutex_lock(&hdev->msg_tx_mutex);
740
741 if (hdev->cmd_pending_msg == NULL) {
742 nfc_driver_failure(hdev->ndev, err);
743 goto exit;
744 }
745
746 __nfc_hci_cmd_completion(hdev, err, NULL);
747
748exit:
749 mutex_unlock(&hdev->msg_tx_mutex);
Eric Lapuyadea9a741a2012-04-30 18:21:51 +0200750}
Eric Lapuyade72b06f72012-06-11 13:36:52 +0200751
752void nfc_hci_driver_failure(struct nfc_hci_dev *hdev, int err)
753{
754 nfc_hci_failure(hdev, err);
755}
Eric Lapuyadea9a741a2012-04-30 18:21:51 +0200756EXPORT_SYMBOL(nfc_hci_driver_failure);
757
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200758void nfc_hci_recv_frame(struct nfc_hci_dev *hdev, struct sk_buff *skb)
759{
760 struct hcp_packet *packet;
761 u8 type;
762 u8 instruction;
763 struct sk_buff *hcp_skb;
764 u8 pipe;
765 struct sk_buff *frag_skb;
766 int msg_len;
767
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200768 packet = (struct hcp_packet *)skb->data;
769 if ((packet->header & ~NFC_HCI_FRAGMENT) == 0) {
770 skb_queue_tail(&hdev->rx_hcp_frags, skb);
771 return;
772 }
773
774 /* it's the last fragment. Does it need re-aggregation? */
775 if (skb_queue_len(&hdev->rx_hcp_frags)) {
776 pipe = packet->header & NFC_HCI_FRAGMENT;
777 skb_queue_tail(&hdev->rx_hcp_frags, skb);
778
779 msg_len = 0;
780 skb_queue_walk(&hdev->rx_hcp_frags, frag_skb) {
781 msg_len += (frag_skb->len -
782 NFC_HCI_HCP_PACKET_HEADER_LEN);
783 }
784
785 hcp_skb = nfc_alloc_recv_skb(NFC_HCI_HCP_PACKET_HEADER_LEN +
786 msg_len, GFP_KERNEL);
787 if (hcp_skb == NULL) {
Eric Lapuyade72b06f72012-06-11 13:36:52 +0200788 nfc_hci_failure(hdev, -ENOMEM);
789 return;
Eric Lapuyade8b8d2e02012-04-10 19:43:06 +0200790 }
791
792 *skb_put(hcp_skb, NFC_HCI_HCP_PACKET_HEADER_LEN) = pipe;
793
794 skb_queue_walk(&hdev->rx_hcp_frags, frag_skb) {
795 msg_len = frag_skb->len - NFC_HCI_HCP_PACKET_HEADER_LEN;
796 memcpy(skb_put(hcp_skb, msg_len),
797 frag_skb->data + NFC_HCI_HCP_PACKET_HEADER_LEN,
798 msg_len);
799 }
800
801 skb_queue_purge(&hdev->rx_hcp_frags);
802 } else {
803 packet->header &= NFC_HCI_FRAGMENT;
804 hcp_skb = skb;
805 }
806
807 /* if this is a response, dispatch immediately to
808 * unblock waiting cmd context. Otherwise, enqueue to dispatch
809 * in separate context where handler can also execute command.
810 */
811 packet = (struct hcp_packet *)hcp_skb->data;
812 type = HCP_MSG_GET_TYPE(packet->message.header);
813 if (type == NFC_HCI_HCP_RESPONSE) {
814 pipe = packet->header;
815 instruction = HCP_MSG_GET_CMD(packet->message.header);
816 skb_pull(hcp_skb, NFC_HCI_HCP_PACKET_HEADER_LEN +
817 NFC_HCI_HCP_MESSAGE_HEADER_LEN);
818 nfc_hci_hcp_message_rx(hdev, pipe, type, instruction, hcp_skb);
819 } else {
820 skb_queue_tail(&hdev->msg_rx_queue, hcp_skb);
821 queue_work(hdev->msg_rx_wq, &hdev->msg_rx_work);
822 }
823}
824EXPORT_SYMBOL(nfc_hci_recv_frame);
825
826MODULE_LICENSE("GPL");