diff options
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r-- | net/bluetooth/l2cap.c | 137 |
1 files changed, 99 insertions, 38 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 947f8bbb4bb3..5129b88c8e5b 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #define VERSION "2.14" | 54 | #define VERSION "2.14" |
55 | 55 | ||
56 | static int enable_ertm = 0; | 56 | static int enable_ertm = 0; |
57 | static int max_transmit = L2CAP_DEFAULT_MAX_TX; | ||
57 | 58 | ||
58 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; | 59 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; |
59 | static u8 l2cap_fixed_chan[8] = { 0x02, }; | 60 | static u8 l2cap_fixed_chan[8] = { 0x02, }; |
@@ -373,6 +374,8 @@ static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control) | |||
373 | else | 374 | else |
374 | control |= L2CAP_SUPER_RCV_READY; | 375 | control |= L2CAP_SUPER_RCV_READY; |
375 | 376 | ||
377 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | ||
378 | |||
376 | return l2cap_send_sframe(pi, control); | 379 | return l2cap_send_sframe(pi, control); |
377 | } | 380 | } |
378 | 381 | ||
@@ -819,7 +822,8 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p | |||
819 | return sk; | 822 | return sk; |
820 | } | 823 | } |
821 | 824 | ||
822 | static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol) | 825 | static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, |
826 | int kern) | ||
823 | { | 827 | { |
824 | struct sock *sk; | 828 | struct sock *sk; |
825 | 829 | ||
@@ -831,7 +835,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol) | |||
831 | sock->type != SOCK_DGRAM && sock->type != SOCK_RAW) | 835 | sock->type != SOCK_DGRAM && sock->type != SOCK_RAW) |
832 | return -ESOCKTNOSUPPORT; | 836 | return -ESOCKTNOSUPPORT; |
833 | 837 | ||
834 | if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW)) | 838 | if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW)) |
835 | return -EPERM; | 839 | return -EPERM; |
836 | 840 | ||
837 | sock->ops = &l2cap_sock_ops; | 841 | sock->ops = &l2cap_sock_ops; |
@@ -1332,7 +1336,7 @@ static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq) | |||
1332 | tx_skb = skb_clone(skb, GFP_ATOMIC); | 1336 | tx_skb = skb_clone(skb, GFP_ATOMIC); |
1333 | bt_cb(skb)->retries++; | 1337 | bt_cb(skb)->retries++; |
1334 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1338 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); |
1335 | control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1339 | control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) |
1336 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1340 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); |
1337 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1341 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); |
1338 | 1342 | ||
@@ -1361,8 +1365,8 @@ static int l2cap_ertm_send(struct sock *sk) | |||
1361 | if (pi->conn_state & L2CAP_CONN_WAIT_F) | 1365 | if (pi->conn_state & L2CAP_CONN_WAIT_F) |
1362 | return 0; | 1366 | return 0; |
1363 | 1367 | ||
1364 | while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) | 1368 | while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) && |
1365 | && !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) { | 1369 | !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) { |
1366 | tx_skb = skb_clone(skb, GFP_ATOMIC); | 1370 | tx_skb = skb_clone(skb, GFP_ATOMIC); |
1367 | 1371 | ||
1368 | if (pi->remote_max_tx && | 1372 | if (pi->remote_max_tx && |
@@ -1374,7 +1378,7 @@ static int l2cap_ertm_send(struct sock *sk) | |||
1374 | bt_cb(skb)->retries++; | 1378 | bt_cb(skb)->retries++; |
1375 | 1379 | ||
1376 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1380 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); |
1377 | control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1381 | control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) |
1378 | | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1382 | | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); |
1379 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1383 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); |
1380 | 1384 | ||
@@ -1603,8 +1607,8 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1603 | return -EOPNOTSUPP; | 1607 | return -EOPNOTSUPP; |
1604 | 1608 | ||
1605 | /* Check outgoing MTU */ | 1609 | /* Check outgoing MTU */ |
1606 | if (sk->sk_type == SOCK_SEQPACKET && pi->mode == L2CAP_MODE_BASIC | 1610 | if (sk->sk_type == SOCK_SEQPACKET && pi->mode == L2CAP_MODE_BASIC && |
1607 | && len > pi->omtu) | 1611 | len > pi->omtu) |
1608 | return -EINVAL; | 1612 | return -EINVAL; |
1609 | 1613 | ||
1610 | lock_sock(sk); | 1614 | lock_sock(sk); |
@@ -2172,6 +2176,21 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) | |||
2172 | *ptr += L2CAP_CONF_OPT_SIZE + len; | 2176 | *ptr += L2CAP_CONF_OPT_SIZE + len; |
2173 | } | 2177 | } |
2174 | 2178 | ||
2179 | static inline void l2cap_ertm_init(struct sock *sk) | ||
2180 | { | ||
2181 | l2cap_pi(sk)->expected_ack_seq = 0; | ||
2182 | l2cap_pi(sk)->unacked_frames = 0; | ||
2183 | l2cap_pi(sk)->buffer_seq = 0; | ||
2184 | l2cap_pi(sk)->num_to_ack = 0; | ||
2185 | |||
2186 | setup_timer(&l2cap_pi(sk)->retrans_timer, | ||
2187 | l2cap_retrans_timeout, (unsigned long) sk); | ||
2188 | setup_timer(&l2cap_pi(sk)->monitor_timer, | ||
2189 | l2cap_monitor_timeout, (unsigned long) sk); | ||
2190 | |||
2191 | __skb_queue_head_init(SREJ_QUEUE(sk)); | ||
2192 | } | ||
2193 | |||
2175 | static int l2cap_mode_supported(__u8 mode, __u32 feat_mask) | 2194 | static int l2cap_mode_supported(__u8 mode, __u32 feat_mask) |
2176 | { | 2195 | { |
2177 | u32 local_feat_mask = l2cap_feat_mask; | 2196 | u32 local_feat_mask = l2cap_feat_mask; |
@@ -2235,7 +2254,7 @@ done: | |||
2235 | case L2CAP_MODE_ERTM: | 2254 | case L2CAP_MODE_ERTM: |
2236 | rfc.mode = L2CAP_MODE_ERTM; | 2255 | rfc.mode = L2CAP_MODE_ERTM; |
2237 | rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW; | 2256 | rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW; |
2238 | rfc.max_transmit = L2CAP_DEFAULT_MAX_TX; | 2257 | rfc.max_transmit = max_transmit; |
2239 | rfc.retrans_timeout = 0; | 2258 | rfc.retrans_timeout = 0; |
2240 | rfc.monitor_timeout = 0; | 2259 | rfc.monitor_timeout = 0; |
2241 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); | 2260 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); |
@@ -2755,22 +2774,18 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2755 | goto unlock; | 2774 | goto unlock; |
2756 | 2775 | ||
2757 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { | 2776 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { |
2758 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) | 2777 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || |
2759 | || l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) | 2778 | l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) |
2760 | l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; | 2779 | l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; |
2761 | 2780 | ||
2762 | sk->sk_state = BT_CONNECTED; | 2781 | sk->sk_state = BT_CONNECTED; |
2763 | l2cap_pi(sk)->next_tx_seq = 0; | ||
2764 | l2cap_pi(sk)->expected_ack_seq = 0; | ||
2765 | l2cap_pi(sk)->unacked_frames = 0; | ||
2766 | |||
2767 | setup_timer(&l2cap_pi(sk)->retrans_timer, | ||
2768 | l2cap_retrans_timeout, (unsigned long) sk); | ||
2769 | setup_timer(&l2cap_pi(sk)->monitor_timer, | ||
2770 | l2cap_monitor_timeout, (unsigned long) sk); | ||
2771 | 2782 | ||
2783 | l2cap_pi(sk)->next_tx_seq = 0; | ||
2784 | l2cap_pi(sk)->expected_tx_seq = 0; | ||
2772 | __skb_queue_head_init(TX_QUEUE(sk)); | 2785 | __skb_queue_head_init(TX_QUEUE(sk)); |
2773 | __skb_queue_head_init(SREJ_QUEUE(sk)); | 2786 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) |
2787 | l2cap_ertm_init(sk); | ||
2788 | |||
2774 | l2cap_chan_ready(sk); | 2789 | l2cap_chan_ready(sk); |
2775 | goto unlock; | 2790 | goto unlock; |
2776 | } | 2791 | } |
@@ -2844,16 +2859,17 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2844 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; | 2859 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; |
2845 | 2860 | ||
2846 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { | 2861 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { |
2847 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) | 2862 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || |
2848 | || l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) | 2863 | l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) |
2849 | l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; | 2864 | l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; |
2850 | 2865 | ||
2851 | sk->sk_state = BT_CONNECTED; | 2866 | sk->sk_state = BT_CONNECTED; |
2867 | l2cap_pi(sk)->next_tx_seq = 0; | ||
2852 | l2cap_pi(sk)->expected_tx_seq = 0; | 2868 | l2cap_pi(sk)->expected_tx_seq = 0; |
2853 | l2cap_pi(sk)->buffer_seq = 0; | ||
2854 | l2cap_pi(sk)->num_to_ack = 0; | ||
2855 | __skb_queue_head_init(TX_QUEUE(sk)); | 2869 | __skb_queue_head_init(TX_QUEUE(sk)); |
2856 | __skb_queue_head_init(SREJ_QUEUE(sk)); | 2870 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) |
2871 | l2cap_ertm_init(sk); | ||
2872 | |||
2857 | l2cap_chan_ready(sk); | 2873 | l2cap_chan_ready(sk); |
2858 | } | 2874 | } |
2859 | 2875 | ||
@@ -2885,9 +2901,12 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
2885 | sk->sk_shutdown = SHUTDOWN_MASK; | 2901 | sk->sk_shutdown = SHUTDOWN_MASK; |
2886 | 2902 | ||
2887 | skb_queue_purge(TX_QUEUE(sk)); | 2903 | skb_queue_purge(TX_QUEUE(sk)); |
2888 | skb_queue_purge(SREJ_QUEUE(sk)); | 2904 | |
2889 | del_timer(&l2cap_pi(sk)->retrans_timer); | 2905 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { |
2890 | del_timer(&l2cap_pi(sk)->monitor_timer); | 2906 | skb_queue_purge(SREJ_QUEUE(sk)); |
2907 | del_timer(&l2cap_pi(sk)->retrans_timer); | ||
2908 | del_timer(&l2cap_pi(sk)->monitor_timer); | ||
2909 | } | ||
2891 | 2910 | ||
2892 | l2cap_chan_del(sk, ECONNRESET); | 2911 | l2cap_chan_del(sk, ECONNRESET); |
2893 | bh_unlock_sock(sk); | 2912 | bh_unlock_sock(sk); |
@@ -2912,9 +2931,12 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd | |||
2912 | return 0; | 2931 | return 0; |
2913 | 2932 | ||
2914 | skb_queue_purge(TX_QUEUE(sk)); | 2933 | skb_queue_purge(TX_QUEUE(sk)); |
2915 | skb_queue_purge(SREJ_QUEUE(sk)); | 2934 | |
2916 | del_timer(&l2cap_pi(sk)->retrans_timer); | 2935 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { |
2917 | del_timer(&l2cap_pi(sk)->monitor_timer); | 2936 | skb_queue_purge(SREJ_QUEUE(sk)); |
2937 | del_timer(&l2cap_pi(sk)->retrans_timer); | ||
2938 | del_timer(&l2cap_pi(sk)->monitor_timer); | ||
2939 | } | ||
2918 | 2940 | ||
2919 | l2cap_chan_del(sk, 0); | 2941 | l2cap_chan_del(sk, 0); |
2920 | bh_unlock_sock(sk); | 2942 | bh_unlock_sock(sk); |
@@ -3279,12 +3301,16 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str | |||
3279 | { | 3301 | { |
3280 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 3302 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
3281 | u8 tx_seq = __get_txseq(rx_control); | 3303 | u8 tx_seq = __get_txseq(rx_control); |
3304 | u8 req_seq = __get_reqseq(rx_control); | ||
3282 | u16 tx_control = 0; | 3305 | u16 tx_control = 0; |
3283 | u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; | 3306 | u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; |
3284 | int err = 0; | 3307 | int err = 0; |
3285 | 3308 | ||
3286 | BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len); | 3309 | BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len); |
3287 | 3310 | ||
3311 | pi->expected_ack_seq = req_seq; | ||
3312 | l2cap_drop_acked_frames(sk); | ||
3313 | |||
3288 | if (tx_seq == pi->expected_tx_seq) | 3314 | if (tx_seq == pi->expected_tx_seq) |
3289 | goto expected; | 3315 | goto expected; |
3290 | 3316 | ||
@@ -3339,6 +3365,16 @@ expected: | |||
3339 | return 0; | 3365 | return 0; |
3340 | } | 3366 | } |
3341 | 3367 | ||
3368 | if (rx_control & L2CAP_CTRL_FINAL) { | ||
3369 | if (pi->conn_state & L2CAP_CONN_REJ_ACT) | ||
3370 | pi->conn_state &= ~L2CAP_CONN_REJ_ACT; | ||
3371 | else { | ||
3372 | sk->sk_send_head = TX_QUEUE(sk)->next; | ||
3373 | pi->next_tx_seq = pi->expected_ack_seq; | ||
3374 | l2cap_ertm_send(sk); | ||
3375 | } | ||
3376 | } | ||
3377 | |||
3342 | pi->buffer_seq = (pi->buffer_seq + 1) % 64; | 3378 | pi->buffer_seq = (pi->buffer_seq + 1) % 64; |
3343 | 3379 | ||
3344 | err = l2cap_sar_reassembly_sdu(sk, skb, rx_control); | 3380 | err = l2cap_sar_reassembly_sdu(sk, skb, rx_control); |
@@ -3375,6 +3411,14 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str | |||
3375 | pi->expected_ack_seq = tx_seq; | 3411 | pi->expected_ack_seq = tx_seq; |
3376 | l2cap_drop_acked_frames(sk); | 3412 | l2cap_drop_acked_frames(sk); |
3377 | 3413 | ||
3414 | if (pi->conn_state & L2CAP_CONN_REJ_ACT) | ||
3415 | pi->conn_state &= ~L2CAP_CONN_REJ_ACT; | ||
3416 | else { | ||
3417 | sk->sk_send_head = TX_QUEUE(sk)->next; | ||
3418 | pi->next_tx_seq = pi->expected_ack_seq; | ||
3419 | l2cap_ertm_send(sk); | ||
3420 | } | ||
3421 | |||
3378 | if (!(pi->conn_state & L2CAP_CONN_WAIT_F)) | 3422 | if (!(pi->conn_state & L2CAP_CONN_WAIT_F)) |
3379 | break; | 3423 | break; |
3380 | 3424 | ||
@@ -3387,8 +3431,8 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str | |||
3387 | pi->expected_ack_seq = tx_seq; | 3431 | pi->expected_ack_seq = tx_seq; |
3388 | l2cap_drop_acked_frames(sk); | 3432 | l2cap_drop_acked_frames(sk); |
3389 | 3433 | ||
3390 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) | 3434 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && |
3391 | && (pi->unacked_frames > 0)) | 3435 | (pi->unacked_frames > 0)) |
3392 | __mod_retrans_timer(); | 3436 | __mod_retrans_timer(); |
3393 | 3437 | ||
3394 | l2cap_ertm_send(sk); | 3438 | l2cap_ertm_send(sk); |
@@ -3402,10 +3446,24 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str | |||
3402 | pi->expected_ack_seq = __get_reqseq(rx_control); | 3446 | pi->expected_ack_seq = __get_reqseq(rx_control); |
3403 | l2cap_drop_acked_frames(sk); | 3447 | l2cap_drop_acked_frames(sk); |
3404 | 3448 | ||
3405 | sk->sk_send_head = TX_QUEUE(sk)->next; | 3449 | if (rx_control & L2CAP_CTRL_FINAL) { |
3406 | pi->next_tx_seq = pi->expected_ack_seq; | 3450 | if (pi->conn_state & L2CAP_CONN_REJ_ACT) |
3451 | pi->conn_state &= ~L2CAP_CONN_REJ_ACT; | ||
3452 | else { | ||
3453 | sk->sk_send_head = TX_QUEUE(sk)->next; | ||
3454 | pi->next_tx_seq = pi->expected_ack_seq; | ||
3455 | l2cap_ertm_send(sk); | ||
3456 | } | ||
3457 | } else { | ||
3458 | sk->sk_send_head = TX_QUEUE(sk)->next; | ||
3459 | pi->next_tx_seq = pi->expected_ack_seq; | ||
3460 | l2cap_ertm_send(sk); | ||
3407 | 3461 | ||
3408 | l2cap_ertm_send(sk); | 3462 | if (pi->conn_state & L2CAP_CONN_WAIT_F) { |
3463 | pi->srej_save_reqseq = tx_seq; | ||
3464 | pi->conn_state |= L2CAP_CONN_REJ_ACT; | ||
3465 | } | ||
3466 | } | ||
3409 | 3467 | ||
3410 | break; | 3468 | break; |
3411 | 3469 | ||
@@ -3424,7 +3482,7 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str | |||
3424 | } else if (rx_control & L2CAP_CTRL_FINAL) { | 3482 | } else if (rx_control & L2CAP_CTRL_FINAL) { |
3425 | if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) && | 3483 | if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) && |
3426 | pi->srej_save_reqseq == tx_seq) | 3484 | pi->srej_save_reqseq == tx_seq) |
3427 | pi->srej_save_reqseq &= ~L2CAP_CONN_SREJ_ACT; | 3485 | pi->conn_state &= ~L2CAP_CONN_SREJ_ACT; |
3428 | else | 3486 | else |
3429 | l2cap_retransmit_frame(sk, tx_seq); | 3487 | l2cap_retransmit_frame(sk, tx_seq); |
3430 | } | 3488 | } |
@@ -3924,7 +3982,7 @@ static const struct proto_ops l2cap_sock_ops = { | |||
3924 | .getsockopt = l2cap_sock_getsockopt | 3982 | .getsockopt = l2cap_sock_getsockopt |
3925 | }; | 3983 | }; |
3926 | 3984 | ||
3927 | static struct net_proto_family l2cap_sock_family_ops = { | 3985 | static const struct net_proto_family l2cap_sock_family_ops = { |
3928 | .family = PF_BLUETOOTH, | 3986 | .family = PF_BLUETOOTH, |
3929 | .owner = THIS_MODULE, | 3987 | .owner = THIS_MODULE, |
3930 | .create = l2cap_sock_create, | 3988 | .create = l2cap_sock_create, |
@@ -4003,6 +4061,9 @@ module_exit(l2cap_exit); | |||
4003 | module_param(enable_ertm, bool, 0644); | 4061 | module_param(enable_ertm, bool, 0644); |
4004 | MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode"); | 4062 | MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode"); |
4005 | 4063 | ||
4064 | module_param(max_transmit, uint, 0644); | ||
4065 | MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)"); | ||
4066 | |||
4006 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); | 4067 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); |
4007 | MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); | 4068 | MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); |
4008 | MODULE_VERSION(VERSION); | 4069 | MODULE_VERSION(VERSION); |