static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control)
{
- struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
-
if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
chan->conn_state |= L2CAP_CONN_RNR_SENT;
} else
control |= L2CAP_SUPER_RCV_READY;
- control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
l2cap_send_sframe(chan, control);
}
bh_unlock_sock(sk);
}
-static void l2cap_drop_acked_frames(struct sock *sk)
+static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
{
+ struct sock *sk = chan->sk;
struct sk_buff *skb;
while ((skb = skb_peek(TX_QUEUE(sk))) &&
l2cap_pi(sk)->unacked_frames) {
- if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
+ if (bt_cb(skb)->tx_seq == chan->expected_ack_seq)
break;
skb = skb_dequeue(TX_QUEUE(sk));
hci_send_acl(hcon, skb, flags);
}
-void l2cap_streaming_send(struct sock *sk)
+void l2cap_streaming_send(struct l2cap_chan *chan)
{
+ struct sock *sk = chan->sk;
struct sk_buff *skb;
struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control, fcs;
while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
- control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
+ control |= chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
if (pi->fcs == L2CAP_FCS_CRC16) {
l2cap_do_send(sk, skb);
- pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
+ chan->next_tx_seq = (chan->next_tx_seq + 1) % 64;
}
}
chan->conn_state &= ~L2CAP_CONN_SEND_FBIT;
}
- control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
+ control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
| (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
if (sk->sk_state != BT_CONNECTED)
return -ENOTCONN;
- while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) {
+ while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(chan))) {
if (pi->remote_max_tx &&
bt_cb(skb)->retries == pi->remote_max_tx) {
control |= L2CAP_CTRL_FINAL;
chan->conn_state &= ~L2CAP_CONN_SEND_FBIT;
}
- control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
- | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
+ control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
+ | (chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
__mod_retrans_timer();
- bt_cb(skb)->tx_seq = pi->next_tx_seq;
- pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
+ bt_cb(skb)->tx_seq = chan->next_tx_seq;
+ chan->next_tx_seq = (chan->next_tx_seq + 1) % 64;
if (bt_cb(skb)->retries == 1)
pi->unacked_frames++;
static int l2cap_retransmit_frames(struct l2cap_chan *chan)
{
struct sock *sk = chan->sk;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
int ret;
if (!skb_queue_empty(TX_QUEUE(sk)))
sk->sk_send_head = TX_QUEUE(sk)->next;
- pi->next_tx_seq = pi->expected_ack_seq;
+ chan->next_tx_seq = chan->expected_ack_seq;
ret = l2cap_ertm_send(chan);
return ret;
}
static void l2cap_send_ack(struct l2cap_chan *chan)
{
- struct sock *sk = chan->sk;
u16 control = 0;
- control |= l2cap_pi(sk)->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
{
struct sock *sk = chan->sk;
- l2cap_pi(sk)->expected_ack_seq = 0;
+ chan->expected_ack_seq = 0;
l2cap_pi(sk)->unacked_frames = 0;
- l2cap_pi(sk)->buffer_seq = 0;
+ chan->buffer_seq = 0;
l2cap_pi(sk)->num_acked = 0;
l2cap_pi(sk)->frames_sent = 0;
sk->sk_state = BT_CONNECTED;
- l2cap_pi(sk)->next_tx_seq = 0;
- l2cap_pi(sk)->expected_tx_seq = 0;
+ chan->next_tx_seq = 0;
+ chan->expected_tx_seq = 0;
__skb_queue_head_init(TX_QUEUE(sk));
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
l2cap_ertm_init(chan);
set_default_fcs(l2cap_pi(sk));
sk->sk_state = BT_CONNECTED;
- l2cap_pi(sk)->next_tx_seq = 0;
- l2cap_pi(sk)->expected_tx_seq = 0;
+ chan->next_tx_seq = 0;
+ chan->expected_tx_seq = 0;
__skb_queue_head_init(TX_QUEUE(sk));
if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM)
l2cap_ertm_init(chan);
pi->frames_sent = 0;
- control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) {
control |= L2CAP_SUPER_RCV_NOT_READY;
}
}
-static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
+static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u8 tx_seq, u8 sar)
{
+ struct sock *sk = chan->sk;
struct sk_buff *next_skb;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
int tx_seq_offset, next_tx_seq_offset;
bt_cb(skb)->tx_seq = tx_seq;
return 0;
}
- tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
+ tx_seq_offset = (tx_seq - chan->buffer_seq) % 64;
if (tx_seq_offset < 0)
tx_seq_offset += 64;
return -EINVAL;
next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
- pi->buffer_seq) % 64;
+ chan->buffer_seq) % 64;
if (next_tx_seq_offset < 0)
next_tx_seq_offset += 64;
return -EBUSY;
}
- pi->buffer_seq = (pi->buffer_seq + 1) % 64;
+ chan->buffer_seq = (chan->buffer_seq + 1) % 64;
}
if (!(chan->conn_state & L2CAP_CONN_RNR_SENT))
goto done;
- control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL;
l2cap_send_sframe(chan, control);
l2cap_pi(sk)->retry_count = 1;
err = l2cap_ertm_reassembly_sdu(chan, skb, control);
if (err >= 0) {
- pi->buffer_seq = (pi->buffer_seq + 1) % 64;
+ chan->buffer_seq = (chan->buffer_seq + 1) % 64;
return err;
}
bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT;
__skb_queue_tail(BUSY_QUEUE(sk), skb);
- sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ sctrl = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
sctrl |= L2CAP_SUPER_RCV_NOT_READY;
l2cap_send_sframe(chan, sctrl);
skb = skb_dequeue(SREJ_QUEUE(sk));
control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
l2cap_ertm_reassembly_sdu(chan, skb, control);
- l2cap_pi(sk)->buffer_seq_srej =
- (l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
+ chan->buffer_seq_srej =
+ (chan->buffer_seq_srej + 1) % 64;
tx_seq = (tx_seq + 1) % 64;
}
}
static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq)
{
struct sock *sk = chan->sk;
- struct l2cap_pinfo *pi = l2cap_pi(sk);
struct srej_list *new;
u16 control;
- while (tx_seq != pi->expected_tx_seq) {
+ while (tx_seq != chan->expected_tx_seq) {
control = L2CAP_SUPER_SELECT_REJECT;
- control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+ control |= chan->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
l2cap_send_sframe(chan, control);
new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
- new->tx_seq = pi->expected_tx_seq;
- pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+ new->tx_seq = chan->expected_tx_seq;
+ chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
list_add_tail(&new->list, SREJ_LIST(sk));
}
- pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+ chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
}
static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb)
chan->conn_state &= ~L2CAP_CONN_WAIT_F;
}
- pi->expected_ack_seq = req_seq;
- l2cap_drop_acked_frames(sk);
+ chan->expected_ack_seq = req_seq;
+ l2cap_drop_acked_frames(chan);
- if (tx_seq == pi->expected_tx_seq)
+ if (tx_seq == chan->expected_tx_seq)
goto expected;
- tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
+ tx_seq_offset = (tx_seq - chan->buffer_seq) % 64;
if (tx_seq_offset < 0)
tx_seq_offset += 64;
first = list_first_entry(SREJ_LIST(sk),
struct srej_list, list);
if (tx_seq == first->tx_seq) {
- l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
+ l2cap_add_to_srej_queue(chan, skb, tx_seq, sar);
l2cap_check_srej_gap(chan, tx_seq);
list_del(&first->list);
kfree(first);
if (list_empty(SREJ_LIST(sk))) {
- pi->buffer_seq = pi->buffer_seq_srej;
+ chan->buffer_seq = chan->buffer_seq_srej;
chan->conn_state &= ~L2CAP_CONN_SREJ_SENT;
l2cap_send_ack(chan);
BT_DBG("sk %p, Exit SREJ_SENT", sk);
struct srej_list *l;
/* duplicated tx_seq */
- if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0)
+ if (l2cap_add_to_srej_queue(chan, skb, tx_seq, sar) < 0)
goto drop;
list_for_each_entry(l, SREJ_LIST(sk), list) {
}
} else {
expected_tx_seq_offset =
- (pi->expected_tx_seq - pi->buffer_seq) % 64;
+ (chan->expected_tx_seq - chan->buffer_seq) % 64;
if (expected_tx_seq_offset < 0)
expected_tx_seq_offset += 64;
BT_DBG("sk %p, Enter SREJ", sk);
INIT_LIST_HEAD(SREJ_LIST(sk));
- pi->buffer_seq_srej = pi->buffer_seq;
+ chan->buffer_seq_srej = chan->buffer_seq;
__skb_queue_head_init(SREJ_QUEUE(sk));
__skb_queue_head_init(BUSY_QUEUE(sk));
- l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
+ l2cap_add_to_srej_queue(chan, skb, tx_seq, sar);
chan->conn_state |= L2CAP_CONN_SEND_PBIT;
return 0;
expected:
- pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+ chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
if (chan->conn_state & L2CAP_CONN_SREJ_SENT) {
bt_cb(skb)->tx_seq = tx_seq;
BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control),
rx_control);
- pi->expected_ack_seq = __get_reqseq(rx_control);
- l2cap_drop_acked_frames(sk);
+ chan->expected_ack_seq = __get_reqseq(rx_control);
+ l2cap_drop_acked_frames(chan);
if (rx_control & L2CAP_CTRL_POLL) {
chan->conn_state |= L2CAP_CONN_SEND_FBIT;
static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_control)
{
- struct l2cap_pinfo *pi = l2cap_pi(chan->sk);
u8 tx_seq = __get_reqseq(rx_control);
BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control);
chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(chan->sk);
+ chan->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(chan);
if (rx_control & L2CAP_CTRL_FINAL) {
if (chan->conn_state & L2CAP_CONN_REJ_ACT)
chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
if (rx_control & L2CAP_CTRL_POLL) {
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(chan->sk);
+ chan->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(chan);
chan->conn_state |= L2CAP_CONN_SEND_FBIT;
l2cap_retransmit_one_frame(chan, tx_seq);
BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control);
chan->conn_state |= L2CAP_CONN_REMOTE_BUSY;
- pi->expected_ack_seq = tx_seq;
- l2cap_drop_acked_frames(chan->sk);
+ chan->expected_ack_seq = tx_seq;
+ l2cap_drop_acked_frames(chan);
if (rx_control & L2CAP_CTRL_POLL)
chan->conn_state |= L2CAP_CONN_SEND_FBIT;
}
req_seq = __get_reqseq(control);
- req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
+ req_seq_offset = (req_seq - chan->expected_ack_seq) % 64;
if (req_seq_offset < 0)
req_seq_offset += 64;
next_tx_seq_offset =
- (pi->next_tx_seq - pi->expected_ack_seq) % 64;
+ (chan->next_tx_seq - chan->expected_ack_seq) % 64;
if (next_tx_seq_offset < 0)
next_tx_seq_offset += 64;
tx_seq = __get_txseq(control);
- if (pi->expected_tx_seq == tx_seq)
- pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+ if (chan->expected_tx_seq == tx_seq)
+ chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64;
else
- pi->expected_tx_seq = (tx_seq + 1) % 64;
+ chan->expected_tx_seq = (tx_seq + 1) % 64;
l2cap_streaming_reassembly_sdu(chan, skb, control);