aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/l2cap.h27
-rw-r--r--net/bluetooth/l2cap_core.c41
2 files changed, 45 insertions, 23 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index fa7edabde4d9..f24f5cf820d7 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -140,10 +140,10 @@ struct l2cap_conninfo {
140#define L2CAP_EXT_CTRL_TXSEQ_SHIFT 18 140#define L2CAP_EXT_CTRL_TXSEQ_SHIFT 18
141 141
142/* L2CAP Supervisory Function */ 142/* L2CAP Supervisory Function */
143#define L2CAP_SUPER_RCV_READY 0x0000 143#define L2CAP_SUPER_RR 0x00
144#define L2CAP_SUPER_REJECT 0x0004 144#define L2CAP_SUPER_REJ 0x01
145#define L2CAP_SUPER_RCV_NOT_READY 0x0008 145#define L2CAP_SUPER_RNR 0x02
146#define L2CAP_SUPER_SELECT_REJECT 0x000C 146#define L2CAP_SUPER_SREJ 0x03
147 147
148/* L2CAP Segmentation and Reassembly */ 148/* L2CAP Segmentation and Reassembly */
149#define L2CAP_SDU_UNSEGMENTED 0x0000 149#define L2CAP_SDU_UNSEGMENTED 0x0000
@@ -518,6 +518,25 @@ static inline int l2cap_tx_window_full(struct l2cap_chan *ch)
518#define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE) 518#define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE)
519#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) 519#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
520 520
521static inline __u8 __get_ctrl_super(struct l2cap_chan *chan, __u32 ctrl)
522{
523 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
524 return (ctrl & L2CAP_EXT_CTRL_SUPERVISE) >>
525 L2CAP_EXT_CTRL_SUPER_SHIFT;
526 else
527 return (ctrl & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
528}
529
530static inline __u32 __set_ctrl_super(struct l2cap_chan *chan, __u32 super)
531{
532 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
533 return (super << L2CAP_EXT_CTRL_SUPER_SHIFT) &
534 L2CAP_EXT_CTRL_SUPERVISE;
535 else
536 return (super << L2CAP_CTRL_SUPER_SHIFT) &
537 L2CAP_CTRL_SUPERVISE;
538}
539
521extern int disable_ertm; 540extern int disable_ertm;
522 541
523int l2cap_init_sockets(void); 542int l2cap_init_sockets(void);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 6e343126f388..93b5da69cda5 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -613,10 +613,10 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control)
613static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control) 613static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control)
614{ 614{
615 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { 615 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
616 control |= L2CAP_SUPER_RCV_NOT_READY; 616 control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR);
617 set_bit(CONN_RNR_SENT, &chan->conn_state); 617 set_bit(CONN_RNR_SENT, &chan->conn_state);
618 } else 618 } else
619 control |= L2CAP_SUPER_RCV_READY; 619 control |= __set_ctrl_super(chan, L2CAP_SUPER_RR);
620 620
621 control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; 621 control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
622 622
@@ -1408,7 +1408,7 @@ static void l2cap_send_ack(struct l2cap_chan *chan)
1408 control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; 1408 control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
1409 1409
1410 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { 1410 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
1411 control |= L2CAP_SUPER_RCV_NOT_READY; 1411 control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR);
1412 set_bit(CONN_RNR_SENT, &chan->conn_state); 1412 set_bit(CONN_RNR_SENT, &chan->conn_state);
1413 l2cap_send_sframe(chan, control); 1413 l2cap_send_sframe(chan, control);
1414 return; 1414 return;
@@ -1417,7 +1417,7 @@ static void l2cap_send_ack(struct l2cap_chan *chan)
1417 if (l2cap_ertm_send(chan) > 0) 1417 if (l2cap_ertm_send(chan) > 0)
1418 return; 1418 return;
1419 1419
1420 control |= L2CAP_SUPER_RCV_READY; 1420 control |= __set_ctrl_super(chan, L2CAP_SUPER_RR);
1421 l2cap_send_sframe(chan, control); 1421 l2cap_send_sframe(chan, control);
1422} 1422}
1423 1423
@@ -1426,7 +1426,7 @@ static void l2cap_send_srejtail(struct l2cap_chan *chan)
1426 struct srej_list *tail; 1426 struct srej_list *tail;
1427 u16 control; 1427 u16 control;
1428 1428
1429 control = L2CAP_SUPER_SELECT_REJECT; 1429 control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ);
1430 control |= L2CAP_CTRL_FINAL; 1430 control |= L2CAP_CTRL_FINAL;
1431 1431
1432 tail = list_entry((&chan->srej_l)->prev, struct srej_list, list); 1432 tail = list_entry((&chan->srej_l)->prev, struct srej_list, list);
@@ -3119,7 +3119,7 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
3119 control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; 3119 control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3120 3120
3121 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { 3121 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
3122 control |= L2CAP_SUPER_RCV_NOT_READY; 3122 control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR);
3123 l2cap_send_sframe(chan, control); 3123 l2cap_send_sframe(chan, control);
3124 set_bit(CONN_RNR_SENT, &chan->conn_state); 3124 set_bit(CONN_RNR_SENT, &chan->conn_state);
3125 } 3125 }
@@ -3131,7 +3131,7 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
3131 3131
3132 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) && 3132 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
3133 chan->frames_sent == 0) { 3133 chan->frames_sent == 0) {
3134 control |= L2CAP_SUPER_RCV_READY; 3134 control |= __set_ctrl_super(chan, L2CAP_SUPER_RR);
3135 l2cap_send_sframe(chan, control); 3135 l2cap_send_sframe(chan, control);
3136 } 3136 }
3137} 3137}
@@ -3287,7 +3287,7 @@ static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan)
3287 set_bit(CONN_LOCAL_BUSY, &chan->conn_state); 3287 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
3288 3288
3289 control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; 3289 control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3290 control |= L2CAP_SUPER_RCV_NOT_READY; 3290 control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR);
3291 l2cap_send_sframe(chan, control); 3291 l2cap_send_sframe(chan, control);
3292 3292
3293 set_bit(CONN_RNR_SENT, &chan->conn_state); 3293 set_bit(CONN_RNR_SENT, &chan->conn_state);
@@ -3303,7 +3303,8 @@ static void l2cap_ertm_exit_local_busy(struct l2cap_chan *chan)
3303 goto done; 3303 goto done;
3304 3304
3305 control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; 3305 control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3306 control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; 3306 control |= L2CAP_CTRL_POLL;
3307 control |= __set_ctrl_super(chan, L2CAP_SUPER_RR);
3307 l2cap_send_sframe(chan, control); 3308 l2cap_send_sframe(chan, control);
3308 chan->retry_count = 1; 3309 chan->retry_count = 1;
3309 3310
@@ -3367,7 +3368,7 @@ static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq)
3367 kfree(l); 3368 kfree(l);
3368 return; 3369 return;
3369 } 3370 }
3370 control = L2CAP_SUPER_SELECT_REJECT; 3371 control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ);
3371 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; 3372 control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3372 l2cap_send_sframe(chan, control); 3373 l2cap_send_sframe(chan, control);
3373 list_del(&l->list); 3374 list_del(&l->list);
@@ -3381,7 +3382,7 @@ static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq)
3381 u16 control; 3382 u16 control;
3382 3383
3383 while (tx_seq != chan->expected_tx_seq) { 3384 while (tx_seq != chan->expected_tx_seq) {
3384 control = L2CAP_SUPER_SELECT_REJECT; 3385 control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ);
3385 control |= chan->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; 3386 control |= chan->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
3386 l2cap_send_sframe(chan, control); 3387 l2cap_send_sframe(chan, control);
3387 3388
@@ -3645,10 +3646,12 @@ static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_c
3645 return; 3646 return;
3646 } 3647 }
3647 3648
3648 if (rx_control & L2CAP_CTRL_POLL) 3649 if (rx_control & L2CAP_CTRL_POLL) {
3649 l2cap_send_srejtail(chan); 3650 l2cap_send_srejtail(chan);
3650 else 3651 } else {
3651 l2cap_send_sframe(chan, L2CAP_SUPER_RCV_READY); 3652 rx_control = __set_ctrl_super(chan, L2CAP_SUPER_RR);
3653 l2cap_send_sframe(chan, rx_control);
3654 }
3652} 3655}
3653 3656
3654static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) 3657static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb)
@@ -3663,20 +3666,20 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_cont
3663 clear_bit(CONN_WAIT_F, &chan->conn_state); 3666 clear_bit(CONN_WAIT_F, &chan->conn_state);
3664 } 3667 }
3665 3668
3666 switch (rx_control & L2CAP_CTRL_SUPERVISE) { 3669 switch (__get_ctrl_super(chan, rx_control)) {
3667 case L2CAP_SUPER_RCV_READY: 3670 case L2CAP_SUPER_RR:
3668 l2cap_data_channel_rrframe(chan, rx_control); 3671 l2cap_data_channel_rrframe(chan, rx_control);
3669 break; 3672 break;
3670 3673
3671 case L2CAP_SUPER_REJECT: 3674 case L2CAP_SUPER_REJ:
3672 l2cap_data_channel_rejframe(chan, rx_control); 3675 l2cap_data_channel_rejframe(chan, rx_control);
3673 break; 3676 break;
3674 3677
3675 case L2CAP_SUPER_SELECT_REJECT: 3678 case L2CAP_SUPER_SREJ:
3676 l2cap_data_channel_srejframe(chan, rx_control); 3679 l2cap_data_channel_srejframe(chan, rx_control);
3677 break; 3680 break;
3678 3681
3679 case L2CAP_SUPER_RCV_NOT_READY: 3682 case L2CAP_SUPER_RNR:
3680 l2cap_data_channel_rnrframe(chan, rx_control); 3683 l2cap_data_channel_rnrframe(chan, rx_control);
3681 break; 3684 break;
3682 } 3685 }