aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2013-05-17 06:09:05 -0400
committerMarcel Holtmann <marcel@holtmann.org>2013-12-05 10:05:34 -0500
commit0cd75f7ed740a8c605fe55ac71a9b5162c612422 (patch)
treeb155f3faacfeeaf1f244405b26e5b2f1105b53a2 /net
parent3831971355d901ccfb76533a422b4395072849a3 (diff)
Bluetooth: Track LE L2CAP credits in l2cap_chan
This patch adds tracking of L2CAP connection oriented channel local and remote credits to struct l2cap_chan and ensures that connect requests and responses contain the right values. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap_core.c16
-rw-r--r--net/bluetooth/l2cap_sock.c2
2 files changed, 13 insertions, 5 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index e260753184b6..fe55162947f8 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -495,6 +495,8 @@ void l2cap_le_flowctl_init(struct l2cap_chan *chan)
495 chan->imtu = L2CAP_DEFAULT_MTU; 495 chan->imtu = L2CAP_DEFAULT_MTU;
496 chan->omtu = L2CAP_LE_MIN_MTU; 496 chan->omtu = L2CAP_LE_MIN_MTU;
497 chan->mode = L2CAP_MODE_LE_FLOWCTL; 497 chan->mode = L2CAP_MODE_LE_FLOWCTL;
498 chan->tx_credits = 0;
499 chan->rx_credits = L2CAP_LE_MAX_CREDITS;
498} 500}
499 501
500void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) 502void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
@@ -643,7 +645,7 @@ static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
643 rsp.dcid = cpu_to_le16(chan->scid); 645 rsp.dcid = cpu_to_le16(chan->scid);
644 rsp.mtu = cpu_to_le16(chan->imtu); 646 rsp.mtu = cpu_to_le16(chan->imtu);
645 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS); 647 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
646 rsp.credits = __constant_cpu_to_le16(L2CAP_LE_MAX_CREDITS); 648 rsp.credits = cpu_to_le16(chan->rx_credits);
647 rsp.result = cpu_to_le16(result); 649 rsp.result = cpu_to_le16(result);
648 650
649 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), 651 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
@@ -1212,7 +1214,7 @@ static void l2cap_le_connect(struct l2cap_chan *chan)
1212 req.scid = cpu_to_le16(chan->scid); 1214 req.scid = cpu_to_le16(chan->scid);
1213 req.mtu = cpu_to_le16(chan->imtu); 1215 req.mtu = cpu_to_le16(chan->imtu);
1214 req.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS); 1216 req.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
1215 req.credits = __constant_cpu_to_le16(L2CAP_LE_MAX_CREDITS); 1217 req.credits = cpu_to_le16(chan->rx_credits);
1216 1218
1217 chan->ident = l2cap_get_ident(conn); 1219 chan->ident = l2cap_get_ident(conn);
1218 1220
@@ -3690,7 +3692,7 @@ void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
3690 rsp.dcid = cpu_to_le16(chan->scid); 3692 rsp.dcid = cpu_to_le16(chan->scid);
3691 rsp.mtu = cpu_to_le16(chan->imtu); 3693 rsp.mtu = cpu_to_le16(chan->imtu);
3692 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS); 3694 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
3693 rsp.credits = __constant_cpu_to_le16(L2CAP_LE_MAX_CREDITS); 3695 rsp.credits = cpu_to_le16(chan->rx_credits);
3694 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); 3696 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3695 3697
3696 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), 3698 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
@@ -5342,6 +5344,7 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5342 chan->dcid = dcid; 5344 chan->dcid = dcid;
5343 chan->omtu = mtu; 5345 chan->omtu = mtu;
5344 chan->remote_mps = mps; 5346 chan->remote_mps = mps;
5347 chan->tx_credits = credits;
5345 l2cap_chan_ready(chan); 5348 l2cap_chan_ready(chan);
5346 break; 5349 break;
5347 5350
@@ -5445,7 +5448,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
5445 struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data; 5448 struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
5446 struct l2cap_le_conn_rsp rsp; 5449 struct l2cap_le_conn_rsp rsp;
5447 struct l2cap_chan *chan, *pchan; 5450 struct l2cap_chan *chan, *pchan;
5448 u16 dcid, scid, mtu, mps; 5451 u16 dcid, scid, credits, mtu, mps;
5449 __le16 psm; 5452 __le16 psm;
5450 u8 result; 5453 u8 result;
5451 5454
@@ -5457,6 +5460,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
5457 mps = __le16_to_cpu(req->mps); 5460 mps = __le16_to_cpu(req->mps);
5458 psm = req->psm; 5461 psm = req->psm;
5459 dcid = 0; 5462 dcid = 0;
5463 credits = 0;
5460 5464
5461 if (mtu < 23 || mps < 23) 5465 if (mtu < 23 || mps < 23)
5462 return -EPROTO; 5466 return -EPROTO;
@@ -5503,9 +5507,11 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
5503 chan->dcid = scid; 5507 chan->dcid = scid;
5504 chan->omtu = mtu; 5508 chan->omtu = mtu;
5505 chan->remote_mps = mps; 5509 chan->remote_mps = mps;
5510 chan->tx_credits = __le16_to_cpu(req->credits);
5506 5511
5507 __l2cap_chan_add(conn, chan); 5512 __l2cap_chan_add(conn, chan);
5508 dcid = chan->scid; 5513 dcid = chan->scid;
5514 credits = chan->rx_credits;
5509 5515
5510 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan)); 5516 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
5511 5517
@@ -5537,7 +5543,7 @@ response:
5537 } 5543 }
5538 5544
5539 rsp.dcid = cpu_to_le16(dcid); 5545 rsp.dcid = cpu_to_le16(dcid);
5540 rsp.credits = __constant_cpu_to_le16(L2CAP_LE_MAX_CREDITS); 5546 rsp.credits = cpu_to_le16(credits);
5541 rsp.result = cpu_to_le16(result); 5547 rsp.result = cpu_to_le16(result);
5542 5548
5543 l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp); 5549 l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 485ca349fed5..61e25bafdf43 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1321,6 +1321,8 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
1321 chan->tx_win_max = pchan->tx_win_max; 1321 chan->tx_win_max = pchan->tx_win_max;
1322 chan->sec_level = pchan->sec_level; 1322 chan->sec_level = pchan->sec_level;
1323 chan->flags = pchan->flags; 1323 chan->flags = pchan->flags;
1324 chan->tx_credits = pchan->tx_credits;
1325 chan->rx_credits = pchan->rx_credits;
1324 1326
1325 security_sk_clone(parent, sk); 1327 security_sk_clone(parent, sk);
1326 } else { 1328 } else {