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

NFC: digital: Fix RTOX supervisor PDU handling

When the target needs more time to process the received PDU, it sends
Response Timeout Extension (RTOX) PDU.

When the initiator receives a RTOX PDU, it must reply with a RTOX PDU
and extends the current rwt value with the formula:
rwt_int = rwt * rtox

This patch takes care of the rtox value passed by the target in the RTOX
PDU and extends the timeout for the next response accordingly.

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
d85a301c 1a09c56f

+24 -2
+24 -2
net/nfc/digital_dep.c
··· 65 65 #define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_DID_BIT) 66 66 #define DIGITAL_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03) 67 67 68 + #define DIGITAL_NFC_DEP_RTOX_VALUE(data) ((data) & 0x3F) 69 + #define DIGITAL_NFC_DEP_RTOX_MAX 59 70 + 68 71 #define DIGITAL_NFC_DEP_PFB_I_PDU 0x00 69 72 #define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU 0x40 70 73 #define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80 ··· 646 643 struct digital_dep_req_res *dep_req; 647 644 struct sk_buff *skb; 648 645 int rc; 646 + u16 rwt_int; 647 + 648 + rwt_int = ddev->dep_rwt * rtox; 649 + if (rwt_int > digital_rwt_map[DIGITAL_NFC_DEP_IN_MAX_WT]) 650 + rwt_int = digital_rwt_map[DIGITAL_NFC_DEP_IN_MAX_WT]; 649 651 650 652 skb = digital_skb_alloc(ddev, 1); 651 653 if (!skb) ··· 671 663 672 664 ddev->skb_add_crc(skb); 673 665 674 - rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt, 666 + rc = digital_in_send_cmd(ddev, skb, rwt_int, 675 667 digital_in_recv_dep_res, data_exch); 676 668 if (rc) 677 669 kfree_skb(skb); ··· 705 697 u8 pfb; 706 698 uint size; 707 699 int rc; 700 + u8 rtox; 708 701 709 702 if (IS_ERR(resp)) { 710 703 rc = PTR_ERR(resp); ··· 874 865 goto free_resp; 875 866 } 876 867 877 - rc = digital_in_send_rtox(ddev, data_exch, resp->data[0]); 868 + if (ddev->atn_count || ddev->nack_count) { 869 + PROTOCOL_ERR("14.12.4.4"); 870 + rc = -EIO; 871 + goto error; 872 + } 873 + 874 + rtox = DIGITAL_NFC_DEP_RTOX_VALUE(resp->data[0]); 875 + if (!rtox || rtox > DIGITAL_NFC_DEP_RTOX_MAX) { 876 + PROTOCOL_ERR("14.8.4.1"); 877 + rc = -EIO; 878 + goto error; 879 + } 880 + 881 + rc = digital_in_send_rtox(ddev, data_exch, rtox); 878 882 if (rc) 879 883 goto error; 880 884