| .. | .. |
|---|
| 40 | 40 | static bool disable_cfc; |
|---|
| 41 | 41 | static bool l2cap_ertm; |
|---|
| 42 | 42 | static int channel_mtu = -1; |
|---|
| 43 | | -static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU; |
|---|
| 44 | 43 | |
|---|
| 45 | 44 | static struct task_struct *rfcomm_thread; |
|---|
| 46 | 45 | |
|---|
| .. | .. |
|---|
| 73 | 72 | |
|---|
| 74 | 73 | /* ---- RFCOMM frame parsing macros ---- */ |
|---|
| 75 | 74 | #define __get_dlci(b) ((b & 0xfc) >> 2) |
|---|
| 76 | | -#define __get_channel(b) ((b & 0xf8) >> 3) |
|---|
| 77 | | -#define __get_dir(b) ((b & 0x04) >> 2) |
|---|
| 78 | 75 | #define __get_type(b) ((b & 0xef)) |
|---|
| 79 | 76 | |
|---|
| 80 | 77 | #define __test_ea(b) ((b & 0x01)) |
|---|
| .. | .. |
|---|
| 87 | 84 | #define __ctrl(type, pf) (((type & 0xef) | (pf << 4))) |
|---|
| 88 | 85 | #define __dlci(dir, chn) (((chn & 0x1f) << 1) | dir) |
|---|
| 89 | 86 | #define __srv_channel(dlci) (dlci >> 1) |
|---|
| 90 | | -#define __dir(dlci) (dlci & 0x01) |
|---|
| 91 | 87 | |
|---|
| 92 | 88 | #define __len8(len) (((len) << 1) | 1) |
|---|
| 93 | 89 | #define __len16(len) ((len) << 1) |
|---|
| .. | .. |
|---|
| 483 | 479 | /* if closing a dlc in a session that hasn't been started, |
|---|
| 484 | 480 | * just close and unlink the dlc |
|---|
| 485 | 481 | */ |
|---|
| 482 | + fallthrough; |
|---|
| 486 | 483 | |
|---|
| 487 | 484 | default: |
|---|
| 488 | 485 | rfcomm_dlc_clear_timer(d); |
|---|
| .. | .. |
|---|
| 552 | 549 | return dlc; |
|---|
| 553 | 550 | } |
|---|
| 554 | 551 | |
|---|
| 555 | | -int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) |
|---|
| 552 | +static int rfcomm_dlc_send_frag(struct rfcomm_dlc *d, struct sk_buff *frag) |
|---|
| 556 | 553 | { |
|---|
| 557 | | - int len = skb->len; |
|---|
| 558 | | - |
|---|
| 559 | | - if (d->state != BT_CONNECTED) |
|---|
| 560 | | - return -ENOTCONN; |
|---|
| 554 | + int len = frag->len; |
|---|
| 561 | 555 | |
|---|
| 562 | 556 | BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len); |
|---|
| 563 | 557 | |
|---|
| 564 | 558 | if (len > d->mtu) |
|---|
| 565 | 559 | return -EINVAL; |
|---|
| 566 | 560 | |
|---|
| 567 | | - rfcomm_make_uih(skb, d->addr); |
|---|
| 568 | | - skb_queue_tail(&d->tx_queue, skb); |
|---|
| 561 | + rfcomm_make_uih(frag, d->addr); |
|---|
| 562 | + __skb_queue_tail(&d->tx_queue, frag); |
|---|
| 569 | 563 | |
|---|
| 570 | | - if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags)) |
|---|
| 564 | + return len; |
|---|
| 565 | +} |
|---|
| 566 | + |
|---|
| 567 | +int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) |
|---|
| 568 | +{ |
|---|
| 569 | + unsigned long flags; |
|---|
| 570 | + struct sk_buff *frag, *next; |
|---|
| 571 | + int len; |
|---|
| 572 | + |
|---|
| 573 | + if (d->state != BT_CONNECTED) |
|---|
| 574 | + return -ENOTCONN; |
|---|
| 575 | + |
|---|
| 576 | + frag = skb_shinfo(skb)->frag_list; |
|---|
| 577 | + skb_shinfo(skb)->frag_list = NULL; |
|---|
| 578 | + |
|---|
| 579 | + /* Queue all fragments atomically. */ |
|---|
| 580 | + spin_lock_irqsave(&d->tx_queue.lock, flags); |
|---|
| 581 | + |
|---|
| 582 | + len = rfcomm_dlc_send_frag(d, skb); |
|---|
| 583 | + if (len < 0 || !frag) |
|---|
| 584 | + goto unlock; |
|---|
| 585 | + |
|---|
| 586 | + for (; frag; frag = next) { |
|---|
| 587 | + int ret; |
|---|
| 588 | + |
|---|
| 589 | + next = frag->next; |
|---|
| 590 | + |
|---|
| 591 | + ret = rfcomm_dlc_send_frag(d, frag); |
|---|
| 592 | + if (ret < 0) { |
|---|
| 593 | + dev_kfree_skb_irq(frag); |
|---|
| 594 | + goto unlock; |
|---|
| 595 | + } |
|---|
| 596 | + |
|---|
| 597 | + len += ret; |
|---|
| 598 | + } |
|---|
| 599 | + |
|---|
| 600 | +unlock: |
|---|
| 601 | + spin_unlock_irqrestore(&d->tx_queue.lock, flags); |
|---|
| 602 | + |
|---|
| 603 | + if (len > 0 && !test_bit(RFCOMM_TX_THROTTLED, &d->flags)) |
|---|
| 571 | 604 | rfcomm_schedule(); |
|---|
| 572 | 605 | return len; |
|---|
| 573 | 606 | } |
|---|
| .. | .. |
|---|
| 751 | 784 | /* Set L2CAP options */ |
|---|
| 752 | 785 | sk = sock->sk; |
|---|
| 753 | 786 | lock_sock(sk); |
|---|
| 754 | | - l2cap_pi(sk)->chan->imtu = l2cap_mtu; |
|---|
| 787 | + /* Set MTU to 0 so L2CAP can auto select the MTU */ |
|---|
| 788 | + l2cap_pi(sk)->chan->imtu = 0; |
|---|
| 755 | 789 | l2cap_pi(sk)->chan->sec_level = sec_level; |
|---|
| 756 | 790 | if (l2cap_ertm) |
|---|
| 757 | 791 | l2cap_pi(sk)->chan->mode = L2CAP_MODE_ERTM; |
|---|
| .. | .. |
|---|
| 2038 | 2072 | /* Set L2CAP options */ |
|---|
| 2039 | 2073 | sk = sock->sk; |
|---|
| 2040 | 2074 | lock_sock(sk); |
|---|
| 2041 | | - l2cap_pi(sk)->chan->imtu = l2cap_mtu; |
|---|
| 2075 | + /* Set MTU to 0 so L2CAP can auto select the MTU */ |
|---|
| 2076 | + l2cap_pi(sk)->chan->imtu = 0; |
|---|
| 2042 | 2077 | release_sock(sk); |
|---|
| 2043 | 2078 | |
|---|
| 2044 | 2079 | /* Start listening on the socket */ |
|---|
| .. | .. |
|---|
| 2166 | 2201 | return 0; |
|---|
| 2167 | 2202 | } |
|---|
| 2168 | 2203 | |
|---|
| 2169 | | -static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file) |
|---|
| 2170 | | -{ |
|---|
| 2171 | | - return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private); |
|---|
| 2172 | | -} |
|---|
| 2173 | | - |
|---|
| 2174 | | -static const struct file_operations rfcomm_dlc_debugfs_fops = { |
|---|
| 2175 | | - .open = rfcomm_dlc_debugfs_open, |
|---|
| 2176 | | - .read = seq_read, |
|---|
| 2177 | | - .llseek = seq_lseek, |
|---|
| 2178 | | - .release = single_release, |
|---|
| 2179 | | -}; |
|---|
| 2204 | +DEFINE_SHOW_ATTRIBUTE(rfcomm_dlc_debugfs); |
|---|
| 2180 | 2205 | |
|---|
| 2181 | 2206 | static struct dentry *rfcomm_dlc_debugfs; |
|---|
| 2182 | 2207 | |
|---|
| .. | .. |
|---|
| 2245 | 2270 | |
|---|
| 2246 | 2271 | module_param(channel_mtu, int, 0644); |
|---|
| 2247 | 2272 | MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel"); |
|---|
| 2248 | | - |
|---|
| 2249 | | -module_param(l2cap_mtu, uint, 0644); |
|---|
| 2250 | | -MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection"); |
|---|
| 2251 | 2273 | |
|---|
| 2252 | 2274 | module_param(l2cap_ertm, bool, 0644); |
|---|
| 2253 | 2275 | MODULE_PARM_DESC(l2cap_ertm, "Use L2CAP ERTM mode for connection"); |
|---|