Commit d094afa155273e03b82981ea818d39c7a2dfba86
Committed by
John W. Linville
1 parent
0767a7fa87
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
NFC: Send LLCP RR frames to acknowledge received I frames
In order to acknowledge an I frame, we have to either queue pending local I frames or queue a receiver ready frame. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Showing 3 changed files with 33 additions and 3 deletions Side-by-side Diff
net/nfc/llcp/commands.c
... | ... | @@ -428,4 +428,28 @@ |
428 | 428 | |
429 | 429 | return 0; |
430 | 430 | } |
431 | + | |
432 | +int nfc_llcp_send_rr(struct nfc_llcp_sock *sock) | |
433 | +{ | |
434 | + struct sk_buff *skb; | |
435 | + struct nfc_llcp_local *local; | |
436 | + | |
437 | + pr_debug("Send rr nr %d\n", sock->recv_n); | |
438 | + | |
439 | + local = sock->local; | |
440 | + if (local == NULL) | |
441 | + return -ENODEV; | |
442 | + | |
443 | + skb = llcp_allocate_pdu(sock, LLCP_PDU_RR, LLCP_SEQUENCE_SIZE); | |
444 | + if (skb == NULL) | |
445 | + return -ENOMEM; | |
446 | + | |
447 | + skb_put(skb, LLCP_SEQUENCE_SIZE); | |
448 | + | |
449 | + skb->data[2] = sock->recv_n % 16; | |
450 | + | |
451 | + skb_queue_head(&local->tx_queue, skb); | |
452 | + | |
453 | + return 0; | |
454 | +} |
net/nfc/llcp/llcp.c
... | ... | @@ -627,8 +627,9 @@ |
627 | 627 | |
628 | 628 | } |
629 | 629 | |
630 | -void nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) | |
630 | +int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) | |
631 | 631 | { |
632 | + int nr_frames = 0; | |
632 | 633 | struct nfc_llcp_local *local = sock->local; |
633 | 634 | |
634 | 635 | pr_debug("Remote ready %d tx queue len %d remote rw %d", |
635 | 636 | |
... | ... | @@ -651,7 +652,10 @@ |
651 | 652 | |
652 | 653 | skb_queue_tail(&local->tx_queue, pdu); |
653 | 654 | skb_queue_tail(&sock->tx_pending_queue, pending_pdu); |
655 | + nr_frames++; | |
654 | 656 | } |
657 | + | |
658 | + return nr_frames; | |
655 | 659 | } |
656 | 660 | |
657 | 661 | static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, |
... | ... | @@ -716,7 +720,8 @@ |
716 | 720 | else if (ptype == LLCP_PDU_RNR) |
717 | 721 | llcp_sock->remote_ready = false; |
718 | 722 | |
719 | - nfc_llcp_queue_i_frames(llcp_sock); | |
723 | + if (nfc_llcp_queue_i_frames(llcp_sock) == 0) | |
724 | + nfc_llcp_send_rr(llcp_sock); | |
720 | 725 | |
721 | 726 | release_sock(sk); |
722 | 727 | nfc_llcp_sock_put(llcp_sock); |
net/nfc/llcp/llcp.h
... | ... | @@ -165,7 +165,7 @@ |
165 | 165 | struct nfc_llcp_sock *sock); |
166 | 166 | u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local); |
167 | 167 | void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap); |
168 | -void nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock); | |
168 | +int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock); | |
169 | 169 | |
170 | 170 | /* Sock API */ |
171 | 171 | struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp); |
... | ... | @@ -190,6 +190,7 @@ |
190 | 190 | int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); |
191 | 191 | int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, |
192 | 192 | struct msghdr *msg, size_t len); |
193 | +int nfc_llcp_send_rr(struct nfc_llcp_sock *sock); | |
193 | 194 | |
194 | 195 | /* Socket API */ |
195 | 196 | int __init nfc_llcp_sock_init(void); |