Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Thierry Escande and committed by
Samuel Ortiz
1a09c56f e200f008

+56 -16
+1
include/net/nfc/digital.h
··· 226 226 u8 curr_rf_tech; 227 227 u8 curr_nfc_dep_pni; 228 228 u8 did; 229 + u16 dep_rwt; 229 230 230 231 u8 local_payload_max; 231 232 u8 remote_payload_max;
+55 -16
net/nfc/digital_dep.c
··· 35 35 #define DIGITAL_ATR_REQ_MIN_SIZE 16 36 36 #define DIGITAL_ATR_REQ_MAX_SIZE 64 37 37 38 + #define DIGITAL_ATR_RES_TO_WT(s) ((s) & 0xF) 39 + 38 40 #define DIGITAL_DID_MAX 14 39 41 40 42 #define DIGITAL_PAYLOAD_SIZE_MAX 254 ··· 122 120 [1] = 128, 123 121 [2] = 192, 124 122 [3] = 254 123 + }; 124 + 125 + /* Response Waiting Time for ATR_RES PDU in ms 126 + * 127 + * RWT(ATR_RES) = RWT(nfcdep,activation) + dRWT(nfcdep) + dT(nfcdep,initiator) 128 + * 129 + * with: 130 + * RWT(nfcdep,activation) = 4096 * 2^12 / f(c) s 131 + * dRWT(nfcdep) = 16 / f(c) s 132 + * dT(nfcdep,initiator) = 100 ms 133 + * f(c) = 13560000 Hz 134 + */ 135 + #define DIGITAL_ATR_RES_RWT 1337 136 + 137 + /* Response Waiting Time for other DEP PDUs in ms 138 + * 139 + * max_rwt = rwt + dRWT(nfcdep) + dT(nfcdep,initiator) 140 + * 141 + * with: 142 + * rwt = (256 * 16 / f(c)) * 2^wt s 143 + * dRWT(nfcdep) = 16 / f(c) s 144 + * dT(nfcdep,initiator) = 100 ms 145 + * f(c) = 13560000 Hz 146 + * 0 <= wt <= 14 (given by the target by the TO field of ATR_RES response) 147 + */ 148 + #define DIGITAL_NFC_DEP_IN_MAX_WT 14 149 + #define DIGITAL_NFC_DEP_TG_MAX_WT 8 150 + static const u16 digital_rwt_map[DIGITAL_NFC_DEP_IN_MAX_WT + 1] = { 151 + 100, 101, 101, 102, 105, 152 + 110, 119, 139, 177, 255, 153 + 409, 719, 1337, 2575, 5049, 125 154 }; 126 155 127 156 static u8 digital_payload_bits_to_size(u8 payload_bits) ··· 399 366 400 367 ddev->skb_add_crc(skb); 401 368 402 - rc = digital_in_send_cmd(ddev, skb, 500, digital_in_recv_psl_res, 403 - target); 369 + rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt, 370 + digital_in_recv_psl_res, target); 404 371 if (rc) 405 372 kfree_skb(skb); 406 373 ··· 413 380 struct nfc_target *target = arg; 414 381 struct digital_atr_res *atr_res; 415 382 u8 gb_len, payload_bits; 383 + u8 wt; 416 384 int rc; 417 385 418 386 if (IS_ERR(resp)) { ··· 442 408 gb_len = resp->len - sizeof(struct digital_atr_res); 443 409 444 410 atr_res = (struct digital_atr_res *)resp->data; 411 + 412 + wt = DIGITAL_ATR_RES_TO_WT(atr_res->to); 413 + if (wt > DIGITAL_NFC_DEP_IN_MAX_WT) 414 + wt = DIGITAL_NFC_DEP_IN_MAX_WT; 415 + ddev->dep_rwt = digital_rwt_map[wt]; 445 416 446 417 payload_bits = DIGITAL_PAYLOAD_PP_TO_BITS(atr_res->pp); 447 418 ddev->remote_payload_max = digital_payload_bits_to_size(payload_bits); ··· 529 490 530 491 ddev->skb_add_crc(skb); 531 492 532 - rc = digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res, 533 - target); 493 + rc = digital_in_send_cmd(ddev, skb, DIGITAL_ATR_RES_RWT, 494 + digital_in_recv_atr_res, target); 534 495 if (rc) 535 496 kfree_skb(skb); 536 497 ··· 563 524 564 525 ddev->saved_skb = pskb_copy(skb, GFP_KERNEL); 565 526 566 - rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, 567 - data_exch); 527 + rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt, 528 + digital_in_recv_dep_res, data_exch); 568 529 if (rc) { 569 530 kfree_skb(skb); 570 531 kfree_skb(ddev->saved_skb); ··· 598 559 599 560 ddev->skb_add_crc(skb); 600 561 601 - rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, 602 - data_exch); 562 + rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt, 563 + digital_in_recv_dep_res, data_exch); 603 564 if (rc) 604 565 kfree_skb(skb); 605 566 ··· 629 590 630 591 ddev->skb_add_crc(skb); 631 592 632 - rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, 633 - data_exch); 593 + rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt, 594 + digital_in_recv_dep_res, data_exch); 634 595 if (rc) 635 596 kfree_skb(skb); 636 597 ··· 663 624 664 625 ddev->skb_add_crc(skb); 665 626 666 - rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, 667 - data_exch); 627 + rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt, 628 + digital_in_recv_dep_res, data_exch); 668 629 if (rc) 669 630 kfree_skb(skb); 670 631 ··· 681 642 682 643 skb_get(ddev->saved_skb); 683 644 684 - rc = digital_in_send_cmd(ddev, ddev->saved_skb, 1500, 645 + rc = digital_in_send_cmd(ddev, ddev->saved_skb, ddev->dep_rwt, 685 646 digital_in_recv_dep_res, data_exch); 686 647 if (rc) 687 648 kfree_skb(ddev->saved_skb); ··· 924 885 925 886 ddev->saved_skb = pskb_copy(tmp_skb, GFP_KERNEL); 926 887 927 - rc = digital_in_send_cmd(ddev, tmp_skb, 1500, digital_in_recv_dep_res, 928 - data_exch); 888 + rc = digital_in_send_cmd(ddev, tmp_skb, ddev->dep_rwt, 889 + digital_in_recv_dep_res, data_exch); 929 890 if (rc) { 930 891 if (tmp_skb != skb) 931 892 kfree_skb(tmp_skb); ··· 1504 1465 atr_res->dir = DIGITAL_NFC_DEP_FRAME_DIR_IN; 1505 1466 atr_res->cmd = DIGITAL_CMD_ATR_RES; 1506 1467 memcpy(atr_res->nfcid3, atr_req->nfcid3, sizeof(atr_req->nfcid3)); 1507 - atr_res->to = 8; 1468 + atr_res->to = DIGITAL_NFC_DEP_TG_MAX_WT; 1508 1469 1509 1470 ddev->local_payload_max = DIGITAL_PAYLOAD_SIZE_MAX; 1510 1471 payload_bits = digital_payload_size_to_bits(ddev->local_payload_max);