diff options
author | Thierry Escande <thierry.escande@collabora.com> | 2016-07-08 09:52:45 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2016-07-10 20:01:14 -0400 |
commit | 1a09c56f545c8ff8d338a38c7c40d79f4165a94c (patch) | |
tree | b9324ff10a1ecd1432449a18c3aeba9de7b5c330 /net/nfc | |
parent | e200f008ace69eebac0a1432dc9e24ab5cd0d029 (diff) |
NFC: digital: Add support for NFC DEP Response Waiting Time
When sending an ATR_REQ, the initiator must wait for the ATR_RES at
least 'RWT(nfcdep,activation) + dRWT(nfcdep)' and no more than
'RWT(nfcdep,activation) + dRWT(nfcdep) + dT(nfcdep,initiator)'. This
gives a timeout value between 1237 ms and 1337 ms. This patch defines
DIGITAL_ATR_RES_RWT to 1337 used for the timeout value of ATR_REQ
command.
For other DEP PDUs, the initiator must wait between 'RWT + dRWT(nfcdep)'
and 'RWT + dRWT(nfcdep) + dT(nfcdep,initiator)' where RWT is given by
the following formula: '(256 * 16 / f(c)) * 2^wt' where wt is the value
of the TO field in the ATR_RES response and is in the range between 0
and 14. This patch declares a mapping table for wt values and gives RWT
max values between 100 ms and 5049 ms.
This patch also defines DIGITAL_ATR_RES_TO_WT, the maximum wt value in
target mode, to 8.
Signed-off-by: Thierry Escande <thierry.escande@collabora.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r-- | net/nfc/digital_dep.c | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/net/nfc/digital_dep.c b/net/nfc/digital_dep.c index ba52a5dbf3cc..6cf2eeb2e865 100644 --- a/net/nfc/digital_dep.c +++ b/net/nfc/digital_dep.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #define DIGITAL_ATR_REQ_MIN_SIZE 16 | 35 | #define DIGITAL_ATR_REQ_MIN_SIZE 16 |
36 | #define DIGITAL_ATR_REQ_MAX_SIZE 64 | 36 | #define DIGITAL_ATR_REQ_MAX_SIZE 64 |
37 | 37 | ||
38 | #define DIGITAL_ATR_RES_TO_WT(s) ((s) & 0xF) | ||
39 | |||
38 | #define DIGITAL_DID_MAX 14 | 40 | #define DIGITAL_DID_MAX 14 |
39 | 41 | ||
40 | #define DIGITAL_PAYLOAD_SIZE_MAX 254 | 42 | #define DIGITAL_PAYLOAD_SIZE_MAX 254 |
@@ -122,6 +124,37 @@ static const u8 digital_payload_bits_map[4] = { | |||
122 | [3] = 254 | 124 | [3] = 254 |
123 | }; | 125 | }; |
124 | 126 | ||
127 | /* Response Waiting Time for ATR_RES PDU in ms | ||
128 | * | ||
129 | * RWT(ATR_RES) = RWT(nfcdep,activation) + dRWT(nfcdep) + dT(nfcdep,initiator) | ||
130 | * | ||
131 | * with: | ||
132 | * RWT(nfcdep,activation) = 4096 * 2^12 / f(c) s | ||
133 | * dRWT(nfcdep) = 16 / f(c) s | ||
134 | * dT(nfcdep,initiator) = 100 ms | ||
135 | * f(c) = 13560000 Hz | ||
136 | */ | ||
137 | #define DIGITAL_ATR_RES_RWT 1337 | ||
138 | |||
139 | /* Response Waiting Time for other DEP PDUs in ms | ||
140 | * | ||
141 | * max_rwt = rwt + dRWT(nfcdep) + dT(nfcdep,initiator) | ||
142 | * | ||
143 | * with: | ||
144 | * rwt = (256 * 16 / f(c)) * 2^wt s | ||
145 | * dRWT(nfcdep) = 16 / f(c) s | ||
146 | * dT(nfcdep,initiator) = 100 ms | ||
147 | * f(c) = 13560000 Hz | ||
148 | * 0 <= wt <= 14 (given by the target by the TO field of ATR_RES response) | ||
149 | */ | ||
150 | #define DIGITAL_NFC_DEP_IN_MAX_WT 14 | ||
151 | #define DIGITAL_NFC_DEP_TG_MAX_WT 8 | ||
152 | static const u16 digital_rwt_map[DIGITAL_NFC_DEP_IN_MAX_WT + 1] = { | ||
153 | 100, 101, 101, 102, 105, | ||
154 | 110, 119, 139, 177, 255, | ||
155 | 409, 719, 1337, 2575, 5049, | ||
156 | }; | ||
157 | |||
125 | static u8 digital_payload_bits_to_size(u8 payload_bits) | 158 | static u8 digital_payload_bits_to_size(u8 payload_bits) |
126 | { | 159 | { |
127 | if (payload_bits >= ARRAY_SIZE(digital_payload_bits_map)) | 160 | if (payload_bits >= ARRAY_SIZE(digital_payload_bits_map)) |
@@ -366,8 +399,8 @@ static int digital_in_send_psl_req(struct nfc_digital_dev *ddev, | |||
366 | 399 | ||
367 | ddev->skb_add_crc(skb); | 400 | ddev->skb_add_crc(skb); |
368 | 401 | ||
369 | rc = digital_in_send_cmd(ddev, skb, 500, digital_in_recv_psl_res, | 402 | rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt, |
370 | target); | 403 | digital_in_recv_psl_res, target); |
371 | if (rc) | 404 | if (rc) |
372 | kfree_skb(skb); | 405 | kfree_skb(skb); |
373 | 406 | ||
@@ -380,6 +413,7 @@ static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg, | |||
380 | struct nfc_target *target = arg; | 413 | struct nfc_target *target = arg; |
381 | struct digital_atr_res *atr_res; | 414 | struct digital_atr_res *atr_res; |
382 | u8 gb_len, payload_bits; | 415 | u8 gb_len, payload_bits; |
416 | u8 wt; | ||
383 | int rc; | 417 | int rc; |
384 | 418 | ||
385 | if (IS_ERR(resp)) { | 419 | if (IS_ERR(resp)) { |
@@ -409,6 +443,11 @@ static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg, | |||
409 | 443 | ||
410 | atr_res = (struct digital_atr_res *)resp->data; | 444 | atr_res = (struct digital_atr_res *)resp->data; |
411 | 445 | ||
446 | wt = DIGITAL_ATR_RES_TO_WT(atr_res->to); | ||
447 | if (wt > DIGITAL_NFC_DEP_IN_MAX_WT) | ||
448 | wt = DIGITAL_NFC_DEP_IN_MAX_WT; | ||
449 | ddev->dep_rwt = digital_rwt_map[wt]; | ||
450 | |||
412 | payload_bits = DIGITAL_PAYLOAD_PP_TO_BITS(atr_res->pp); | 451 | payload_bits = DIGITAL_PAYLOAD_PP_TO_BITS(atr_res->pp); |
413 | ddev->remote_payload_max = digital_payload_bits_to_size(payload_bits); | 452 | ddev->remote_payload_max = digital_payload_bits_to_size(payload_bits); |
414 | 453 | ||
@@ -490,8 +529,8 @@ int digital_in_send_atr_req(struct nfc_digital_dev *ddev, | |||
490 | 529 | ||
491 | ddev->skb_add_crc(skb); | 530 | ddev->skb_add_crc(skb); |
492 | 531 | ||
493 | rc = digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res, | 532 | rc = digital_in_send_cmd(ddev, skb, DIGITAL_ATR_RES_RWT, |
494 | target); | 533 | digital_in_recv_atr_res, target); |
495 | if (rc) | 534 | if (rc) |
496 | kfree_skb(skb); | 535 | kfree_skb(skb); |
497 | 536 | ||
@@ -524,8 +563,8 @@ static int digital_in_send_ack(struct nfc_digital_dev *ddev, | |||
524 | 563 | ||
525 | ddev->saved_skb = pskb_copy(skb, GFP_KERNEL); | 564 | ddev->saved_skb = pskb_copy(skb, GFP_KERNEL); |
526 | 565 | ||
527 | rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, | 566 | rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt, |
528 | data_exch); | 567 | digital_in_recv_dep_res, data_exch); |
529 | if (rc) { | 568 | if (rc) { |
530 | kfree_skb(skb); | 569 | kfree_skb(skb); |
531 | kfree_skb(ddev->saved_skb); | 570 | kfree_skb(ddev->saved_skb); |
@@ -559,8 +598,8 @@ static int digital_in_send_nack(struct nfc_digital_dev *ddev, | |||
559 | 598 | ||
560 | ddev->skb_add_crc(skb); | 599 | ddev->skb_add_crc(skb); |
561 | 600 | ||
562 | rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, | 601 | rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt, |
563 | data_exch); | 602 | digital_in_recv_dep_res, data_exch); |
564 | if (rc) | 603 | if (rc) |
565 | kfree_skb(skb); | 604 | kfree_skb(skb); |
566 | 605 | ||
@@ -590,8 +629,8 @@ static int digital_in_send_atn(struct nfc_digital_dev *ddev, | |||
590 | 629 | ||
591 | ddev->skb_add_crc(skb); | 630 | ddev->skb_add_crc(skb); |
592 | 631 | ||
593 | rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, | 632 | rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt, |
594 | data_exch); | 633 | digital_in_recv_dep_res, data_exch); |
595 | if (rc) | 634 | if (rc) |
596 | kfree_skb(skb); | 635 | kfree_skb(skb); |
597 | 636 | ||
@@ -624,8 +663,8 @@ static int digital_in_send_rtox(struct nfc_digital_dev *ddev, | |||
624 | 663 | ||
625 | ddev->skb_add_crc(skb); | 664 | ddev->skb_add_crc(skb); |
626 | 665 | ||
627 | rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, | 666 | rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt, |
628 | data_exch); | 667 | digital_in_recv_dep_res, data_exch); |
629 | if (rc) | 668 | if (rc) |
630 | kfree_skb(skb); | 669 | kfree_skb(skb); |
631 | 670 | ||
@@ -642,7 +681,7 @@ static int digital_in_send_saved_skb(struct nfc_digital_dev *ddev, | |||
642 | 681 | ||
643 | skb_get(ddev->saved_skb); | 682 | skb_get(ddev->saved_skb); |
644 | 683 | ||
645 | rc = digital_in_send_cmd(ddev, ddev->saved_skb, 1500, | 684 | rc = digital_in_send_cmd(ddev, ddev->saved_skb, ddev->dep_rwt, |
646 | digital_in_recv_dep_res, data_exch); | 685 | digital_in_recv_dep_res, data_exch); |
647 | if (rc) | 686 | if (rc) |
648 | kfree_skb(ddev->saved_skb); | 687 | kfree_skb(ddev->saved_skb); |
@@ -885,8 +924,8 @@ int digital_in_send_dep_req(struct nfc_digital_dev *ddev, | |||
885 | 924 | ||
886 | ddev->saved_skb = pskb_copy(tmp_skb, GFP_KERNEL); | 925 | ddev->saved_skb = pskb_copy(tmp_skb, GFP_KERNEL); |
887 | 926 | ||
888 | rc = digital_in_send_cmd(ddev, tmp_skb, 1500, digital_in_recv_dep_res, | 927 | rc = digital_in_send_cmd(ddev, tmp_skb, ddev->dep_rwt, |
889 | data_exch); | 928 | digital_in_recv_dep_res, data_exch); |
890 | if (rc) { | 929 | if (rc) { |
891 | if (tmp_skb != skb) | 930 | if (tmp_skb != skb) |
892 | kfree_skb(tmp_skb); | 931 | kfree_skb(tmp_skb); |
@@ -1465,7 +1504,7 @@ static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev, | |||
1465 | atr_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN; | 1504 | atr_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN; |
1466 | atr_res->cmd = DIGITAL_CMD_ATR_RES; | 1505 | atr_res->cmd = DIGITAL_CMD_ATR_RES; |
1467 | memcpy(atr_res->nfcid3, atr_req->nfcid3, sizeof(atr_req->nfcid3)); | 1506 | memcpy(atr_res->nfcid3, atr_req->nfcid3, sizeof(atr_req->nfcid3)); |
1468 | atr_res->to = 8; | 1507 | atr_res->to = DIGITAL_NFC_DEP_TG_MAX_WT; |
1469 | 1508 | ||
1470 | ddev->local_payload_max = DIGITAL_PAYLOAD_SIZE_MAX; | 1509 | ddev->local_payload_max = DIGITAL_PAYLOAD_SIZE_MAX; |
1471 | payload_bits = digital_payload_size_to_bits(ddev->local_payload_max); | 1510 | payload_bits = digital_payload_size_to_bits(ddev->local_payload_max); |