diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2013-05-17 06:09:05 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2013-12-05 10:05:34 -0500 |
commit | 0cd75f7ed740a8c605fe55ac71a9b5162c612422 (patch) | |
tree | b155f3faacfeeaf1f244405b26e5b2f1105b53a2 /net | |
parent | 3831971355d901ccfb76533a422b4395072849a3 (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.c | 16 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 2 |
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 | ||
500 | void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | 502 | void __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 { |