Bluetooth: Implement returning of LE L2CAP credits
authorJohan Hedberg <johan.hedberg@intel.com>
Thu, 5 Dec 2013 07:43:34 +0000 (09:43 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 5 Dec 2013 15:05:34 +0000 (07:05 -0800)
We should return credits to the remote side whenever they fall below a
certain level (in our case under half of the initially given amount).

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/l2cap_core.c

index fe55162947f83449e2237a9de86fe970935dd5bd..4e0e2bedd4573e2d3122f462d810ab006e335bbd 100644 (file)
@@ -6610,6 +6610,32 @@ drop:
        return 0;
 }
 
+static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
+{
+       struct l2cap_conn *conn = chan->conn;
+       struct l2cap_le_credits pkt;
+       u16 return_credits;
+
+       /* We return more credits to the sender only after the amount of
+        * credits falls below half of the initial amount.
+        */
+       if (chan->rx_credits >= (L2CAP_LE_MAX_CREDITS + 1) / 2)
+               return;
+
+       return_credits = L2CAP_LE_MAX_CREDITS - chan->rx_credits;
+
+       BT_DBG("chan %p returning %u credits to sender", chan, return_credits);
+
+       chan->rx_credits += return_credits;
+
+       pkt.cid     = cpu_to_le16(chan->scid);
+       pkt.credits = cpu_to_le16(return_credits);
+
+       chan->ident = l2cap_get_ident(conn);
+
+       l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
+}
+
 static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
                               struct sk_buff *skb)
 {