Bluetooth: L2CAP: Add l2cap_le_flowctl_send
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 11 Apr 2017 19:21:01 +0000 (22:21 +0300)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 12 Apr 2017 20:02:41 +0000 (22:02 +0200)
Consolidate code sending data to LE CoC channels and adds proper
accounting of packets sent, the remaining credits and how many packets
are queued.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Acked-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/l2cap_core.c

index 3a202b09d4acd212b2d2663baef31f863dabca10..f88ac99528ce448d8e0f8ea5eb06ee2d7719afab 100644 (file)
@@ -2425,6 +2425,22 @@ static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
        return 0;
 }
 
+static void l2cap_le_flowctl_send(struct l2cap_chan *chan)
+{
+       int sent = 0;
+
+       BT_DBG("chan %p", chan);
+
+       while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
+               l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
+               chan->tx_credits--;
+               sent++;
+       }
+
+       BT_DBG("Sent %d credits %u queued %u", sent, chan->tx_credits,
+              skb_queue_len(&chan->tx_q));
+}
+
 int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
 {
        struct sk_buff *skb;
@@ -2472,10 +2488,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
 
                skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
 
-               while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
-                       l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
-                       chan->tx_credits--;
-               }
+               l2cap_le_flowctl_send(chan);
 
                if (!chan->tx_credits)
                        chan->ops->suspend(chan);
@@ -5567,10 +5580,8 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn,
 
        chan->tx_credits += credits;
 
-       while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
-               l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
-               chan->tx_credits--;
-       }
+       /* Resume sending */
+       l2cap_le_flowctl_send(chan);
 
        if (chan->tx_credits)
                chan->ops->resume(chan);