NFC Digital: Add NFC-A technology support
[deliverable/linux.git] / net / nfc / digital_core.c
CommitLineData
4b10884e
TE
1/*
2 * NFC Digital Protocol stack
3 * Copyright (c) 2013, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 */
15
16#include <linux/module.h>
17
18#include "digital.h"
19
59ee2361
TE
20#define DIGITAL_PROTO_NFCA_RF_TECH \
21 (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK)
22
23struct digital_cmd {
24 struct list_head queue;
25
26 u8 type;
27 u8 pending;
28
29 u16 timeout;
30 struct sk_buff *req;
31 struct sk_buff *resp;
32
33 nfc_digital_cmd_complete_t cmd_cb;
34 void *cb_context;
35};
36
37struct sk_buff *digital_skb_alloc(struct nfc_digital_dev *ddev,
38 unsigned int len)
39{
40 struct sk_buff *skb;
41
42 skb = alloc_skb(len + ddev->tx_headroom + ddev->tx_tailroom,
43 GFP_KERNEL);
44 if (skb)
45 skb_reserve(skb, ddev->tx_headroom);
46
47 return skb;
48}
49
2c66daec
TE
50void digital_skb_add_crc(struct sk_buff *skb, crc_func_t crc_func, u16 init,
51 u8 bitwise_inv, u8 msb_first)
52{
53 u16 crc;
54
55 crc = crc_func(init, skb->data, skb->len);
56
57 if (bitwise_inv)
58 crc = ~crc;
59
60 if (msb_first)
61 crc = __fswab16(crc);
62
63 *skb_put(skb, 1) = crc & 0xFF;
64 *skb_put(skb, 1) = (crc >> 8) & 0xFF;
65}
66
67int digital_skb_check_crc(struct sk_buff *skb, crc_func_t crc_func,
68 u16 crc_init, u8 bitwise_inv, u8 msb_first)
69{
70 int rc;
71 u16 crc;
72
73 if (skb->len <= 2)
74 return -EIO;
75
76 crc = crc_func(crc_init, skb->data, skb->len - 2);
77
78 if (bitwise_inv)
79 crc = ~crc;
80
81 if (msb_first)
82 crc = __swab16(crc);
83
84 rc = (skb->data[skb->len - 2] - (crc & 0xFF)) +
85 (skb->data[skb->len - 1] - ((crc >> 8) & 0xFF));
86
87 if (rc)
88 return -EIO;
89
90 skb_trim(skb, skb->len - 2);
91
92 return 0;
93}
94
59ee2361
TE
95static inline void digital_switch_rf(struct nfc_digital_dev *ddev, bool on)
96{
97 ddev->ops->switch_rf(ddev, on);
98}
99
100static inline void digital_abort_cmd(struct nfc_digital_dev *ddev)
101{
102 ddev->ops->abort_cmd(ddev);
103}
104
105static void digital_wq_cmd_complete(struct work_struct *work)
106{
107 struct digital_cmd *cmd;
108 struct nfc_digital_dev *ddev = container_of(work,
109 struct nfc_digital_dev,
110 cmd_complete_work);
111
112 mutex_lock(&ddev->cmd_lock);
113
114 cmd = list_first_entry_or_null(&ddev->cmd_queue, struct digital_cmd,
115 queue);
116 if (!cmd) {
117 mutex_unlock(&ddev->cmd_lock);
118 return;
119 }
120
121 list_del(&cmd->queue);
122
123 mutex_unlock(&ddev->cmd_lock);
124
125 if (!IS_ERR(cmd->resp))
126 print_hex_dump_debug("DIGITAL RX: ", DUMP_PREFIX_NONE, 16, 1,
127 cmd->resp->data, cmd->resp->len, false);
128
129 cmd->cmd_cb(ddev, cmd->cb_context, cmd->resp);
130
131 kfree(cmd);
132
133 schedule_work(&ddev->cmd_work);
134}
135
136static void digital_send_cmd_complete(struct nfc_digital_dev *ddev,
137 void *arg, struct sk_buff *resp)
138{
139 struct digital_cmd *cmd = arg;
140
141 cmd->resp = resp;
142
143 schedule_work(&ddev->cmd_complete_work);
144}
145
146static void digital_wq_cmd(struct work_struct *work)
147{
148 int rc;
149 struct digital_cmd *cmd;
150 struct nfc_digital_dev *ddev = container_of(work,
151 struct nfc_digital_dev,
152 cmd_work);
153
154 mutex_lock(&ddev->cmd_lock);
155
156 cmd = list_first_entry_or_null(&ddev->cmd_queue, struct digital_cmd,
157 queue);
158 if (!cmd || cmd->pending) {
159 mutex_unlock(&ddev->cmd_lock);
160 return;
161 }
162
163 mutex_unlock(&ddev->cmd_lock);
164
165 if (cmd->req)
166 print_hex_dump_debug("DIGITAL TX: ", DUMP_PREFIX_NONE, 16, 1,
167 cmd->req->data, cmd->req->len, false);
168
169 switch (cmd->type) {
170 case DIGITAL_CMD_IN_SEND:
171 rc = ddev->ops->in_send_cmd(ddev, cmd->req, cmd->timeout,
172 digital_send_cmd_complete, cmd);
173 break;
174 default:
175 PR_ERR("Unknown cmd type %d", cmd->type);
176 return;
177 }
178
179 if (!rc)
180 return;
181
182 PR_ERR("in_send_command returned err %d", rc);
183
184 mutex_lock(&ddev->cmd_lock);
185 list_del(&cmd->queue);
186 mutex_unlock(&ddev->cmd_lock);
187
188 kfree_skb(cmd->req);
189 kfree(cmd);
190
191 schedule_work(&ddev->cmd_work);
192}
193
194int digital_send_cmd(struct nfc_digital_dev *ddev, u8 cmd_type,
195 struct sk_buff *skb, u16 timeout,
196 nfc_digital_cmd_complete_t cmd_cb, void *cb_context)
197{
198 struct digital_cmd *cmd;
199
200 cmd = kzalloc(sizeof(struct digital_cmd), GFP_KERNEL);
201 if (!cmd)
202 return -ENOMEM;
203
204 cmd->type = cmd_type;
205 cmd->timeout = timeout;
206 cmd->req = skb;
207 cmd->cmd_cb = cmd_cb;
208 cmd->cb_context = cb_context;
209 INIT_LIST_HEAD(&cmd->queue);
210
211 mutex_lock(&ddev->cmd_lock);
212 list_add_tail(&cmd->queue, &ddev->cmd_queue);
213 mutex_unlock(&ddev->cmd_lock);
214
215 schedule_work(&ddev->cmd_work);
216
217 return 0;
218}
219
220int digital_in_configure_hw(struct nfc_digital_dev *ddev, int type, int param)
221{
222 int rc;
223
224 rc = ddev->ops->in_configure_hw(ddev, type, param);
225 if (rc)
226 PR_ERR("in_configure_hw failed: %d", rc);
227
228 return rc;
229}
230
2c66daec
TE
231int digital_target_found(struct nfc_digital_dev *ddev,
232 struct nfc_target *target, u8 protocol)
233{
234 int rc;
235 u8 framing;
236 u8 rf_tech;
237 int (*check_crc)(struct sk_buff *skb);
238 void (*add_crc)(struct sk_buff *skb);
239
240 rf_tech = ddev->poll_techs[ddev->poll_tech_index].rf_tech;
241
242 switch (protocol) {
243 case NFC_PROTO_JEWEL:
244 framing = NFC_DIGITAL_FRAMING_NFCA_T1T;
245 check_crc = digital_skb_check_crc_b;
246 add_crc = digital_skb_add_crc_b;
247 break;
248
249 case NFC_PROTO_MIFARE:
250 framing = NFC_DIGITAL_FRAMING_NFCA_T2T;
251 check_crc = digital_skb_check_crc_a;
252 add_crc = digital_skb_add_crc_a;
253 break;
254
255 default:
256 PR_ERR("Invalid protocol %d", protocol);
257 return -EINVAL;
258 }
259
260 PR_DBG("rf_tech=%d, protocol=%d", rf_tech, protocol);
261
262 ddev->curr_rf_tech = rf_tech;
263 ddev->curr_protocol = protocol;
264
265 if (DIGITAL_DRV_CAPS_IN_CRC(ddev)) {
266 ddev->skb_add_crc = digital_skb_add_crc_none;
267 ddev->skb_check_crc = digital_skb_check_crc_none;
268 } else {
269 ddev->skb_add_crc = add_crc;
270 ddev->skb_check_crc = check_crc;
271 }
272
273 rc = digital_in_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, framing);
274 if (rc)
275 return rc;
276
277 target->supported_protocols = (1 << protocol);
278 rc = nfc_targets_found(ddev->nfc_dev, target, 1);
279 if (rc)
280 return rc;
281
282 ddev->poll_tech_count = 0;
283
284 return 0;
285}
286
59ee2361
TE
287void digital_poll_next_tech(struct nfc_digital_dev *ddev)
288{
289 digital_switch_rf(ddev, 0);
290
291 mutex_lock(&ddev->poll_lock);
292
293 if (!ddev->poll_tech_count) {
294 mutex_unlock(&ddev->poll_lock);
295 return;
296 }
297
298 ddev->poll_tech_index = (ddev->poll_tech_index + 1) %
299 ddev->poll_tech_count;
300
301 mutex_unlock(&ddev->poll_lock);
302
303 schedule_work(&ddev->poll_work);
304}
305
306static void digital_wq_poll(struct work_struct *work)
307{
308 int rc;
309 struct digital_poll_tech *poll_tech;
310 struct nfc_digital_dev *ddev = container_of(work,
311 struct nfc_digital_dev,
312 poll_work);
313 mutex_lock(&ddev->poll_lock);
314
315 if (!ddev->poll_tech_count) {
316 mutex_unlock(&ddev->poll_lock);
317 return;
318 }
319
320 poll_tech = &ddev->poll_techs[ddev->poll_tech_index];
321
322 mutex_unlock(&ddev->poll_lock);
323
324 rc = poll_tech->poll_func(ddev, poll_tech->rf_tech);
325 if (rc)
326 digital_poll_next_tech(ddev);
327}
328
329static void digital_add_poll_tech(struct nfc_digital_dev *ddev, u8 rf_tech,
330 digital_poll_t poll_func)
331{
332 struct digital_poll_tech *poll_tech;
333
334 if (ddev->poll_tech_count >= NFC_DIGITAL_POLL_MODE_COUNT_MAX)
335 return;
336
337 poll_tech = &ddev->poll_techs[ddev->poll_tech_count++];
338
339 poll_tech->rf_tech = rf_tech;
340 poll_tech->poll_func = poll_func;
341}
342
343/**
344 * start_poll operation
345 *
346 * For every supported protocol, the corresponding polling function is added
347 * to the table of polling technologies (ddev->poll_techs[]) using
348 * digital_add_poll_tech().
349 * When a polling function fails (by timeout or protocol error) the next one is
350 * schedule by digital_poll_next_tech() on the poll workqueue (ddev->poll_work).
351 */
4b10884e
TE
352static int digital_start_poll(struct nfc_dev *nfc_dev, __u32 im_protocols,
353 __u32 tm_protocols)
354{
59ee2361
TE
355 struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);
356 u32 matching_im_protocols, matching_tm_protocols;
357
358 PR_DBG("protocols: im 0x%x, tm 0x%x, supported 0x%x", im_protocols,
359 tm_protocols, ddev->protocols);
360
361 matching_im_protocols = ddev->protocols & im_protocols;
362 matching_tm_protocols = ddev->protocols & tm_protocols;
363
364 if (!matching_im_protocols && !matching_tm_protocols) {
365 PR_ERR("No known protocol");
366 return -EINVAL;
367 }
368
369 if (ddev->poll_tech_count) {
370 PR_ERR("Already polling");
371 return -EBUSY;
372 }
373
374 if (ddev->curr_protocol) {
375 PR_ERR("A target is already active");
376 return -EBUSY;
377 }
378
379 ddev->poll_tech_count = 0;
380 ddev->poll_tech_index = 0;
381
382 if (matching_im_protocols & DIGITAL_PROTO_NFCA_RF_TECH)
383 digital_add_poll_tech(ddev, NFC_DIGITAL_RF_TECH_106A,
384 digital_in_send_sens_req);
385
386 if (!ddev->poll_tech_count) {
387 PR_ERR("Unsupported protocols: im=0x%x, tm=0x%x",
388 matching_im_protocols, matching_tm_protocols);
389 return -EINVAL;
390 }
391
392 schedule_work(&ddev->poll_work);
393
394 return 0;
4b10884e
TE
395}
396
397static void digital_stop_poll(struct nfc_dev *nfc_dev)
398{
59ee2361
TE
399 struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);
400
401 mutex_lock(&ddev->poll_lock);
402
403 if (!ddev->poll_tech_count) {
404 PR_ERR("Polling operation was not running");
405 mutex_unlock(&ddev->poll_lock);
406 return;
407 }
408
409 ddev->poll_tech_count = 0;
410
411 mutex_unlock(&ddev->poll_lock);
412
413 cancel_work_sync(&ddev->poll_work);
414
415 digital_abort_cmd(ddev);
4b10884e
TE
416}
417
418static int digital_dev_up(struct nfc_dev *nfc_dev)
419{
59ee2361
TE
420 struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);
421
422 digital_switch_rf(ddev, 1);
423
424 return 0;
4b10884e
TE
425}
426
427static int digital_dev_down(struct nfc_dev *nfc_dev)
428{
59ee2361
TE
429 struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);
430
431 digital_switch_rf(ddev, 0);
432
433 return 0;
4b10884e
TE
434}
435
436static int digital_dep_link_up(struct nfc_dev *nfc_dev,
437 struct nfc_target *target,
438 __u8 comm_mode, __u8 *gb, size_t gb_len)
439{
440 return -EOPNOTSUPP;
441}
442
443static int digital_dep_link_down(struct nfc_dev *nfc_dev)
444{
445 return -EOPNOTSUPP;
446}
447
448static int digital_activate_target(struct nfc_dev *nfc_dev,
449 struct nfc_target *target, __u32 protocol)
450{
59ee2361 451 return 0;
4b10884e
TE
452}
453
454static void digital_deactivate_target(struct nfc_dev *nfc_dev,
455 struct nfc_target *target)
456{
59ee2361
TE
457 struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);
458
459 ddev->curr_protocol = 0;
4b10884e
TE
460}
461
462static int digital_tg_send(struct nfc_dev *dev, struct sk_buff *skb)
463{
464 return -EOPNOTSUPP;
465}
466
2c66daec
TE
467static void digital_in_send_complete(struct nfc_digital_dev *ddev, void *arg,
468 struct sk_buff *resp)
469{
470 struct digital_data_exch *data_exch = arg;
471 int rc;
472
473 if (IS_ERR(resp)) {
474 rc = PTR_ERR(resp);
475 goto done;
476 }
477
478 if (ddev->curr_protocol == NFC_PROTO_MIFARE)
479 rc = digital_in_recv_mifare_res(resp);
480 else
481 rc = ddev->skb_check_crc(resp);
482
483 if (rc) {
484 kfree_skb(resp);
485 resp = NULL;
486 }
487
488done:
489 data_exch->cb(data_exch->cb_context, resp, rc);
490
491 kfree(data_exch);
492}
493
4b10884e
TE
494static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target,
495 struct sk_buff *skb, data_exchange_cb_t cb,
496 void *cb_context)
497{
2c66daec
TE
498 struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);
499 struct digital_data_exch *data_exch;
500
501 data_exch = kzalloc(sizeof(struct digital_data_exch), GFP_KERNEL);
502 if (!data_exch) {
503 PR_ERR("Failed to allocate data_exch struct");
504 return -ENOMEM;
505 }
506
507 data_exch->cb = cb;
508 data_exch->cb_context = cb_context;
509
510 ddev->skb_add_crc(skb);
511
512 return digital_in_send_cmd(ddev, skb, 500, digital_in_send_complete,
513 data_exch);
4b10884e
TE
514}
515
516static struct nfc_ops digital_nfc_ops = {
517 .dev_up = digital_dev_up,
518 .dev_down = digital_dev_down,
519 .start_poll = digital_start_poll,
520 .stop_poll = digital_stop_poll,
521 .dep_link_up = digital_dep_link_up,
522 .dep_link_down = digital_dep_link_down,
523 .activate_target = digital_activate_target,
524 .deactivate_target = digital_deactivate_target,
525 .tm_send = digital_tg_send,
526 .im_transceive = digital_in_send,
527};
528
529struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops,
530 __u32 supported_protocols,
531 __u32 driver_capabilities,
532 int tx_headroom, int tx_tailroom)
533{
534 struct nfc_digital_dev *ddev;
535
536 if (!ops->in_configure_hw || !ops->in_send_cmd || !ops->tg_listen ||
537 !ops->tg_configure_hw || !ops->tg_send_cmd || !ops->abort_cmd ||
538 !ops->switch_rf)
539 return NULL;
540
541 ddev = kzalloc(sizeof(struct nfc_digital_dev), GFP_KERNEL);
542 if (!ddev) {
543 PR_ERR("kzalloc failed");
544 return NULL;
545 }
546
547 ddev->driver_capabilities = driver_capabilities;
548 ddev->ops = ops;
549
59ee2361
TE
550 mutex_init(&ddev->cmd_lock);
551 INIT_LIST_HEAD(&ddev->cmd_queue);
552
553 INIT_WORK(&ddev->cmd_work, digital_wq_cmd);
554 INIT_WORK(&ddev->cmd_complete_work, digital_wq_cmd_complete);
555
556 mutex_init(&ddev->poll_lock);
557 INIT_WORK(&ddev->poll_work, digital_wq_poll);
558
559 if (supported_protocols & NFC_PROTO_JEWEL_MASK)
560 ddev->protocols |= NFC_PROTO_JEWEL_MASK;
561 if (supported_protocols & NFC_PROTO_MIFARE_MASK)
562 ddev->protocols |= NFC_PROTO_MIFARE_MASK;
563
564 ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN;
565 ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN;
4b10884e
TE
566
567 ddev->nfc_dev = nfc_allocate_device(&digital_nfc_ops, ddev->protocols,
568 ddev->tx_headroom,
569 ddev->tx_tailroom);
570 if (!ddev->nfc_dev) {
571 PR_ERR("nfc_allocate_device failed");
572 goto free_dev;
573 }
574
575 nfc_set_drvdata(ddev->nfc_dev, ddev);
576
577 return ddev;
578
579free_dev:
580 kfree(ddev);
581
582 return NULL;
583}
584EXPORT_SYMBOL(nfc_digital_allocate_device);
585
586void nfc_digital_free_device(struct nfc_digital_dev *ddev)
587{
588 nfc_free_device(ddev->nfc_dev);
4b10884e
TE
589 kfree(ddev);
590}
591EXPORT_SYMBOL(nfc_digital_free_device);
592
593int nfc_digital_register_device(struct nfc_digital_dev *ddev)
594{
595 return nfc_register_device(ddev->nfc_dev);
596}
597EXPORT_SYMBOL(nfc_digital_register_device);
598
599void nfc_digital_unregister_device(struct nfc_digital_dev *ddev)
600{
59ee2361
TE
601 struct digital_cmd *cmd, *n;
602
4b10884e 603 nfc_unregister_device(ddev->nfc_dev);
59ee2361
TE
604
605 mutex_lock(&ddev->poll_lock);
606 ddev->poll_tech_count = 0;
607 mutex_unlock(&ddev->poll_lock);
608
609 cancel_work_sync(&ddev->poll_work);
610 cancel_work_sync(&ddev->cmd_work);
611 cancel_work_sync(&ddev->cmd_complete_work);
612
613 list_for_each_entry_safe(cmd, n, &ddev->cmd_queue, queue) {
614 list_del(&cmd->queue);
615 kfree(cmd);
616 }
4b10884e
TE
617}
618EXPORT_SYMBOL(nfc_digital_unregister_device);
619
620MODULE_LICENSE("GPL");
This page took 0.046937 seconds and 5 git commands to generate.