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

NFC: digital: Rework ACK PDU handling in initiator mode

With this patch, ACK PDU sk_buffs are now freed and code has been
refactored for better errors handling.

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
e073eb67 482333b2

+28 -14
+28 -14
net/nfc/digital_dep.c
··· 782 782 break; 783 783 784 784 case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: 785 + if (DIGITAL_NFC_DEP_NACK_BIT_SET(pfb)) { 786 + PROTOCOL_ERR("14.12.4.5"); 787 + rc = -EIO; 788 + goto exit; 789 + } 790 + 785 791 if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) { 786 792 PROTOCOL_ERR("14.12.3.3"); 787 793 rc = -EIO; ··· 797 791 ddev->curr_nfc_dep_pni = 798 792 DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1); 799 793 800 - if (ddev->chaining_skb && !DIGITAL_NFC_DEP_NACK_BIT_SET(pfb)) { 801 - kfree_skb(ddev->saved_skb); 802 - ddev->saved_skb = NULL; 803 - 804 - rc = digital_in_send_dep_req(ddev, NULL, 805 - ddev->chaining_skb, 806 - ddev->data_exch); 807 - if (rc) 808 - goto error; 809 - 810 - return; 794 + if (!ddev->chaining_skb) { 795 + PROTOCOL_ERR("14.12.4.3"); 796 + rc = -EIO; 797 + goto exit; 811 798 } 812 799 813 - pr_err("Received a ACK/NACK PDU\n"); 814 - rc = -EINVAL; 815 - goto exit; 800 + /* The initiator has received a valid ACK. Free the last sent 801 + * PDU and keep on sending chained skb. 802 + */ 803 + kfree_skb(ddev->saved_skb); 804 + ddev->saved_skb = NULL; 805 + 806 + rc = digital_in_send_dep_req(ddev, NULL, 807 + ddev->chaining_skb, 808 + ddev->data_exch); 809 + if (rc) 810 + goto error; 811 + 812 + goto free_resp; 816 813 817 814 case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU: 818 815 if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) { /* ATN */ ··· 848 839 849 840 if (rc) 850 841 kfree_skb(resp); 842 + 843 + return; 844 + 845 + free_resp: 846 + dev_kfree_skb(resp); 851 847 } 852 848 853 849 int digital_in_send_dep_req(struct nfc_digital_dev *ddev,