diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-07-29 14:47:07 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-07-29 14:47:07 -0400 |
commit | ae3568adf42d5d3bb3cfa505b94351c5d1ce4924 (patch) | |
tree | 112865a6e6b1e4ddf70362f3efb295c495ec85b9 /net | |
parent | 7f3e01fee41a322747db2d7574516d9fbd3785c0 (diff) | |
parent | b7753c8cd51dce67a0b152efb456a21ff1cc241b (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'net')
29 files changed, 907 insertions, 402 deletions
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index ee3b3049d385..ed371684c133 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig | |||
@@ -43,19 +43,6 @@ config BT_L2CAP | |||
43 | Say Y here to compile L2CAP support into the kernel or say M to | 43 | Say Y here to compile L2CAP support into the kernel or say M to |
44 | compile it as module (l2cap). | 44 | compile it as module (l2cap). |
45 | 45 | ||
46 | config BT_L2CAP_EXT_FEATURES | ||
47 | bool "L2CAP Extended Features support (EXPERIMENTAL)" | ||
48 | depends on BT_L2CAP && EXPERIMENTAL | ||
49 | help | ||
50 | This option enables the L2CAP Extended Features support. These | ||
51 | new features include the Enhanced Retransmission and Streaming | ||
52 | Modes, the Frame Check Sequence (FCS), and Segmentation and | ||
53 | Reassembly (SAR) for L2CAP packets. They are a required for the | ||
54 | new Alternate MAC/PHY and the Bluetooth Medical Profile. | ||
55 | |||
56 | You should say N unless you know what you are doing. Note that | ||
57 | this is in an experimental state yet. | ||
58 | |||
59 | config BT_SCO | 46 | config BT_SCO |
60 | tristate "SCO links support" | 47 | tristate "SCO links support" |
61 | depends on BT | 48 | depends on BT |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 800b6b9fbbae..0b1e460fe440 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | BlueZ - Bluetooth protocol stack for Linux | 2 | BlueZ - Bluetooth protocol stack for Linux |
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | 3 | Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. |
4 | 4 | ||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | 5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> |
6 | 6 | ||
@@ -155,6 +155,27 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) | |||
155 | hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp); | 155 | hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp); |
156 | } | 156 | } |
157 | 157 | ||
158 | /* Device _must_ be locked */ | ||
159 | void hci_sco_setup(struct hci_conn *conn, __u8 status) | ||
160 | { | ||
161 | struct hci_conn *sco = conn->link; | ||
162 | |||
163 | BT_DBG("%p", conn); | ||
164 | |||
165 | if (!sco) | ||
166 | return; | ||
167 | |||
168 | if (!status) { | ||
169 | if (lmp_esco_capable(conn->hdev)) | ||
170 | hci_setup_sync(sco, conn->handle); | ||
171 | else | ||
172 | hci_add_sco(sco, conn->handle); | ||
173 | } else { | ||
174 | hci_proto_connect_cfm(sco, status); | ||
175 | hci_conn_del(sco); | ||
176 | } | ||
177 | } | ||
178 | |||
158 | static void hci_conn_timeout(unsigned long arg) | 179 | static void hci_conn_timeout(unsigned long arg) |
159 | { | 180 | { |
160 | struct hci_conn *conn = (void *) arg; | 181 | struct hci_conn *conn = (void *) arg; |
@@ -385,10 +406,13 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
385 | acl->power_save = 1; | 406 | acl->power_save = 1; |
386 | hci_conn_enter_active_mode(acl); | 407 | hci_conn_enter_active_mode(acl); |
387 | 408 | ||
388 | if (lmp_esco_capable(hdev)) | 409 | if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) { |
389 | hci_setup_sync(sco, acl->handle); | 410 | /* defer SCO setup until mode change completed */ |
390 | else | 411 | set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->pend); |
391 | hci_add_sco(sco, acl->handle); | 412 | return sco; |
413 | } | ||
414 | |||
415 | hci_sco_setup(acl, 0x00); | ||
392 | } | 416 | } |
393 | 417 | ||
394 | return sco; | 418 | return sco; |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 2f768de87011..8303f1c9ef54 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -562,6 +562,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
562 | hci_dev_lock_bh(hdev); | 562 | hci_dev_lock_bh(hdev); |
563 | inquiry_cache_flush(hdev); | 563 | inquiry_cache_flush(hdev); |
564 | hci_conn_hash_flush(hdev); | 564 | hci_conn_hash_flush(hdev); |
565 | hci_blacklist_clear(hdev); | ||
565 | hci_dev_unlock_bh(hdev); | 566 | hci_dev_unlock_bh(hdev); |
566 | 567 | ||
567 | hci_notify(hdev, HCI_DEV_DOWN); | 568 | hci_notify(hdev, HCI_DEV_DOWN); |
@@ -913,7 +914,7 @@ int hci_register_dev(struct hci_dev *hdev) | |||
913 | skb_queue_head_init(&hdev->cmd_q); | 914 | skb_queue_head_init(&hdev->cmd_q); |
914 | skb_queue_head_init(&hdev->raw_q); | 915 | skb_queue_head_init(&hdev->raw_q); |
915 | 916 | ||
916 | for (i = 0; i < 3; i++) | 917 | for (i = 0; i < NUM_REASSEMBLY; i++) |
917 | hdev->reassembly[i] = NULL; | 918 | hdev->reassembly[i] = NULL; |
918 | 919 | ||
919 | init_waitqueue_head(&hdev->req_wait_q); | 920 | init_waitqueue_head(&hdev->req_wait_q); |
@@ -923,6 +924,8 @@ int hci_register_dev(struct hci_dev *hdev) | |||
923 | 924 | ||
924 | hci_conn_hash_init(hdev); | 925 | hci_conn_hash_init(hdev); |
925 | 926 | ||
927 | INIT_LIST_HEAD(&hdev->blacklist.list); | ||
928 | |||
926 | memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); | 929 | memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); |
927 | 930 | ||
928 | atomic_set(&hdev->promisc, 0); | 931 | atomic_set(&hdev->promisc, 0); |
@@ -970,7 +973,7 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
970 | 973 | ||
971 | hci_dev_do_close(hdev); | 974 | hci_dev_do_close(hdev); |
972 | 975 | ||
973 | for (i = 0; i < 3; i++) | 976 | for (i = 0; i < NUM_REASSEMBLY; i++) |
974 | kfree_skb(hdev->reassembly[i]); | 977 | kfree_skb(hdev->reassembly[i]); |
975 | 978 | ||
976 | hci_notify(hdev, HCI_DEV_UNREG); | 979 | hci_notify(hdev, HCI_DEV_UNREG); |
@@ -1030,89 +1033,170 @@ int hci_recv_frame(struct sk_buff *skb) | |||
1030 | } | 1033 | } |
1031 | EXPORT_SYMBOL(hci_recv_frame); | 1034 | EXPORT_SYMBOL(hci_recv_frame); |
1032 | 1035 | ||
1033 | /* Receive packet type fragment */ | 1036 | static int hci_reassembly(struct hci_dev *hdev, int type, void *data, |
1034 | #define __reassembly(hdev, type) ((hdev)->reassembly[(type) - 2]) | 1037 | int count, __u8 index, gfp_t gfp_mask) |
1035 | |||
1036 | int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) | ||
1037 | { | 1038 | { |
1038 | if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) | 1039 | int len = 0; |
1040 | int hlen = 0; | ||
1041 | int remain = count; | ||
1042 | struct sk_buff *skb; | ||
1043 | struct bt_skb_cb *scb; | ||
1044 | |||
1045 | if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || | ||
1046 | index >= NUM_REASSEMBLY) | ||
1039 | return -EILSEQ; | 1047 | return -EILSEQ; |
1040 | 1048 | ||
1049 | skb = hdev->reassembly[index]; | ||
1050 | |||
1051 | if (!skb) { | ||
1052 | switch (type) { | ||
1053 | case HCI_ACLDATA_PKT: | ||
1054 | len = HCI_MAX_FRAME_SIZE; | ||
1055 | hlen = HCI_ACL_HDR_SIZE; | ||
1056 | break; | ||
1057 | case HCI_EVENT_PKT: | ||
1058 | len = HCI_MAX_EVENT_SIZE; | ||
1059 | hlen = HCI_EVENT_HDR_SIZE; | ||
1060 | break; | ||
1061 | case HCI_SCODATA_PKT: | ||
1062 | len = HCI_MAX_SCO_SIZE; | ||
1063 | hlen = HCI_SCO_HDR_SIZE; | ||
1064 | break; | ||
1065 | } | ||
1066 | |||
1067 | skb = bt_skb_alloc(len, gfp_mask); | ||
1068 | if (!skb) | ||
1069 | return -ENOMEM; | ||
1070 | |||
1071 | scb = (void *) skb->cb; | ||
1072 | scb->expect = hlen; | ||
1073 | scb->pkt_type = type; | ||
1074 | |||
1075 | skb->dev = (void *) hdev; | ||
1076 | hdev->reassembly[index] = skb; | ||
1077 | } | ||
1078 | |||
1041 | while (count) { | 1079 | while (count) { |
1042 | struct sk_buff *skb = __reassembly(hdev, type); | 1080 | scb = (void *) skb->cb; |
1043 | struct { int expect; } *scb; | 1081 | len = min(scb->expect, (__u16)count); |
1044 | int len = 0; | ||
1045 | 1082 | ||
1046 | if (!skb) { | 1083 | memcpy(skb_put(skb, len), data, len); |
1047 | /* Start of the frame */ | ||
1048 | 1084 | ||
1049 | switch (type) { | 1085 | count -= len; |
1050 | case HCI_EVENT_PKT: | 1086 | data += len; |
1051 | if (count >= HCI_EVENT_HDR_SIZE) { | 1087 | scb->expect -= len; |
1052 | struct hci_event_hdr *h = data; | 1088 | remain = count; |
1053 | len = HCI_EVENT_HDR_SIZE + h->plen; | ||
1054 | } else | ||
1055 | return -EILSEQ; | ||
1056 | break; | ||
1057 | 1089 | ||
1058 | case HCI_ACLDATA_PKT: | 1090 | switch (type) { |
1059 | if (count >= HCI_ACL_HDR_SIZE) { | 1091 | case HCI_EVENT_PKT: |
1060 | struct hci_acl_hdr *h = data; | 1092 | if (skb->len == HCI_EVENT_HDR_SIZE) { |
1061 | len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen); | 1093 | struct hci_event_hdr *h = hci_event_hdr(skb); |
1062 | } else | 1094 | scb->expect = h->plen; |
1063 | return -EILSEQ; | 1095 | |
1064 | break; | 1096 | if (skb_tailroom(skb) < scb->expect) { |
1097 | kfree_skb(skb); | ||
1098 | hdev->reassembly[index] = NULL; | ||
1099 | return -ENOMEM; | ||
1100 | } | ||
1101 | } | ||
1102 | break; | ||
1065 | 1103 | ||
1066 | case HCI_SCODATA_PKT: | 1104 | case HCI_ACLDATA_PKT: |
1067 | if (count >= HCI_SCO_HDR_SIZE) { | 1105 | if (skb->len == HCI_ACL_HDR_SIZE) { |
1068 | struct hci_sco_hdr *h = data; | 1106 | struct hci_acl_hdr *h = hci_acl_hdr(skb); |
1069 | len = HCI_SCO_HDR_SIZE + h->dlen; | 1107 | scb->expect = __le16_to_cpu(h->dlen); |
1070 | } else | 1108 | |
1071 | return -EILSEQ; | 1109 | if (skb_tailroom(skb) < scb->expect) { |
1072 | break; | 1110 | kfree_skb(skb); |
1111 | hdev->reassembly[index] = NULL; | ||
1112 | return -ENOMEM; | ||
1113 | } | ||
1073 | } | 1114 | } |
1115 | break; | ||
1074 | 1116 | ||
1075 | skb = bt_skb_alloc(len, GFP_ATOMIC); | 1117 | case HCI_SCODATA_PKT: |
1076 | if (!skb) { | 1118 | if (skb->len == HCI_SCO_HDR_SIZE) { |
1077 | BT_ERR("%s no memory for packet", hdev->name); | 1119 | struct hci_sco_hdr *h = hci_sco_hdr(skb); |
1078 | return -ENOMEM; | 1120 | scb->expect = h->dlen; |
1121 | |||
1122 | if (skb_tailroom(skb) < scb->expect) { | ||
1123 | kfree_skb(skb); | ||
1124 | hdev->reassembly[index] = NULL; | ||
1125 | return -ENOMEM; | ||
1126 | } | ||
1079 | } | 1127 | } |
1128 | break; | ||
1129 | } | ||
1130 | |||
1131 | if (scb->expect == 0) { | ||
1132 | /* Complete frame */ | ||
1080 | 1133 | ||
1081 | skb->dev = (void *) hdev; | ||
1082 | bt_cb(skb)->pkt_type = type; | 1134 | bt_cb(skb)->pkt_type = type; |
1135 | hci_recv_frame(skb); | ||
1083 | 1136 | ||
1084 | __reassembly(hdev, type) = skb; | 1137 | hdev->reassembly[index] = NULL; |
1138 | return remain; | ||
1139 | } | ||
1140 | } | ||
1085 | 1141 | ||
1086 | scb = (void *) skb->cb; | 1142 | return remain; |
1087 | scb->expect = len; | 1143 | } |
1088 | } else { | ||
1089 | /* Continuation */ | ||
1090 | 1144 | ||
1091 | scb = (void *) skb->cb; | 1145 | int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) |
1092 | len = scb->expect; | 1146 | { |
1093 | } | 1147 | int rem = 0; |
1094 | 1148 | ||
1095 | len = min(len, count); | 1149 | if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) |
1150 | return -EILSEQ; | ||
1096 | 1151 | ||
1097 | memcpy(skb_put(skb, len), data, len); | 1152 | while (count) { |
1153 | rem = hci_reassembly(hdev, type, data, count, | ||
1154 | type - 1, GFP_ATOMIC); | ||
1155 | if (rem < 0) | ||
1156 | return rem; | ||
1098 | 1157 | ||
1099 | scb->expect -= len; | 1158 | data += (count - rem); |
1159 | count = rem; | ||
1160 | }; | ||
1100 | 1161 | ||
1101 | if (scb->expect == 0) { | 1162 | return rem; |
1102 | /* Complete frame */ | 1163 | } |
1164 | EXPORT_SYMBOL(hci_recv_fragment); | ||
1103 | 1165 | ||
1104 | __reassembly(hdev, type) = NULL; | 1166 | #define STREAM_REASSEMBLY 0 |
1105 | 1167 | ||
1106 | bt_cb(skb)->pkt_type = type; | 1168 | int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) |
1107 | hci_recv_frame(skb); | 1169 | { |
1108 | } | 1170 | int type; |
1171 | int rem = 0; | ||
1109 | 1172 | ||
1110 | count -= len; data += len; | 1173 | while (count) { |
1111 | } | 1174 | struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; |
1112 | 1175 | ||
1113 | return 0; | 1176 | if (!skb) { |
1177 | struct { char type; } *pkt; | ||
1178 | |||
1179 | /* Start of the frame */ | ||
1180 | pkt = data; | ||
1181 | type = pkt->type; | ||
1182 | |||
1183 | data++; | ||
1184 | count--; | ||
1185 | } else | ||
1186 | type = bt_cb(skb)->pkt_type; | ||
1187 | |||
1188 | rem = hci_reassembly(hdev, type, data, | ||
1189 | count, STREAM_REASSEMBLY, GFP_ATOMIC); | ||
1190 | if (rem < 0) | ||
1191 | return rem; | ||
1192 | |||
1193 | data += (count - rem); | ||
1194 | count = rem; | ||
1195 | }; | ||
1196 | |||
1197 | return rem; | ||
1114 | } | 1198 | } |
1115 | EXPORT_SYMBOL(hci_recv_fragment); | 1199 | EXPORT_SYMBOL(hci_recv_stream_fragment); |
1116 | 1200 | ||
1117 | /* ---- Interface to upper protocols ---- */ | 1201 | /* ---- Interface to upper protocols ---- */ |
1118 | 1202 | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 786b5de0bac4..bfef5bae0b3a 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | BlueZ - Bluetooth protocol stack for Linux | 2 | BlueZ - Bluetooth protocol stack for Linux |
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | 3 | Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. |
4 | 4 | ||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | 5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> |
6 | 6 | ||
@@ -584,7 +584,7 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | |||
584 | conn->out = 1; | 584 | conn->out = 1; |
585 | conn->link_mode |= HCI_LM_MASTER; | 585 | conn->link_mode |= HCI_LM_MASTER; |
586 | } else | 586 | } else |
587 | BT_ERR("No memmory for new connection"); | 587 | BT_ERR("No memory for new connection"); |
588 | } | 588 | } |
589 | } | 589 | } |
590 | 590 | ||
@@ -785,9 +785,13 @@ static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) | |||
785 | hci_dev_lock(hdev); | 785 | hci_dev_lock(hdev); |
786 | 786 | ||
787 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | 787 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); |
788 | if (conn) | 788 | if (conn) { |
789 | clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); | 789 | clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); |
790 | 790 | ||
791 | if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend)) | ||
792 | hci_sco_setup(conn, status); | ||
793 | } | ||
794 | |||
791 | hci_dev_unlock(hdev); | 795 | hci_dev_unlock(hdev); |
792 | } | 796 | } |
793 | 797 | ||
@@ -808,9 +812,13 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) | |||
808 | hci_dev_lock(hdev); | 812 | hci_dev_lock(hdev); |
809 | 813 | ||
810 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); | 814 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); |
811 | if (conn) | 815 | if (conn) { |
812 | clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); | 816 | clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); |
813 | 817 | ||
818 | if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend)) | ||
819 | hci_sco_setup(conn, status); | ||
820 | } | ||
821 | |||
814 | hci_dev_unlock(hdev); | 822 | hci_dev_unlock(hdev); |
815 | } | 823 | } |
816 | 824 | ||
@@ -915,20 +923,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
915 | } else | 923 | } else |
916 | conn->state = BT_CLOSED; | 924 | conn->state = BT_CLOSED; |
917 | 925 | ||
918 | if (conn->type == ACL_LINK) { | 926 | if (conn->type == ACL_LINK) |
919 | struct hci_conn *sco = conn->link; | 927 | hci_sco_setup(conn, ev->status); |
920 | if (sco) { | ||
921 | if (!ev->status) { | ||
922 | if (lmp_esco_capable(hdev)) | ||
923 | hci_setup_sync(sco, conn->handle); | ||
924 | else | ||
925 | hci_add_sco(sco, conn->handle); | ||
926 | } else { | ||
927 | hci_proto_connect_cfm(sco, ev->status); | ||
928 | hci_conn_del(sco); | ||
929 | } | ||
930 | } | ||
931 | } | ||
932 | 928 | ||
933 | if (ev->status) { | 929 | if (ev->status) { |
934 | hci_proto_connect_cfm(conn, ev->status); | 930 | hci_proto_connect_cfm(conn, ev->status); |
@@ -952,7 +948,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
952 | 948 | ||
953 | mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); | 949 | mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); |
954 | 950 | ||
955 | if (mask & HCI_LM_ACCEPT) { | 951 | if ((mask & HCI_LM_ACCEPT) && !hci_blacklist_lookup(hdev, &ev->bdaddr)) { |
956 | /* Connection accepted */ | 952 | /* Connection accepted */ |
957 | struct inquiry_entry *ie; | 953 | struct inquiry_entry *ie; |
958 | struct hci_conn *conn; | 954 | struct hci_conn *conn; |
@@ -965,7 +961,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
965 | conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); | 961 | conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); |
966 | if (!conn) { | 962 | if (!conn) { |
967 | if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) { | 963 | if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) { |
968 | BT_ERR("No memmory for new connection"); | 964 | BT_ERR("No memory for new connection"); |
969 | hci_dev_unlock(hdev); | 965 | hci_dev_unlock(hdev); |
970 | return; | 966 | return; |
971 | } | 967 | } |
@@ -1481,6 +1477,9 @@ static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb | |||
1481 | else | 1477 | else |
1482 | conn->power_save = 0; | 1478 | conn->power_save = 0; |
1483 | } | 1479 | } |
1480 | |||
1481 | if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend)) | ||
1482 | hci_sco_setup(conn, ev->status); | ||
1484 | } | 1483 | } |
1485 | 1484 | ||
1486 | hci_dev_unlock(hdev); | 1485 | hci_dev_unlock(hdev); |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 38f08f6b86f6..4f170a595934 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -165,6 +165,86 @@ static int hci_sock_release(struct socket *sock) | |||
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | 167 | ||
168 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) | ||
169 | { | ||
170 | struct list_head *p; | ||
171 | struct bdaddr_list *blacklist = &hdev->blacklist; | ||
172 | |||
173 | list_for_each(p, &blacklist->list) { | ||
174 | struct bdaddr_list *b; | ||
175 | |||
176 | b = list_entry(p, struct bdaddr_list, list); | ||
177 | |||
178 | if (bacmp(bdaddr, &b->bdaddr) == 0) | ||
179 | return b; | ||
180 | } | ||
181 | |||
182 | return NULL; | ||
183 | } | ||
184 | |||
185 | static int hci_blacklist_add(struct hci_dev *hdev, void __user *arg) | ||
186 | { | ||
187 | bdaddr_t bdaddr; | ||
188 | struct bdaddr_list *entry; | ||
189 | |||
190 | if (copy_from_user(&bdaddr, arg, sizeof(bdaddr))) | ||
191 | return -EFAULT; | ||
192 | |||
193 | if (bacmp(&bdaddr, BDADDR_ANY) == 0) | ||
194 | return -EBADF; | ||
195 | |||
196 | if (hci_blacklist_lookup(hdev, &bdaddr)) | ||
197 | return -EEXIST; | ||
198 | |||
199 | entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); | ||
200 | if (!entry) | ||
201 | return -ENOMEM; | ||
202 | |||
203 | bacpy(&entry->bdaddr, &bdaddr); | ||
204 | |||
205 | list_add(&entry->list, &hdev->blacklist.list); | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | int hci_blacklist_clear(struct hci_dev *hdev) | ||
211 | { | ||
212 | struct list_head *p, *n; | ||
213 | struct bdaddr_list *blacklist = &hdev->blacklist; | ||
214 | |||
215 | list_for_each_safe(p, n, &blacklist->list) { | ||
216 | struct bdaddr_list *b; | ||
217 | |||
218 | b = list_entry(p, struct bdaddr_list, list); | ||
219 | |||
220 | list_del(p); | ||
221 | kfree(b); | ||
222 | } | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int hci_blacklist_del(struct hci_dev *hdev, void __user *arg) | ||
228 | { | ||
229 | bdaddr_t bdaddr; | ||
230 | struct bdaddr_list *entry; | ||
231 | |||
232 | if (copy_from_user(&bdaddr, arg, sizeof(bdaddr))) | ||
233 | return -EFAULT; | ||
234 | |||
235 | if (bacmp(&bdaddr, BDADDR_ANY) == 0) | ||
236 | return hci_blacklist_clear(hdev); | ||
237 | |||
238 | entry = hci_blacklist_lookup(hdev, &bdaddr); | ||
239 | if (!entry) | ||
240 | return -ENOENT; | ||
241 | |||
242 | list_del(&entry->list); | ||
243 | kfree(entry); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
168 | /* Ioctls that require bound socket */ | 248 | /* Ioctls that require bound socket */ |
169 | static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) | 249 | static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) |
170 | { | 250 | { |
@@ -194,6 +274,16 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign | |||
194 | case HCIGETAUTHINFO: | 274 | case HCIGETAUTHINFO: |
195 | return hci_get_auth_info(hdev, (void __user *) arg); | 275 | return hci_get_auth_info(hdev, (void __user *) arg); |
196 | 276 | ||
277 | case HCIBLOCKADDR: | ||
278 | if (!capable(CAP_NET_ADMIN)) | ||
279 | return -EACCES; | ||
280 | return hci_blacklist_add(hdev, (void __user *) arg); | ||
281 | |||
282 | case HCIUNBLOCKADDR: | ||
283 | if (!capable(CAP_NET_ADMIN)) | ||
284 | return -EACCES; | ||
285 | return hci_blacklist_del(hdev, (void __user *) arg); | ||
286 | |||
197 | default: | 287 | default: |
198 | if (hdev->ioctl) | 288 | if (hdev->ioctl) |
199 | return hdev->ioctl(hdev, cmd, arg); | 289 | return hdev->ioctl(hdev, cmd, arg); |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 463ffa4fe042..ce44c47eeac1 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -436,6 +436,41 @@ static const struct file_operations inquiry_cache_fops = { | |||
436 | .release = single_release, | 436 | .release = single_release, |
437 | }; | 437 | }; |
438 | 438 | ||
439 | static int blacklist_show(struct seq_file *f, void *p) | ||
440 | { | ||
441 | struct hci_dev *hdev = f->private; | ||
442 | struct bdaddr_list *blacklist = &hdev->blacklist; | ||
443 | struct list_head *l; | ||
444 | |||
445 | hci_dev_lock_bh(hdev); | ||
446 | |||
447 | list_for_each(l, &blacklist->list) { | ||
448 | struct bdaddr_list *b; | ||
449 | bdaddr_t bdaddr; | ||
450 | |||
451 | b = list_entry(l, struct bdaddr_list, list); | ||
452 | |||
453 | baswap(&bdaddr, &b->bdaddr); | ||
454 | |||
455 | seq_printf(f, "%s\n", batostr(&bdaddr)); | ||
456 | } | ||
457 | |||
458 | hci_dev_unlock_bh(hdev); | ||
459 | |||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | static int blacklist_open(struct inode *inode, struct file *file) | ||
464 | { | ||
465 | return single_open(file, blacklist_show, inode->i_private); | ||
466 | } | ||
467 | |||
468 | static const struct file_operations blacklist_fops = { | ||
469 | .open = blacklist_open, | ||
470 | .read = seq_read, | ||
471 | .llseek = seq_lseek, | ||
472 | .release = single_release, | ||
473 | }; | ||
439 | int hci_register_sysfs(struct hci_dev *hdev) | 474 | int hci_register_sysfs(struct hci_dev *hdev) |
440 | { | 475 | { |
441 | struct device *dev = &hdev->dev; | 476 | struct device *dev = &hdev->dev; |
@@ -465,6 +500,9 @@ int hci_register_sysfs(struct hci_dev *hdev) | |||
465 | debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, | 500 | debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, |
466 | hdev, &inquiry_cache_fops); | 501 | hdev, &inquiry_cache_fops); |
467 | 502 | ||
503 | debugfs_create_file("blacklist", 0444, hdev->debugfs, | ||
504 | hdev, &blacklist_fops); | ||
505 | |||
468 | return 0; | 506 | return 0; |
469 | } | 507 | } |
470 | 508 | ||
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index cf3c4073a8a6..9ba1e8eee37c 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | BlueZ - Bluetooth protocol stack for Linux | 2 | BlueZ - Bluetooth protocol stack for Linux |
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | 3 | Copyright (C) 2000-2001 Qualcomm Incorporated |
4 | Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> | ||
5 | Copyright (C) 2010 Google Inc. | ||
4 | 6 | ||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | 7 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> |
6 | 8 | ||
@@ -53,15 +55,9 @@ | |||
53 | #include <net/bluetooth/hci_core.h> | 55 | #include <net/bluetooth/hci_core.h> |
54 | #include <net/bluetooth/l2cap.h> | 56 | #include <net/bluetooth/l2cap.h> |
55 | 57 | ||
56 | #define VERSION "2.14" | 58 | #define VERSION "2.15" |
57 | 59 | ||
58 | #ifdef CONFIG_BT_L2CAP_EXT_FEATURES | 60 | static int disable_ertm = 0; |
59 | static int enable_ertm = 1; | ||
60 | #else | ||
61 | static int enable_ertm = 0; | ||
62 | #endif | ||
63 | static int max_transmit = L2CAP_DEFAULT_MAX_TX; | ||
64 | static int tx_window = L2CAP_DEFAULT_TX_WINDOW; | ||
65 | 61 | ||
66 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; | 62 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; |
67 | static u8 l2cap_fixed_chan[8] = { 0x02, }; | 63 | static u8 l2cap_fixed_chan[8] = { 0x02, }; |
@@ -80,9 +76,12 @@ static void __l2cap_sock_close(struct sock *sk, int reason); | |||
80 | static void l2cap_sock_close(struct sock *sk); | 76 | static void l2cap_sock_close(struct sock *sk); |
81 | static void l2cap_sock_kill(struct sock *sk); | 77 | static void l2cap_sock_kill(struct sock *sk); |
82 | 78 | ||
79 | static int l2cap_build_conf_req(struct sock *sk, void *data); | ||
83 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | 80 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, |
84 | u8 code, u8 ident, u16 dlen, void *data); | 81 | u8 code, u8 ident, u16 dlen, void *data); |
85 | 82 | ||
83 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); | ||
84 | |||
86 | /* ---- L2CAP timers ---- */ | 85 | /* ---- L2CAP timers ---- */ |
87 | static void l2cap_sock_timeout(unsigned long arg) | 86 | static void l2cap_sock_timeout(unsigned long arg) |
88 | { | 87 | { |
@@ -278,6 +277,24 @@ static void l2cap_chan_del(struct sock *sk, int err) | |||
278 | parent->sk_data_ready(parent, 0); | 277 | parent->sk_data_ready(parent, 0); |
279 | } else | 278 | } else |
280 | sk->sk_state_change(sk); | 279 | sk->sk_state_change(sk); |
280 | |||
281 | skb_queue_purge(TX_QUEUE(sk)); | ||
282 | |||
283 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { | ||
284 | struct srej_list *l, *tmp; | ||
285 | |||
286 | del_timer(&l2cap_pi(sk)->retrans_timer); | ||
287 | del_timer(&l2cap_pi(sk)->monitor_timer); | ||
288 | del_timer(&l2cap_pi(sk)->ack_timer); | ||
289 | |||
290 | skb_queue_purge(SREJ_QUEUE(sk)); | ||
291 | skb_queue_purge(BUSY_QUEUE(sk)); | ||
292 | |||
293 | list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) { | ||
294 | list_del(&l->list); | ||
295 | kfree(l); | ||
296 | } | ||
297 | } | ||
281 | } | 298 | } |
282 | 299 | ||
283 | /* Service level security */ | 300 | /* Service level security */ |
@@ -351,8 +368,12 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) | |||
351 | struct sk_buff *skb; | 368 | struct sk_buff *skb; |
352 | struct l2cap_hdr *lh; | 369 | struct l2cap_hdr *lh; |
353 | struct l2cap_conn *conn = pi->conn; | 370 | struct l2cap_conn *conn = pi->conn; |
371 | struct sock *sk = (struct sock *)pi; | ||
354 | int count, hlen = L2CAP_HDR_SIZE + 2; | 372 | int count, hlen = L2CAP_HDR_SIZE + 2; |
355 | 373 | ||
374 | if (sk->sk_state != BT_CONNECTED) | ||
375 | return; | ||
376 | |||
356 | if (pi->fcs == L2CAP_FCS_CRC16) | 377 | if (pi->fcs == L2CAP_FCS_CRC16) |
357 | hlen += 2; | 378 | hlen += 2; |
358 | 379 | ||
@@ -440,24 +461,57 @@ static void l2cap_do_start(struct sock *sk) | |||
440 | } | 461 | } |
441 | } | 462 | } |
442 | 463 | ||
443 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk) | 464 | static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) |
465 | { | ||
466 | u32 local_feat_mask = l2cap_feat_mask; | ||
467 | if (!disable_ertm) | ||
468 | local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING; | ||
469 | |||
470 | switch (mode) { | ||
471 | case L2CAP_MODE_ERTM: | ||
472 | return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask; | ||
473 | case L2CAP_MODE_STREAMING: | ||
474 | return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask; | ||
475 | default: | ||
476 | return 0x00; | ||
477 | } | ||
478 | } | ||
479 | |||
480 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err) | ||
444 | { | 481 | { |
445 | struct l2cap_disconn_req req; | 482 | struct l2cap_disconn_req req; |
446 | 483 | ||
484 | if (!conn) | ||
485 | return; | ||
486 | |||
487 | skb_queue_purge(TX_QUEUE(sk)); | ||
488 | |||
489 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { | ||
490 | del_timer(&l2cap_pi(sk)->retrans_timer); | ||
491 | del_timer(&l2cap_pi(sk)->monitor_timer); | ||
492 | del_timer(&l2cap_pi(sk)->ack_timer); | ||
493 | } | ||
494 | |||
447 | req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid); | 495 | req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid); |
448 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 496 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); |
449 | l2cap_send_cmd(conn, l2cap_get_ident(conn), | 497 | l2cap_send_cmd(conn, l2cap_get_ident(conn), |
450 | L2CAP_DISCONN_REQ, sizeof(req), &req); | 498 | L2CAP_DISCONN_REQ, sizeof(req), &req); |
499 | |||
500 | sk->sk_state = BT_DISCONN; | ||
501 | sk->sk_err = err; | ||
451 | } | 502 | } |
452 | 503 | ||
453 | /* ---- L2CAP connections ---- */ | 504 | /* ---- L2CAP connections ---- */ |
454 | static void l2cap_conn_start(struct l2cap_conn *conn) | 505 | static void l2cap_conn_start(struct l2cap_conn *conn) |
455 | { | 506 | { |
456 | struct l2cap_chan_list *l = &conn->chan_list; | 507 | struct l2cap_chan_list *l = &conn->chan_list; |
508 | struct sock_del_list del, *tmp1, *tmp2; | ||
457 | struct sock *sk; | 509 | struct sock *sk; |
458 | 510 | ||
459 | BT_DBG("conn %p", conn); | 511 | BT_DBG("conn %p", conn); |
460 | 512 | ||
513 | INIT_LIST_HEAD(&del.list); | ||
514 | |||
461 | read_lock(&l->lock); | 515 | read_lock(&l->lock); |
462 | 516 | ||
463 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { | 517 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { |
@@ -470,20 +524,38 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
470 | } | 524 | } |
471 | 525 | ||
472 | if (sk->sk_state == BT_CONNECT) { | 526 | if (sk->sk_state == BT_CONNECT) { |
473 | if (l2cap_check_security(sk) && | 527 | struct l2cap_conn_req req; |
474 | __l2cap_no_conn_pending(sk)) { | ||
475 | struct l2cap_conn_req req; | ||
476 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
477 | req.psm = l2cap_pi(sk)->psm; | ||
478 | 528 | ||
479 | l2cap_pi(sk)->ident = l2cap_get_ident(conn); | 529 | if (!l2cap_check_security(sk) || |
480 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; | 530 | !__l2cap_no_conn_pending(sk)) { |
531 | bh_unlock_sock(sk); | ||
532 | continue; | ||
533 | } | ||
481 | 534 | ||
482 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 535 | if (!l2cap_mode_supported(l2cap_pi(sk)->mode, |
483 | L2CAP_CONN_REQ, sizeof(req), &req); | 536 | conn->feat_mask) |
537 | && l2cap_pi(sk)->conf_state & | ||
538 | L2CAP_CONF_STATE2_DEVICE) { | ||
539 | tmp1 = kzalloc(sizeof(struct sock_del_list), | ||
540 | GFP_ATOMIC); | ||
541 | tmp1->sk = sk; | ||
542 | list_add_tail(&tmp1->list, &del.list); | ||
543 | bh_unlock_sock(sk); | ||
544 | continue; | ||
484 | } | 545 | } |
546 | |||
547 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
548 | req.psm = l2cap_pi(sk)->psm; | ||
549 | |||
550 | l2cap_pi(sk)->ident = l2cap_get_ident(conn); | ||
551 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; | ||
552 | |||
553 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | ||
554 | L2CAP_CONN_REQ, sizeof(req), &req); | ||
555 | |||
485 | } else if (sk->sk_state == BT_CONNECT2) { | 556 | } else if (sk->sk_state == BT_CONNECT2) { |
486 | struct l2cap_conn_rsp rsp; | 557 | struct l2cap_conn_rsp rsp; |
558 | char buf[128]; | ||
487 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 559 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); |
488 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 560 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); |
489 | 561 | ||
@@ -506,12 +578,31 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
506 | 578 | ||
507 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 579 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, |
508 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | 580 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); |
581 | |||
582 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT || | ||
583 | rsp.result != L2CAP_CR_SUCCESS) { | ||
584 | bh_unlock_sock(sk); | ||
585 | continue; | ||
586 | } | ||
587 | |||
588 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | ||
589 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | ||
590 | l2cap_build_conf_req(sk, buf), buf); | ||
591 | l2cap_pi(sk)->num_conf_req++; | ||
509 | } | 592 | } |
510 | 593 | ||
511 | bh_unlock_sock(sk); | 594 | bh_unlock_sock(sk); |
512 | } | 595 | } |
513 | 596 | ||
514 | read_unlock(&l->lock); | 597 | read_unlock(&l->lock); |
598 | |||
599 | list_for_each_entry_safe(tmp1, tmp2, &del.list, list) { | ||
600 | bh_lock_sock(tmp1->sk); | ||
601 | __l2cap_sock_close(tmp1->sk, ECONNRESET); | ||
602 | bh_unlock_sock(tmp1->sk); | ||
603 | list_del(&tmp1->list); | ||
604 | kfree(tmp1); | ||
605 | } | ||
515 | } | 606 | } |
516 | 607 | ||
517 | static void l2cap_conn_ready(struct l2cap_conn *conn) | 608 | static void l2cap_conn_ready(struct l2cap_conn *conn) |
@@ -740,9 +831,8 @@ static void __l2cap_sock_close(struct sock *sk, int reason) | |||
740 | sk->sk_type == SOCK_STREAM) { | 831 | sk->sk_type == SOCK_STREAM) { |
741 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 832 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
742 | 833 | ||
743 | sk->sk_state = BT_DISCONN; | ||
744 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | 834 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); |
745 | l2cap_send_disconn_req(conn, sk); | 835 | l2cap_send_disconn_req(conn, sk, reason); |
746 | } else | 836 | } else |
747 | l2cap_chan_del(sk, reason); | 837 | l2cap_chan_del(sk, reason); |
748 | break; | 838 | break; |
@@ -802,6 +892,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
802 | 892 | ||
803 | pi->imtu = l2cap_pi(parent)->imtu; | 893 | pi->imtu = l2cap_pi(parent)->imtu; |
804 | pi->omtu = l2cap_pi(parent)->omtu; | 894 | pi->omtu = l2cap_pi(parent)->omtu; |
895 | pi->conf_state = l2cap_pi(parent)->conf_state; | ||
805 | pi->mode = l2cap_pi(parent)->mode; | 896 | pi->mode = l2cap_pi(parent)->mode; |
806 | pi->fcs = l2cap_pi(parent)->fcs; | 897 | pi->fcs = l2cap_pi(parent)->fcs; |
807 | pi->max_tx = l2cap_pi(parent)->max_tx; | 898 | pi->max_tx = l2cap_pi(parent)->max_tx; |
@@ -812,13 +903,15 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
812 | } else { | 903 | } else { |
813 | pi->imtu = L2CAP_DEFAULT_MTU; | 904 | pi->imtu = L2CAP_DEFAULT_MTU; |
814 | pi->omtu = 0; | 905 | pi->omtu = 0; |
815 | if (enable_ertm && sk->sk_type == SOCK_STREAM) | 906 | if (!disable_ertm && sk->sk_type == SOCK_STREAM) { |
816 | pi->mode = L2CAP_MODE_ERTM; | 907 | pi->mode = L2CAP_MODE_ERTM; |
817 | else | 908 | pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; |
909 | } else { | ||
818 | pi->mode = L2CAP_MODE_BASIC; | 910 | pi->mode = L2CAP_MODE_BASIC; |
819 | pi->max_tx = max_transmit; | 911 | } |
912 | pi->max_tx = L2CAP_DEFAULT_MAX_TX; | ||
820 | pi->fcs = L2CAP_FCS_CRC16; | 913 | pi->fcs = L2CAP_FCS_CRC16; |
821 | pi->tx_win = tx_window; | 914 | pi->tx_win = L2CAP_DEFAULT_TX_WINDOW; |
822 | pi->sec_level = BT_SECURITY_LOW; | 915 | pi->sec_level = BT_SECURITY_LOW; |
823 | pi->role_switch = 0; | 916 | pi->role_switch = 0; |
824 | pi->force_reliable = 0; | 917 | pi->force_reliable = 0; |
@@ -1067,7 +1160,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
1067 | break; | 1160 | break; |
1068 | case L2CAP_MODE_ERTM: | 1161 | case L2CAP_MODE_ERTM: |
1069 | case L2CAP_MODE_STREAMING: | 1162 | case L2CAP_MODE_STREAMING: |
1070 | if (enable_ertm) | 1163 | if (!disable_ertm) |
1071 | break; | 1164 | break; |
1072 | /* fall through */ | 1165 | /* fall through */ |
1073 | default: | 1166 | default: |
@@ -1084,6 +1177,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
1084 | 1177 | ||
1085 | case BT_CONNECTED: | 1178 | case BT_CONNECTED: |
1086 | /* Already connected */ | 1179 | /* Already connected */ |
1180 | err = -EISCONN; | ||
1087 | goto done; | 1181 | goto done; |
1088 | 1182 | ||
1089 | case BT_OPEN: | 1183 | case BT_OPEN: |
@@ -1132,7 +1226,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) | |||
1132 | break; | 1226 | break; |
1133 | case L2CAP_MODE_ERTM: | 1227 | case L2CAP_MODE_ERTM: |
1134 | case L2CAP_MODE_STREAMING: | 1228 | case L2CAP_MODE_STREAMING: |
1135 | if (enable_ertm) | 1229 | if (!disable_ertm) |
1136 | break; | 1230 | break; |
1137 | /* fall through */ | 1231 | /* fall through */ |
1138 | default: | 1232 | default: |
@@ -1285,9 +1379,11 @@ static void l2cap_monitor_timeout(unsigned long arg) | |||
1285 | { | 1379 | { |
1286 | struct sock *sk = (void *) arg; | 1380 | struct sock *sk = (void *) arg; |
1287 | 1381 | ||
1382 | BT_DBG("sk %p", sk); | ||
1383 | |||
1288 | bh_lock_sock(sk); | 1384 | bh_lock_sock(sk); |
1289 | if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) { | 1385 | if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) { |
1290 | l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk); | 1386 | l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED); |
1291 | bh_unlock_sock(sk); | 1387 | bh_unlock_sock(sk); |
1292 | return; | 1388 | return; |
1293 | } | 1389 | } |
@@ -1303,6 +1399,8 @@ static void l2cap_retrans_timeout(unsigned long arg) | |||
1303 | { | 1399 | { |
1304 | struct sock *sk = (void *) arg; | 1400 | struct sock *sk = (void *) arg; |
1305 | 1401 | ||
1402 | BT_DBG("sk %p", sk); | ||
1403 | |||
1306 | bh_lock_sock(sk); | 1404 | bh_lock_sock(sk); |
1307 | l2cap_pi(sk)->retry_count = 1; | 1405 | l2cap_pi(sk)->retry_count = 1; |
1308 | __mod_monitor_timer(); | 1406 | __mod_monitor_timer(); |
@@ -1341,7 +1439,7 @@ static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb) | |||
1341 | hci_send_acl(pi->conn->hcon, skb, 0); | 1439 | hci_send_acl(pi->conn->hcon, skb, 0); |
1342 | } | 1440 | } |
1343 | 1441 | ||
1344 | static int l2cap_streaming_send(struct sock *sk) | 1442 | static void l2cap_streaming_send(struct sock *sk) |
1345 | { | 1443 | { |
1346 | struct sk_buff *skb, *tx_skb; | 1444 | struct sk_buff *skb, *tx_skb; |
1347 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1445 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
@@ -1371,7 +1469,6 @@ static int l2cap_streaming_send(struct sock *sk) | |||
1371 | skb = skb_dequeue(TX_QUEUE(sk)); | 1469 | skb = skb_dequeue(TX_QUEUE(sk)); |
1372 | kfree_skb(skb); | 1470 | kfree_skb(skb); |
1373 | } | 1471 | } |
1374 | return 0; | ||
1375 | } | 1472 | } |
1376 | 1473 | ||
1377 | static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) | 1474 | static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) |
@@ -1395,15 +1492,22 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) | |||
1395 | 1492 | ||
1396 | if (pi->remote_max_tx && | 1493 | if (pi->remote_max_tx && |
1397 | bt_cb(skb)->retries == pi->remote_max_tx) { | 1494 | bt_cb(skb)->retries == pi->remote_max_tx) { |
1398 | l2cap_send_disconn_req(pi->conn, sk); | 1495 | l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED); |
1399 | return; | 1496 | return; |
1400 | } | 1497 | } |
1401 | 1498 | ||
1402 | tx_skb = skb_clone(skb, GFP_ATOMIC); | 1499 | tx_skb = skb_clone(skb, GFP_ATOMIC); |
1403 | bt_cb(skb)->retries++; | 1500 | bt_cb(skb)->retries++; |
1404 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1501 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); |
1502 | |||
1503 | if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { | ||
1504 | control |= L2CAP_CTRL_FINAL; | ||
1505 | pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; | ||
1506 | } | ||
1507 | |||
1405 | control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1508 | control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) |
1406 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1509 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); |
1510 | |||
1407 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1511 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); |
1408 | 1512 | ||
1409 | if (pi->fcs == L2CAP_FCS_CRC16) { | 1513 | if (pi->fcs == L2CAP_FCS_CRC16) { |
@@ -1421,15 +1525,14 @@ static int l2cap_ertm_send(struct sock *sk) | |||
1421 | u16 control, fcs; | 1525 | u16 control, fcs; |
1422 | int nsent = 0; | 1526 | int nsent = 0; |
1423 | 1527 | ||
1424 | if (pi->conn_state & L2CAP_CONN_WAIT_F) | 1528 | if (sk->sk_state != BT_CONNECTED) |
1425 | return 0; | 1529 | return -ENOTCONN; |
1426 | 1530 | ||
1427 | while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) && | 1531 | while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) { |
1428 | !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) { | ||
1429 | 1532 | ||
1430 | if (pi->remote_max_tx && | 1533 | if (pi->remote_max_tx && |
1431 | bt_cb(skb)->retries == pi->remote_max_tx) { | 1534 | bt_cb(skb)->retries == pi->remote_max_tx) { |
1432 | l2cap_send_disconn_req(pi->conn, sk); | 1535 | l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED); |
1433 | break; | 1536 | break; |
1434 | } | 1537 | } |
1435 | 1538 | ||
@@ -1438,6 +1541,8 @@ static int l2cap_ertm_send(struct sock *sk) | |||
1438 | bt_cb(skb)->retries++; | 1541 | bt_cb(skb)->retries++; |
1439 | 1542 | ||
1440 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1543 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); |
1544 | control &= L2CAP_CTRL_SAR; | ||
1545 | |||
1441 | if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { | 1546 | if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { |
1442 | control |= L2CAP_CTRL_FINAL; | 1547 | control |= L2CAP_CTRL_FINAL; |
1443 | pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; | 1548 | pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; |
@@ -1478,16 +1583,11 @@ static int l2cap_retransmit_frames(struct sock *sk) | |||
1478 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1583 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
1479 | int ret; | 1584 | int ret; |
1480 | 1585 | ||
1481 | spin_lock_bh(&pi->send_lock); | ||
1482 | |||
1483 | if (!skb_queue_empty(TX_QUEUE(sk))) | 1586 | if (!skb_queue_empty(TX_QUEUE(sk))) |
1484 | sk->sk_send_head = TX_QUEUE(sk)->next; | 1587 | sk->sk_send_head = TX_QUEUE(sk)->next; |
1485 | 1588 | ||
1486 | pi->next_tx_seq = pi->expected_ack_seq; | 1589 | pi->next_tx_seq = pi->expected_ack_seq; |
1487 | ret = l2cap_ertm_send(sk); | 1590 | ret = l2cap_ertm_send(sk); |
1488 | |||
1489 | spin_unlock_bh(&pi->send_lock); | ||
1490 | |||
1491 | return ret; | 1591 | return ret; |
1492 | } | 1592 | } |
1493 | 1593 | ||
@@ -1495,7 +1595,6 @@ static void l2cap_send_ack(struct l2cap_pinfo *pi) | |||
1495 | { | 1595 | { |
1496 | struct sock *sk = (struct sock *)pi; | 1596 | struct sock *sk = (struct sock *)pi; |
1497 | u16 control = 0; | 1597 | u16 control = 0; |
1498 | int nframes; | ||
1499 | 1598 | ||
1500 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 1599 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
1501 | 1600 | ||
@@ -1506,11 +1605,7 @@ static void l2cap_send_ack(struct l2cap_pinfo *pi) | |||
1506 | return; | 1605 | return; |
1507 | } | 1606 | } |
1508 | 1607 | ||
1509 | spin_lock_bh(&pi->send_lock); | 1608 | if (l2cap_ertm_send(sk) > 0) |
1510 | nframes = l2cap_ertm_send(sk); | ||
1511 | spin_unlock_bh(&pi->send_lock); | ||
1512 | |||
1513 | if (nframes > 0) | ||
1514 | return; | 1609 | return; |
1515 | 1610 | ||
1516 | control |= L2CAP_SUPER_RCV_READY; | 1611 | control |= L2CAP_SUPER_RCV_READY; |
@@ -1705,10 +1800,8 @@ static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, siz | |||
1705 | size += buflen; | 1800 | size += buflen; |
1706 | } | 1801 | } |
1707 | skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk)); | 1802 | skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk)); |
1708 | spin_lock_bh(&pi->send_lock); | ||
1709 | if (sk->sk_send_head == NULL) | 1803 | if (sk->sk_send_head == NULL) |
1710 | sk->sk_send_head = sar_queue.next; | 1804 | sk->sk_send_head = sar_queue.next; |
1711 | spin_unlock_bh(&pi->send_lock); | ||
1712 | 1805 | ||
1713 | return size; | 1806 | return size; |
1714 | } | 1807 | } |
@@ -1753,7 +1846,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1753 | case L2CAP_MODE_BASIC: | 1846 | case L2CAP_MODE_BASIC: |
1754 | /* Check outgoing MTU */ | 1847 | /* Check outgoing MTU */ |
1755 | if (len > pi->omtu) { | 1848 | if (len > pi->omtu) { |
1756 | err = -EINVAL; | 1849 | err = -EMSGSIZE; |
1757 | goto done; | 1850 | goto done; |
1758 | } | 1851 | } |
1759 | 1852 | ||
@@ -1780,14 +1873,9 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1780 | } | 1873 | } |
1781 | __skb_queue_tail(TX_QUEUE(sk), skb); | 1874 | __skb_queue_tail(TX_QUEUE(sk), skb); |
1782 | 1875 | ||
1783 | if (pi->mode == L2CAP_MODE_ERTM) | ||
1784 | spin_lock_bh(&pi->send_lock); | ||
1785 | |||
1786 | if (sk->sk_send_head == NULL) | 1876 | if (sk->sk_send_head == NULL) |
1787 | sk->sk_send_head = skb; | 1877 | sk->sk_send_head = skb; |
1788 | 1878 | ||
1789 | if (pi->mode == L2CAP_MODE_ERTM) | ||
1790 | spin_unlock_bh(&pi->send_lock); | ||
1791 | } else { | 1879 | } else { |
1792 | /* Segment SDU into multiples PDUs */ | 1880 | /* Segment SDU into multiples PDUs */ |
1793 | err = l2cap_sar_segment_sdu(sk, msg, len); | 1881 | err = l2cap_sar_segment_sdu(sk, msg, len); |
@@ -1796,11 +1884,14 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1796 | } | 1884 | } |
1797 | 1885 | ||
1798 | if (pi->mode == L2CAP_MODE_STREAMING) { | 1886 | if (pi->mode == L2CAP_MODE_STREAMING) { |
1799 | err = l2cap_streaming_send(sk); | 1887 | l2cap_streaming_send(sk); |
1800 | } else { | 1888 | } else { |
1801 | spin_lock_bh(&pi->send_lock); | 1889 | if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && |
1890 | pi->conn_state && L2CAP_CONN_WAIT_F) { | ||
1891 | err = len; | ||
1892 | break; | ||
1893 | } | ||
1802 | err = l2cap_ertm_send(sk); | 1894 | err = l2cap_ertm_send(sk); |
1803 | spin_unlock_bh(&pi->send_lock); | ||
1804 | } | 1895 | } |
1805 | 1896 | ||
1806 | if (err >= 0) | 1897 | if (err >= 0) |
@@ -1809,7 +1900,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1809 | 1900 | ||
1810 | default: | 1901 | default: |
1811 | BT_DBG("bad state %1.1x", pi->mode); | 1902 | BT_DBG("bad state %1.1x", pi->mode); |
1812 | err = -EINVAL; | 1903 | err = -EBADFD; |
1813 | } | 1904 | } |
1814 | 1905 | ||
1815 | done: | 1906 | done: |
@@ -1825,6 +1916,8 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1825 | 1916 | ||
1826 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { | 1917 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { |
1827 | struct l2cap_conn_rsp rsp; | 1918 | struct l2cap_conn_rsp rsp; |
1919 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
1920 | u8 buf[128]; | ||
1828 | 1921 | ||
1829 | sk->sk_state = BT_CONFIG; | 1922 | sk->sk_state = BT_CONFIG; |
1830 | 1923 | ||
@@ -1835,6 +1928,16 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1835 | l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident, | 1928 | l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident, |
1836 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | 1929 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); |
1837 | 1930 | ||
1931 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) { | ||
1932 | release_sock(sk); | ||
1933 | return 0; | ||
1934 | } | ||
1935 | |||
1936 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | ||
1937 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | ||
1938 | l2cap_build_conf_req(sk, buf), buf); | ||
1939 | l2cap_pi(sk)->num_conf_req++; | ||
1940 | |||
1838 | release_sock(sk); | 1941 | release_sock(sk); |
1839 | return 0; | 1942 | return 0; |
1840 | } | 1943 | } |
@@ -1871,13 +1974,19 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
1871 | break; | 1974 | break; |
1872 | } | 1975 | } |
1873 | 1976 | ||
1977 | if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) { | ||
1978 | err = -EINVAL; | ||
1979 | break; | ||
1980 | } | ||
1981 | |||
1874 | l2cap_pi(sk)->mode = opts.mode; | 1982 | l2cap_pi(sk)->mode = opts.mode; |
1875 | switch (l2cap_pi(sk)->mode) { | 1983 | switch (l2cap_pi(sk)->mode) { |
1876 | case L2CAP_MODE_BASIC: | 1984 | case L2CAP_MODE_BASIC: |
1985 | l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE; | ||
1877 | break; | 1986 | break; |
1878 | case L2CAP_MODE_ERTM: | 1987 | case L2CAP_MODE_ERTM: |
1879 | case L2CAP_MODE_STREAMING: | 1988 | case L2CAP_MODE_STREAMING: |
1880 | if (enable_ertm) | 1989 | if (!disable_ertm) |
1881 | break; | 1990 | break; |
1882 | /* fall through */ | 1991 | /* fall through */ |
1883 | default: | 1992 | default: |
@@ -2145,6 +2254,10 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) | |||
2145 | err = bt_sock_wait_state(sk, BT_CLOSED, | 2254 | err = bt_sock_wait_state(sk, BT_CLOSED, |
2146 | sk->sk_lingertime); | 2255 | sk->sk_lingertime); |
2147 | } | 2256 | } |
2257 | |||
2258 | if (!err && sk->sk_err) | ||
2259 | err = -sk->sk_err; | ||
2260 | |||
2148 | release_sock(sk); | 2261 | release_sock(sk); |
2149 | return err; | 2262 | return err; |
2150 | } | 2263 | } |
@@ -2365,25 +2478,10 @@ static inline void l2cap_ertm_init(struct sock *sk) | |||
2365 | 2478 | ||
2366 | __skb_queue_head_init(SREJ_QUEUE(sk)); | 2479 | __skb_queue_head_init(SREJ_QUEUE(sk)); |
2367 | __skb_queue_head_init(BUSY_QUEUE(sk)); | 2480 | __skb_queue_head_init(BUSY_QUEUE(sk)); |
2368 | spin_lock_init(&l2cap_pi(sk)->send_lock); | ||
2369 | 2481 | ||
2370 | INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work); | 2482 | INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work); |
2371 | } | ||
2372 | 2483 | ||
2373 | static int l2cap_mode_supported(__u8 mode, __u32 feat_mask) | 2484 | sk->sk_backlog_rcv = l2cap_ertm_data_rcv; |
2374 | { | ||
2375 | u32 local_feat_mask = l2cap_feat_mask; | ||
2376 | if (enable_ertm) | ||
2377 | local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING; | ||
2378 | |||
2379 | switch (mode) { | ||
2380 | case L2CAP_MODE_ERTM: | ||
2381 | return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask; | ||
2382 | case L2CAP_MODE_STREAMING: | ||
2383 | return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask; | ||
2384 | default: | ||
2385 | return 0x00; | ||
2386 | } | ||
2387 | } | 2485 | } |
2388 | 2486 | ||
2389 | static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) | 2487 | static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) |
@@ -2414,10 +2512,10 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) | |||
2414 | switch (pi->mode) { | 2512 | switch (pi->mode) { |
2415 | case L2CAP_MODE_STREAMING: | 2513 | case L2CAP_MODE_STREAMING: |
2416 | case L2CAP_MODE_ERTM: | 2514 | case L2CAP_MODE_ERTM: |
2417 | pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; | 2515 | if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE) |
2418 | if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask)) | 2516 | break; |
2419 | l2cap_send_disconn_req(pi->conn, sk); | 2517 | |
2420 | break; | 2518 | /* fall through */ |
2421 | default: | 2519 | default: |
2422 | pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask); | 2520 | pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask); |
2423 | break; | 2521 | break; |
@@ -2428,6 +2526,14 @@ done: | |||
2428 | case L2CAP_MODE_BASIC: | 2526 | case L2CAP_MODE_BASIC: |
2429 | if (pi->imtu != L2CAP_DEFAULT_MTU) | 2527 | if (pi->imtu != L2CAP_DEFAULT_MTU) |
2430 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); | 2528 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); |
2529 | |||
2530 | rfc.mode = L2CAP_MODE_BASIC; | ||
2531 | rfc.txwin_size = 0; | ||
2532 | rfc.max_transmit = 0; | ||
2533 | rfc.retrans_timeout = 0; | ||
2534 | rfc.monitor_timeout = 0; | ||
2535 | rfc.max_pdu_size = 0; | ||
2536 | |||
2431 | break; | 2537 | break; |
2432 | 2538 | ||
2433 | case L2CAP_MODE_ERTM: | 2539 | case L2CAP_MODE_ERTM: |
@@ -2440,9 +2546,6 @@ done: | |||
2440 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) | 2546 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) |
2441 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); | 2547 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); |
2442 | 2548 | ||
2443 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
2444 | sizeof(rfc), (unsigned long) &rfc); | ||
2445 | |||
2446 | if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) | 2549 | if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) |
2447 | break; | 2550 | break; |
2448 | 2551 | ||
@@ -2463,9 +2566,6 @@ done: | |||
2463 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) | 2566 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) |
2464 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); | 2567 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); |
2465 | 2568 | ||
2466 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
2467 | sizeof(rfc), (unsigned long) &rfc); | ||
2468 | |||
2469 | if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) | 2569 | if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) |
2470 | break; | 2570 | break; |
2471 | 2571 | ||
@@ -2477,6 +2577,9 @@ done: | |||
2477 | break; | 2577 | break; |
2478 | } | 2578 | } |
2479 | 2579 | ||
2580 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | ||
2581 | (unsigned long) &rfc); | ||
2582 | |||
2480 | /* FIXME: Need actual value of the flush timeout */ | 2583 | /* FIXME: Need actual value of the flush timeout */ |
2481 | //if (flush_to != L2CAP_DEFAULT_FLUSH_TO) | 2584 | //if (flush_to != L2CAP_DEFAULT_FLUSH_TO) |
2482 | // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to); | 2585 | // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to); |
@@ -2541,18 +2644,21 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data) | |||
2541 | } | 2644 | } |
2542 | } | 2645 | } |
2543 | 2646 | ||
2544 | if (pi->num_conf_rsp || pi->num_conf_req) | 2647 | if (pi->num_conf_rsp || pi->num_conf_req > 1) |
2545 | goto done; | 2648 | goto done; |
2546 | 2649 | ||
2547 | switch (pi->mode) { | 2650 | switch (pi->mode) { |
2548 | case L2CAP_MODE_STREAMING: | 2651 | case L2CAP_MODE_STREAMING: |
2549 | case L2CAP_MODE_ERTM: | 2652 | case L2CAP_MODE_ERTM: |
2550 | pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; | 2653 | if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) { |
2551 | if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask)) | 2654 | pi->mode = l2cap_select_mode(rfc.mode, |
2655 | pi->conn->feat_mask); | ||
2656 | break; | ||
2657 | } | ||
2658 | |||
2659 | if (pi->mode != rfc.mode) | ||
2552 | return -ECONNREFUSED; | 2660 | return -ECONNREFUSED; |
2553 | break; | 2661 | |
2554 | default: | ||
2555 | pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask); | ||
2556 | break; | 2662 | break; |
2557 | } | 2663 | } |
2558 | 2664 | ||
@@ -2675,7 +2781,6 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, | |||
2675 | rfc.mode != pi->mode) | 2781 | rfc.mode != pi->mode) |
2676 | return -ECONNREFUSED; | 2782 | return -ECONNREFUSED; |
2677 | 2783 | ||
2678 | pi->mode = rfc.mode; | ||
2679 | pi->fcs = 0; | 2784 | pi->fcs = 0; |
2680 | 2785 | ||
2681 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 2786 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
@@ -2684,6 +2789,11 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, | |||
2684 | } | 2789 | } |
2685 | } | 2790 | } |
2686 | 2791 | ||
2792 | if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode) | ||
2793 | return -ECONNREFUSED; | ||
2794 | |||
2795 | pi->mode = rfc.mode; | ||
2796 | |||
2687 | if (*result == L2CAP_CONF_SUCCESS) { | 2797 | if (*result == L2CAP_CONF_SUCCESS) { |
2688 | switch (rfc.mode) { | 2798 | switch (rfc.mode) { |
2689 | case L2CAP_MODE_ERTM: | 2799 | case L2CAP_MODE_ERTM: |
@@ -2778,7 +2888,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2778 | struct l2cap_chan_list *list = &conn->chan_list; | 2888 | struct l2cap_chan_list *list = &conn->chan_list; |
2779 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; | 2889 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; |
2780 | struct l2cap_conn_rsp rsp; | 2890 | struct l2cap_conn_rsp rsp; |
2781 | struct sock *sk, *parent; | 2891 | struct sock *parent, *uninitialized_var(sk); |
2782 | int result, status = L2CAP_CS_NO_INFO; | 2892 | int result, status = L2CAP_CS_NO_INFO; |
2783 | 2893 | ||
2784 | u16 dcid = 0, scid = __le16_to_cpu(req->scid); | 2894 | u16 dcid = 0, scid = __le16_to_cpu(req->scid); |
@@ -2887,6 +2997,15 @@ sendresp: | |||
2887 | L2CAP_INFO_REQ, sizeof(info), &info); | 2997 | L2CAP_INFO_REQ, sizeof(info), &info); |
2888 | } | 2998 | } |
2889 | 2999 | ||
3000 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && | ||
3001 | result == L2CAP_CR_SUCCESS) { | ||
3002 | u8 buf[128]; | ||
3003 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | ||
3004 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | ||
3005 | l2cap_build_conf_req(sk, buf), buf); | ||
3006 | l2cap_pi(sk)->num_conf_req++; | ||
3007 | } | ||
3008 | |||
2890 | return 0; | 3009 | return 0; |
2891 | } | 3010 | } |
2892 | 3011 | ||
@@ -2907,11 +3026,11 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2907 | if (scid) { | 3026 | if (scid) { |
2908 | sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); | 3027 | sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); |
2909 | if (!sk) | 3028 | if (!sk) |
2910 | return 0; | 3029 | return -EFAULT; |
2911 | } else { | 3030 | } else { |
2912 | sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident); | 3031 | sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident); |
2913 | if (!sk) | 3032 | if (!sk) |
2914 | return 0; | 3033 | return -EFAULT; |
2915 | } | 3034 | } |
2916 | 3035 | ||
2917 | switch (result) { | 3036 | switch (result) { |
@@ -2919,9 +3038,13 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2919 | sk->sk_state = BT_CONFIG; | 3038 | sk->sk_state = BT_CONFIG; |
2920 | l2cap_pi(sk)->ident = 0; | 3039 | l2cap_pi(sk)->ident = 0; |
2921 | l2cap_pi(sk)->dcid = dcid; | 3040 | l2cap_pi(sk)->dcid = dcid; |
2922 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | ||
2923 | l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND; | 3041 | l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND; |
2924 | 3042 | ||
3043 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) | ||
3044 | break; | ||
3045 | |||
3046 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | ||
3047 | |||
2925 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 3048 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
2926 | l2cap_build_conf_req(sk, req), req); | 3049 | l2cap_build_conf_req(sk, req), req); |
2927 | l2cap_pi(sk)->num_conf_req++; | 3050 | l2cap_pi(sk)->num_conf_req++; |
@@ -2957,8 +3080,14 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2957 | if (!sk) | 3080 | if (!sk) |
2958 | return -ENOENT; | 3081 | return -ENOENT; |
2959 | 3082 | ||
2960 | if (sk->sk_state == BT_DISCONN) | 3083 | if (sk->sk_state != BT_CONFIG) { |
3084 | struct l2cap_cmd_rej rej; | ||
3085 | |||
3086 | rej.reason = cpu_to_le16(0x0002); | ||
3087 | l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, | ||
3088 | sizeof(rej), &rej); | ||
2961 | goto unlock; | 3089 | goto unlock; |
3090 | } | ||
2962 | 3091 | ||
2963 | /* Reject if config buffer is too small. */ | 3092 | /* Reject if config buffer is too small. */ |
2964 | len = cmd_len - sizeof(*req); | 3093 | len = cmd_len - sizeof(*req); |
@@ -2984,7 +3113,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2984 | /* Complete config. */ | 3113 | /* Complete config. */ |
2985 | len = l2cap_parse_conf_req(sk, rsp); | 3114 | len = l2cap_parse_conf_req(sk, rsp); |
2986 | if (len < 0) { | 3115 | if (len < 0) { |
2987 | l2cap_send_disconn_req(conn, sk); | 3116 | l2cap_send_disconn_req(conn, sk, ECONNRESET); |
2988 | goto unlock; | 3117 | goto unlock; |
2989 | } | 3118 | } |
2990 | 3119 | ||
@@ -3054,7 +3183,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
3054 | char req[64]; | 3183 | char req[64]; |
3055 | 3184 | ||
3056 | if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { | 3185 | if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { |
3057 | l2cap_send_disconn_req(conn, sk); | 3186 | l2cap_send_disconn_req(conn, sk, ECONNRESET); |
3058 | goto done; | 3187 | goto done; |
3059 | } | 3188 | } |
3060 | 3189 | ||
@@ -3063,7 +3192,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
3063 | len = l2cap_parse_conf_rsp(sk, rsp->data, | 3192 | len = l2cap_parse_conf_rsp(sk, rsp->data, |
3064 | len, req, &result); | 3193 | len, req, &result); |
3065 | if (len < 0) { | 3194 | if (len < 0) { |
3066 | l2cap_send_disconn_req(conn, sk); | 3195 | l2cap_send_disconn_req(conn, sk, ECONNRESET); |
3067 | goto done; | 3196 | goto done; |
3068 | } | 3197 | } |
3069 | 3198 | ||
@@ -3076,10 +3205,9 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
3076 | } | 3205 | } |
3077 | 3206 | ||
3078 | default: | 3207 | default: |
3079 | sk->sk_state = BT_DISCONN; | ||
3080 | sk->sk_err = ECONNRESET; | 3208 | sk->sk_err = ECONNRESET; |
3081 | l2cap_sock_set_timer(sk, HZ * 5); | 3209 | l2cap_sock_set_timer(sk, HZ * 5); |
3082 | l2cap_send_disconn_req(conn, sk); | 3210 | l2cap_send_disconn_req(conn, sk, ECONNRESET); |
3083 | goto done; | 3211 | goto done; |
3084 | } | 3212 | } |
3085 | 3213 | ||
@@ -3130,16 +3258,6 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
3130 | 3258 | ||
3131 | sk->sk_shutdown = SHUTDOWN_MASK; | 3259 | sk->sk_shutdown = SHUTDOWN_MASK; |
3132 | 3260 | ||
3133 | skb_queue_purge(TX_QUEUE(sk)); | ||
3134 | |||
3135 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { | ||
3136 | skb_queue_purge(SREJ_QUEUE(sk)); | ||
3137 | skb_queue_purge(BUSY_QUEUE(sk)); | ||
3138 | del_timer(&l2cap_pi(sk)->retrans_timer); | ||
3139 | del_timer(&l2cap_pi(sk)->monitor_timer); | ||
3140 | del_timer(&l2cap_pi(sk)->ack_timer); | ||
3141 | } | ||
3142 | |||
3143 | l2cap_chan_del(sk, ECONNRESET); | 3261 | l2cap_chan_del(sk, ECONNRESET); |
3144 | bh_unlock_sock(sk); | 3262 | bh_unlock_sock(sk); |
3145 | 3263 | ||
@@ -3162,16 +3280,6 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd | |||
3162 | if (!sk) | 3280 | if (!sk) |
3163 | return 0; | 3281 | return 0; |
3164 | 3282 | ||
3165 | skb_queue_purge(TX_QUEUE(sk)); | ||
3166 | |||
3167 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { | ||
3168 | skb_queue_purge(SREJ_QUEUE(sk)); | ||
3169 | skb_queue_purge(BUSY_QUEUE(sk)); | ||
3170 | del_timer(&l2cap_pi(sk)->retrans_timer); | ||
3171 | del_timer(&l2cap_pi(sk)->monitor_timer); | ||
3172 | del_timer(&l2cap_pi(sk)->ack_timer); | ||
3173 | } | ||
3174 | |||
3175 | l2cap_chan_del(sk, 0); | 3283 | l2cap_chan_del(sk, 0); |
3176 | bh_unlock_sock(sk); | 3284 | bh_unlock_sock(sk); |
3177 | 3285 | ||
@@ -3194,7 +3302,7 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm | |||
3194 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; | 3302 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; |
3195 | rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK); | 3303 | rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK); |
3196 | rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); | 3304 | rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); |
3197 | if (enable_ertm) | 3305 | if (!disable_ertm) |
3198 | feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING | 3306 | feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING |
3199 | | L2CAP_FEAT_FCS; | 3307 | | L2CAP_FEAT_FCS; |
3200 | put_unaligned_le32(feat_mask, rsp->data); | 3308 | put_unaligned_le32(feat_mask, rsp->data); |
@@ -3359,7 +3467,7 @@ static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb) | |||
3359 | our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size); | 3467 | our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size); |
3360 | 3468 | ||
3361 | if (our_fcs != rcv_fcs) | 3469 | if (our_fcs != rcv_fcs) |
3362 | return -EINVAL; | 3470 | return -EBADMSG; |
3363 | } | 3471 | } |
3364 | return 0; | 3472 | return 0; |
3365 | } | 3473 | } |
@@ -3370,25 +3478,19 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk) | |||
3370 | u16 control = 0; | 3478 | u16 control = 0; |
3371 | 3479 | ||
3372 | pi->frames_sent = 0; | 3480 | pi->frames_sent = 0; |
3373 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; | ||
3374 | 3481 | ||
3375 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3482 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
3376 | 3483 | ||
3377 | if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { | 3484 | if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { |
3378 | control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL; | 3485 | control |= L2CAP_SUPER_RCV_NOT_READY; |
3379 | l2cap_send_sframe(pi, control); | 3486 | l2cap_send_sframe(pi, control); |
3380 | pi->conn_state |= L2CAP_CONN_RNR_SENT; | 3487 | pi->conn_state |= L2CAP_CONN_RNR_SENT; |
3381 | pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; | ||
3382 | } | 3488 | } |
3383 | 3489 | ||
3384 | if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0) | 3490 | if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY) |
3385 | __mod_retrans_timer(); | 3491 | l2cap_retransmit_frames(sk); |
3386 | |||
3387 | pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | ||
3388 | 3492 | ||
3389 | spin_lock_bh(&pi->send_lock); | ||
3390 | l2cap_ertm_send(sk); | 3493 | l2cap_ertm_send(sk); |
3391 | spin_unlock_bh(&pi->send_lock); | ||
3392 | 3494 | ||
3393 | if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) && | 3495 | if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) && |
3394 | pi->frames_sent == 0) { | 3496 | pi->frames_sent == 0) { |
@@ -3400,6 +3502,8 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk) | |||
3400 | static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar) | 3502 | static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar) |
3401 | { | 3503 | { |
3402 | struct sk_buff *next_skb; | 3504 | struct sk_buff *next_skb; |
3505 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
3506 | int tx_seq_offset, next_tx_seq_offset; | ||
3403 | 3507 | ||
3404 | bt_cb(skb)->tx_seq = tx_seq; | 3508 | bt_cb(skb)->tx_seq = tx_seq; |
3405 | bt_cb(skb)->sar = sar; | 3509 | bt_cb(skb)->sar = sar; |
@@ -3410,11 +3514,20 @@ static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_s | |||
3410 | return 0; | 3514 | return 0; |
3411 | } | 3515 | } |
3412 | 3516 | ||
3517 | tx_seq_offset = (tx_seq - pi->buffer_seq) % 64; | ||
3518 | if (tx_seq_offset < 0) | ||
3519 | tx_seq_offset += 64; | ||
3520 | |||
3413 | do { | 3521 | do { |
3414 | if (bt_cb(next_skb)->tx_seq == tx_seq) | 3522 | if (bt_cb(next_skb)->tx_seq == tx_seq) |
3415 | return -EINVAL; | 3523 | return -EINVAL; |
3416 | 3524 | ||
3417 | if (bt_cb(next_skb)->tx_seq > tx_seq) { | 3525 | next_tx_seq_offset = (bt_cb(next_skb)->tx_seq - |
3526 | pi->buffer_seq) % 64; | ||
3527 | if (next_tx_seq_offset < 0) | ||
3528 | next_tx_seq_offset += 64; | ||
3529 | |||
3530 | if (next_tx_seq_offset > tx_seq_offset) { | ||
3418 | __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb); | 3531 | __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb); |
3419 | return 0; | 3532 | return 0; |
3420 | } | 3533 | } |
@@ -3532,11 +3645,51 @@ drop: | |||
3532 | pi->sdu = NULL; | 3645 | pi->sdu = NULL; |
3533 | 3646 | ||
3534 | disconnect: | 3647 | disconnect: |
3535 | l2cap_send_disconn_req(pi->conn, sk); | 3648 | l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); |
3536 | kfree_skb(skb); | 3649 | kfree_skb(skb); |
3537 | return 0; | 3650 | return 0; |
3538 | } | 3651 | } |
3539 | 3652 | ||
3653 | static int l2cap_try_push_rx_skb(struct sock *sk) | ||
3654 | { | ||
3655 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
3656 | struct sk_buff *skb; | ||
3657 | u16 control; | ||
3658 | int err; | ||
3659 | |||
3660 | while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) { | ||
3661 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; | ||
3662 | err = l2cap_ertm_reassembly_sdu(sk, skb, control); | ||
3663 | if (err < 0) { | ||
3664 | skb_queue_head(BUSY_QUEUE(sk), skb); | ||
3665 | return -EBUSY; | ||
3666 | } | ||
3667 | |||
3668 | pi->buffer_seq = (pi->buffer_seq + 1) % 64; | ||
3669 | } | ||
3670 | |||
3671 | if (!(pi->conn_state & L2CAP_CONN_RNR_SENT)) | ||
3672 | goto done; | ||
3673 | |||
3674 | control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | ||
3675 | control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; | ||
3676 | l2cap_send_sframe(pi, control); | ||
3677 | l2cap_pi(sk)->retry_count = 1; | ||
3678 | |||
3679 | del_timer(&pi->retrans_timer); | ||
3680 | __mod_monitor_timer(); | ||
3681 | |||
3682 | l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F; | ||
3683 | |||
3684 | done: | ||
3685 | pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY; | ||
3686 | pi->conn_state &= ~L2CAP_CONN_RNR_SENT; | ||
3687 | |||
3688 | BT_DBG("sk %p, Exit local busy", sk); | ||
3689 | |||
3690 | return 0; | ||
3691 | } | ||
3692 | |||
3540 | static void l2cap_busy_work(struct work_struct *work) | 3693 | static void l2cap_busy_work(struct work_struct *work) |
3541 | { | 3694 | { |
3542 | DECLARE_WAITQUEUE(wait, current); | 3695 | DECLARE_WAITQUEUE(wait, current); |
@@ -3545,7 +3698,6 @@ static void l2cap_busy_work(struct work_struct *work) | |||
3545 | struct sock *sk = (struct sock *)pi; | 3698 | struct sock *sk = (struct sock *)pi; |
3546 | int n_tries = 0, timeo = HZ/5, err; | 3699 | int n_tries = 0, timeo = HZ/5, err; |
3547 | struct sk_buff *skb; | 3700 | struct sk_buff *skb; |
3548 | u16 control; | ||
3549 | 3701 | ||
3550 | lock_sock(sk); | 3702 | lock_sock(sk); |
3551 | 3703 | ||
@@ -3555,8 +3707,8 @@ static void l2cap_busy_work(struct work_struct *work) | |||
3555 | 3707 | ||
3556 | if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) { | 3708 | if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) { |
3557 | err = -EBUSY; | 3709 | err = -EBUSY; |
3558 | l2cap_send_disconn_req(pi->conn, sk); | 3710 | l2cap_send_disconn_req(pi->conn, sk, EBUSY); |
3559 | goto done; | 3711 | break; |
3560 | } | 3712 | } |
3561 | 3713 | ||
3562 | if (!timeo) | 3714 | if (!timeo) |
@@ -3564,7 +3716,7 @@ static void l2cap_busy_work(struct work_struct *work) | |||
3564 | 3716 | ||
3565 | if (signal_pending(current)) { | 3717 | if (signal_pending(current)) { |
3566 | err = sock_intr_errno(timeo); | 3718 | err = sock_intr_errno(timeo); |
3567 | goto done; | 3719 | break; |
3568 | } | 3720 | } |
3569 | 3721 | ||
3570 | release_sock(sk); | 3722 | release_sock(sk); |
@@ -3573,40 +3725,12 @@ static void l2cap_busy_work(struct work_struct *work) | |||
3573 | 3725 | ||
3574 | err = sock_error(sk); | 3726 | err = sock_error(sk); |
3575 | if (err) | 3727 | if (err) |
3576 | goto done; | 3728 | break; |
3577 | |||
3578 | while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) { | ||
3579 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; | ||
3580 | err = l2cap_ertm_reassembly_sdu(sk, skb, control); | ||
3581 | if (err < 0) { | ||
3582 | skb_queue_head(BUSY_QUEUE(sk), skb); | ||
3583 | break; | ||
3584 | } | ||
3585 | |||
3586 | pi->buffer_seq = (pi->buffer_seq + 1) % 64; | ||
3587 | } | ||
3588 | 3729 | ||
3589 | if (!skb) | 3730 | if (l2cap_try_push_rx_skb(sk) == 0) |
3590 | break; | 3731 | break; |
3591 | } | 3732 | } |
3592 | 3733 | ||
3593 | if (!(pi->conn_state & L2CAP_CONN_RNR_SENT)) | ||
3594 | goto done; | ||
3595 | |||
3596 | control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | ||
3597 | control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; | ||
3598 | l2cap_send_sframe(pi, control); | ||
3599 | l2cap_pi(sk)->retry_count = 1; | ||
3600 | |||
3601 | del_timer(&pi->retrans_timer); | ||
3602 | __mod_monitor_timer(); | ||
3603 | |||
3604 | l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F; | ||
3605 | |||
3606 | done: | ||
3607 | pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY; | ||
3608 | pi->conn_state &= ~L2CAP_CONN_RNR_SENT; | ||
3609 | |||
3610 | set_current_state(TASK_RUNNING); | 3734 | set_current_state(TASK_RUNNING); |
3611 | remove_wait_queue(sk_sleep(sk), &wait); | 3735 | remove_wait_queue(sk_sleep(sk), &wait); |
3612 | 3736 | ||
@@ -3621,7 +3745,9 @@ static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control) | |||
3621 | if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { | 3745 | if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { |
3622 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; | 3746 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; |
3623 | __skb_queue_tail(BUSY_QUEUE(sk), skb); | 3747 | __skb_queue_tail(BUSY_QUEUE(sk), skb); |
3624 | return -EBUSY; | 3748 | return l2cap_try_push_rx_skb(sk); |
3749 | |||
3750 | |||
3625 | } | 3751 | } |
3626 | 3752 | ||
3627 | err = l2cap_ertm_reassembly_sdu(sk, skb, control); | 3753 | err = l2cap_ertm_reassembly_sdu(sk, skb, control); |
@@ -3631,6 +3757,8 @@ static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control) | |||
3631 | } | 3757 | } |
3632 | 3758 | ||
3633 | /* Busy Condition */ | 3759 | /* Busy Condition */ |
3760 | BT_DBG("sk %p, Enter local busy", sk); | ||
3761 | |||
3634 | pi->conn_state |= L2CAP_CONN_LOCAL_BUSY; | 3762 | pi->conn_state |= L2CAP_CONN_LOCAL_BUSY; |
3635 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; | 3763 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; |
3636 | __skb_queue_tail(BUSY_QUEUE(sk), skb); | 3764 | __skb_queue_tail(BUSY_QUEUE(sk), skb); |
@@ -3641,6 +3769,8 @@ static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control) | |||
3641 | 3769 | ||
3642 | pi->conn_state |= L2CAP_CONN_RNR_SENT; | 3770 | pi->conn_state |= L2CAP_CONN_RNR_SENT; |
3643 | 3771 | ||
3772 | del_timer(&pi->ack_timer); | ||
3773 | |||
3644 | queue_work(_busy_wq, &pi->busy_work); | 3774 | queue_work(_busy_wq, &pi->busy_work); |
3645 | 3775 | ||
3646 | return err; | 3776 | return err; |
@@ -3754,7 +3884,7 @@ static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq) | |||
3754 | l2cap_ertm_reassembly_sdu(sk, skb, control); | 3884 | l2cap_ertm_reassembly_sdu(sk, skb, control); |
3755 | l2cap_pi(sk)->buffer_seq_srej = | 3885 | l2cap_pi(sk)->buffer_seq_srej = |
3756 | (l2cap_pi(sk)->buffer_seq_srej + 1) % 64; | 3886 | (l2cap_pi(sk)->buffer_seq_srej + 1) % 64; |
3757 | tx_seq++; | 3887 | tx_seq = (tx_seq + 1) % 64; |
3758 | } | 3888 | } |
3759 | } | 3889 | } |
3760 | 3890 | ||
@@ -3790,10 +3920,11 @@ static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq) | |||
3790 | l2cap_send_sframe(pi, control); | 3920 | l2cap_send_sframe(pi, control); |
3791 | 3921 | ||
3792 | new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); | 3922 | new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); |
3793 | new->tx_seq = pi->expected_tx_seq++; | 3923 | new->tx_seq = pi->expected_tx_seq; |
3924 | pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; | ||
3794 | list_add_tail(&new->list, SREJ_LIST(sk)); | 3925 | list_add_tail(&new->list, SREJ_LIST(sk)); |
3795 | } | 3926 | } |
3796 | pi->expected_tx_seq++; | 3927 | pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; |
3797 | } | 3928 | } |
3798 | 3929 | ||
3799 | static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) | 3930 | static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) |
@@ -3802,11 +3933,12 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str | |||
3802 | u8 tx_seq = __get_txseq(rx_control); | 3933 | u8 tx_seq = __get_txseq(rx_control); |
3803 | u8 req_seq = __get_reqseq(rx_control); | 3934 | u8 req_seq = __get_reqseq(rx_control); |
3804 | u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; | 3935 | u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; |
3805 | u8 tx_seq_offset, expected_tx_seq_offset; | 3936 | int tx_seq_offset, expected_tx_seq_offset; |
3806 | int num_to_ack = (pi->tx_win/6) + 1; | 3937 | int num_to_ack = (pi->tx_win/6) + 1; |
3807 | int err = 0; | 3938 | int err = 0; |
3808 | 3939 | ||
3809 | BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len); | 3940 | BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq, |
3941 | rx_control); | ||
3810 | 3942 | ||
3811 | if (L2CAP_CTRL_FINAL & rx_control && | 3943 | if (L2CAP_CTRL_FINAL & rx_control && |
3812 | l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) { | 3944 | l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) { |
@@ -3828,7 +3960,7 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str | |||
3828 | 3960 | ||
3829 | /* invalid tx_seq */ | 3961 | /* invalid tx_seq */ |
3830 | if (tx_seq_offset >= pi->tx_win) { | 3962 | if (tx_seq_offset >= pi->tx_win) { |
3831 | l2cap_send_disconn_req(pi->conn, sk); | 3963 | l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); |
3832 | goto drop; | 3964 | goto drop; |
3833 | } | 3965 | } |
3834 | 3966 | ||
@@ -3851,6 +3983,7 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str | |||
3851 | pi->buffer_seq = pi->buffer_seq_srej; | 3983 | pi->buffer_seq = pi->buffer_seq_srej; |
3852 | pi->conn_state &= ~L2CAP_CONN_SREJ_SENT; | 3984 | pi->conn_state &= ~L2CAP_CONN_SREJ_SENT; |
3853 | l2cap_send_ack(pi); | 3985 | l2cap_send_ack(pi); |
3986 | BT_DBG("sk %p, Exit SREJ_SENT", sk); | ||
3854 | } | 3987 | } |
3855 | } else { | 3988 | } else { |
3856 | struct srej_list *l; | 3989 | struct srej_list *l; |
@@ -3879,6 +4012,8 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str | |||
3879 | 4012 | ||
3880 | pi->conn_state |= L2CAP_CONN_SREJ_SENT; | 4013 | pi->conn_state |= L2CAP_CONN_SREJ_SENT; |
3881 | 4014 | ||
4015 | BT_DBG("sk %p, Enter SREJ", sk); | ||
4016 | |||
3882 | INIT_LIST_HEAD(SREJ_LIST(sk)); | 4017 | INIT_LIST_HEAD(SREJ_LIST(sk)); |
3883 | pi->buffer_seq_srej = pi->buffer_seq; | 4018 | pi->buffer_seq_srej = pi->buffer_seq; |
3884 | 4019 | ||
@@ -3889,6 +4024,8 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str | |||
3889 | pi->conn_state |= L2CAP_CONN_SEND_PBIT; | 4024 | pi->conn_state |= L2CAP_CONN_SEND_PBIT; |
3890 | 4025 | ||
3891 | l2cap_send_srejframe(sk, tx_seq); | 4026 | l2cap_send_srejframe(sk, tx_seq); |
4027 | |||
4028 | del_timer(&pi->ack_timer); | ||
3892 | } | 4029 | } |
3893 | return 0; | 4030 | return 0; |
3894 | 4031 | ||
@@ -3902,6 +4039,10 @@ expected: | |||
3902 | return 0; | 4039 | return 0; |
3903 | } | 4040 | } |
3904 | 4041 | ||
4042 | err = l2cap_push_rx_skb(sk, skb, rx_control); | ||
4043 | if (err < 0) | ||
4044 | return 0; | ||
4045 | |||
3905 | if (rx_control & L2CAP_CTRL_FINAL) { | 4046 | if (rx_control & L2CAP_CTRL_FINAL) { |
3906 | if (pi->conn_state & L2CAP_CONN_REJ_ACT) | 4047 | if (pi->conn_state & L2CAP_CONN_REJ_ACT) |
3907 | pi->conn_state &= ~L2CAP_CONN_REJ_ACT; | 4048 | pi->conn_state &= ~L2CAP_CONN_REJ_ACT; |
@@ -3909,10 +4050,6 @@ expected: | |||
3909 | l2cap_retransmit_frames(sk); | 4050 | l2cap_retransmit_frames(sk); |
3910 | } | 4051 | } |
3911 | 4052 | ||
3912 | err = l2cap_push_rx_skb(sk, skb, rx_control); | ||
3913 | if (err < 0) | ||
3914 | return 0; | ||
3915 | |||
3916 | __mod_ack_timer(); | 4053 | __mod_ack_timer(); |
3917 | 4054 | ||
3918 | pi->num_acked = (pi->num_acked + 1) % num_to_ack; | 4055 | pi->num_acked = (pi->num_acked + 1) % num_to_ack; |
@@ -3930,10 +4067,14 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) | |||
3930 | { | 4067 | { |
3931 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 4068 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
3932 | 4069 | ||
4070 | BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control), | ||
4071 | rx_control); | ||
4072 | |||
3933 | pi->expected_ack_seq = __get_reqseq(rx_control); | 4073 | pi->expected_ack_seq = __get_reqseq(rx_control); |
3934 | l2cap_drop_acked_frames(sk); | 4074 | l2cap_drop_acked_frames(sk); |
3935 | 4075 | ||
3936 | if (rx_control & L2CAP_CTRL_POLL) { | 4076 | if (rx_control & L2CAP_CTRL_POLL) { |
4077 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; | ||
3937 | if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { | 4078 | if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { |
3938 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && | 4079 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && |
3939 | (pi->unacked_frames > 0)) | 4080 | (pi->unacked_frames > 0)) |
@@ -3962,9 +4103,7 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) | |||
3962 | if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { | 4103 | if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { |
3963 | l2cap_send_ack(pi); | 4104 | l2cap_send_ack(pi); |
3964 | } else { | 4105 | } else { |
3965 | spin_lock_bh(&pi->send_lock); | ||
3966 | l2cap_ertm_send(sk); | 4106 | l2cap_ertm_send(sk); |
3967 | spin_unlock_bh(&pi->send_lock); | ||
3968 | } | 4107 | } |
3969 | } | 4108 | } |
3970 | } | 4109 | } |
@@ -3974,6 +4113,8 @@ static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control) | |||
3974 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 4113 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
3975 | u8 tx_seq = __get_reqseq(rx_control); | 4114 | u8 tx_seq = __get_reqseq(rx_control); |
3976 | 4115 | ||
4116 | BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); | ||
4117 | |||
3977 | pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | 4118 | pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; |
3978 | 4119 | ||
3979 | pi->expected_ack_seq = tx_seq; | 4120 | pi->expected_ack_seq = tx_seq; |
@@ -3996,16 +4137,18 @@ static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control) | |||
3996 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 4137 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
3997 | u8 tx_seq = __get_reqseq(rx_control); | 4138 | u8 tx_seq = __get_reqseq(rx_control); |
3998 | 4139 | ||
4140 | BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); | ||
4141 | |||
3999 | pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | 4142 | pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; |
4000 | 4143 | ||
4001 | if (rx_control & L2CAP_CTRL_POLL) { | 4144 | if (rx_control & L2CAP_CTRL_POLL) { |
4002 | pi->expected_ack_seq = tx_seq; | 4145 | pi->expected_ack_seq = tx_seq; |
4003 | l2cap_drop_acked_frames(sk); | 4146 | l2cap_drop_acked_frames(sk); |
4147 | |||
4148 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; | ||
4004 | l2cap_retransmit_one_frame(sk, tx_seq); | 4149 | l2cap_retransmit_one_frame(sk, tx_seq); |
4005 | 4150 | ||
4006 | spin_lock_bh(&pi->send_lock); | ||
4007 | l2cap_ertm_send(sk); | 4151 | l2cap_ertm_send(sk); |
4008 | spin_unlock_bh(&pi->send_lock); | ||
4009 | 4152 | ||
4010 | if (pi->conn_state & L2CAP_CONN_WAIT_F) { | 4153 | if (pi->conn_state & L2CAP_CONN_WAIT_F) { |
4011 | pi->srej_save_reqseq = tx_seq; | 4154 | pi->srej_save_reqseq = tx_seq; |
@@ -4031,10 +4174,15 @@ static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control) | |||
4031 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 4174 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
4032 | u8 tx_seq = __get_reqseq(rx_control); | 4175 | u8 tx_seq = __get_reqseq(rx_control); |
4033 | 4176 | ||
4177 | BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); | ||
4178 | |||
4034 | pi->conn_state |= L2CAP_CONN_REMOTE_BUSY; | 4179 | pi->conn_state |= L2CAP_CONN_REMOTE_BUSY; |
4035 | pi->expected_ack_seq = tx_seq; | 4180 | pi->expected_ack_seq = tx_seq; |
4036 | l2cap_drop_acked_frames(sk); | 4181 | l2cap_drop_acked_frames(sk); |
4037 | 4182 | ||
4183 | if (rx_control & L2CAP_CTRL_POLL) | ||
4184 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; | ||
4185 | |||
4038 | if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) { | 4186 | if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) { |
4039 | del_timer(&pi->retrans_timer); | 4187 | del_timer(&pi->retrans_timer); |
4040 | if (rx_control & L2CAP_CTRL_POLL) | 4188 | if (rx_control & L2CAP_CTRL_POLL) |
@@ -4082,12 +4230,83 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str | |||
4082 | return 0; | 4230 | return 0; |
4083 | } | 4231 | } |
4084 | 4232 | ||
4233 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | ||
4234 | { | ||
4235 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
4236 | u16 control; | ||
4237 | u8 req_seq; | ||
4238 | int len, next_tx_seq_offset, req_seq_offset; | ||
4239 | |||
4240 | control = get_unaligned_le16(skb->data); | ||
4241 | skb_pull(skb, 2); | ||
4242 | len = skb->len; | ||
4243 | |||
4244 | /* | ||
4245 | * We can just drop the corrupted I-frame here. | ||
4246 | * Receiver will miss it and start proper recovery | ||
4247 | * procedures and ask retransmission. | ||
4248 | */ | ||
4249 | if (l2cap_check_fcs(pi, skb)) | ||
4250 | goto drop; | ||
4251 | |||
4252 | if (__is_sar_start(control) && __is_iframe(control)) | ||
4253 | len -= 2; | ||
4254 | |||
4255 | if (pi->fcs == L2CAP_FCS_CRC16) | ||
4256 | len -= 2; | ||
4257 | |||
4258 | if (len > pi->mps) { | ||
4259 | l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); | ||
4260 | goto drop; | ||
4261 | } | ||
4262 | |||
4263 | req_seq = __get_reqseq(control); | ||
4264 | req_seq_offset = (req_seq - pi->expected_ack_seq) % 64; | ||
4265 | if (req_seq_offset < 0) | ||
4266 | req_seq_offset += 64; | ||
4267 | |||
4268 | next_tx_seq_offset = | ||
4269 | (pi->next_tx_seq - pi->expected_ack_seq) % 64; | ||
4270 | if (next_tx_seq_offset < 0) | ||
4271 | next_tx_seq_offset += 64; | ||
4272 | |||
4273 | /* check for invalid req-seq */ | ||
4274 | if (req_seq_offset > next_tx_seq_offset) { | ||
4275 | l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); | ||
4276 | goto drop; | ||
4277 | } | ||
4278 | |||
4279 | if (__is_iframe(control)) { | ||
4280 | if (len < 0) { | ||
4281 | l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); | ||
4282 | goto drop; | ||
4283 | } | ||
4284 | |||
4285 | l2cap_data_channel_iframe(sk, control, skb); | ||
4286 | } else { | ||
4287 | if (len != 0) { | ||
4288 | BT_ERR("%d", len); | ||
4289 | l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); | ||
4290 | goto drop; | ||
4291 | } | ||
4292 | |||
4293 | l2cap_data_channel_sframe(sk, control, skb); | ||
4294 | } | ||
4295 | |||
4296 | return 0; | ||
4297 | |||
4298 | drop: | ||
4299 | kfree_skb(skb); | ||
4300 | return 0; | ||
4301 | } | ||
4302 | |||
4085 | static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) | 4303 | static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) |
4086 | { | 4304 | { |
4087 | struct sock *sk; | 4305 | struct sock *sk; |
4088 | struct l2cap_pinfo *pi; | 4306 | struct l2cap_pinfo *pi; |
4089 | u16 control, len; | 4307 | u16 control; |
4090 | u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset; | 4308 | u8 tx_seq; |
4309 | int len; | ||
4091 | 4310 | ||
4092 | sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); | 4311 | sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); |
4093 | if (!sk) { | 4312 | if (!sk) { |
@@ -4117,59 +4336,11 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
4117 | break; | 4336 | break; |
4118 | 4337 | ||
4119 | case L2CAP_MODE_ERTM: | 4338 | case L2CAP_MODE_ERTM: |
4120 | control = get_unaligned_le16(skb->data); | 4339 | if (!sock_owned_by_user(sk)) { |
4121 | skb_pull(skb, 2); | 4340 | l2cap_ertm_data_rcv(sk, skb); |
4122 | len = skb->len; | ||
4123 | |||
4124 | if (__is_sar_start(control)) | ||
4125 | len -= 2; | ||
4126 | |||
4127 | if (pi->fcs == L2CAP_FCS_CRC16) | ||
4128 | len -= 2; | ||
4129 | |||
4130 | /* | ||
4131 | * We can just drop the corrupted I-frame here. | ||
4132 | * Receiver will miss it and start proper recovery | ||
4133 | * procedures and ask retransmission. | ||
4134 | */ | ||
4135 | if (len > pi->mps) { | ||
4136 | l2cap_send_disconn_req(pi->conn, sk); | ||
4137 | goto drop; | ||
4138 | } | ||
4139 | |||
4140 | if (l2cap_check_fcs(pi, skb)) | ||
4141 | goto drop; | ||
4142 | |||
4143 | req_seq = __get_reqseq(control); | ||
4144 | req_seq_offset = (req_seq - pi->expected_ack_seq) % 64; | ||
4145 | if (req_seq_offset < 0) | ||
4146 | req_seq_offset += 64; | ||
4147 | |||
4148 | next_tx_seq_offset = | ||
4149 | (pi->next_tx_seq - pi->expected_ack_seq) % 64; | ||
4150 | if (next_tx_seq_offset < 0) | ||
4151 | next_tx_seq_offset += 64; | ||
4152 | |||
4153 | /* check for invalid req-seq */ | ||
4154 | if (req_seq_offset > next_tx_seq_offset) { | ||
4155 | l2cap_send_disconn_req(pi->conn, sk); | ||
4156 | goto drop; | ||
4157 | } | ||
4158 | |||
4159 | if (__is_iframe(control)) { | ||
4160 | if (len < 4) { | ||
4161 | l2cap_send_disconn_req(pi->conn, sk); | ||
4162 | goto drop; | ||
4163 | } | ||
4164 | |||
4165 | l2cap_data_channel_iframe(sk, control, skb); | ||
4166 | } else { | 4341 | } else { |
4167 | if (len != 0) { | 4342 | if (sk_add_backlog(sk, skb)) |
4168 | l2cap_send_disconn_req(pi->conn, sk); | ||
4169 | goto drop; | 4343 | goto drop; |
4170 | } | ||
4171 | |||
4172 | l2cap_data_channel_sframe(sk, control, skb); | ||
4173 | } | 4344 | } |
4174 | 4345 | ||
4175 | goto done; | 4346 | goto done; |
@@ -4179,16 +4350,16 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
4179 | skb_pull(skb, 2); | 4350 | skb_pull(skb, 2); |
4180 | len = skb->len; | 4351 | len = skb->len; |
4181 | 4352 | ||
4353 | if (l2cap_check_fcs(pi, skb)) | ||
4354 | goto drop; | ||
4355 | |||
4182 | if (__is_sar_start(control)) | 4356 | if (__is_sar_start(control)) |
4183 | len -= 2; | 4357 | len -= 2; |
4184 | 4358 | ||
4185 | if (pi->fcs == L2CAP_FCS_CRC16) | 4359 | if (pi->fcs == L2CAP_FCS_CRC16) |
4186 | len -= 2; | 4360 | len -= 2; |
4187 | 4361 | ||
4188 | if (len > pi->mps || len < 4 || __is_sframe(control)) | 4362 | if (len > pi->mps || len < 0 || __is_sframe(control)) |
4189 | goto drop; | ||
4190 | |||
4191 | if (l2cap_check_fcs(pi, skb)) | ||
4192 | goto drop; | 4363 | goto drop; |
4193 | 4364 | ||
4194 | tx_seq = __get_txseq(control); | 4365 | tx_seq = __get_txseq(control); |
@@ -4288,7 +4459,7 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
4288 | struct hlist_node *node; | 4459 | struct hlist_node *node; |
4289 | 4460 | ||
4290 | if (type != ACL_LINK) | 4461 | if (type != ACL_LINK) |
4291 | return 0; | 4462 | return -EINVAL; |
4292 | 4463 | ||
4293 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); | 4464 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); |
4294 | 4465 | ||
@@ -4321,7 +4492,7 @@ static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) | |||
4321 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); | 4492 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); |
4322 | 4493 | ||
4323 | if (hcon->type != ACL_LINK) | 4494 | if (hcon->type != ACL_LINK) |
4324 | return 0; | 4495 | return -EINVAL; |
4325 | 4496 | ||
4326 | if (!status) { | 4497 | if (!status) { |
4327 | conn = l2cap_conn_add(hcon, status); | 4498 | conn = l2cap_conn_add(hcon, status); |
@@ -4350,7 +4521,7 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) | |||
4350 | BT_DBG("hcon %p reason %d", hcon, reason); | 4521 | BT_DBG("hcon %p reason %d", hcon, reason); |
4351 | 4522 | ||
4352 | if (hcon->type != ACL_LINK) | 4523 | if (hcon->type != ACL_LINK) |
4353 | return 0; | 4524 | return -EINVAL; |
4354 | 4525 | ||
4355 | l2cap_conn_del(hcon, bt_err(reason)); | 4526 | l2cap_conn_del(hcon, bt_err(reason)); |
4356 | 4527 | ||
@@ -4679,14 +4850,8 @@ EXPORT_SYMBOL(l2cap_load); | |||
4679 | module_init(l2cap_init); | 4850 | module_init(l2cap_init); |
4680 | module_exit(l2cap_exit); | 4851 | module_exit(l2cap_exit); |
4681 | 4852 | ||
4682 | module_param(enable_ertm, bool, 0644); | 4853 | module_param(disable_ertm, bool, 0644); |
4683 | MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode"); | 4854 | MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); |
4684 | |||
4685 | module_param(max_transmit, uint, 0644); | ||
4686 | MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)"); | ||
4687 | |||
4688 | module_param(tx_window, uint, 0644); | ||
4689 | MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)"); | ||
4690 | 4855 | ||
4691 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); | 4856 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); |
4692 | MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); | 4857 | MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 43fbf6b4b4bf..44a623275951 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -1152,7 +1152,7 @@ error: | |||
1152 | return err; | 1152 | return err; |
1153 | } | 1153 | } |
1154 | 1154 | ||
1155 | void rfcomm_cleanup_sockets(void) | 1155 | void __exit rfcomm_cleanup_sockets(void) |
1156 | { | 1156 | { |
1157 | debugfs_remove(rfcomm_sock_debugfs); | 1157 | debugfs_remove(rfcomm_sock_debugfs); |
1158 | 1158 | ||
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 309b6c261b25..026205c18b78 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -1153,7 +1153,7 @@ static const struct tty_operations rfcomm_ops = { | |||
1153 | .tiocmset = rfcomm_tty_tiocmset, | 1153 | .tiocmset = rfcomm_tty_tiocmset, |
1154 | }; | 1154 | }; |
1155 | 1155 | ||
1156 | int rfcomm_init_ttys(void) | 1156 | int __init rfcomm_init_ttys(void) |
1157 | { | 1157 | { |
1158 | rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS); | 1158 | rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS); |
1159 | if (!rfcomm_tty_driver) | 1159 | if (!rfcomm_tty_driver) |
@@ -1183,7 +1183,7 @@ int rfcomm_init_ttys(void) | |||
1183 | return 0; | 1183 | return 0; |
1184 | } | 1184 | } |
1185 | 1185 | ||
1186 | void rfcomm_cleanup_ttys(void) | 1186 | void __exit rfcomm_cleanup_ttys(void) |
1187 | { | 1187 | { |
1188 | tty_unregister_driver(rfcomm_tty_driver); | 1188 | tty_unregister_driver(rfcomm_tty_driver); |
1189 | put_tty_driver(rfcomm_tty_driver); | 1189 | put_tty_driver(rfcomm_tty_driver); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index db4d9340c846..29ac8e1a509e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -158,7 +158,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
158 | if (mac_addr) { | 158 | if (mac_addr) { |
159 | sta = sta_info_get_bss(sdata, mac_addr); | 159 | sta = sta_info_get_bss(sdata, mac_addr); |
160 | if (!sta) { | 160 | if (!sta) { |
161 | ieee80211_key_free(key); | 161 | ieee80211_key_free(sdata->local, key); |
162 | err = -ENOENT; | 162 | err = -ENOENT; |
163 | goto out_unlock; | 163 | goto out_unlock; |
164 | } | 164 | } |
@@ -192,7 +192,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
192 | goto out_unlock; | 192 | goto out_unlock; |
193 | 193 | ||
194 | if (sta->key) { | 194 | if (sta->key) { |
195 | ieee80211_key_free(sta->key); | 195 | ieee80211_key_free(sdata->local, sta->key); |
196 | WARN_ON(sta->key); | 196 | WARN_ON(sta->key); |
197 | ret = 0; | 197 | ret = 0; |
198 | } | 198 | } |
@@ -205,7 +205,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
205 | goto out_unlock; | 205 | goto out_unlock; |
206 | } | 206 | } |
207 | 207 | ||
208 | ieee80211_key_free(sdata->keys[key_idx]); | 208 | ieee80211_key_free(sdata->local, sdata->keys[key_idx]); |
209 | WARN_ON(sdata->keys[key_idx]); | 209 | WARN_ON(sdata->keys[key_idx]); |
210 | 210 | ||
211 | ret = 0; | 211 | ret = 0; |
@@ -324,15 +324,10 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy, | |||
324 | struct net_device *dev, | 324 | struct net_device *dev, |
325 | u8 key_idx) | 325 | u8 key_idx) |
326 | { | 326 | { |
327 | struct ieee80211_sub_if_data *sdata; | 327 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
328 | |||
329 | rcu_read_lock(); | ||
330 | 328 | ||
331 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
332 | ieee80211_set_default_mgmt_key(sdata, key_idx); | 329 | ieee80211_set_default_mgmt_key(sdata, key_idx); |
333 | 330 | ||
334 | rcu_read_unlock(); | ||
335 | |||
336 | return 0; | 331 | return 0; |
337 | } | 332 | } |
338 | 333 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ef470064b154..65e0ed6c2975 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -238,6 +238,7 @@ enum ieee80211_work_type { | |||
238 | IEEE80211_WORK_ABORT, | 238 | IEEE80211_WORK_ABORT, |
239 | IEEE80211_WORK_DIRECT_PROBE, | 239 | IEEE80211_WORK_DIRECT_PROBE, |
240 | IEEE80211_WORK_AUTH, | 240 | IEEE80211_WORK_AUTH, |
241 | IEEE80211_WORK_ASSOC_BEACON_WAIT, | ||
241 | IEEE80211_WORK_ASSOC, | 242 | IEEE80211_WORK_ASSOC, |
242 | IEEE80211_WORK_REMAIN_ON_CHANNEL, | 243 | IEEE80211_WORK_REMAIN_ON_CHANNEL, |
243 | }; | 244 | }; |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 50d1cff23d8e..1b9d87ed143a 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -323,13 +323,15 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) | |||
323 | if (!key) | 323 | if (!key) |
324 | return; | 324 | return; |
325 | 325 | ||
326 | ieee80211_key_disable_hw_accel(key); | 326 | if (key->local) |
327 | ieee80211_key_disable_hw_accel(key); | ||
327 | 328 | ||
328 | if (key->conf.alg == ALG_CCMP) | 329 | if (key->conf.alg == ALG_CCMP) |
329 | ieee80211_aes_key_free(key->u.ccmp.tfm); | 330 | ieee80211_aes_key_free(key->u.ccmp.tfm); |
330 | if (key->conf.alg == ALG_AES_CMAC) | 331 | if (key->conf.alg == ALG_AES_CMAC) |
331 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); | 332 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); |
332 | ieee80211_debugfs_key_remove(key); | 333 | if (key->local) |
334 | ieee80211_debugfs_key_remove(key); | ||
333 | 335 | ||
334 | kfree(key); | 336 | kfree(key); |
335 | } | 337 | } |
@@ -410,15 +412,12 @@ static void __ieee80211_key_free(struct ieee80211_key *key) | |||
410 | __ieee80211_key_destroy(key); | 412 | __ieee80211_key_destroy(key); |
411 | } | 413 | } |
412 | 414 | ||
413 | void ieee80211_key_free(struct ieee80211_key *key) | 415 | void ieee80211_key_free(struct ieee80211_local *local, |
416 | struct ieee80211_key *key) | ||
414 | { | 417 | { |
415 | struct ieee80211_local *local; | ||
416 | |||
417 | if (!key) | 418 | if (!key) |
418 | return; | 419 | return; |
419 | 420 | ||
420 | local = key->sdata->local; | ||
421 | |||
422 | mutex_lock(&local->key_mtx); | 421 | mutex_lock(&local->key_mtx); |
423 | __ieee80211_key_free(key); | 422 | __ieee80211_key_free(key); |
424 | mutex_unlock(&local->key_mtx); | 423 | mutex_unlock(&local->key_mtx); |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index a3849fa3fce8..b665bbb7a471 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -135,7 +135,8 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, | |||
135 | void ieee80211_key_link(struct ieee80211_key *key, | 135 | void ieee80211_key_link(struct ieee80211_key *key, |
136 | struct ieee80211_sub_if_data *sdata, | 136 | struct ieee80211_sub_if_data *sdata, |
137 | struct sta_info *sta); | 137 | struct sta_info *sta); |
138 | void ieee80211_key_free(struct ieee80211_key *key); | 138 | void ieee80211_key_free(struct ieee80211_local *local, |
139 | struct ieee80211_key *key); | ||
139 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); | 140 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); |
140 | void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, | 141 | void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, |
141 | int idx); | 142 | int idx); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0e95c750ded9..7cc4f913a431 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -107,12 +107,15 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
107 | if (scan_chan) { | 107 | if (scan_chan) { |
108 | chan = scan_chan; | 108 | chan = scan_chan; |
109 | channel_type = NL80211_CHAN_NO_HT; | 109 | channel_type = NL80211_CHAN_NO_HT; |
110 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | ||
110 | } else if (local->tmp_channel) { | 111 | } else if (local->tmp_channel) { |
111 | chan = scan_chan = local->tmp_channel; | 112 | chan = scan_chan = local->tmp_channel; |
112 | channel_type = local->tmp_channel_type; | 113 | channel_type = local->tmp_channel_type; |
114 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | ||
113 | } else { | 115 | } else { |
114 | chan = local->oper_channel; | 116 | chan = local->oper_channel; |
115 | channel_type = local->_oper_channel_type; | 117 | channel_type = local->_oper_channel_type; |
118 | local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; | ||
116 | } | 119 | } |
117 | 120 | ||
118 | if (chan != local->hw.conf.channel || | 121 | if (chan != local->hw.conf.channel || |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index cf8d72196c65..b6c163ac22da 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -870,6 +870,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
870 | 870 | ||
871 | ieee80211_led_assoc(local, 1); | 871 | ieee80211_led_assoc(local, 1); |
872 | 872 | ||
873 | if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) | ||
874 | bss_conf->dtim_period = bss->dtim_period; | ||
875 | else | ||
876 | bss_conf->dtim_period = 0; | ||
877 | |||
873 | bss_conf->assoc = 1; | 878 | bss_conf->assoc = 1; |
874 | /* | 879 | /* |
875 | * For now just always ask the driver to update the basic rateset | 880 | * For now just always ask the driver to update the basic rateset |
@@ -1751,7 +1756,8 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1751 | if (wk->sdata != sdata) | 1756 | if (wk->sdata != sdata) |
1752 | continue; | 1757 | continue; |
1753 | 1758 | ||
1754 | if (wk->type != IEEE80211_WORK_ASSOC) | 1759 | if (wk->type != IEEE80211_WORK_ASSOC && |
1760 | wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) | ||
1755 | continue; | 1761 | continue; |
1756 | 1762 | ||
1757 | if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN)) | 1763 | if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN)) |
@@ -2086,6 +2092,8 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, | |||
2086 | struct sk_buff *skb) | 2092 | struct sk_buff *skb) |
2087 | { | 2093 | { |
2088 | struct ieee80211_mgmt *mgmt; | 2094 | struct ieee80211_mgmt *mgmt; |
2095 | struct ieee80211_rx_status *rx_status; | ||
2096 | struct ieee802_11_elems elems; | ||
2089 | u16 status; | 2097 | u16 status; |
2090 | 2098 | ||
2091 | if (!skb) { | 2099 | if (!skb) { |
@@ -2093,6 +2101,19 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, | |||
2093 | return WORK_DONE_DESTROY; | 2101 | return WORK_DONE_DESTROY; |
2094 | } | 2102 | } |
2095 | 2103 | ||
2104 | if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) { | ||
2105 | mutex_lock(&wk->sdata->u.mgd.mtx); | ||
2106 | rx_status = (void *) skb->cb; | ||
2107 | ieee802_11_parse_elems(skb->data + 24 + 12, skb->len - 24 - 12, &elems); | ||
2108 | ieee80211_rx_bss_info(wk->sdata, (void *)skb->data, skb->len, rx_status, | ||
2109 | &elems, true); | ||
2110 | mutex_unlock(&wk->sdata->u.mgd.mtx); | ||
2111 | |||
2112 | wk->type = IEEE80211_WORK_ASSOC; | ||
2113 | /* not really done yet */ | ||
2114 | return WORK_DONE_REQUEUE; | ||
2115 | } | ||
2116 | |||
2096 | mgmt = (void *)skb->data; | 2117 | mgmt = (void *)skb->data; |
2097 | status = le16_to_cpu(mgmt->u.assoc_resp.status_code); | 2118 | status = le16_to_cpu(mgmt->u.assoc_resp.status_code); |
2098 | 2119 | ||
@@ -2206,10 +2227,14 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2206 | if (req->prev_bssid) | 2227 | if (req->prev_bssid) |
2207 | memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); | 2228 | memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); |
2208 | 2229 | ||
2209 | wk->type = IEEE80211_WORK_ASSOC; | ||
2210 | wk->chan = req->bss->channel; | 2230 | wk->chan = req->bss->channel; |
2211 | wk->sdata = sdata; | 2231 | wk->sdata = sdata; |
2212 | wk->done = ieee80211_assoc_done; | 2232 | wk->done = ieee80211_assoc_done; |
2233 | if (!bss->dtim_period && | ||
2234 | sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) | ||
2235 | wk->type = IEEE80211_WORK_ASSOC_BEACON_WAIT; | ||
2236 | else | ||
2237 | wk->type = IEEE80211_WORK_ASSOC; | ||
2213 | 2238 | ||
2214 | if (req->use_mfp) { | 2239 | if (req->use_mfp) { |
2215 | ifmgd->mfp = IEEE80211_MFP_REQUIRED; | 2240 | ifmgd->mfp = IEEE80211_MFP_REQUIRED; |
@@ -2257,7 +2282,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2257 | 2282 | ||
2258 | if (wk->type != IEEE80211_WORK_DIRECT_PROBE && | 2283 | if (wk->type != IEEE80211_WORK_DIRECT_PROBE && |
2259 | wk->type != IEEE80211_WORK_AUTH && | 2284 | wk->type != IEEE80211_WORK_AUTH && |
2260 | wk->type != IEEE80211_WORK_ASSOC) | 2285 | wk->type != IEEE80211_WORK_ASSOC && |
2286 | wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) | ||
2261 | continue; | 2287 | continue; |
2262 | 2288 | ||
2263 | if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) | 2289 | if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index f65ce6dcc8e2..778c604d7939 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -67,7 +67,6 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix) | |||
67 | for (i = rix; i >= 0; i--) | 67 | for (i = rix; i >= 0; i--) |
68 | if (mi->r[i].rix == rix) | 68 | if (mi->r[i].rix == rix) |
69 | break; | 69 | break; |
70 | WARN_ON(i < 0); | ||
71 | return i; | 70 | return i; |
72 | } | 71 | } |
73 | 72 | ||
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index b5ace243546c..c5b465904e3b 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -636,7 +636,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, | |||
636 | int i; | 636 | int i; |
637 | 637 | ||
638 | /* fall back to the old minstrel for legacy stations */ | 638 | /* fall back to the old minstrel for legacy stations */ |
639 | if (sta && !sta->ht_cap.ht_supported) { | 639 | if (!sta->ht_cap.ht_supported) { |
640 | msp->is_ht = false; | 640 | msp->is_ht = false; |
641 | memset(&msp->legacy, 0, sizeof(msp->legacy)); | 641 | memset(&msp->legacy, 0, sizeof(msp->legacy)); |
642 | msp->legacy.r = msp->ratelist; | 642 | msp->legacy.r = msp->ratelist; |
@@ -748,7 +748,7 @@ minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | |||
748 | return msp; | 748 | return msp; |
749 | 749 | ||
750 | error1: | 750 | error1: |
751 | kfree(msp->sample_table); | 751 | kfree(msp->ratelist); |
752 | error: | 752 | error: |
753 | kfree(msp); | 753 | kfree(msp); |
754 | return NULL; | 754 | return NULL; |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 439c98d93a79..41f20fb7e670 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -114,6 +114,10 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
114 | bss->dtim_period = tim_ie->dtim_period; | 114 | bss->dtim_period = tim_ie->dtim_period; |
115 | } | 115 | } |
116 | 116 | ||
117 | /* If the beacon had no TIM IE, or it was invalid, use 1 */ | ||
118 | if (beacon && !bss->dtim_period) | ||
119 | bss->dtim_period = 1; | ||
120 | |||
117 | /* replace old supported rates if we get new values */ | 121 | /* replace old supported rates if we get new values */ |
118 | srlen = 0; | 122 | srlen = 0; |
119 | if (elems->supp_rates) { | 123 | if (elems->supp_rates) { |
@@ -286,8 +290,6 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
286 | local->scanning = 0; | 290 | local->scanning = 0; |
287 | local->scan_channel = NULL; | 291 | local->scan_channel = NULL; |
288 | 292 | ||
289 | drv_sw_scan_complete(local); | ||
290 | |||
291 | /* we only have to protect scan_req and hw/sw scan */ | 293 | /* we only have to protect scan_req and hw/sw scan */ |
292 | mutex_unlock(&local->scan_mtx); | 294 | mutex_unlock(&local->scan_mtx); |
293 | 295 | ||
@@ -297,6 +299,8 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
297 | 299 | ||
298 | ieee80211_configure_filter(local); | 300 | ieee80211_configure_filter(local); |
299 | 301 | ||
302 | drv_sw_scan_complete(local); | ||
303 | |||
300 | ieee80211_offchannel_return(local, true); | 304 | ieee80211_offchannel_return(local, true); |
301 | 305 | ||
302 | done: | 306 | done: |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 67656cbf2b15..6d86f0c1ad04 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -647,7 +647,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
647 | return ret; | 647 | return ret; |
648 | 648 | ||
649 | if (sta->key) { | 649 | if (sta->key) { |
650 | ieee80211_key_free(sta->key); | 650 | ieee80211_key_free(local, sta->key); |
651 | WARN_ON(sta->key); | 651 | WARN_ON(sta->key); |
652 | } | 652 | } |
653 | 653 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 698d4718b1a4..c54db966926b 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -576,17 +576,6 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
576 | } | 576 | } |
577 | 577 | ||
578 | static ieee80211_tx_result debug_noinline | 578 | static ieee80211_tx_result debug_noinline |
579 | ieee80211_tx_h_sta(struct ieee80211_tx_data *tx) | ||
580 | { | ||
581 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
582 | |||
583 | if (tx->sta && tx->sta->uploaded) | ||
584 | info->control.sta = &tx->sta->sta; | ||
585 | |||
586 | return TX_CONTINUE; | ||
587 | } | ||
588 | |||
589 | static ieee80211_tx_result debug_noinline | ||
590 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | 579 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) |
591 | { | 580 | { |
592 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 581 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
@@ -1307,6 +1296,11 @@ static int __ieee80211_tx(struct ieee80211_local *local, | |||
1307 | break; | 1296 | break; |
1308 | } | 1297 | } |
1309 | 1298 | ||
1299 | if (sta && sta->uploaded) | ||
1300 | info->control.sta = &sta->sta; | ||
1301 | else | ||
1302 | info->control.sta = NULL; | ||
1303 | |||
1310 | ret = drv_tx(local, skb); | 1304 | ret = drv_tx(local, skb); |
1311 | if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { | 1305 | if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { |
1312 | dev_kfree_skb(skb); | 1306 | dev_kfree_skb(skb); |
@@ -1346,7 +1340,6 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1346 | CALL_TXH(ieee80211_tx_h_check_assoc); | 1340 | CALL_TXH(ieee80211_tx_h_check_assoc); |
1347 | CALL_TXH(ieee80211_tx_h_ps_buf); | 1341 | CALL_TXH(ieee80211_tx_h_ps_buf); |
1348 | CALL_TXH(ieee80211_tx_h_select_key); | 1342 | CALL_TXH(ieee80211_tx_h_select_key); |
1349 | CALL_TXH(ieee80211_tx_h_sta); | ||
1350 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) | 1343 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) |
1351 | CALL_TXH(ieee80211_tx_h_rate_ctrl); | 1344 | CALL_TXH(ieee80211_tx_h_rate_ctrl); |
1352 | 1345 | ||
@@ -1942,11 +1935,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1942 | h_pos += encaps_len; | 1935 | h_pos += encaps_len; |
1943 | } | 1936 | } |
1944 | 1937 | ||
1938 | #ifdef CONFIG_MAC80211_MESH | ||
1945 | if (meshhdrlen > 0) { | 1939 | if (meshhdrlen > 0) { |
1946 | memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen); | 1940 | memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen); |
1947 | nh_pos += meshhdrlen; | 1941 | nh_pos += meshhdrlen; |
1948 | h_pos += meshhdrlen; | 1942 | h_pos += meshhdrlen; |
1949 | } | 1943 | } |
1944 | #endif | ||
1950 | 1945 | ||
1951 | if (ieee80211_is_data_qos(fc)) { | 1946 | if (ieee80211_is_data_qos(fc)) { |
1952 | __le16 *qos_control; | 1947 | __le16 *qos_control; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 794792177376..748387d45bc0 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -803,8 +803,12 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) | |||
803 | 803 | ||
804 | /* after reinitialize QoS TX queues setting to default, | 804 | /* after reinitialize QoS TX queues setting to default, |
805 | * disable QoS at all */ | 805 | * disable QoS at all */ |
806 | sdata->vif.bss_conf.qos = sdata->vif.type != NL80211_IFTYPE_STATION; | 806 | |
807 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); | 807 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
808 | sdata->vif.bss_conf.qos = | ||
809 | sdata->vif.type != NL80211_IFTYPE_STATION; | ||
810 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); | ||
811 | } | ||
808 | } | 812 | } |
809 | 813 | ||
810 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, | 814 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index c22a71c5cb45..81d4ad64184a 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -560,6 +560,22 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk) | |||
560 | return WORK_ACT_TIMEOUT; | 560 | return WORK_ACT_TIMEOUT; |
561 | } | 561 | } |
562 | 562 | ||
563 | static enum work_action __must_check | ||
564 | ieee80211_assoc_beacon_wait(struct ieee80211_work *wk) | ||
565 | { | ||
566 | if (wk->started) | ||
567 | return WORK_ACT_TIMEOUT; | ||
568 | |||
569 | /* | ||
570 | * Wait up to one beacon interval ... | ||
571 | * should this be more if we miss one? | ||
572 | */ | ||
573 | printk(KERN_DEBUG "%s: waiting for beacon from %pM\n", | ||
574 | wk->sdata->name, wk->filter_ta); | ||
575 | wk->timeout = TU_TO_EXP_TIME(wk->assoc.bss->beacon_interval); | ||
576 | return WORK_ACT_NONE; | ||
577 | } | ||
578 | |||
563 | static void ieee80211_auth_challenge(struct ieee80211_work *wk, | 579 | static void ieee80211_auth_challenge(struct ieee80211_work *wk, |
564 | struct ieee80211_mgmt *mgmt, | 580 | struct ieee80211_mgmt *mgmt, |
565 | size_t len) | 581 | size_t len) |
@@ -709,6 +725,25 @@ ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk, | |||
709 | return WORK_ACT_DONE; | 725 | return WORK_ACT_DONE; |
710 | } | 726 | } |
711 | 727 | ||
728 | static enum work_action __must_check | ||
729 | ieee80211_rx_mgmt_beacon(struct ieee80211_work *wk, | ||
730 | struct ieee80211_mgmt *mgmt, size_t len) | ||
731 | { | ||
732 | struct ieee80211_sub_if_data *sdata = wk->sdata; | ||
733 | struct ieee80211_local *local = sdata->local; | ||
734 | |||
735 | ASSERT_WORK_MTX(local); | ||
736 | |||
737 | if (wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) | ||
738 | return WORK_ACT_MISMATCH; | ||
739 | |||
740 | if (len < 24 + 12) | ||
741 | return WORK_ACT_NONE; | ||
742 | |||
743 | printk(KERN_DEBUG "%s: beacon received\n", sdata->name); | ||
744 | return WORK_ACT_DONE; | ||
745 | } | ||
746 | |||
712 | static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | 747 | static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, |
713 | struct sk_buff *skb) | 748 | struct sk_buff *skb) |
714 | { | 749 | { |
@@ -731,6 +766,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
731 | case IEEE80211_WORK_DIRECT_PROBE: | 766 | case IEEE80211_WORK_DIRECT_PROBE: |
732 | case IEEE80211_WORK_AUTH: | 767 | case IEEE80211_WORK_AUTH: |
733 | case IEEE80211_WORK_ASSOC: | 768 | case IEEE80211_WORK_ASSOC: |
769 | case IEEE80211_WORK_ASSOC_BEACON_WAIT: | ||
734 | bssid = wk->filter_ta; | 770 | bssid = wk->filter_ta; |
735 | break; | 771 | break; |
736 | default: | 772 | default: |
@@ -745,6 +781,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
745 | continue; | 781 | continue; |
746 | 782 | ||
747 | switch (fc & IEEE80211_FCTL_STYPE) { | 783 | switch (fc & IEEE80211_FCTL_STYPE) { |
784 | case IEEE80211_STYPE_BEACON: | ||
785 | rma = ieee80211_rx_mgmt_beacon(wk, mgmt, skb->len); | ||
786 | break; | ||
748 | case IEEE80211_STYPE_PROBE_RESP: | 787 | case IEEE80211_STYPE_PROBE_RESP: |
749 | rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len, | 788 | rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len, |
750 | rx_status); | 789 | rx_status); |
@@ -916,6 +955,9 @@ static void ieee80211_work_work(struct work_struct *work) | |||
916 | case IEEE80211_WORK_REMAIN_ON_CHANNEL: | 955 | case IEEE80211_WORK_REMAIN_ON_CHANNEL: |
917 | rma = ieee80211_remain_on_channel_timeout(wk); | 956 | rma = ieee80211_remain_on_channel_timeout(wk); |
918 | break; | 957 | break; |
958 | case IEEE80211_WORK_ASSOC_BEACON_WAIT: | ||
959 | rma = ieee80211_assoc_beacon_wait(wk); | ||
960 | break; | ||
919 | } | 961 | } |
920 | 962 | ||
921 | wk->started = started; | 963 | wk->started = started; |
@@ -1065,6 +1107,7 @@ ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1065 | case IEEE80211_STYPE_PROBE_RESP: | 1107 | case IEEE80211_STYPE_PROBE_RESP: |
1066 | case IEEE80211_STYPE_ASSOC_RESP: | 1108 | case IEEE80211_STYPE_ASSOC_RESP: |
1067 | case IEEE80211_STYPE_REASSOC_RESP: | 1109 | case IEEE80211_STYPE_REASSOC_RESP: |
1110 | case IEEE80211_STYPE_BEACON: | ||
1068 | skb_queue_tail(&local->work_skb_queue, skb); | 1111 | skb_queue_tail(&local->work_skb_queue, skb); |
1069 | ieee80211_queue_work(&local->hw, &local->work_work); | 1112 | ieee80211_queue_work(&local->hw, &local->work_work); |
1070 | return RX_QUEUED; | 1113 | return RX_QUEUED; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index f65c6494ede9..541e2fff5e9c 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -907,3 +907,52 @@ static void __exit cfg80211_exit(void) | |||
907 | destroy_workqueue(cfg80211_wq); | 907 | destroy_workqueue(cfg80211_wq); |
908 | } | 908 | } |
909 | module_exit(cfg80211_exit); | 909 | module_exit(cfg80211_exit); |
910 | |||
911 | static int ___wiphy_printk(const char *level, const struct wiphy *wiphy, | ||
912 | struct va_format *vaf) | ||
913 | { | ||
914 | if (!wiphy) | ||
915 | return printk("%s(NULL wiphy *): %pV", level, vaf); | ||
916 | |||
917 | return printk("%s%s: %pV", level, wiphy_name(wiphy), vaf); | ||
918 | } | ||
919 | |||
920 | int __wiphy_printk(const char *level, const struct wiphy *wiphy, | ||
921 | const char *fmt, ...) | ||
922 | { | ||
923 | struct va_format vaf; | ||
924 | va_list args; | ||
925 | int r; | ||
926 | |||
927 | va_start(args, fmt); | ||
928 | |||
929 | vaf.fmt = fmt; | ||
930 | vaf.va = &args; | ||
931 | |||
932 | r = ___wiphy_printk(level, wiphy, &vaf); | ||
933 | va_end(args); | ||
934 | |||
935 | return r; | ||
936 | } | ||
937 | EXPORT_SYMBOL(__wiphy_printk); | ||
938 | |||
939 | #define define_wiphy_printk_level(func, kern_level) \ | ||
940 | int func(const struct wiphy *wiphy, const char *fmt, ...) \ | ||
941 | { \ | ||
942 | struct va_format vaf; \ | ||
943 | va_list args; \ | ||
944 | int r; \ | ||
945 | \ | ||
946 | va_start(args, fmt); \ | ||
947 | \ | ||
948 | vaf.fmt = fmt; \ | ||
949 | vaf.va = &args; \ | ||
950 | \ | ||
951 | r = ___wiphy_printk(kern_level, wiphy, &vaf); \ | ||
952 | va_end(args); \ | ||
953 | \ | ||
954 | return r; \ | ||
955 | } \ | ||
956 | EXPORT_SYMBOL(func); | ||
957 | |||
958 | define_wiphy_printk_level(wiphy_debug, KERN_DEBUG); | ||
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index adcabba02e20..27a8ce9343c3 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -247,8 +247,10 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, | |||
247 | if (!netif_running(wdev->netdev)) | 247 | if (!netif_running(wdev->netdev)) |
248 | return 0; | 248 | return 0; |
249 | 249 | ||
250 | if (wdev->wext.keys) | 250 | if (wdev->wext.keys) { |
251 | wdev->wext.keys->def = wdev->wext.default_key; | 251 | wdev->wext.keys->def = wdev->wext.default_key; |
252 | wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key; | ||
253 | } | ||
252 | 254 | ||
253 | wdev->wext.ibss.privacy = wdev->wext.default_key != -1; | 255 | wdev->wext.ibss.privacy = wdev->wext.default_key != -1; |
254 | 256 | ||
diff --git a/net/wireless/lib80211_crypt_ccmp.c b/net/wireless/lib80211_crypt_ccmp.c index b7fa31d5fd13..dacb3b4b1bdb 100644 --- a/net/wireless/lib80211_crypt_ccmp.c +++ b/net/wireless/lib80211_crypt_ccmp.c | |||
@@ -467,7 +467,6 @@ static struct lib80211_crypto_ops lib80211_crypt_ccmp = { | |||
467 | .name = "CCMP", | 467 | .name = "CCMP", |
468 | .init = lib80211_ccmp_init, | 468 | .init = lib80211_ccmp_init, |
469 | .deinit = lib80211_ccmp_deinit, | 469 | .deinit = lib80211_ccmp_deinit, |
470 | .build_iv = lib80211_ccmp_hdr, | ||
471 | .encrypt_mpdu = lib80211_ccmp_encrypt, | 470 | .encrypt_mpdu = lib80211_ccmp_encrypt, |
472 | .decrypt_mpdu = lib80211_ccmp_decrypt, | 471 | .decrypt_mpdu = lib80211_ccmp_decrypt, |
473 | .encrypt_msdu = NULL, | 472 | .encrypt_msdu = NULL, |
diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c index a7f995613f1f..0fe40510e2cb 100644 --- a/net/wireless/lib80211_crypt_tkip.c +++ b/net/wireless/lib80211_crypt_tkip.c | |||
@@ -757,7 +757,6 @@ static struct lib80211_crypto_ops lib80211_crypt_tkip = { | |||
757 | .name = "TKIP", | 757 | .name = "TKIP", |
758 | .init = lib80211_tkip_init, | 758 | .init = lib80211_tkip_init, |
759 | .deinit = lib80211_tkip_deinit, | 759 | .deinit = lib80211_tkip_deinit, |
760 | .build_iv = lib80211_tkip_hdr, | ||
761 | .encrypt_mpdu = lib80211_tkip_encrypt, | 760 | .encrypt_mpdu = lib80211_tkip_encrypt, |
762 | .decrypt_mpdu = lib80211_tkip_decrypt, | 761 | .decrypt_mpdu = lib80211_tkip_decrypt, |
763 | .encrypt_msdu = lib80211_michael_mic_add, | 762 | .encrypt_msdu = lib80211_michael_mic_add, |
diff --git a/net/wireless/lib80211_crypt_wep.c b/net/wireless/lib80211_crypt_wep.c index 6d41e05ca33b..e2e88878ba35 100644 --- a/net/wireless/lib80211_crypt_wep.c +++ b/net/wireless/lib80211_crypt_wep.c | |||
@@ -269,7 +269,6 @@ static struct lib80211_crypto_ops lib80211_crypt_wep = { | |||
269 | .name = "WEP", | 269 | .name = "WEP", |
270 | .init = lib80211_wep_init, | 270 | .init = lib80211_wep_init, |
271 | .deinit = lib80211_wep_deinit, | 271 | .deinit = lib80211_wep_deinit, |
272 | .build_iv = lib80211_wep_build_iv, | ||
273 | .encrypt_mpdu = lib80211_wep_encrypt, | 272 | .encrypt_mpdu = lib80211_wep_encrypt, |
274 | .decrypt_mpdu = lib80211_wep_decrypt, | 273 | .decrypt_mpdu = lib80211_wep_decrypt, |
275 | .encrypt_msdu = NULL, | 274 | .encrypt_msdu = NULL, |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index fbfac588297c..37902a54e9c1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2769,6 +2769,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb, | |||
2769 | 2769 | ||
2770 | nla_put_failure: | 2770 | nla_put_failure: |
2771 | genlmsg_cancel(msg, hdr); | 2771 | genlmsg_cancel(msg, hdr); |
2772 | nlmsg_free(msg); | ||
2772 | err = -EMSGSIZE; | 2773 | err = -EMSGSIZE; |
2773 | out: | 2774 | out: |
2774 | /* Cleanup */ | 2775 | /* Cleanup */ |
@@ -2960,6 +2961,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) | |||
2960 | 2961 | ||
2961 | nla_put_failure: | 2962 | nla_put_failure: |
2962 | genlmsg_cancel(msg, hdr); | 2963 | genlmsg_cancel(msg, hdr); |
2964 | nlmsg_free(msg); | ||
2963 | err = -EMSGSIZE; | 2965 | err = -EMSGSIZE; |
2964 | out: | 2966 | out: |
2965 | mutex_unlock(&cfg80211_mutex); | 2967 | mutex_unlock(&cfg80211_mutex); |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 48baf28cc4b6..f180db0de66c 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -1306,6 +1306,7 @@ static void reg_process_hint(struct regulatory_request *reg_request) | |||
1306 | { | 1306 | { |
1307 | int r = 0; | 1307 | int r = 0; |
1308 | struct wiphy *wiphy = NULL; | 1308 | struct wiphy *wiphy = NULL; |
1309 | enum nl80211_reg_initiator initiator = reg_request->initiator; | ||
1309 | 1310 | ||
1310 | BUG_ON(!reg_request->alpha2); | 1311 | BUG_ON(!reg_request->alpha2); |
1311 | 1312 | ||
@@ -1325,7 +1326,7 @@ static void reg_process_hint(struct regulatory_request *reg_request) | |||
1325 | /* This is required so that the orig_* parameters are saved */ | 1326 | /* This is required so that the orig_* parameters are saved */ |
1326 | if (r == -EALREADY && wiphy && | 1327 | if (r == -EALREADY && wiphy && |
1327 | wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) | 1328 | wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) |
1328 | wiphy_update_regulatory(wiphy, reg_request->initiator); | 1329 | wiphy_update_regulatory(wiphy, initiator); |
1329 | out: | 1330 | out: |
1330 | mutex_unlock(®_mutex); | 1331 | mutex_unlock(®_mutex); |
1331 | mutex_unlock(&cfg80211_mutex); | 1332 | mutex_unlock(&cfg80211_mutex); |
@@ -1492,7 +1493,6 @@ void regulatory_hint_11d(struct wiphy *wiphy, | |||
1492 | u8 *country_ie, | 1493 | u8 *country_ie, |
1493 | u8 country_ie_len) | 1494 | u8 country_ie_len) |
1494 | { | 1495 | { |
1495 | struct ieee80211_regdomain *rd = NULL; | ||
1496 | char alpha2[2]; | 1496 | char alpha2[2]; |
1497 | enum environment_cap env = ENVIRON_ANY; | 1497 | enum environment_cap env = ENVIRON_ANY; |
1498 | struct regulatory_request *request; | 1498 | struct regulatory_request *request; |
@@ -1529,7 +1529,7 @@ void regulatory_hint_11d(struct wiphy *wiphy, | |||
1529 | 1529 | ||
1530 | request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); | 1530 | request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); |
1531 | if (!request) | 1531 | if (!request) |
1532 | goto free_rd_out; | 1532 | goto out; |
1533 | 1533 | ||
1534 | request->wiphy_idx = get_wiphy_idx(wiphy); | 1534 | request->wiphy_idx = get_wiphy_idx(wiphy); |
1535 | request->alpha2[0] = alpha2[0]; | 1535 | request->alpha2[0] = alpha2[0]; |
@@ -1543,8 +1543,6 @@ void regulatory_hint_11d(struct wiphy *wiphy, | |||
1543 | 1543 | ||
1544 | return; | 1544 | return; |
1545 | 1545 | ||
1546 | free_rd_out: | ||
1547 | kfree(rd); | ||
1548 | out: | 1546 | out: |
1549 | mutex_unlock(®_mutex); | 1547 | mutex_unlock(®_mutex); |
1550 | } | 1548 | } |