diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-05 17:54:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-05 17:54:29 -0400 |
commit | cc998ff8811530be521f6b316f37ab7676a07938 (patch) | |
tree | a054b3bf4b2ef406bf756a6cfc9be2f9115f17ae /net/bluetooth/sco.c | |
parent | 57d730924d5cc2c3e280af16a9306587c3a511db (diff) | |
parent | 0d40f75bdab241868c0eb6f97aef9f8b3a66f7b3 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking changes from David Miller:
"Noteworthy changes this time around:
1) Multicast rejoin support for team driver, from Jiri Pirko.
2) Centralize and simplify TCP RTT measurement handling in order to
reduce the impact of bad RTO seeding from SYN/ACKs. Also, when
both timestamps and local RTT measurements are available prefer
the later because there are broken middleware devices which
scramble the timestamp.
From Yuchung Cheng.
3) Add TCP_NOTSENT_LOWAT socket option to limit the amount of kernel
memory consumed to queue up unsend user data. From Eric Dumazet.
4) Add a "physical port ID" abstraction for network devices, from
Jiri Pirko.
5) Add a "suppress" operation to influence fib_rules lookups, from
Stefan Tomanek.
6) Add a networking development FAQ, from Paul Gortmaker.
7) Extend the information provided by tcp_probe and add ipv6 support,
from Daniel Borkmann.
8) Use RCU locking more extensively in openvswitch data paths, from
Pravin B Shelar.
9) Add SCTP support to openvswitch, from Joe Stringer.
10) Add EF10 chip support to SFC driver, from Ben Hutchings.
11) Add new SYNPROXY netfilter target, from Patrick McHardy.
12) Compute a rate approximation for sending in TCP sockets, and use
this to more intelligently coalesce TSO frames. Furthermore, add
a new packet scheduler which takes advantage of this estimate when
available. From Eric Dumazet.
13) Allow AF_PACKET fanouts with random selection, from Daniel
Borkmann.
14) Add ipv6 support to vxlan driver, from Cong Wang"
Resolved conflicts as per discussion.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1218 commits)
openvswitch: Fix alignment of struct sw_flow_key.
netfilter: Fix build errors with xt_socket.c
tcp: Add missing braces to do_tcp_setsockopt
caif: Add missing braces to multiline if in cfctrl_linkup_request
bnx2x: Add missing braces in bnx2x:bnx2x_link_initialize
vxlan: Fix kernel panic on device delete.
net: mvneta: implement ->ndo_do_ioctl() to support PHY ioctls
net: mvneta: properly disable HW PHY polling and ensure adjust_link() works
icplus: Use netif_running to determine device state
ethernet/arc/arc_emac: Fix huge delays in large file copies
tuntap: orphan frags before trying to set tx timestamp
tuntap: purge socket error queue on detach
qlcnic: use standard NAPI weights
ipv6:introduce function to find route for redirect
bnx2x: VF RSS support - VF side
bnx2x: VF RSS support - PF side
vxlan: Notify drivers for listening UDP port changes
net: usbnet: update addr_assign_type if appropriate
driver/net: enic: update enic maintainers and driver
driver/net: enic: Exposing symbols for Cisco's low latency driver
...
Diffstat (limited to 'net/bluetooth/sco.c')
-rw-r--r-- | net/bluetooth/sco.c | 85 |
1 files changed, 70 insertions, 15 deletions
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index e7bd4eea575c..96bd388d93a4 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -176,8 +176,13 @@ static int sco_connect(struct sock *sk) | |||
176 | else | 176 | else |
177 | type = SCO_LINK; | 177 | type = SCO_LINK; |
178 | 178 | ||
179 | hcon = hci_connect(hdev, type, dst, BDADDR_BREDR, BT_SECURITY_LOW, | 179 | if (sco_pi(sk)->setting == BT_VOICE_TRANSPARENT && |
180 | HCI_AT_NO_BONDING); | 180 | (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev))) { |
181 | err = -EOPNOTSUPP; | ||
182 | goto done; | ||
183 | } | ||
184 | |||
185 | hcon = hci_connect_sco(hdev, type, dst, sco_pi(sk)->setting); | ||
181 | if (IS_ERR(hcon)) { | 186 | if (IS_ERR(hcon)) { |
182 | err = PTR_ERR(hcon); | 187 | err = PTR_ERR(hcon); |
183 | goto done; | 188 | goto done; |
@@ -417,6 +422,8 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int pro | |||
417 | sk->sk_protocol = proto; | 422 | sk->sk_protocol = proto; |
418 | sk->sk_state = BT_OPEN; | 423 | sk->sk_state = BT_OPEN; |
419 | 424 | ||
425 | sco_pi(sk)->setting = BT_VOICE_CVSD_16BIT; | ||
426 | |||
420 | setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk); | 427 | setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk); |
421 | 428 | ||
422 | bt_sock_link(&sco_sk_list, sk); | 429 | bt_sock_link(&sco_sk_list, sk); |
@@ -652,7 +659,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
652 | return err; | 659 | return err; |
653 | } | 660 | } |
654 | 661 | ||
655 | static void sco_conn_defer_accept(struct hci_conn *conn, int mask) | 662 | static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting) |
656 | { | 663 | { |
657 | struct hci_dev *hdev = conn->hdev; | 664 | struct hci_dev *hdev = conn->hdev; |
658 | 665 | ||
@@ -664,11 +671,7 @@ static void sco_conn_defer_accept(struct hci_conn *conn, int mask) | |||
664 | struct hci_cp_accept_conn_req cp; | 671 | struct hci_cp_accept_conn_req cp; |
665 | 672 | ||
666 | bacpy(&cp.bdaddr, &conn->dst); | 673 | bacpy(&cp.bdaddr, &conn->dst); |
667 | 674 | cp.role = 0x00; /* Ignored */ | |
668 | if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) | ||
669 | cp.role = 0x00; /* Become master */ | ||
670 | else | ||
671 | cp.role = 0x01; /* Remain slave */ | ||
672 | 675 | ||
673 | hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); | 676 | hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); |
674 | } else { | 677 | } else { |
@@ -679,9 +682,21 @@ static void sco_conn_defer_accept(struct hci_conn *conn, int mask) | |||
679 | 682 | ||
680 | cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); | 683 | cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); |
681 | cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); | 684 | cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); |
682 | cp.max_latency = __constant_cpu_to_le16(0xffff); | 685 | cp.content_format = cpu_to_le16(setting); |
683 | cp.content_format = cpu_to_le16(hdev->voice_setting); | 686 | |
684 | cp.retrans_effort = 0xff; | 687 | switch (setting & SCO_AIRMODE_MASK) { |
688 | case SCO_AIRMODE_TRANSP: | ||
689 | if (conn->pkt_type & ESCO_2EV3) | ||
690 | cp.max_latency = __constant_cpu_to_le16(0x0008); | ||
691 | else | ||
692 | cp.max_latency = __constant_cpu_to_le16(0x000D); | ||
693 | cp.retrans_effort = 0x02; | ||
694 | break; | ||
695 | case SCO_AIRMODE_CVSD: | ||
696 | cp.max_latency = __constant_cpu_to_le16(0xffff); | ||
697 | cp.retrans_effort = 0xff; | ||
698 | break; | ||
699 | } | ||
685 | 700 | ||
686 | hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, | 701 | hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, |
687 | sizeof(cp), &cp); | 702 | sizeof(cp), &cp); |
@@ -698,7 +713,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
698 | 713 | ||
699 | if (sk->sk_state == BT_CONNECT2 && | 714 | if (sk->sk_state == BT_CONNECT2 && |
700 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { | 715 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { |
701 | sco_conn_defer_accept(pi->conn->hcon, 0); | 716 | sco_conn_defer_accept(pi->conn->hcon, pi->setting); |
702 | sk->sk_state = BT_CONFIG; | 717 | sk->sk_state = BT_CONFIG; |
703 | msg->msg_namelen = 0; | 718 | msg->msg_namelen = 0; |
704 | 719 | ||
@@ -714,7 +729,8 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
714 | static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) | 729 | static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) |
715 | { | 730 | { |
716 | struct sock *sk = sock->sk; | 731 | struct sock *sk = sock->sk; |
717 | int err = 0; | 732 | int len, err = 0; |
733 | struct bt_voice voice; | ||
718 | u32 opt; | 734 | u32 opt; |
719 | 735 | ||
720 | BT_DBG("sk %p", sk); | 736 | BT_DBG("sk %p", sk); |
@@ -740,6 +756,31 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char | |||
740 | clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); | 756 | clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); |
741 | break; | 757 | break; |
742 | 758 | ||
759 | case BT_VOICE: | ||
760 | if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND && | ||
761 | sk->sk_state != BT_CONNECT2) { | ||
762 | err = -EINVAL; | ||
763 | break; | ||
764 | } | ||
765 | |||
766 | voice.setting = sco_pi(sk)->setting; | ||
767 | |||
768 | len = min_t(unsigned int, sizeof(voice), optlen); | ||
769 | if (copy_from_user((char *) &voice, optval, len)) { | ||
770 | err = -EFAULT; | ||
771 | break; | ||
772 | } | ||
773 | |||
774 | /* Explicitly check for these values */ | ||
775 | if (voice.setting != BT_VOICE_TRANSPARENT && | ||
776 | voice.setting != BT_VOICE_CVSD_16BIT) { | ||
777 | err = -EINVAL; | ||
778 | break; | ||
779 | } | ||
780 | |||
781 | sco_pi(sk)->setting = voice.setting; | ||
782 | break; | ||
783 | |||
743 | default: | 784 | default: |
744 | err = -ENOPROTOOPT; | 785 | err = -ENOPROTOOPT; |
745 | break; | 786 | break; |
@@ -765,7 +806,9 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user | |||
765 | 806 | ||
766 | switch (optname) { | 807 | switch (optname) { |
767 | case SCO_OPTIONS: | 808 | case SCO_OPTIONS: |
768 | if (sk->sk_state != BT_CONNECTED) { | 809 | if (sk->sk_state != BT_CONNECTED && |
810 | !(sk->sk_state == BT_CONNECT2 && | ||
811 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) { | ||
769 | err = -ENOTCONN; | 812 | err = -ENOTCONN; |
770 | break; | 813 | break; |
771 | } | 814 | } |
@@ -781,7 +824,9 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user | |||
781 | break; | 824 | break; |
782 | 825 | ||
783 | case SCO_CONNINFO: | 826 | case SCO_CONNINFO: |
784 | if (sk->sk_state != BT_CONNECTED) { | 827 | if (sk->sk_state != BT_CONNECTED && |
828 | !(sk->sk_state == BT_CONNECT2 && | ||
829 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))) { | ||
785 | err = -ENOTCONN; | 830 | err = -ENOTCONN; |
786 | break; | 831 | break; |
787 | } | 832 | } |
@@ -809,6 +854,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char | |||
809 | { | 854 | { |
810 | struct sock *sk = sock->sk; | 855 | struct sock *sk = sock->sk; |
811 | int len, err = 0; | 856 | int len, err = 0; |
857 | struct bt_voice voice; | ||
812 | 858 | ||
813 | BT_DBG("sk %p", sk); | 859 | BT_DBG("sk %p", sk); |
814 | 860 | ||
@@ -834,6 +880,15 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char | |||
834 | 880 | ||
835 | break; | 881 | break; |
836 | 882 | ||
883 | case BT_VOICE: | ||
884 | voice.setting = sco_pi(sk)->setting; | ||
885 | |||
886 | len = min_t(unsigned int, len, sizeof(voice)); | ||
887 | if (copy_to_user(optval, (char *)&voice, len)) | ||
888 | err = -EFAULT; | ||
889 | |||
890 | break; | ||
891 | |||
837 | default: | 892 | default: |
838 | err = -ENOPROTOOPT; | 893 | err = -ENOPROTOOPT; |
839 | break; | 894 | break; |