aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Escande <thierry.escande@collabora.com>2016-07-08 09:52:46 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2016-07-10 20:02:03 -0400
commitd85a301c26621d3466956dc477c32c20c15a52ee (patch)
tree9cf96aa5fbd857d44e49a8e2abc79a3e3af2f70a
parent1a09c56f545c8ff8d338a38c7c40d79f4165a94c (diff)
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>
-rw-r--r--net/nfc/digital_dep.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/net/nfc/digital_dep.c b/net/nfc/digital_dep.c
index 6cf2eeb2e865..f864ce19e13d 100644
--- a/net/nfc/digital_dep.c
+++ b/net/nfc/digital_dep.c
@@ -65,6 +65,9 @@
65#define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_DID_BIT) 65#define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & DIGITAL_NFC_DEP_PFB_DID_BIT)
66#define DIGITAL_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03) 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#define DIGITAL_NFC_DEP_PFB_I_PDU 0x00 71#define DIGITAL_NFC_DEP_PFB_I_PDU 0x00
69#define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU 0x40 72#define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU 0x40
70#define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80 73#define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
@@ -643,6 +646,11 @@ static int digital_in_send_rtox(struct nfc_digital_dev *ddev,
643 struct digital_dep_req_res *dep_req; 646 struct digital_dep_req_res *dep_req;
644 struct sk_buff *skb; 647 struct sk_buff *skb;
645 int rc; 648 int rc;
649 u16 rwt_int;
650
651 rwt_int = ddev->dep_rwt * rtox;
652 if (rwt_int > digital_rwt_map[DIGITAL_NFC_DEP_IN_MAX_WT])
653 rwt_int = digital_rwt_map[DIGITAL_NFC_DEP_IN_MAX_WT];
646 654
647 skb = digital_skb_alloc(ddev, 1); 655 skb = digital_skb_alloc(ddev, 1);
648 if (!skb) 656 if (!skb)
@@ -663,7 +671,7 @@ static int digital_in_send_rtox(struct nfc_digital_dev *ddev,
663 671
664 ddev->skb_add_crc(skb); 672 ddev->skb_add_crc(skb);
665 673
666 rc = digital_in_send_cmd(ddev, skb, ddev->dep_rwt, 674 rc = digital_in_send_cmd(ddev, skb, rwt_int,
667 digital_in_recv_dep_res, data_exch); 675 digital_in_recv_dep_res, data_exch);
668 if (rc) 676 if (rc)
669 kfree_skb(skb); 677 kfree_skb(skb);
@@ -697,6 +705,7 @@ static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
697 u8 pfb; 705 u8 pfb;
698 uint size; 706 uint size;
699 int rc; 707 int rc;
708 u8 rtox;
700 709
701 if (IS_ERR(resp)) { 710 if (IS_ERR(resp)) {
702 rc = PTR_ERR(resp); 711 rc = PTR_ERR(resp);
@@ -865,7 +874,20 @@ static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
865 goto free_resp; 874 goto free_resp;
866 } 875 }
867 876
868 rc = digital_in_send_rtox(ddev, data_exch, resp->data[0]); 877 if (ddev->atn_count || ddev->nack_count) {
878 PROTOCOL_ERR("14.12.4.4");
879 rc = -EIO;
880 goto error;
881 }
882
883 rtox = DIGITAL_NFC_DEP_RTOX_VALUE(resp->data[0]);
884 if (!rtox || rtox > DIGITAL_NFC_DEP_RTOX_MAX) {
885 PROTOCOL_ERR("14.8.4.1");
886 rc = -EIO;
887 goto error;
888 }
889
890 rc = digital_in_send_rtox(ddev, data_exch, rtox);
869 if (rc) 891 if (rc)
870 goto error; 892 goto error;
871 893