diff options
author | David S. Miller <davem@davemloft.net> | 2013-11-08 13:15:39 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-11-08 13:15:39 -0500 |
commit | 74ecd3d1dd26f54ff36a0392f10e50fa8e256bd3 (patch) | |
tree | 878833c714ddcb35f1574f2b11e1f69d1130d206 /net | |
parent | dcd607718385d02ce3741de225927a57f528f93b (diff) | |
parent | c1f3bb6bd317994beb3af7bbec4bf54ed0035509 (diff) |
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says:
====================
Here is one more pull request for the 3.13 window. This is primarily
composed of downstream pull requests that were posted while I was
traveling during the last part of the 3.12 release.
For the mac80211 bits, Johannes says:
"I have two DFS fixes (ath9k already supports DFS) and a fix for a
pointer race."
And...
"In this round for mac80211-next I have:
* mesh channel switch support
* a CCM rewrite, using potential hardware offloads
* SMPS for AP mode
* RF-kill GPIO driver updates to make it usable as an ACPI driver
* regulatory improvements
* documentation fixes
* DFS for IBSS mode
* and a few small other fixes/improvements"
For the TI driver bits, Luca says:
"Some patches intended for 3.13. Eliad continues upstreaming pending
patches from the internal tree."
For the iwlwifi bits, Emmanuel says:
"There are a few fixes from Johannes mostly clean up patches. We have
also a few other fixes that are relevant for the new firmware that has
not been released yet."
For the Bluetooth bits, Gustavo says:
"A last fix to the 3.12. I ended forgetting to send it before, I hope we can
still make the way to 3.12. It is a revert and it fixes an issue with bluetooth
suspend/hibernate that had many bug reports. Please pull or let me know of any
problems. Thanks!" (Obviously, that one didn't make 3.12...)
Also...
"One more big pull request for 3.13. These are the patches we queued during
last week. Here you will find a lot of improvements to the HCI and L2CAP and
MGMT layers with the main ones being a better debugfs support and end of work
of splitting L2CAP into Core and Socket parts."
Additionally, there is one ath9k patch to enable DFS in IBSS mode for
that driver.
I appreciate your consideration for taking this extra pull request
this cycle. Please let me know if there are problems!
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
48 files changed, 2645 insertions, 1350 deletions
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 60ca52819247..efcd108822c4 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c | |||
@@ -672,7 +672,8 @@ static void a2mp_chan_close_cb(struct l2cap_chan *chan) | |||
672 | l2cap_chan_put(chan); | 672 | l2cap_chan_put(chan); |
673 | } | 673 | } |
674 | 674 | ||
675 | static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state) | 675 | static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state, |
676 | int err) | ||
676 | { | 677 | { |
677 | struct amp_mgr *mgr = chan->data; | 678 | struct amp_mgr *mgr = chan->data; |
678 | 679 | ||
@@ -709,6 +710,9 @@ static struct l2cap_ops a2mp_chan_ops = { | |||
709 | .teardown = l2cap_chan_no_teardown, | 710 | .teardown = l2cap_chan_no_teardown, |
710 | .ready = l2cap_chan_no_ready, | 711 | .ready = l2cap_chan_no_ready, |
711 | .defer = l2cap_chan_no_defer, | 712 | .defer = l2cap_chan_no_defer, |
713 | .resume = l2cap_chan_no_resume, | ||
714 | .set_shutdown = l2cap_chan_no_set_shutdown, | ||
715 | .get_sndtimeo = l2cap_chan_no_get_sndtimeo, | ||
712 | }; | 716 | }; |
713 | 717 | ||
714 | static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) | 718 | static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) |
@@ -832,6 +836,9 @@ struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, | |||
832 | { | 836 | { |
833 | struct amp_mgr *mgr; | 837 | struct amp_mgr *mgr; |
834 | 838 | ||
839 | if (conn->hcon->type != ACL_LINK) | ||
840 | return NULL; | ||
841 | |||
835 | mgr = amp_mgr_create(conn, false); | 842 | mgr = amp_mgr_create(conn, false); |
836 | if (!mgr) { | 843 | if (!mgr) { |
837 | BT_ERR("Could not create AMP manager"); | 844 | BT_ERR("Could not create AMP manager"); |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 1f1a1118f489..f6a1671ea2ff 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -25,6 +25,7 @@ | |||
25 | /* Bluetooth address family and sockets. */ | 25 | /* Bluetooth address family and sockets. */ |
26 | 26 | ||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/debugfs.h> | ||
28 | #include <asm/ioctls.h> | 29 | #include <asm/ioctls.h> |
29 | 30 | ||
30 | #include <net/bluetooth/bluetooth.h> | 31 | #include <net/bluetooth/bluetooth.h> |
@@ -708,12 +709,17 @@ static struct net_proto_family bt_sock_family_ops = { | |||
708 | .create = bt_sock_create, | 709 | .create = bt_sock_create, |
709 | }; | 710 | }; |
710 | 711 | ||
712 | struct dentry *bt_debugfs; | ||
713 | EXPORT_SYMBOL_GPL(bt_debugfs); | ||
714 | |||
711 | static int __init bt_init(void) | 715 | static int __init bt_init(void) |
712 | { | 716 | { |
713 | int err; | 717 | int err; |
714 | 718 | ||
715 | BT_INFO("Core ver %s", VERSION); | 719 | BT_INFO("Core ver %s", VERSION); |
716 | 720 | ||
721 | bt_debugfs = debugfs_create_dir("bluetooth", NULL); | ||
722 | |||
717 | err = bt_sysfs_init(); | 723 | err = bt_sysfs_init(); |
718 | if (err < 0) | 724 | if (err < 0) |
719 | return err; | 725 | return err; |
@@ -754,7 +760,6 @@ error: | |||
754 | 760 | ||
755 | static void __exit bt_exit(void) | 761 | static void __exit bt_exit(void) |
756 | { | 762 | { |
757 | |||
758 | sco_exit(); | 763 | sco_exit(); |
759 | 764 | ||
760 | l2cap_exit(); | 765 | l2cap_exit(); |
@@ -764,6 +769,8 @@ static void __exit bt_exit(void) | |||
764 | sock_unregister(PF_BLUETOOTH); | 769 | sock_unregister(PF_BLUETOOTH); |
765 | 770 | ||
766 | bt_sysfs_cleanup(); | 771 | bt_sysfs_cleanup(); |
772 | |||
773 | debugfs_remove_recursive(bt_debugfs); | ||
767 | } | 774 | } |
768 | 775 | ||
769 | subsys_initcall(bt_init); | 776 | subsys_initcall(bt_init); |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index ff04b051792d..ba5366c320da 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -317,8 +317,10 @@ static void hci_conn_timeout(struct work_struct *work) | |||
317 | } | 317 | } |
318 | 318 | ||
319 | /* Enter sniff mode */ | 319 | /* Enter sniff mode */ |
320 | static void hci_conn_enter_sniff_mode(struct hci_conn *conn) | 320 | static void hci_conn_idle(struct work_struct *work) |
321 | { | 321 | { |
322 | struct hci_conn *conn = container_of(work, struct hci_conn, | ||
323 | idle_work.work); | ||
322 | struct hci_dev *hdev = conn->hdev; | 324 | struct hci_dev *hdev = conn->hdev; |
323 | 325 | ||
324 | BT_DBG("hcon %p mode %d", conn, conn->mode); | 326 | BT_DBG("hcon %p mode %d", conn, conn->mode); |
@@ -352,21 +354,12 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn) | |||
352 | } | 354 | } |
353 | } | 355 | } |
354 | 356 | ||
355 | static void hci_conn_idle(unsigned long arg) | 357 | static void hci_conn_auto_accept(struct work_struct *work) |
356 | { | ||
357 | struct hci_conn *conn = (void *) arg; | ||
358 | |||
359 | BT_DBG("hcon %p mode %d", conn, conn->mode); | ||
360 | |||
361 | hci_conn_enter_sniff_mode(conn); | ||
362 | } | ||
363 | |||
364 | static void hci_conn_auto_accept(unsigned long arg) | ||
365 | { | 358 | { |
366 | struct hci_conn *conn = (void *) arg; | 359 | struct hci_conn *conn = container_of(work, struct hci_conn, |
367 | struct hci_dev *hdev = conn->hdev; | 360 | auto_accept_work.work); |
368 | 361 | ||
369 | hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst), | 362 | hci_send_cmd(conn->hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst), |
370 | &conn->dst); | 363 | &conn->dst); |
371 | } | 364 | } |
372 | 365 | ||
@@ -415,9 +408,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
415 | INIT_LIST_HEAD(&conn->chan_list); | 408 | INIT_LIST_HEAD(&conn->chan_list); |
416 | 409 | ||
417 | INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout); | 410 | INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout); |
418 | setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); | 411 | INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept); |
419 | setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept, | 412 | INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle); |
420 | (unsigned long) conn); | ||
421 | 413 | ||
422 | atomic_set(&conn->refcnt, 0); | 414 | atomic_set(&conn->refcnt, 0); |
423 | 415 | ||
@@ -438,11 +430,9 @@ int hci_conn_del(struct hci_conn *conn) | |||
438 | 430 | ||
439 | BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle); | 431 | BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle); |
440 | 432 | ||
441 | del_timer(&conn->idle_timer); | ||
442 | |||
443 | cancel_delayed_work_sync(&conn->disc_work); | 433 | cancel_delayed_work_sync(&conn->disc_work); |
444 | 434 | cancel_delayed_work_sync(&conn->auto_accept_work); | |
445 | del_timer(&conn->auto_accept_timer); | 435 | cancel_delayed_work_sync(&conn->idle_work); |
446 | 436 | ||
447 | if (conn->type == ACL_LINK) { | 437 | if (conn->type == ACL_LINK) { |
448 | struct hci_conn *sco = conn->link; | 438 | struct hci_conn *sco = conn->link; |
@@ -568,11 +558,12 @@ static int hci_create_le_conn(struct hci_conn *conn) | |||
568 | bacpy(&cp.peer_addr, &conn->dst); | 558 | bacpy(&cp.peer_addr, &conn->dst); |
569 | cp.peer_addr_type = conn->dst_type; | 559 | cp.peer_addr_type = conn->dst_type; |
570 | cp.own_address_type = conn->src_type; | 560 | cp.own_address_type = conn->src_type; |
571 | cp.conn_interval_min = __constant_cpu_to_le16(0x0028); | 561 | cp.conn_interval_min = cpu_to_le16(hdev->le_conn_min_interval); |
572 | cp.conn_interval_max = __constant_cpu_to_le16(0x0038); | 562 | cp.conn_interval_max = cpu_to_le16(hdev->le_conn_max_interval); |
573 | cp.supervision_timeout = __constant_cpu_to_le16(0x002a); | 563 | cp.supervision_timeout = __constant_cpu_to_le16(0x002a); |
574 | cp.min_ce_len = __constant_cpu_to_le16(0x0000); | 564 | cp.min_ce_len = __constant_cpu_to_le16(0x0000); |
575 | cp.max_ce_len = __constant_cpu_to_le16(0x0000); | 565 | cp.max_ce_len = __constant_cpu_to_le16(0x0000); |
566 | |||
576 | hci_req_add(&req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); | 567 | hci_req_add(&req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); |
577 | 568 | ||
578 | err = hci_req_run(&req, create_le_conn_complete); | 569 | err = hci_req_run(&req, create_le_conn_complete); |
@@ -625,12 +616,7 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, | |||
625 | else | 616 | else |
626 | conn->dst_type = ADDR_LE_DEV_RANDOM; | 617 | conn->dst_type = ADDR_LE_DEV_RANDOM; |
627 | 618 | ||
628 | if (bacmp(&conn->src, BDADDR_ANY)) { | 619 | conn->src_type = hdev->own_addr_type; |
629 | conn->src_type = ADDR_LE_DEV_PUBLIC; | ||
630 | } else { | ||
631 | bacpy(&conn->src, &hdev->static_addr); | ||
632 | conn->src_type = ADDR_LE_DEV_RANDOM; | ||
633 | } | ||
634 | 620 | ||
635 | conn->state = BT_CONNECT; | 621 | conn->state = BT_CONNECT; |
636 | conn->out = true; | 622 | conn->out = true; |
@@ -922,8 +908,8 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) | |||
922 | 908 | ||
923 | timer: | 909 | timer: |
924 | if (hdev->idle_timeout > 0) | 910 | if (hdev->idle_timeout > 0) |
925 | mod_timer(&conn->idle_timer, | 911 | queue_delayed_work(hdev->workqueue, &conn->idle_work, |
926 | jiffies + msecs_to_jiffies(hdev->idle_timeout)); | 912 | msecs_to_jiffies(hdev->idle_timeout)); |
927 | } | 913 | } |
928 | 914 | ||
929 | /* Drop all connection on the device */ | 915 | /* Drop all connection on the device */ |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 7add9c96e32c..6ccc4eb9e55e 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -27,8 +27,9 @@ | |||
27 | 27 | ||
28 | #include <linux/export.h> | 28 | #include <linux/export.h> |
29 | #include <linux/idr.h> | 29 | #include <linux/idr.h> |
30 | |||
31 | #include <linux/rfkill.h> | 30 | #include <linux/rfkill.h> |
31 | #include <linux/debugfs.h> | ||
32 | #include <asm/unaligned.h> | ||
32 | 33 | ||
33 | #include <net/bluetooth/bluetooth.h> | 34 | #include <net/bluetooth/bluetooth.h> |
34 | #include <net/bluetooth/hci_core.h> | 35 | #include <net/bluetooth/hci_core.h> |
@@ -55,6 +56,586 @@ static void hci_notify(struct hci_dev *hdev, int event) | |||
55 | hci_sock_dev_event(hdev, event); | 56 | hci_sock_dev_event(hdev, event); |
56 | } | 57 | } |
57 | 58 | ||
59 | /* ---- HCI debugfs entries ---- */ | ||
60 | |||
61 | static ssize_t dut_mode_read(struct file *file, char __user *user_buf, | ||
62 | size_t count, loff_t *ppos) | ||
63 | { | ||
64 | struct hci_dev *hdev = file->private_data; | ||
65 | char buf[3]; | ||
66 | |||
67 | buf[0] = test_bit(HCI_DUT_MODE, &hdev->dev_flags) ? 'Y': 'N'; | ||
68 | buf[1] = '\n'; | ||
69 | buf[2] = '\0'; | ||
70 | return simple_read_from_buffer(user_buf, count, ppos, buf, 2); | ||
71 | } | ||
72 | |||
73 | static ssize_t dut_mode_write(struct file *file, const char __user *user_buf, | ||
74 | size_t count, loff_t *ppos) | ||
75 | { | ||
76 | struct hci_dev *hdev = file->private_data; | ||
77 | struct sk_buff *skb; | ||
78 | char buf[32]; | ||
79 | size_t buf_size = min(count, (sizeof(buf)-1)); | ||
80 | bool enable; | ||
81 | int err; | ||
82 | |||
83 | if (!test_bit(HCI_UP, &hdev->flags)) | ||
84 | return -ENETDOWN; | ||
85 | |||
86 | if (copy_from_user(buf, user_buf, buf_size)) | ||
87 | return -EFAULT; | ||
88 | |||
89 | buf[buf_size] = '\0'; | ||
90 | if (strtobool(buf, &enable)) | ||
91 | return -EINVAL; | ||
92 | |||
93 | if (enable == test_bit(HCI_DUT_MODE, &hdev->dev_flags)) | ||
94 | return -EALREADY; | ||
95 | |||
96 | hci_req_lock(hdev); | ||
97 | if (enable) | ||
98 | skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL, | ||
99 | HCI_CMD_TIMEOUT); | ||
100 | else | ||
101 | skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, | ||
102 | HCI_CMD_TIMEOUT); | ||
103 | hci_req_unlock(hdev); | ||
104 | |||
105 | if (IS_ERR(skb)) | ||
106 | return PTR_ERR(skb); | ||
107 | |||
108 | err = -bt_to_errno(skb->data[0]); | ||
109 | kfree_skb(skb); | ||
110 | |||
111 | if (err < 0) | ||
112 | return err; | ||
113 | |||
114 | change_bit(HCI_DUT_MODE, &hdev->dev_flags); | ||
115 | |||
116 | return count; | ||
117 | } | ||
118 | |||
119 | static const struct file_operations dut_mode_fops = { | ||
120 | .open = simple_open, | ||
121 | .read = dut_mode_read, | ||
122 | .write = dut_mode_write, | ||
123 | .llseek = default_llseek, | ||
124 | }; | ||
125 | |||
126 | static int features_show(struct seq_file *f, void *ptr) | ||
127 | { | ||
128 | struct hci_dev *hdev = f->private; | ||
129 | u8 p; | ||
130 | |||
131 | hci_dev_lock(hdev); | ||
132 | for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) { | ||
133 | seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " | ||
134 | "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p, | ||
135 | hdev->features[p][0], hdev->features[p][1], | ||
136 | hdev->features[p][2], hdev->features[p][3], | ||
137 | hdev->features[p][4], hdev->features[p][5], | ||
138 | hdev->features[p][6], hdev->features[p][7]); | ||
139 | } | ||
140 | if (lmp_le_capable(hdev)) | ||
141 | seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " | ||
142 | "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", | ||
143 | hdev->le_features[0], hdev->le_features[1], | ||
144 | hdev->le_features[2], hdev->le_features[3], | ||
145 | hdev->le_features[4], hdev->le_features[5], | ||
146 | hdev->le_features[6], hdev->le_features[7]); | ||
147 | hci_dev_unlock(hdev); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static int features_open(struct inode *inode, struct file *file) | ||
153 | { | ||
154 | return single_open(file, features_show, inode->i_private); | ||
155 | } | ||
156 | |||
157 | static const struct file_operations features_fops = { | ||
158 | .open = features_open, | ||
159 | .read = seq_read, | ||
160 | .llseek = seq_lseek, | ||
161 | .release = single_release, | ||
162 | }; | ||
163 | |||
164 | static int blacklist_show(struct seq_file *f, void *p) | ||
165 | { | ||
166 | struct hci_dev *hdev = f->private; | ||
167 | struct bdaddr_list *b; | ||
168 | |||
169 | hci_dev_lock(hdev); | ||
170 | list_for_each_entry(b, &hdev->blacklist, list) | ||
171 | seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type); | ||
172 | hci_dev_unlock(hdev); | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static int blacklist_open(struct inode *inode, struct file *file) | ||
178 | { | ||
179 | return single_open(file, blacklist_show, inode->i_private); | ||
180 | } | ||
181 | |||
182 | static const struct file_operations blacklist_fops = { | ||
183 | .open = blacklist_open, | ||
184 | .read = seq_read, | ||
185 | .llseek = seq_lseek, | ||
186 | .release = single_release, | ||
187 | }; | ||
188 | |||
189 | static int uuids_show(struct seq_file *f, void *p) | ||
190 | { | ||
191 | struct hci_dev *hdev = f->private; | ||
192 | struct bt_uuid *uuid; | ||
193 | |||
194 | hci_dev_lock(hdev); | ||
195 | list_for_each_entry(uuid, &hdev->uuids, list) { | ||
196 | u8 i, val[16]; | ||
197 | |||
198 | /* The Bluetooth UUID values are stored in big endian, | ||
199 | * but with reversed byte order. So convert them into | ||
200 | * the right order for the %pUb modifier. | ||
201 | */ | ||
202 | for (i = 0; i < 16; i++) | ||
203 | val[i] = uuid->uuid[15 - i]; | ||
204 | |||
205 | seq_printf(f, "%pUb\n", val); | ||
206 | } | ||
207 | hci_dev_unlock(hdev); | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int uuids_open(struct inode *inode, struct file *file) | ||
213 | { | ||
214 | return single_open(file, uuids_show, inode->i_private); | ||
215 | } | ||
216 | |||
217 | static const struct file_operations uuids_fops = { | ||
218 | .open = uuids_open, | ||
219 | .read = seq_read, | ||
220 | .llseek = seq_lseek, | ||
221 | .release = single_release, | ||
222 | }; | ||
223 | |||
224 | static int inquiry_cache_show(struct seq_file *f, void *p) | ||
225 | { | ||
226 | struct hci_dev *hdev = f->private; | ||
227 | struct discovery_state *cache = &hdev->discovery; | ||
228 | struct inquiry_entry *e; | ||
229 | |||
230 | hci_dev_lock(hdev); | ||
231 | |||
232 | list_for_each_entry(e, &cache->all, all) { | ||
233 | struct inquiry_data *data = &e->data; | ||
234 | seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", | ||
235 | &data->bdaddr, | ||
236 | data->pscan_rep_mode, data->pscan_period_mode, | ||
237 | data->pscan_mode, data->dev_class[2], | ||
238 | data->dev_class[1], data->dev_class[0], | ||
239 | __le16_to_cpu(data->clock_offset), | ||
240 | data->rssi, data->ssp_mode, e->timestamp); | ||
241 | } | ||
242 | |||
243 | hci_dev_unlock(hdev); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int inquiry_cache_open(struct inode *inode, struct file *file) | ||
249 | { | ||
250 | return single_open(file, inquiry_cache_show, inode->i_private); | ||
251 | } | ||
252 | |||
253 | static const struct file_operations inquiry_cache_fops = { | ||
254 | .open = inquiry_cache_open, | ||
255 | .read = seq_read, | ||
256 | .llseek = seq_lseek, | ||
257 | .release = single_release, | ||
258 | }; | ||
259 | |||
260 | static int link_keys_show(struct seq_file *f, void *ptr) | ||
261 | { | ||
262 | struct hci_dev *hdev = f->private; | ||
263 | struct list_head *p, *n; | ||
264 | |||
265 | hci_dev_lock(hdev); | ||
266 | list_for_each_safe(p, n, &hdev->link_keys) { | ||
267 | struct link_key *key = list_entry(p, struct link_key, list); | ||
268 | seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type, | ||
269 | HCI_LINK_KEY_SIZE, key->val, key->pin_len); | ||
270 | } | ||
271 | hci_dev_unlock(hdev); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int link_keys_open(struct inode *inode, struct file *file) | ||
277 | { | ||
278 | return single_open(file, link_keys_show, inode->i_private); | ||
279 | } | ||
280 | |||
281 | static const struct file_operations link_keys_fops = { | ||
282 | .open = link_keys_open, | ||
283 | .read = seq_read, | ||
284 | .llseek = seq_lseek, | ||
285 | .release = single_release, | ||
286 | }; | ||
287 | |||
288 | static ssize_t use_debug_keys_read(struct file *file, char __user *user_buf, | ||
289 | size_t count, loff_t *ppos) | ||
290 | { | ||
291 | struct hci_dev *hdev = file->private_data; | ||
292 | char buf[3]; | ||
293 | |||
294 | buf[0] = test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) ? 'Y': 'N'; | ||
295 | buf[1] = '\n'; | ||
296 | buf[2] = '\0'; | ||
297 | return simple_read_from_buffer(user_buf, count, ppos, buf, 2); | ||
298 | } | ||
299 | |||
300 | static const struct file_operations use_debug_keys_fops = { | ||
301 | .open = simple_open, | ||
302 | .read = use_debug_keys_read, | ||
303 | .llseek = default_llseek, | ||
304 | }; | ||
305 | |||
306 | static int dev_class_show(struct seq_file *f, void *ptr) | ||
307 | { | ||
308 | struct hci_dev *hdev = f->private; | ||
309 | |||
310 | hci_dev_lock(hdev); | ||
311 | seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2], | ||
312 | hdev->dev_class[1], hdev->dev_class[0]); | ||
313 | hci_dev_unlock(hdev); | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static int dev_class_open(struct inode *inode, struct file *file) | ||
319 | { | ||
320 | return single_open(file, dev_class_show, inode->i_private); | ||
321 | } | ||
322 | |||
323 | static const struct file_operations dev_class_fops = { | ||
324 | .open = dev_class_open, | ||
325 | .read = seq_read, | ||
326 | .llseek = seq_lseek, | ||
327 | .release = single_release, | ||
328 | }; | ||
329 | |||
330 | static int voice_setting_get(void *data, u64 *val) | ||
331 | { | ||
332 | struct hci_dev *hdev = data; | ||
333 | |||
334 | hci_dev_lock(hdev); | ||
335 | *val = hdev->voice_setting; | ||
336 | hci_dev_unlock(hdev); | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get, | ||
342 | NULL, "0x%4.4llx\n"); | ||
343 | |||
344 | static int auto_accept_delay_set(void *data, u64 val) | ||
345 | { | ||
346 | struct hci_dev *hdev = data; | ||
347 | |||
348 | hci_dev_lock(hdev); | ||
349 | hdev->auto_accept_delay = val; | ||
350 | hci_dev_unlock(hdev); | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static int auto_accept_delay_get(void *data, u64 *val) | ||
356 | { | ||
357 | struct hci_dev *hdev = data; | ||
358 | |||
359 | hci_dev_lock(hdev); | ||
360 | *val = hdev->auto_accept_delay; | ||
361 | hci_dev_unlock(hdev); | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, | ||
367 | auto_accept_delay_set, "%llu\n"); | ||
368 | |||
369 | static int ssp_debug_mode_set(void *data, u64 val) | ||
370 | { | ||
371 | struct hci_dev *hdev = data; | ||
372 | struct sk_buff *skb; | ||
373 | __u8 mode; | ||
374 | int err; | ||
375 | |||
376 | if (val != 0 && val != 1) | ||
377 | return -EINVAL; | ||
378 | |||
379 | if (!test_bit(HCI_UP, &hdev->flags)) | ||
380 | return -ENETDOWN; | ||
381 | |||
382 | hci_req_lock(hdev); | ||
383 | mode = val; | ||
384 | skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode), | ||
385 | &mode, HCI_CMD_TIMEOUT); | ||
386 | hci_req_unlock(hdev); | ||
387 | |||
388 | if (IS_ERR(skb)) | ||
389 | return PTR_ERR(skb); | ||
390 | |||
391 | err = -bt_to_errno(skb->data[0]); | ||
392 | kfree_skb(skb); | ||
393 | |||
394 | if (err < 0) | ||
395 | return err; | ||
396 | |||
397 | hci_dev_lock(hdev); | ||
398 | hdev->ssp_debug_mode = val; | ||
399 | hci_dev_unlock(hdev); | ||
400 | |||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | static int ssp_debug_mode_get(void *data, u64 *val) | ||
405 | { | ||
406 | struct hci_dev *hdev = data; | ||
407 | |||
408 | hci_dev_lock(hdev); | ||
409 | *val = hdev->ssp_debug_mode; | ||
410 | hci_dev_unlock(hdev); | ||
411 | |||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get, | ||
416 | ssp_debug_mode_set, "%llu\n"); | ||
417 | |||
418 | static int idle_timeout_set(void *data, u64 val) | ||
419 | { | ||
420 | struct hci_dev *hdev = data; | ||
421 | |||
422 | if (val != 0 && (val < 500 || val > 3600000)) | ||
423 | return -EINVAL; | ||
424 | |||
425 | hci_dev_lock(hdev); | ||
426 | hdev->idle_timeout = val; | ||
427 | hci_dev_unlock(hdev); | ||
428 | |||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static int idle_timeout_get(void *data, u64 *val) | ||
433 | { | ||
434 | struct hci_dev *hdev = data; | ||
435 | |||
436 | hci_dev_lock(hdev); | ||
437 | *val = hdev->idle_timeout; | ||
438 | hci_dev_unlock(hdev); | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get, | ||
444 | idle_timeout_set, "%llu\n"); | ||
445 | |||
446 | static int sniff_min_interval_set(void *data, u64 val) | ||
447 | { | ||
448 | struct hci_dev *hdev = data; | ||
449 | |||
450 | if (val == 0 || val % 2 || val > hdev->sniff_max_interval) | ||
451 | return -EINVAL; | ||
452 | |||
453 | hci_dev_lock(hdev); | ||
454 | hdev->sniff_min_interval = val; | ||
455 | hci_dev_unlock(hdev); | ||
456 | |||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | static int sniff_min_interval_get(void *data, u64 *val) | ||
461 | { | ||
462 | struct hci_dev *hdev = data; | ||
463 | |||
464 | hci_dev_lock(hdev); | ||
465 | *val = hdev->sniff_min_interval; | ||
466 | hci_dev_unlock(hdev); | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get, | ||
472 | sniff_min_interval_set, "%llu\n"); | ||
473 | |||
474 | static int sniff_max_interval_set(void *data, u64 val) | ||
475 | { | ||
476 | struct hci_dev *hdev = data; | ||
477 | |||
478 | if (val == 0 || val % 2 || val < hdev->sniff_min_interval) | ||
479 | return -EINVAL; | ||
480 | |||
481 | hci_dev_lock(hdev); | ||
482 | hdev->sniff_max_interval = val; | ||
483 | hci_dev_unlock(hdev); | ||
484 | |||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | static int sniff_max_interval_get(void *data, u64 *val) | ||
489 | { | ||
490 | struct hci_dev *hdev = data; | ||
491 | |||
492 | hci_dev_lock(hdev); | ||
493 | *val = hdev->sniff_max_interval; | ||
494 | hci_dev_unlock(hdev); | ||
495 | |||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get, | ||
500 | sniff_max_interval_set, "%llu\n"); | ||
501 | |||
502 | static int static_address_show(struct seq_file *f, void *p) | ||
503 | { | ||
504 | struct hci_dev *hdev = f->private; | ||
505 | |||
506 | hci_dev_lock(hdev); | ||
507 | seq_printf(f, "%pMR\n", &hdev->static_addr); | ||
508 | hci_dev_unlock(hdev); | ||
509 | |||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | static int static_address_open(struct inode *inode, struct file *file) | ||
514 | { | ||
515 | return single_open(file, static_address_show, inode->i_private); | ||
516 | } | ||
517 | |||
518 | static const struct file_operations static_address_fops = { | ||
519 | .open = static_address_open, | ||
520 | .read = seq_read, | ||
521 | .llseek = seq_lseek, | ||
522 | .release = single_release, | ||
523 | }; | ||
524 | |||
525 | static int own_address_type_set(void *data, u64 val) | ||
526 | { | ||
527 | struct hci_dev *hdev = data; | ||
528 | |||
529 | if (val != 0 && val != 1) | ||
530 | return -EINVAL; | ||
531 | |||
532 | hci_dev_lock(hdev); | ||
533 | hdev->own_addr_type = val; | ||
534 | hci_dev_unlock(hdev); | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | static int own_address_type_get(void *data, u64 *val) | ||
540 | { | ||
541 | struct hci_dev *hdev = data; | ||
542 | |||
543 | hci_dev_lock(hdev); | ||
544 | *val = hdev->own_addr_type; | ||
545 | hci_dev_unlock(hdev); | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | DEFINE_SIMPLE_ATTRIBUTE(own_address_type_fops, own_address_type_get, | ||
551 | own_address_type_set, "%llu\n"); | ||
552 | |||
553 | static int long_term_keys_show(struct seq_file *f, void *ptr) | ||
554 | { | ||
555 | struct hci_dev *hdev = f->private; | ||
556 | struct list_head *p, *n; | ||
557 | |||
558 | hci_dev_lock(hdev); | ||
559 | list_for_each_safe(p, n, &hdev->link_keys) { | ||
560 | struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list); | ||
561 | seq_printf(f, "%pMR (type %u) %u %u %u %.4x %*phN %*phN\\n", | ||
562 | <k->bdaddr, ltk->bdaddr_type, ltk->authenticated, | ||
563 | ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv), | ||
564 | 8, ltk->rand, 16, ltk->val); | ||
565 | } | ||
566 | hci_dev_unlock(hdev); | ||
567 | |||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | static int long_term_keys_open(struct inode *inode, struct file *file) | ||
572 | { | ||
573 | return single_open(file, long_term_keys_show, inode->i_private); | ||
574 | } | ||
575 | |||
576 | static const struct file_operations long_term_keys_fops = { | ||
577 | .open = long_term_keys_open, | ||
578 | .read = seq_read, | ||
579 | .llseek = seq_lseek, | ||
580 | .release = single_release, | ||
581 | }; | ||
582 | |||
583 | static int conn_min_interval_set(void *data, u64 val) | ||
584 | { | ||
585 | struct hci_dev *hdev = data; | ||
586 | |||
587 | if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval) | ||
588 | return -EINVAL; | ||
589 | |||
590 | hci_dev_lock(hdev); | ||
591 | hdev->le_conn_min_interval = val; | ||
592 | hci_dev_unlock(hdev); | ||
593 | |||
594 | return 0; | ||
595 | } | ||
596 | |||
597 | static int conn_min_interval_get(void *data, u64 *val) | ||
598 | { | ||
599 | struct hci_dev *hdev = data; | ||
600 | |||
601 | hci_dev_lock(hdev); | ||
602 | *val = hdev->le_conn_min_interval; | ||
603 | hci_dev_unlock(hdev); | ||
604 | |||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get, | ||
609 | conn_min_interval_set, "%llu\n"); | ||
610 | |||
611 | static int conn_max_interval_set(void *data, u64 val) | ||
612 | { | ||
613 | struct hci_dev *hdev = data; | ||
614 | |||
615 | if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval) | ||
616 | return -EINVAL; | ||
617 | |||
618 | hci_dev_lock(hdev); | ||
619 | hdev->le_conn_max_interval = val; | ||
620 | hci_dev_unlock(hdev); | ||
621 | |||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | static int conn_max_interval_get(void *data, u64 *val) | ||
626 | { | ||
627 | struct hci_dev *hdev = data; | ||
628 | |||
629 | hci_dev_lock(hdev); | ||
630 | *val = hdev->le_conn_max_interval; | ||
631 | hci_dev_unlock(hdev); | ||
632 | |||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get, | ||
637 | conn_max_interval_set, "%llu\n"); | ||
638 | |||
58 | /* ---- HCI requests ---- */ | 639 | /* ---- HCI requests ---- */ |
59 | 640 | ||
60 | static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) | 641 | static void hci_req_sync_complete(struct hci_dev *hdev, u8 result) |
@@ -556,6 +1137,14 @@ static void hci_init2_req(struct hci_request *req, unsigned long opt) | |||
556 | hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); | 1137 | hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); |
557 | 1138 | ||
558 | if (lmp_ssp_capable(hdev)) { | 1139 | if (lmp_ssp_capable(hdev)) { |
1140 | /* When SSP is available, then the host features page | ||
1141 | * should also be available as well. However some | ||
1142 | * controllers list the max_page as 0 as long as SSP | ||
1143 | * has not been enabled. To achieve proper debugging | ||
1144 | * output, force the minimum max_page to 1 at least. | ||
1145 | */ | ||
1146 | hdev->max_page = 0x01; | ||
1147 | |||
559 | if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { | 1148 | if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { |
560 | u8 mode = 0x01; | 1149 | u8 mode = 0x01; |
561 | hci_req_add(req, HCI_OP_WRITE_SSP_MODE, | 1150 | hci_req_add(req, HCI_OP_WRITE_SSP_MODE, |
@@ -686,8 +1275,17 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt) | |||
686 | hci_setup_link_policy(req); | 1275 | hci_setup_link_policy(req); |
687 | 1276 | ||
688 | if (lmp_le_capable(hdev)) { | 1277 | if (lmp_le_capable(hdev)) { |
1278 | /* If the controller has a public BD_ADDR, then by | ||
1279 | * default use that one. If this is a LE only | ||
1280 | * controller without one, default to the random | ||
1281 | * address. | ||
1282 | */ | ||
1283 | if (bacmp(&hdev->bdaddr, BDADDR_ANY)) | ||
1284 | hdev->own_addr_type = ADDR_LE_DEV_PUBLIC; | ||
1285 | else | ||
1286 | hdev->own_addr_type = ADDR_LE_DEV_RANDOM; | ||
1287 | |||
689 | hci_set_le_support(req); | 1288 | hci_set_le_support(req); |
690 | hci_update_ad(req); | ||
691 | } | 1289 | } |
692 | 1290 | ||
693 | /* Read features beyond page 1 if available */ | 1291 | /* Read features beyond page 1 if available */ |
@@ -721,6 +1319,14 @@ static int __hci_init(struct hci_dev *hdev) | |||
721 | if (err < 0) | 1319 | if (err < 0) |
722 | return err; | 1320 | return err; |
723 | 1321 | ||
1322 | /* The Device Under Test (DUT) mode is special and available for | ||
1323 | * all controller types. So just create it early on. | ||
1324 | */ | ||
1325 | if (test_bit(HCI_SETUP, &hdev->dev_flags)) { | ||
1326 | debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev, | ||
1327 | &dut_mode_fops); | ||
1328 | } | ||
1329 | |||
724 | /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode | 1330 | /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode |
725 | * BR/EDR/LE type controllers. AMP controllers only need the | 1331 | * BR/EDR/LE type controllers. AMP controllers only need the |
726 | * first stage init. | 1332 | * first stage init. |
@@ -736,7 +1342,71 @@ static int __hci_init(struct hci_dev *hdev) | |||
736 | if (err < 0) | 1342 | if (err < 0) |
737 | return err; | 1343 | return err; |
738 | 1344 | ||
739 | return __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); | 1345 | err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT); |
1346 | if (err < 0) | ||
1347 | return err; | ||
1348 | |||
1349 | /* Only create debugfs entries during the initial setup | ||
1350 | * phase and not every time the controller gets powered on. | ||
1351 | */ | ||
1352 | if (!test_bit(HCI_SETUP, &hdev->dev_flags)) | ||
1353 | return 0; | ||
1354 | |||
1355 | debugfs_create_file("features", 0444, hdev->debugfs, hdev, | ||
1356 | &features_fops); | ||
1357 | debugfs_create_u16("manufacturer", 0444, hdev->debugfs, | ||
1358 | &hdev->manufacturer); | ||
1359 | debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); | ||
1360 | debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); | ||
1361 | debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, | ||
1362 | &blacklist_fops); | ||
1363 | debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); | ||
1364 | |||
1365 | if (lmp_bredr_capable(hdev)) { | ||
1366 | debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, | ||
1367 | hdev, &inquiry_cache_fops); | ||
1368 | debugfs_create_file("link_keys", 0400, hdev->debugfs, | ||
1369 | hdev, &link_keys_fops); | ||
1370 | debugfs_create_file("use_debug_keys", 0444, hdev->debugfs, | ||
1371 | hdev, &use_debug_keys_fops); | ||
1372 | debugfs_create_file("dev_class", 0444, hdev->debugfs, | ||
1373 | hdev, &dev_class_fops); | ||
1374 | debugfs_create_file("voice_setting", 0444, hdev->debugfs, | ||
1375 | hdev, &voice_setting_fops); | ||
1376 | } | ||
1377 | |||
1378 | if (lmp_ssp_capable(hdev)) { | ||
1379 | debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs, | ||
1380 | hdev, &auto_accept_delay_fops); | ||
1381 | debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs, | ||
1382 | hdev, &ssp_debug_mode_fops); | ||
1383 | } | ||
1384 | |||
1385 | if (lmp_sniff_capable(hdev)) { | ||
1386 | debugfs_create_file("idle_timeout", 0644, hdev->debugfs, | ||
1387 | hdev, &idle_timeout_fops); | ||
1388 | debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs, | ||
1389 | hdev, &sniff_min_interval_fops); | ||
1390 | debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs, | ||
1391 | hdev, &sniff_max_interval_fops); | ||
1392 | } | ||
1393 | |||
1394 | if (lmp_le_capable(hdev)) { | ||
1395 | debugfs_create_u8("white_list_size", 0444, hdev->debugfs, | ||
1396 | &hdev->le_white_list_size); | ||
1397 | debugfs_create_file("static_address", 0444, hdev->debugfs, | ||
1398 | hdev, &static_address_fops); | ||
1399 | debugfs_create_file("own_address_type", 0644, hdev->debugfs, | ||
1400 | hdev, &own_address_type_fops); | ||
1401 | debugfs_create_file("long_term_keys", 0400, hdev->debugfs, | ||
1402 | hdev, &long_term_keys_fops); | ||
1403 | debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, | ||
1404 | hdev, &conn_min_interval_fops); | ||
1405 | debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, | ||
1406 | hdev, &conn_max_interval_fops); | ||
1407 | } | ||
1408 | |||
1409 | return 0; | ||
740 | } | 1410 | } |
741 | 1411 | ||
742 | static void hci_scan_req(struct hci_request *req, unsigned long opt) | 1412 | static void hci_scan_req(struct hci_request *req, unsigned long opt) |
@@ -1127,89 +1797,6 @@ done: | |||
1127 | return err; | 1797 | return err; |
1128 | } | 1798 | } |
1129 | 1799 | ||
1130 | static u8 create_ad(struct hci_dev *hdev, u8 *ptr) | ||
1131 | { | ||
1132 | u8 ad_len = 0, flags = 0; | ||
1133 | size_t name_len; | ||
1134 | |||
1135 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) | ||
1136 | flags |= LE_AD_GENERAL; | ||
1137 | |||
1138 | if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { | ||
1139 | if (lmp_le_br_capable(hdev)) | ||
1140 | flags |= LE_AD_SIM_LE_BREDR_CTRL; | ||
1141 | if (lmp_host_le_br_capable(hdev)) | ||
1142 | flags |= LE_AD_SIM_LE_BREDR_HOST; | ||
1143 | } else { | ||
1144 | flags |= LE_AD_NO_BREDR; | ||
1145 | } | ||
1146 | |||
1147 | if (flags) { | ||
1148 | BT_DBG("adv flags 0x%02x", flags); | ||
1149 | |||
1150 | ptr[0] = 2; | ||
1151 | ptr[1] = EIR_FLAGS; | ||
1152 | ptr[2] = flags; | ||
1153 | |||
1154 | ad_len += 3; | ||
1155 | ptr += 3; | ||
1156 | } | ||
1157 | |||
1158 | if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) { | ||
1159 | ptr[0] = 2; | ||
1160 | ptr[1] = EIR_TX_POWER; | ||
1161 | ptr[2] = (u8) hdev->adv_tx_power; | ||
1162 | |||
1163 | ad_len += 3; | ||
1164 | ptr += 3; | ||
1165 | } | ||
1166 | |||
1167 | name_len = strlen(hdev->dev_name); | ||
1168 | if (name_len > 0) { | ||
1169 | size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2; | ||
1170 | |||
1171 | if (name_len > max_len) { | ||
1172 | name_len = max_len; | ||
1173 | ptr[1] = EIR_NAME_SHORT; | ||
1174 | } else | ||
1175 | ptr[1] = EIR_NAME_COMPLETE; | ||
1176 | |||
1177 | ptr[0] = name_len + 1; | ||
1178 | |||
1179 | memcpy(ptr + 2, hdev->dev_name, name_len); | ||
1180 | |||
1181 | ad_len += (name_len + 2); | ||
1182 | ptr += (name_len + 2); | ||
1183 | } | ||
1184 | |||
1185 | return ad_len; | ||
1186 | } | ||
1187 | |||
1188 | void hci_update_ad(struct hci_request *req) | ||
1189 | { | ||
1190 | struct hci_dev *hdev = req->hdev; | ||
1191 | struct hci_cp_le_set_adv_data cp; | ||
1192 | u8 len; | ||
1193 | |||
1194 | if (!lmp_le_capable(hdev)) | ||
1195 | return; | ||
1196 | |||
1197 | memset(&cp, 0, sizeof(cp)); | ||
1198 | |||
1199 | len = create_ad(hdev, cp.data); | ||
1200 | |||
1201 | if (hdev->adv_data_len == len && | ||
1202 | memcmp(cp.data, hdev->adv_data, len) == 0) | ||
1203 | return; | ||
1204 | |||
1205 | memcpy(hdev->adv_data, cp.data, sizeof(cp.data)); | ||
1206 | hdev->adv_data_len = len; | ||
1207 | |||
1208 | cp.length = len; | ||
1209 | |||
1210 | hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp); | ||
1211 | } | ||
1212 | |||
1213 | static int hci_dev_do_open(struct hci_dev *hdev) | 1800 | static int hci_dev_do_open(struct hci_dev *hdev) |
1214 | { | 1801 | { |
1215 | int ret = 0; | 1802 | int ret = 0; |
@@ -1367,6 +1954,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
1367 | cancel_delayed_work(&hdev->discov_off); | 1954 | cancel_delayed_work(&hdev->discov_off); |
1368 | hdev->discov_timeout = 0; | 1955 | hdev->discov_timeout = 0; |
1369 | clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); | 1956 | clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); |
1957 | clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); | ||
1370 | } | 1958 | } |
1371 | 1959 | ||
1372 | if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) | 1960 | if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) |
@@ -1789,19 +2377,12 @@ static void hci_power_off(struct work_struct *work) | |||
1789 | static void hci_discov_off(struct work_struct *work) | 2377 | static void hci_discov_off(struct work_struct *work) |
1790 | { | 2378 | { |
1791 | struct hci_dev *hdev; | 2379 | struct hci_dev *hdev; |
1792 | u8 scan = SCAN_PAGE; | ||
1793 | 2380 | ||
1794 | hdev = container_of(work, struct hci_dev, discov_off.work); | 2381 | hdev = container_of(work, struct hci_dev, discov_off.work); |
1795 | 2382 | ||
1796 | BT_DBG("%s", hdev->name); | 2383 | BT_DBG("%s", hdev->name); |
1797 | 2384 | ||
1798 | hci_dev_lock(hdev); | 2385 | mgmt_discoverable_timeout(hdev); |
1799 | |||
1800 | hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); | ||
1801 | |||
1802 | hdev->discov_timeout = 0; | ||
1803 | |||
1804 | hci_dev_unlock(hdev); | ||
1805 | } | 2386 | } |
1806 | 2387 | ||
1807 | int hci_uuids_clear(struct hci_dev *hdev) | 2388 | int hci_uuids_clear(struct hci_dev *hdev) |
@@ -2124,13 +2705,15 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, | |||
2124 | return 0; | 2705 | return 0; |
2125 | } | 2706 | } |
2126 | 2707 | ||
2127 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) | 2708 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, |
2709 | bdaddr_t *bdaddr, u8 type) | ||
2128 | { | 2710 | { |
2129 | struct bdaddr_list *b; | 2711 | struct bdaddr_list *b; |
2130 | 2712 | ||
2131 | list_for_each_entry(b, &hdev->blacklist, list) | 2713 | list_for_each_entry(b, &hdev->blacklist, list) { |
2132 | if (bacmp(bdaddr, &b->bdaddr) == 0) | 2714 | if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type) |
2133 | return b; | 2715 | return b; |
2716 | } | ||
2134 | 2717 | ||
2135 | return NULL; | 2718 | return NULL; |
2136 | } | 2719 | } |
@@ -2140,9 +2723,7 @@ int hci_blacklist_clear(struct hci_dev *hdev) | |||
2140 | struct list_head *p, *n; | 2723 | struct list_head *p, *n; |
2141 | 2724 | ||
2142 | list_for_each_safe(p, n, &hdev->blacklist) { | 2725 | list_for_each_safe(p, n, &hdev->blacklist) { |
2143 | struct bdaddr_list *b; | 2726 | struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list); |
2144 | |||
2145 | b = list_entry(p, struct bdaddr_list, list); | ||
2146 | 2727 | ||
2147 | list_del(p); | 2728 | list_del(p); |
2148 | kfree(b); | 2729 | kfree(b); |
@@ -2155,10 +2736,10 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
2155 | { | 2736 | { |
2156 | struct bdaddr_list *entry; | 2737 | struct bdaddr_list *entry; |
2157 | 2738 | ||
2158 | if (bacmp(bdaddr, BDADDR_ANY) == 0) | 2739 | if (!bacmp(bdaddr, BDADDR_ANY)) |
2159 | return -EBADF; | 2740 | return -EBADF; |
2160 | 2741 | ||
2161 | if (hci_blacklist_lookup(hdev, bdaddr)) | 2742 | if (hci_blacklist_lookup(hdev, bdaddr, type)) |
2162 | return -EEXIST; | 2743 | return -EEXIST; |
2163 | 2744 | ||
2164 | entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); | 2745 | entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); |
@@ -2166,6 +2747,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
2166 | return -ENOMEM; | 2747 | return -ENOMEM; |
2167 | 2748 | ||
2168 | bacpy(&entry->bdaddr, bdaddr); | 2749 | bacpy(&entry->bdaddr, bdaddr); |
2750 | entry->bdaddr_type = type; | ||
2169 | 2751 | ||
2170 | list_add(&entry->list, &hdev->blacklist); | 2752 | list_add(&entry->list, &hdev->blacklist); |
2171 | 2753 | ||
@@ -2176,10 +2758,10 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
2176 | { | 2758 | { |
2177 | struct bdaddr_list *entry; | 2759 | struct bdaddr_list *entry; |
2178 | 2760 | ||
2179 | if (bacmp(bdaddr, BDADDR_ANY) == 0) | 2761 | if (!bacmp(bdaddr, BDADDR_ANY)) |
2180 | return hci_blacklist_clear(hdev); | 2762 | return hci_blacklist_clear(hdev); |
2181 | 2763 | ||
2182 | entry = hci_blacklist_lookup(hdev, bdaddr); | 2764 | entry = hci_blacklist_lookup(hdev, bdaddr, type); |
2183 | if (!entry) | 2765 | if (!entry) |
2184 | return -ENOENT; | 2766 | return -ENOENT; |
2185 | 2767 | ||
@@ -2287,6 +2869,8 @@ struct hci_dev *hci_alloc_dev(void) | |||
2287 | 2869 | ||
2288 | hdev->le_scan_interval = 0x0060; | 2870 | hdev->le_scan_interval = 0x0060; |
2289 | hdev->le_scan_window = 0x0030; | 2871 | hdev->le_scan_window = 0x0030; |
2872 | hdev->le_conn_min_interval = 0x0028; | ||
2873 | hdev->le_conn_max_interval = 0x0038; | ||
2290 | 2874 | ||
2291 | mutex_init(&hdev->lock); | 2875 | mutex_init(&hdev->lock); |
2292 | mutex_init(&hdev->req_lock); | 2876 | mutex_init(&hdev->req_lock); |
@@ -2376,7 +2960,12 @@ int hci_register_dev(struct hci_dev *hdev) | |||
2376 | goto err; | 2960 | goto err; |
2377 | } | 2961 | } |
2378 | 2962 | ||
2379 | error = hci_add_sysfs(hdev); | 2963 | if (!IS_ERR_OR_NULL(bt_debugfs)) |
2964 | hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); | ||
2965 | |||
2966 | dev_set_name(&hdev->dev, "%s", hdev->name); | ||
2967 | |||
2968 | error = device_add(&hdev->dev); | ||
2380 | if (error < 0) | 2969 | if (error < 0) |
2381 | goto err_wqueue; | 2970 | goto err_wqueue; |
2382 | 2971 | ||
@@ -2464,7 +3053,9 @@ void hci_unregister_dev(struct hci_dev *hdev) | |||
2464 | rfkill_destroy(hdev->rfkill); | 3053 | rfkill_destroy(hdev->rfkill); |
2465 | } | 3054 | } |
2466 | 3055 | ||
2467 | hci_del_sysfs(hdev); | 3056 | device_del(&hdev->dev); |
3057 | |||
3058 | debugfs_remove_recursive(hdev->debugfs); | ||
2468 | 3059 | ||
2469 | destroy_workqueue(hdev->workqueue); | 3060 | destroy_workqueue(hdev->workqueue); |
2470 | destroy_workqueue(hdev->req_workqueue); | 3061 | destroy_workqueue(hdev->req_workqueue); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 5391469ff1a5..5935f748c0f9 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -195,6 +195,11 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) | |||
195 | 195 | ||
196 | memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); | 196 | memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); |
197 | hdev->adv_data_len = 0; | 197 | hdev->adv_data_len = 0; |
198 | |||
199 | memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data)); | ||
200 | hdev->scan_rsp_data_len = 0; | ||
201 | |||
202 | hdev->ssp_debug_mode = 0; | ||
198 | } | 203 | } |
199 | 204 | ||
200 | static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) | 205 | static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -310,11 +315,6 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
310 | set_bit(HCI_ISCAN, &hdev->flags); | 315 | set_bit(HCI_ISCAN, &hdev->flags); |
311 | if (!old_iscan) | 316 | if (!old_iscan) |
312 | mgmt_discoverable(hdev, 1); | 317 | mgmt_discoverable(hdev, 1); |
313 | if (hdev->discov_timeout > 0) { | ||
314 | int to = msecs_to_jiffies(hdev->discov_timeout * 1000); | ||
315 | queue_delayed_work(hdev->workqueue, &hdev->discov_off, | ||
316 | to); | ||
317 | } | ||
318 | } else if (old_iscan) | 318 | } else if (old_iscan) |
319 | mgmt_discoverable(hdev, 0); | 319 | mgmt_discoverable(hdev, 0); |
320 | 320 | ||
@@ -470,14 +470,13 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | |||
470 | if (rp->status) | 470 | if (rp->status) |
471 | return; | 471 | return; |
472 | 472 | ||
473 | hdev->hci_ver = rp->hci_ver; | 473 | if (test_bit(HCI_SETUP, &hdev->dev_flags)) { |
474 | hdev->hci_rev = __le16_to_cpu(rp->hci_rev); | 474 | hdev->hci_ver = rp->hci_ver; |
475 | hdev->lmp_ver = rp->lmp_ver; | 475 | hdev->hci_rev = __le16_to_cpu(rp->hci_rev); |
476 | hdev->manufacturer = __le16_to_cpu(rp->manufacturer); | 476 | hdev->lmp_ver = rp->lmp_ver; |
477 | hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); | 477 | hdev->manufacturer = __le16_to_cpu(rp->manufacturer); |
478 | 478 | hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); | |
479 | BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name, | 479 | } |
480 | hdev->manufacturer, hdev->hci_ver, hdev->hci_rev); | ||
481 | } | 480 | } |
482 | 481 | ||
483 | static void hci_cc_read_local_commands(struct hci_dev *hdev, | 482 | static void hci_cc_read_local_commands(struct hci_dev *hdev, |
@@ -557,7 +556,8 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev, | |||
557 | if (rp->status) | 556 | if (rp->status) |
558 | return; | 557 | return; |
559 | 558 | ||
560 | hdev->max_page = rp->max_page; | 559 | if (hdev->max_page < rp->max_page) |
560 | hdev->max_page = rp->max_page; | ||
561 | 561 | ||
562 | if (rp->page < HCI_MAX_PAGES) | 562 | if (rp->page < HCI_MAX_PAGES) |
563 | memcpy(hdev->features[rp->page], rp->features, 8); | 563 | memcpy(hdev->features[rp->page], rp->features, 8); |
@@ -939,14 +939,6 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
939 | clear_bit(HCI_ADVERTISING, &hdev->dev_flags); | 939 | clear_bit(HCI_ADVERTISING, &hdev->dev_flags); |
940 | } | 940 | } |
941 | 941 | ||
942 | if (*sent && !test_bit(HCI_INIT, &hdev->flags)) { | ||
943 | struct hci_request req; | ||
944 | |||
945 | hci_req_init(&req, hdev); | ||
946 | hci_update_ad(&req); | ||
947 | hci_req_run(&req, NULL); | ||
948 | } | ||
949 | |||
950 | hci_dev_unlock(hdev); | 942 | hci_dev_unlock(hdev); |
951 | } | 943 | } |
952 | 944 | ||
@@ -1702,7 +1694,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1702 | &flags); | 1694 | &flags); |
1703 | 1695 | ||
1704 | if ((mask & HCI_LM_ACCEPT) && | 1696 | if ((mask & HCI_LM_ACCEPT) && |
1705 | !hci_blacklist_lookup(hdev, &ev->bdaddr)) { | 1697 | !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) { |
1706 | /* Connection accepted */ | 1698 | /* Connection accepted */ |
1707 | struct inquiry_entry *ie; | 1699 | struct inquiry_entry *ie; |
1708 | struct hci_conn *conn; | 1700 | struct hci_conn *conn; |
@@ -2559,7 +2551,6 @@ static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2559 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | 2551 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
2560 | if (conn) { | 2552 | if (conn) { |
2561 | conn->mode = ev->mode; | 2553 | conn->mode = ev->mode; |
2562 | conn->interval = __le16_to_cpu(ev->interval); | ||
2563 | 2554 | ||
2564 | if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, | 2555 | if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, |
2565 | &conn->flags)) { | 2556 | &conn->flags)) { |
@@ -2941,6 +2932,23 @@ unlock: | |||
2941 | hci_dev_unlock(hdev); | 2932 | hci_dev_unlock(hdev); |
2942 | } | 2933 | } |
2943 | 2934 | ||
2935 | static inline size_t eir_get_length(u8 *eir, size_t eir_len) | ||
2936 | { | ||
2937 | size_t parsed = 0; | ||
2938 | |||
2939 | while (parsed < eir_len) { | ||
2940 | u8 field_len = eir[0]; | ||
2941 | |||
2942 | if (field_len == 0) | ||
2943 | return parsed; | ||
2944 | |||
2945 | parsed += field_len + 1; | ||
2946 | eir += field_len + 1; | ||
2947 | } | ||
2948 | |||
2949 | return eir_len; | ||
2950 | } | ||
2951 | |||
2944 | static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, | 2952 | static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, |
2945 | struct sk_buff *skb) | 2953 | struct sk_buff *skb) |
2946 | { | 2954 | { |
@@ -3181,7 +3189,8 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev, | |||
3181 | 3189 | ||
3182 | if (hdev->auto_accept_delay > 0) { | 3190 | if (hdev->auto_accept_delay > 0) { |
3183 | int delay = msecs_to_jiffies(hdev->auto_accept_delay); | 3191 | int delay = msecs_to_jiffies(hdev->auto_accept_delay); |
3184 | mod_timer(&conn->auto_accept_timer, jiffies + delay); | 3192 | queue_delayed_work(conn->hdev->workqueue, |
3193 | &conn->auto_accept_work, delay); | ||
3185 | goto unlock; | 3194 | goto unlock; |
3186 | } | 3195 | } |
3187 | 3196 | ||
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 97f96ebdd56d..71f0be173080 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -481,7 +481,7 @@ static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg) | |||
481 | 481 | ||
482 | hci_dev_lock(hdev); | 482 | hci_dev_lock(hdev); |
483 | 483 | ||
484 | err = hci_blacklist_add(hdev, &bdaddr, 0); | 484 | err = hci_blacklist_add(hdev, &bdaddr, BDADDR_BREDR); |
485 | 485 | ||
486 | hci_dev_unlock(hdev); | 486 | hci_dev_unlock(hdev); |
487 | 487 | ||
@@ -498,7 +498,7 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg) | |||
498 | 498 | ||
499 | hci_dev_lock(hdev); | 499 | hci_dev_lock(hdev); |
500 | 500 | ||
501 | err = hci_blacklist_del(hdev, &bdaddr, 0); | 501 | err = hci_blacklist_del(hdev, &bdaddr, BDADDR_BREDR); |
502 | 502 | ||
503 | hci_dev_unlock(hdev); | 503 | hci_dev_unlock(hdev); |
504 | 504 | ||
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index edf623a29043..0b61250cfdf9 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -1,17 +1,12 @@ | |||
1 | /* Bluetooth HCI driver model support. */ | 1 | /* Bluetooth HCI driver model support. */ |
2 | 2 | ||
3 | #include <linux/debugfs.h> | ||
4 | #include <linux/module.h> | 3 | #include <linux/module.h> |
5 | #include <asm/unaligned.h> | ||
6 | 4 | ||
7 | #include <net/bluetooth/bluetooth.h> | 5 | #include <net/bluetooth/bluetooth.h> |
8 | #include <net/bluetooth/hci_core.h> | 6 | #include <net/bluetooth/hci_core.h> |
9 | 7 | ||
10 | static struct class *bt_class; | 8 | static struct class *bt_class; |
11 | 9 | ||
12 | struct dentry *bt_debugfs; | ||
13 | EXPORT_SYMBOL_GPL(bt_debugfs); | ||
14 | |||
15 | static inline char *link_typetostr(int type) | 10 | static inline char *link_typetostr(int type) |
16 | { | 11 | { |
17 | switch (type) { | 12 | switch (type) { |
@@ -42,29 +37,15 @@ static ssize_t show_link_address(struct device *dev, | |||
42 | return sprintf(buf, "%pMR\n", &conn->dst); | 37 | return sprintf(buf, "%pMR\n", &conn->dst); |
43 | } | 38 | } |
44 | 39 | ||
45 | static ssize_t show_link_features(struct device *dev, | ||
46 | struct device_attribute *attr, char *buf) | ||
47 | { | ||
48 | struct hci_conn *conn = to_hci_conn(dev); | ||
49 | |||
50 | return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", | ||
51 | conn->features[0][0], conn->features[0][1], | ||
52 | conn->features[0][2], conn->features[0][3], | ||
53 | conn->features[0][4], conn->features[0][5], | ||
54 | conn->features[0][6], conn->features[0][7]); | ||
55 | } | ||
56 | |||
57 | #define LINK_ATTR(_name, _mode, _show, _store) \ | 40 | #define LINK_ATTR(_name, _mode, _show, _store) \ |
58 | struct device_attribute link_attr_##_name = __ATTR(_name, _mode, _show, _store) | 41 | struct device_attribute link_attr_##_name = __ATTR(_name, _mode, _show, _store) |
59 | 42 | ||
60 | static LINK_ATTR(type, S_IRUGO, show_link_type, NULL); | 43 | static LINK_ATTR(type, S_IRUGO, show_link_type, NULL); |
61 | static LINK_ATTR(address, S_IRUGO, show_link_address, NULL); | 44 | static LINK_ATTR(address, S_IRUGO, show_link_address, NULL); |
62 | static LINK_ATTR(features, S_IRUGO, show_link_features, NULL); | ||
63 | 45 | ||
64 | static struct attribute *bt_link_attrs[] = { | 46 | static struct attribute *bt_link_attrs[] = { |
65 | &link_attr_type.attr, | 47 | &link_attr_type.attr, |
66 | &link_attr_address.attr, | 48 | &link_attr_address.attr, |
67 | &link_attr_features.attr, | ||
68 | NULL | 49 | NULL |
69 | }; | 50 | }; |
70 | 51 | ||
@@ -150,28 +131,6 @@ void hci_conn_del_sysfs(struct hci_conn *conn) | |||
150 | hci_dev_put(hdev); | 131 | hci_dev_put(hdev); |
151 | } | 132 | } |
152 | 133 | ||
153 | static inline char *host_bustostr(int bus) | ||
154 | { | ||
155 | switch (bus) { | ||
156 | case HCI_VIRTUAL: | ||
157 | return "VIRTUAL"; | ||
158 | case HCI_USB: | ||
159 | return "USB"; | ||
160 | case HCI_PCCARD: | ||
161 | return "PCCARD"; | ||
162 | case HCI_UART: | ||
163 | return "UART"; | ||
164 | case HCI_RS232: | ||
165 | return "RS232"; | ||
166 | case HCI_PCI: | ||
167 | return "PCI"; | ||
168 | case HCI_SDIO: | ||
169 | return "SDIO"; | ||
170 | default: | ||
171 | return "UNKNOWN"; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | static inline char *host_typetostr(int type) | 134 | static inline char *host_typetostr(int type) |
176 | { | 135 | { |
177 | switch (type) { | 136 | switch (type) { |
@@ -184,13 +143,6 @@ static inline char *host_typetostr(int type) | |||
184 | } | 143 | } |
185 | } | 144 | } |
186 | 145 | ||
187 | static ssize_t show_bus(struct device *dev, | ||
188 | struct device_attribute *attr, char *buf) | ||
189 | { | ||
190 | struct hci_dev *hdev = to_hci_dev(dev); | ||
191 | return sprintf(buf, "%s\n", host_bustostr(hdev->bus)); | ||
192 | } | ||
193 | |||
194 | static ssize_t show_type(struct device *dev, | 146 | static ssize_t show_type(struct device *dev, |
195 | struct device_attribute *attr, char *buf) | 147 | struct device_attribute *attr, char *buf) |
196 | { | 148 | { |
@@ -212,14 +164,6 @@ static ssize_t show_name(struct device *dev, | |||
212 | return sprintf(buf, "%s\n", name); | 164 | return sprintf(buf, "%s\n", name); |
213 | } | 165 | } |
214 | 166 | ||
215 | static ssize_t show_class(struct device *dev, | ||
216 | struct device_attribute *attr, char *buf) | ||
217 | { | ||
218 | struct hci_dev *hdev = to_hci_dev(dev); | ||
219 | return sprintf(buf, "0x%.2x%.2x%.2x\n", hdev->dev_class[2], | ||
220 | hdev->dev_class[1], hdev->dev_class[0]); | ||
221 | } | ||
222 | |||
223 | static ssize_t show_address(struct device *dev, | 167 | static ssize_t show_address(struct device *dev, |
224 | struct device_attribute *attr, char *buf) | 168 | struct device_attribute *attr, char *buf) |
225 | { | 169 | { |
@@ -227,150 +171,14 @@ static ssize_t show_address(struct device *dev, | |||
227 | return sprintf(buf, "%pMR\n", &hdev->bdaddr); | 171 | return sprintf(buf, "%pMR\n", &hdev->bdaddr); |
228 | } | 172 | } |
229 | 173 | ||
230 | static ssize_t show_features(struct device *dev, | ||
231 | struct device_attribute *attr, char *buf) | ||
232 | { | ||
233 | struct hci_dev *hdev = to_hci_dev(dev); | ||
234 | |||
235 | return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", | ||
236 | hdev->features[0][0], hdev->features[0][1], | ||
237 | hdev->features[0][2], hdev->features[0][3], | ||
238 | hdev->features[0][4], hdev->features[0][5], | ||
239 | hdev->features[0][6], hdev->features[0][7]); | ||
240 | } | ||
241 | |||
242 | static ssize_t show_manufacturer(struct device *dev, | ||
243 | struct device_attribute *attr, char *buf) | ||
244 | { | ||
245 | struct hci_dev *hdev = to_hci_dev(dev); | ||
246 | return sprintf(buf, "%d\n", hdev->manufacturer); | ||
247 | } | ||
248 | |||
249 | static ssize_t show_hci_version(struct device *dev, | ||
250 | struct device_attribute *attr, char *buf) | ||
251 | { | ||
252 | struct hci_dev *hdev = to_hci_dev(dev); | ||
253 | return sprintf(buf, "%d\n", hdev->hci_ver); | ||
254 | } | ||
255 | |||
256 | static ssize_t show_hci_revision(struct device *dev, | ||
257 | struct device_attribute *attr, char *buf) | ||
258 | { | ||
259 | struct hci_dev *hdev = to_hci_dev(dev); | ||
260 | return sprintf(buf, "%d\n", hdev->hci_rev); | ||
261 | } | ||
262 | |||
263 | static ssize_t show_idle_timeout(struct device *dev, | ||
264 | struct device_attribute *attr, char *buf) | ||
265 | { | ||
266 | struct hci_dev *hdev = to_hci_dev(dev); | ||
267 | return sprintf(buf, "%d\n", hdev->idle_timeout); | ||
268 | } | ||
269 | |||
270 | static ssize_t store_idle_timeout(struct device *dev, | ||
271 | struct device_attribute *attr, | ||
272 | const char *buf, size_t count) | ||
273 | { | ||
274 | struct hci_dev *hdev = to_hci_dev(dev); | ||
275 | unsigned int val; | ||
276 | int rv; | ||
277 | |||
278 | rv = kstrtouint(buf, 0, &val); | ||
279 | if (rv < 0) | ||
280 | return rv; | ||
281 | |||
282 | if (val != 0 && (val < 500 || val > 3600000)) | ||
283 | return -EINVAL; | ||
284 | |||
285 | hdev->idle_timeout = val; | ||
286 | |||
287 | return count; | ||
288 | } | ||
289 | |||
290 | static ssize_t show_sniff_max_interval(struct device *dev, | ||
291 | struct device_attribute *attr, char *buf) | ||
292 | { | ||
293 | struct hci_dev *hdev = to_hci_dev(dev); | ||
294 | return sprintf(buf, "%d\n", hdev->sniff_max_interval); | ||
295 | } | ||
296 | |||
297 | static ssize_t store_sniff_max_interval(struct device *dev, | ||
298 | struct device_attribute *attr, | ||
299 | const char *buf, size_t count) | ||
300 | { | ||
301 | struct hci_dev *hdev = to_hci_dev(dev); | ||
302 | u16 val; | ||
303 | int rv; | ||
304 | |||
305 | rv = kstrtou16(buf, 0, &val); | ||
306 | if (rv < 0) | ||
307 | return rv; | ||
308 | |||
309 | if (val == 0 || val % 2 || val < hdev->sniff_min_interval) | ||
310 | return -EINVAL; | ||
311 | |||
312 | hdev->sniff_max_interval = val; | ||
313 | |||
314 | return count; | ||
315 | } | ||
316 | |||
317 | static ssize_t show_sniff_min_interval(struct device *dev, | ||
318 | struct device_attribute *attr, char *buf) | ||
319 | { | ||
320 | struct hci_dev *hdev = to_hci_dev(dev); | ||
321 | return sprintf(buf, "%d\n", hdev->sniff_min_interval); | ||
322 | } | ||
323 | |||
324 | static ssize_t store_sniff_min_interval(struct device *dev, | ||
325 | struct device_attribute *attr, | ||
326 | const char *buf, size_t count) | ||
327 | { | ||
328 | struct hci_dev *hdev = to_hci_dev(dev); | ||
329 | u16 val; | ||
330 | int rv; | ||
331 | |||
332 | rv = kstrtou16(buf, 0, &val); | ||
333 | if (rv < 0) | ||
334 | return rv; | ||
335 | |||
336 | if (val == 0 || val % 2 || val > hdev->sniff_max_interval) | ||
337 | return -EINVAL; | ||
338 | |||
339 | hdev->sniff_min_interval = val; | ||
340 | |||
341 | return count; | ||
342 | } | ||
343 | |||
344 | static DEVICE_ATTR(bus, S_IRUGO, show_bus, NULL); | ||
345 | static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); | 174 | static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); |
346 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 175 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
347 | static DEVICE_ATTR(class, S_IRUGO, show_class, NULL); | ||
348 | static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); | 176 | static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); |
349 | static DEVICE_ATTR(features, S_IRUGO, show_features, NULL); | ||
350 | static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL); | ||
351 | static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL); | ||
352 | static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL); | ||
353 | |||
354 | static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, | ||
355 | show_idle_timeout, store_idle_timeout); | ||
356 | static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR, | ||
357 | show_sniff_max_interval, store_sniff_max_interval); | ||
358 | static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR, | ||
359 | show_sniff_min_interval, store_sniff_min_interval); | ||
360 | 177 | ||
361 | static struct attribute *bt_host_attrs[] = { | 178 | static struct attribute *bt_host_attrs[] = { |
362 | &dev_attr_bus.attr, | ||
363 | &dev_attr_type.attr, | 179 | &dev_attr_type.attr, |
364 | &dev_attr_name.attr, | 180 | &dev_attr_name.attr, |
365 | &dev_attr_class.attr, | ||
366 | &dev_attr_address.attr, | 181 | &dev_attr_address.attr, |
367 | &dev_attr_features.attr, | ||
368 | &dev_attr_manufacturer.attr, | ||
369 | &dev_attr_hci_version.attr, | ||
370 | &dev_attr_hci_revision.attr, | ||
371 | &dev_attr_idle_timeout.attr, | ||
372 | &dev_attr_sniff_max_interval.attr, | ||
373 | &dev_attr_sniff_min_interval.attr, | ||
374 | NULL | 182 | NULL |
375 | }; | 183 | }; |
376 | 184 | ||
@@ -396,141 +204,6 @@ static struct device_type bt_host = { | |||
396 | .release = bt_host_release, | 204 | .release = bt_host_release, |
397 | }; | 205 | }; |
398 | 206 | ||
399 | static int inquiry_cache_show(struct seq_file *f, void *p) | ||
400 | { | ||
401 | struct hci_dev *hdev = f->private; | ||
402 | struct discovery_state *cache = &hdev->discovery; | ||
403 | struct inquiry_entry *e; | ||
404 | |||
405 | hci_dev_lock(hdev); | ||
406 | |||
407 | list_for_each_entry(e, &cache->all, all) { | ||
408 | struct inquiry_data *data = &e->data; | ||
409 | seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", | ||
410 | &data->bdaddr, | ||
411 | data->pscan_rep_mode, data->pscan_period_mode, | ||
412 | data->pscan_mode, data->dev_class[2], | ||
413 | data->dev_class[1], data->dev_class[0], | ||
414 | __le16_to_cpu(data->clock_offset), | ||
415 | data->rssi, data->ssp_mode, e->timestamp); | ||
416 | } | ||
417 | |||
418 | hci_dev_unlock(hdev); | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int inquiry_cache_open(struct inode *inode, struct file *file) | ||
424 | { | ||
425 | return single_open(file, inquiry_cache_show, inode->i_private); | ||
426 | } | ||
427 | |||
428 | static const struct file_operations inquiry_cache_fops = { | ||
429 | .open = inquiry_cache_open, | ||
430 | .read = seq_read, | ||
431 | .llseek = seq_lseek, | ||
432 | .release = single_release, | ||
433 | }; | ||
434 | |||
435 | static int blacklist_show(struct seq_file *f, void *p) | ||
436 | { | ||
437 | struct hci_dev *hdev = f->private; | ||
438 | struct bdaddr_list *b; | ||
439 | |||
440 | hci_dev_lock(hdev); | ||
441 | |||
442 | list_for_each_entry(b, &hdev->blacklist, list) | ||
443 | seq_printf(f, "%pMR\n", &b->bdaddr); | ||
444 | |||
445 | hci_dev_unlock(hdev); | ||
446 | |||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static int blacklist_open(struct inode *inode, struct file *file) | ||
451 | { | ||
452 | return single_open(file, blacklist_show, inode->i_private); | ||
453 | } | ||
454 | |||
455 | static const struct file_operations blacklist_fops = { | ||
456 | .open = blacklist_open, | ||
457 | .read = seq_read, | ||
458 | .llseek = seq_lseek, | ||
459 | .release = single_release, | ||
460 | }; | ||
461 | |||
462 | static void print_bt_uuid(struct seq_file *f, u8 *uuid) | ||
463 | { | ||
464 | u32 data0, data5; | ||
465 | u16 data1, data2, data3, data4; | ||
466 | |||
467 | data5 = get_unaligned_le32(uuid); | ||
468 | data4 = get_unaligned_le16(uuid + 4); | ||
469 | data3 = get_unaligned_le16(uuid + 6); | ||
470 | data2 = get_unaligned_le16(uuid + 8); | ||
471 | data1 = get_unaligned_le16(uuid + 10); | ||
472 | data0 = get_unaligned_le32(uuid + 12); | ||
473 | |||
474 | seq_printf(f, "%.8x-%.4x-%.4x-%.4x-%.4x%.8x\n", | ||
475 | data0, data1, data2, data3, data4, data5); | ||
476 | } | ||
477 | |||
478 | static int uuids_show(struct seq_file *f, void *p) | ||
479 | { | ||
480 | struct hci_dev *hdev = f->private; | ||
481 | struct bt_uuid *uuid; | ||
482 | |||
483 | hci_dev_lock(hdev); | ||
484 | |||
485 | list_for_each_entry(uuid, &hdev->uuids, list) | ||
486 | print_bt_uuid(f, uuid->uuid); | ||
487 | |||
488 | hci_dev_unlock(hdev); | ||
489 | |||
490 | return 0; | ||
491 | } | ||
492 | |||
493 | static int uuids_open(struct inode *inode, struct file *file) | ||
494 | { | ||
495 | return single_open(file, uuids_show, inode->i_private); | ||
496 | } | ||
497 | |||
498 | static const struct file_operations uuids_fops = { | ||
499 | .open = uuids_open, | ||
500 | .read = seq_read, | ||
501 | .llseek = seq_lseek, | ||
502 | .release = single_release, | ||
503 | }; | ||
504 | |||
505 | static int auto_accept_delay_set(void *data, u64 val) | ||
506 | { | ||
507 | struct hci_dev *hdev = data; | ||
508 | |||
509 | hci_dev_lock(hdev); | ||
510 | |||
511 | hdev->auto_accept_delay = val; | ||
512 | |||
513 | hci_dev_unlock(hdev); | ||
514 | |||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | static int auto_accept_delay_get(void *data, u64 *val) | ||
519 | { | ||
520 | struct hci_dev *hdev = data; | ||
521 | |||
522 | hci_dev_lock(hdev); | ||
523 | |||
524 | *val = hdev->auto_accept_delay; | ||
525 | |||
526 | hci_dev_unlock(hdev); | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, | ||
532 | auto_accept_delay_set, "%llu\n"); | ||
533 | |||
534 | void hci_init_sysfs(struct hci_dev *hdev) | 207 | void hci_init_sysfs(struct hci_dev *hdev) |
535 | { | 208 | { |
536 | struct device *dev = &hdev->dev; | 209 | struct device *dev = &hdev->dev; |
@@ -542,52 +215,8 @@ void hci_init_sysfs(struct hci_dev *hdev) | |||
542 | device_initialize(dev); | 215 | device_initialize(dev); |
543 | } | 216 | } |
544 | 217 | ||
545 | int hci_add_sysfs(struct hci_dev *hdev) | ||
546 | { | ||
547 | struct device *dev = &hdev->dev; | ||
548 | int err; | ||
549 | |||
550 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); | ||
551 | |||
552 | dev_set_name(dev, "%s", hdev->name); | ||
553 | |||
554 | err = device_add(dev); | ||
555 | if (err < 0) | ||
556 | return err; | ||
557 | |||
558 | if (!bt_debugfs) | ||
559 | return 0; | ||
560 | |||
561 | hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); | ||
562 | if (!hdev->debugfs) | ||
563 | return 0; | ||
564 | |||
565 | debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, | ||
566 | hdev, &inquiry_cache_fops); | ||
567 | |||
568 | debugfs_create_file("blacklist", 0444, hdev->debugfs, | ||
569 | hdev, &blacklist_fops); | ||
570 | |||
571 | debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); | ||
572 | |||
573 | debugfs_create_file("auto_accept_delay", 0444, hdev->debugfs, hdev, | ||
574 | &auto_accept_delay_fops); | ||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | void hci_del_sysfs(struct hci_dev *hdev) | ||
579 | { | ||
580 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); | ||
581 | |||
582 | debugfs_remove_recursive(hdev->debugfs); | ||
583 | |||
584 | device_del(&hdev->dev); | ||
585 | } | ||
586 | |||
587 | int __init bt_sysfs_init(void) | 218 | int __init bt_sysfs_init(void) |
588 | { | 219 | { |
589 | bt_debugfs = debugfs_create_dir("bluetooth", NULL); | ||
590 | |||
591 | bt_class = class_create(THIS_MODULE, "bluetooth"); | 220 | bt_class = class_create(THIS_MODULE, "bluetooth"); |
592 | 221 | ||
593 | return PTR_ERR_OR_ZERO(bt_class); | 222 | return PTR_ERR_OR_ZERO(bt_class); |
@@ -596,6 +225,4 @@ int __init bt_sysfs_init(void) | |||
596 | void bt_sysfs_cleanup(void) | 225 | void bt_sysfs_cleanup(void) |
597 | { | 226 | { |
598 | class_destroy(bt_class); | 227 | class_destroy(bt_class); |
599 | |||
600 | debugfs_remove_recursive(bt_debugfs); | ||
601 | } | 228 | } |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 0c3446da1ec9..0cef67707838 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -223,38 +223,25 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) | |||
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
226 | static void __l2cap_state_change(struct l2cap_chan *chan, int state) | 226 | static void l2cap_state_change(struct l2cap_chan *chan, int state) |
227 | { | 227 | { |
228 | BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state), | 228 | BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state), |
229 | state_to_string(state)); | 229 | state_to_string(state)); |
230 | 230 | ||
231 | chan->state = state; | 231 | chan->state = state; |
232 | chan->ops->state_change(chan, state); | 232 | chan->ops->state_change(chan, state, 0); |
233 | } | 233 | } |
234 | 234 | ||
235 | static void l2cap_state_change(struct l2cap_chan *chan, int state) | 235 | static inline void l2cap_state_change_and_error(struct l2cap_chan *chan, |
236 | int state, int err) | ||
236 | { | 237 | { |
237 | struct sock *sk = chan->sk; | 238 | chan->state = state; |
238 | 239 | chan->ops->state_change(chan, chan->state, err); | |
239 | lock_sock(sk); | ||
240 | __l2cap_state_change(chan, state); | ||
241 | release_sock(sk); | ||
242 | } | ||
243 | |||
244 | static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err) | ||
245 | { | ||
246 | struct sock *sk = chan->sk; | ||
247 | |||
248 | sk->sk_err = err; | ||
249 | } | 240 | } |
250 | 241 | ||
251 | static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err) | 242 | static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err) |
252 | { | 243 | { |
253 | struct sock *sk = chan->sk; | 244 | chan->ops->state_change(chan, chan->state, err); |
254 | |||
255 | lock_sock(sk); | ||
256 | __l2cap_chan_set_err(chan, err); | ||
257 | release_sock(sk); | ||
258 | } | 245 | } |
259 | 246 | ||
260 | static void __set_retrans_timer(struct l2cap_chan *chan) | 247 | static void __set_retrans_timer(struct l2cap_chan *chan) |
@@ -645,8 +632,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) | |||
645 | case BT_CONFIG: | 632 | case BT_CONFIG: |
646 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && | 633 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && |
647 | conn->hcon->type == ACL_LINK) { | 634 | conn->hcon->type == ACL_LINK) { |
648 | struct sock *sk = chan->sk; | 635 | __set_chan_timer(chan, chan->ops->get_sndtimeo(chan)); |
649 | __set_chan_timer(chan, sk->sk_sndtimeo); | ||
650 | l2cap_send_disconn_req(chan, reason); | 636 | l2cap_send_disconn_req(chan, reason); |
651 | } else | 637 | } else |
652 | l2cap_chan_del(chan, reason); | 638 | l2cap_chan_del(chan, reason); |
@@ -1230,7 +1216,6 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) | |||
1230 | 1216 | ||
1231 | static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err) | 1217 | static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err) |
1232 | { | 1218 | { |
1233 | struct sock *sk = chan->sk; | ||
1234 | struct l2cap_conn *conn = chan->conn; | 1219 | struct l2cap_conn *conn = chan->conn; |
1235 | struct l2cap_disconn_req req; | 1220 | struct l2cap_disconn_req req; |
1236 | 1221 | ||
@@ -1253,10 +1238,7 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err) | |||
1253 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ, | 1238 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ, |
1254 | sizeof(req), &req); | 1239 | sizeof(req), &req); |
1255 | 1240 | ||
1256 | lock_sock(sk); | 1241 | l2cap_state_change_and_error(chan, BT_DISCONN, err); |
1257 | __l2cap_state_change(chan, BT_DISCONN); | ||
1258 | __l2cap_chan_set_err(chan, err); | ||
1259 | release_sock(sk); | ||
1260 | } | 1242 | } |
1261 | 1243 | ||
1262 | /* ---- L2CAP connections ---- */ | 1244 | /* ---- L2CAP connections ---- */ |
@@ -1300,20 +1282,16 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
1300 | rsp.dcid = cpu_to_le16(chan->scid); | 1282 | rsp.dcid = cpu_to_le16(chan->scid); |
1301 | 1283 | ||
1302 | if (l2cap_chan_check_security(chan)) { | 1284 | if (l2cap_chan_check_security(chan)) { |
1303 | struct sock *sk = chan->sk; | ||
1304 | |||
1305 | lock_sock(sk); | ||
1306 | if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { | 1285 | if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { |
1307 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); | 1286 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); |
1308 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND); | 1287 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND); |
1309 | chan->ops->defer(chan); | 1288 | chan->ops->defer(chan); |
1310 | 1289 | ||
1311 | } else { | 1290 | } else { |
1312 | __l2cap_state_change(chan, BT_CONFIG); | 1291 | l2cap_state_change(chan, BT_CONFIG); |
1313 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); | 1292 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); |
1314 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); | 1293 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); |
1315 | } | 1294 | } |
1316 | release_sock(sk); | ||
1317 | } else { | 1295 | } else { |
1318 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); | 1296 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); |
1319 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND); | 1297 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND); |
@@ -1383,14 +1361,15 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid, | |||
1383 | 1361 | ||
1384 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) | 1362 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) |
1385 | { | 1363 | { |
1386 | struct sock *parent; | 1364 | struct hci_conn *hcon = conn->hcon; |
1387 | struct l2cap_chan *chan, *pchan; | 1365 | struct l2cap_chan *chan, *pchan; |
1366 | u8 dst_type; | ||
1388 | 1367 | ||
1389 | BT_DBG(""); | 1368 | BT_DBG(""); |
1390 | 1369 | ||
1391 | /* Check if we have socket listening on cid */ | 1370 | /* Check if we have socket listening on cid */ |
1392 | pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT, | 1371 | pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT, |
1393 | &conn->hcon->src, &conn->hcon->dst); | 1372 | &hcon->src, &hcon->dst); |
1394 | if (!pchan) | 1373 | if (!pchan) |
1395 | return; | 1374 | return; |
1396 | 1375 | ||
@@ -1398,9 +1377,13 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
1398 | if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT)) | 1377 | if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT)) |
1399 | return; | 1378 | return; |
1400 | 1379 | ||
1401 | parent = pchan->sk; | 1380 | dst_type = bdaddr_type(hcon, hcon->dst_type); |
1381 | |||
1382 | /* If device is blocked, do not create a channel for it */ | ||
1383 | if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type)) | ||
1384 | return; | ||
1402 | 1385 | ||
1403 | lock_sock(parent); | 1386 | l2cap_chan_lock(pchan); |
1404 | 1387 | ||
1405 | chan = pchan->ops->new_connection(pchan); | 1388 | chan = pchan->ops->new_connection(pchan); |
1406 | if (!chan) | 1389 | if (!chan) |
@@ -1408,15 +1391,15 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
1408 | 1391 | ||
1409 | chan->dcid = L2CAP_CID_ATT; | 1392 | chan->dcid = L2CAP_CID_ATT; |
1410 | 1393 | ||
1411 | bacpy(&chan->src, &conn->hcon->src); | 1394 | bacpy(&chan->src, &hcon->src); |
1412 | bacpy(&chan->dst, &conn->hcon->dst); | 1395 | bacpy(&chan->dst, &hcon->dst); |
1413 | chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type); | 1396 | chan->src_type = bdaddr_type(hcon, hcon->src_type); |
1414 | chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type); | 1397 | chan->dst_type = dst_type; |
1415 | 1398 | ||
1416 | __l2cap_chan_add(conn, chan); | 1399 | __l2cap_chan_add(conn, chan); |
1417 | 1400 | ||
1418 | clean: | 1401 | clean: |
1419 | release_sock(parent); | 1402 | l2cap_chan_unlock(pchan); |
1420 | } | 1403 | } |
1421 | 1404 | ||
1422 | static void l2cap_conn_ready(struct l2cap_conn *conn) | 1405 | static void l2cap_conn_ready(struct l2cap_conn *conn) |
@@ -1451,12 +1434,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
1451 | l2cap_chan_ready(chan); | 1434 | l2cap_chan_ready(chan); |
1452 | 1435 | ||
1453 | } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { | 1436 | } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { |
1454 | struct sock *sk = chan->sk; | 1437 | l2cap_chan_ready(chan); |
1455 | __clear_chan_timer(chan); | ||
1456 | lock_sock(sk); | ||
1457 | __l2cap_state_change(chan, BT_CONNECTED); | ||
1458 | sk->sk_state_change(sk); | ||
1459 | release_sock(sk); | ||
1460 | 1438 | ||
1461 | } else if (chan->state == BT_CONNECT) { | 1439 | } else if (chan->state == BT_CONNECT) { |
1462 | l2cap_do_start(chan); | 1440 | l2cap_do_start(chan); |
@@ -1764,7 +1742,6 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, | |||
1764 | int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | 1742 | int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, |
1765 | bdaddr_t *dst, u8 dst_type) | 1743 | bdaddr_t *dst, u8 dst_type) |
1766 | { | 1744 | { |
1767 | struct sock *sk = chan->sk; | ||
1768 | struct l2cap_conn *conn; | 1745 | struct l2cap_conn *conn; |
1769 | struct hci_conn *hcon; | 1746 | struct hci_conn *hcon; |
1770 | struct hci_dev *hdev; | 1747 | struct hci_dev *hdev; |
@@ -1876,7 +1853,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | |||
1876 | hci_conn_drop(hcon); | 1853 | hci_conn_drop(hcon); |
1877 | 1854 | ||
1878 | l2cap_state_change(chan, BT_CONNECT); | 1855 | l2cap_state_change(chan, BT_CONNECT); |
1879 | __set_chan_timer(chan, sk->sk_sndtimeo); | 1856 | __set_chan_timer(chan, chan->ops->get_sndtimeo(chan)); |
1880 | 1857 | ||
1881 | if (hcon->state == BT_CONNECTED) { | 1858 | if (hcon->state == BT_CONNECTED) { |
1882 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { | 1859 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { |
@@ -1896,38 +1873,6 @@ done: | |||
1896 | return err; | 1873 | return err; |
1897 | } | 1874 | } |
1898 | 1875 | ||
1899 | int __l2cap_wait_ack(struct sock *sk) | ||
1900 | { | ||
1901 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
1902 | DECLARE_WAITQUEUE(wait, current); | ||
1903 | int err = 0; | ||
1904 | int timeo = HZ/5; | ||
1905 | |||
1906 | add_wait_queue(sk_sleep(sk), &wait); | ||
1907 | set_current_state(TASK_INTERRUPTIBLE); | ||
1908 | while (chan->unacked_frames > 0 && chan->conn) { | ||
1909 | if (!timeo) | ||
1910 | timeo = HZ/5; | ||
1911 | |||
1912 | if (signal_pending(current)) { | ||
1913 | err = sock_intr_errno(timeo); | ||
1914 | break; | ||
1915 | } | ||
1916 | |||
1917 | release_sock(sk); | ||
1918 | timeo = schedule_timeout(timeo); | ||
1919 | lock_sock(sk); | ||
1920 | set_current_state(TASK_INTERRUPTIBLE); | ||
1921 | |||
1922 | err = sock_error(sk); | ||
1923 | if (err) | ||
1924 | break; | ||
1925 | } | ||
1926 | set_current_state(TASK_RUNNING); | ||
1927 | remove_wait_queue(sk_sleep(sk), &wait); | ||
1928 | return err; | ||
1929 | } | ||
1930 | |||
1931 | static void l2cap_monitor_timeout(struct work_struct *work) | 1876 | static void l2cap_monitor_timeout(struct work_struct *work) |
1932 | { | 1877 | { |
1933 | struct l2cap_chan *chan = container_of(work, struct l2cap_chan, | 1878 | struct l2cap_chan *chan = container_of(work, struct l2cap_chan, |
@@ -2868,17 +2813,16 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) | |||
2868 | mutex_lock(&conn->chan_lock); | 2813 | mutex_lock(&conn->chan_lock); |
2869 | 2814 | ||
2870 | list_for_each_entry(chan, &conn->chan_l, list) { | 2815 | list_for_each_entry(chan, &conn->chan_l, list) { |
2871 | struct sock *sk = chan->sk; | ||
2872 | if (chan->chan_type != L2CAP_CHAN_RAW) | 2816 | if (chan->chan_type != L2CAP_CHAN_RAW) |
2873 | continue; | 2817 | continue; |
2874 | 2818 | ||
2875 | /* Don't send frame to the socket it came from */ | 2819 | /* Don't send frame to the channel it came from */ |
2876 | if (skb->sk == sk) | 2820 | if (bt_cb(skb)->chan == chan) |
2877 | continue; | 2821 | continue; |
2822 | |||
2878 | nskb = skb_clone(skb, GFP_KERNEL); | 2823 | nskb = skb_clone(skb, GFP_KERNEL); |
2879 | if (!nskb) | 2824 | if (!nskb) |
2880 | continue; | 2825 | continue; |
2881 | |||
2882 | if (chan->ops->recv(chan, nskb)) | 2826 | if (chan->ops->recv(chan, nskb)) |
2883 | kfree_skb(nskb); | 2827 | kfree_skb(nskb); |
2884 | } | 2828 | } |
@@ -3757,7 +3701,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, | |||
3757 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; | 3701 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; |
3758 | struct l2cap_conn_rsp rsp; | 3702 | struct l2cap_conn_rsp rsp; |
3759 | struct l2cap_chan *chan = NULL, *pchan; | 3703 | struct l2cap_chan *chan = NULL, *pchan; |
3760 | struct sock *parent, *sk = NULL; | ||
3761 | int result, status = L2CAP_CS_NO_INFO; | 3704 | int result, status = L2CAP_CS_NO_INFO; |
3762 | 3705 | ||
3763 | u16 dcid = 0, scid = __le16_to_cpu(req->scid); | 3706 | u16 dcid = 0, scid = __le16_to_cpu(req->scid); |
@@ -3773,10 +3716,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, | |||
3773 | goto sendresp; | 3716 | goto sendresp; |
3774 | } | 3717 | } |
3775 | 3718 | ||
3776 | parent = pchan->sk; | ||
3777 | |||
3778 | mutex_lock(&conn->chan_lock); | 3719 | mutex_lock(&conn->chan_lock); |
3779 | lock_sock(parent); | 3720 | l2cap_chan_lock(pchan); |
3780 | 3721 | ||
3781 | /* Check if the ACL is secure enough (if not SDP) */ | 3722 | /* Check if the ACL is secure enough (if not SDP) */ |
3782 | if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) && | 3723 | if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) && |
@@ -3796,8 +3737,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, | |||
3796 | if (!chan) | 3737 | if (!chan) |
3797 | goto response; | 3738 | goto response; |
3798 | 3739 | ||
3799 | sk = chan->sk; | ||
3800 | |||
3801 | /* For certain devices (ex: HID mouse), support for authentication, | 3740 | /* For certain devices (ex: HID mouse), support for authentication, |
3802 | * pairing and bonding is optional. For such devices, inorder to avoid | 3741 | * pairing and bonding is optional. For such devices, inorder to avoid |
3803 | * the ACL alive for too long after L2CAP disconnection, reset the ACL | 3742 | * the ACL alive for too long after L2CAP disconnection, reset the ACL |
@@ -3817,14 +3756,14 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, | |||
3817 | 3756 | ||
3818 | dcid = chan->scid; | 3757 | dcid = chan->scid; |
3819 | 3758 | ||
3820 | __set_chan_timer(chan, sk->sk_sndtimeo); | 3759 | __set_chan_timer(chan, chan->ops->get_sndtimeo(chan)); |
3821 | 3760 | ||
3822 | chan->ident = cmd->ident; | 3761 | chan->ident = cmd->ident; |
3823 | 3762 | ||
3824 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { | 3763 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { |
3825 | if (l2cap_chan_check_security(chan)) { | 3764 | if (l2cap_chan_check_security(chan)) { |
3826 | if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { | 3765 | if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { |
3827 | __l2cap_state_change(chan, BT_CONNECT2); | 3766 | l2cap_state_change(chan, BT_CONNECT2); |
3828 | result = L2CAP_CR_PEND; | 3767 | result = L2CAP_CR_PEND; |
3829 | status = L2CAP_CS_AUTHOR_PEND; | 3768 | status = L2CAP_CS_AUTHOR_PEND; |
3830 | chan->ops->defer(chan); | 3769 | chan->ops->defer(chan); |
@@ -3834,27 +3773,27 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, | |||
3834 | * physical link is up. | 3773 | * physical link is up. |
3835 | */ | 3774 | */ |
3836 | if (amp_id == AMP_ID_BREDR) { | 3775 | if (amp_id == AMP_ID_BREDR) { |
3837 | __l2cap_state_change(chan, BT_CONFIG); | 3776 | l2cap_state_change(chan, BT_CONFIG); |
3838 | result = L2CAP_CR_SUCCESS; | 3777 | result = L2CAP_CR_SUCCESS; |
3839 | } else { | 3778 | } else { |
3840 | __l2cap_state_change(chan, BT_CONNECT2); | 3779 | l2cap_state_change(chan, BT_CONNECT2); |
3841 | result = L2CAP_CR_PEND; | 3780 | result = L2CAP_CR_PEND; |
3842 | } | 3781 | } |
3843 | status = L2CAP_CS_NO_INFO; | 3782 | status = L2CAP_CS_NO_INFO; |
3844 | } | 3783 | } |
3845 | } else { | 3784 | } else { |
3846 | __l2cap_state_change(chan, BT_CONNECT2); | 3785 | l2cap_state_change(chan, BT_CONNECT2); |
3847 | result = L2CAP_CR_PEND; | 3786 | result = L2CAP_CR_PEND; |
3848 | status = L2CAP_CS_AUTHEN_PEND; | 3787 | status = L2CAP_CS_AUTHEN_PEND; |
3849 | } | 3788 | } |
3850 | } else { | 3789 | } else { |
3851 | __l2cap_state_change(chan, BT_CONNECT2); | 3790 | l2cap_state_change(chan, BT_CONNECT2); |
3852 | result = L2CAP_CR_PEND; | 3791 | result = L2CAP_CR_PEND; |
3853 | status = L2CAP_CS_NO_INFO; | 3792 | status = L2CAP_CS_NO_INFO; |
3854 | } | 3793 | } |
3855 | 3794 | ||
3856 | response: | 3795 | response: |
3857 | release_sock(parent); | 3796 | l2cap_chan_unlock(pchan); |
3858 | mutex_unlock(&conn->chan_lock); | 3797 | mutex_unlock(&conn->chan_lock); |
3859 | 3798 | ||
3860 | sendresp: | 3799 | sendresp: |
@@ -4010,6 +3949,18 @@ static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data, | |||
4010 | L2CAP_CONF_SUCCESS, flags), data); | 3949 | L2CAP_CONF_SUCCESS, flags), data); |
4011 | } | 3950 | } |
4012 | 3951 | ||
3952 | static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident, | ||
3953 | u16 scid, u16 dcid) | ||
3954 | { | ||
3955 | struct l2cap_cmd_rej_cid rej; | ||
3956 | |||
3957 | rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID); | ||
3958 | rej.scid = __cpu_to_le16(scid); | ||
3959 | rej.dcid = __cpu_to_le16(dcid); | ||
3960 | |||
3961 | l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); | ||
3962 | } | ||
3963 | |||
4013 | static inline int l2cap_config_req(struct l2cap_conn *conn, | 3964 | static inline int l2cap_config_req(struct l2cap_conn *conn, |
4014 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, | 3965 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
4015 | u8 *data) | 3966 | u8 *data) |
@@ -4029,18 +3980,14 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, | |||
4029 | BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); | 3980 | BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); |
4030 | 3981 | ||
4031 | chan = l2cap_get_chan_by_scid(conn, dcid); | 3982 | chan = l2cap_get_chan_by_scid(conn, dcid); |
4032 | if (!chan) | 3983 | if (!chan) { |
4033 | return -EBADSLT; | 3984 | cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0); |
3985 | return 0; | ||
3986 | } | ||
4034 | 3987 | ||
4035 | if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) { | 3988 | if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) { |
4036 | struct l2cap_cmd_rej_cid rej; | 3989 | cmd_reject_invalid_cid(conn, cmd->ident, chan->scid, |
4037 | 3990 | chan->dcid); | |
4038 | rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID); | ||
4039 | rej.scid = cpu_to_le16(chan->scid); | ||
4040 | rej.dcid = cpu_to_le16(chan->dcid); | ||
4041 | |||
4042 | l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, | ||
4043 | sizeof(rej), &rej); | ||
4044 | goto unlock; | 3991 | goto unlock; |
4045 | } | 3992 | } |
4046 | 3993 | ||
@@ -4243,7 +4190,6 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, | |||
4243 | struct l2cap_disconn_rsp rsp; | 4190 | struct l2cap_disconn_rsp rsp; |
4244 | u16 dcid, scid; | 4191 | u16 dcid, scid; |
4245 | struct l2cap_chan *chan; | 4192 | struct l2cap_chan *chan; |
4246 | struct sock *sk; | ||
4247 | 4193 | ||
4248 | if (cmd_len != sizeof(*req)) | 4194 | if (cmd_len != sizeof(*req)) |
4249 | return -EPROTO; | 4195 | return -EPROTO; |
@@ -4258,20 +4204,17 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, | |||
4258 | chan = __l2cap_get_chan_by_scid(conn, dcid); | 4204 | chan = __l2cap_get_chan_by_scid(conn, dcid); |
4259 | if (!chan) { | 4205 | if (!chan) { |
4260 | mutex_unlock(&conn->chan_lock); | 4206 | mutex_unlock(&conn->chan_lock); |
4261 | return -EBADSLT; | 4207 | cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid); |
4208 | return 0; | ||
4262 | } | 4209 | } |
4263 | 4210 | ||
4264 | l2cap_chan_lock(chan); | 4211 | l2cap_chan_lock(chan); |
4265 | 4212 | ||
4266 | sk = chan->sk; | ||
4267 | |||
4268 | rsp.dcid = cpu_to_le16(chan->scid); | 4213 | rsp.dcid = cpu_to_le16(chan->scid); |
4269 | rsp.scid = cpu_to_le16(chan->dcid); | 4214 | rsp.scid = cpu_to_le16(chan->dcid); |
4270 | l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp); | 4215 | l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp); |
4271 | 4216 | ||
4272 | lock_sock(sk); | 4217 | chan->ops->set_shutdown(chan); |
4273 | sk->sk_shutdown = SHUTDOWN_MASK; | ||
4274 | release_sock(sk); | ||
4275 | 4218 | ||
4276 | l2cap_chan_hold(chan); | 4219 | l2cap_chan_hold(chan); |
4277 | l2cap_chan_del(chan, ECONNRESET); | 4220 | l2cap_chan_del(chan, ECONNRESET); |
@@ -4491,7 +4434,9 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn, | |||
4491 | &conn->hcon->dst); | 4434 | &conn->hcon->dst); |
4492 | if (!hs_hcon) { | 4435 | if (!hs_hcon) { |
4493 | hci_dev_put(hdev); | 4436 | hci_dev_put(hdev); |
4494 | return -EBADSLT; | 4437 | cmd_reject_invalid_cid(conn, cmd->ident, chan->scid, |
4438 | chan->dcid); | ||
4439 | return 0; | ||
4495 | } | 4440 | } |
4496 | 4441 | ||
4497 | BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon); | 4442 | BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon); |
@@ -4769,7 +4714,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result, | |||
4769 | sizeof(rsp), &rsp); | 4714 | sizeof(rsp), &rsp); |
4770 | 4715 | ||
4771 | if (result == L2CAP_CR_SUCCESS) { | 4716 | if (result == L2CAP_CR_SUCCESS) { |
4772 | __l2cap_state_change(chan, BT_CONFIG); | 4717 | l2cap_state_change(chan, BT_CONFIG); |
4773 | set_bit(CONF_REQ_SENT, &chan->conf_state); | 4718 | set_bit(CONF_REQ_SENT, &chan->conf_state); |
4774 | l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn), | 4719 | l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn), |
4775 | L2CAP_CONF_REQ, | 4720 | L2CAP_CONF_REQ, |
@@ -5347,20 +5292,6 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, | |||
5347 | } | 5292 | } |
5348 | } | 5293 | } |
5349 | 5294 | ||
5350 | static __le16 l2cap_err_to_reason(int err) | ||
5351 | { | ||
5352 | switch (err) { | ||
5353 | case -EBADSLT: | ||
5354 | return __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID); | ||
5355 | case -EMSGSIZE: | ||
5356 | return __constant_cpu_to_le16(L2CAP_REJ_MTU_EXCEEDED); | ||
5357 | case -EINVAL: | ||
5358 | case -EPROTO: | ||
5359 | default: | ||
5360 | return __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); | ||
5361 | } | ||
5362 | } | ||
5363 | |||
5364 | static inline void l2cap_le_sig_channel(struct l2cap_conn *conn, | 5295 | static inline void l2cap_le_sig_channel(struct l2cap_conn *conn, |
5365 | struct sk_buff *skb) | 5296 | struct sk_buff *skb) |
5366 | { | 5297 | { |
@@ -5393,7 +5324,7 @@ static inline void l2cap_le_sig_channel(struct l2cap_conn *conn, | |||
5393 | 5324 | ||
5394 | BT_ERR("Wrong link type (%d)", err); | 5325 | BT_ERR("Wrong link type (%d)", err); |
5395 | 5326 | ||
5396 | rej.reason = l2cap_err_to_reason(err); | 5327 | rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); |
5397 | l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, | 5328 | l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, |
5398 | sizeof(rej), &rej); | 5329 | sizeof(rej), &rej); |
5399 | } | 5330 | } |
@@ -5438,7 +5369,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, | |||
5438 | 5369 | ||
5439 | BT_ERR("Wrong link type (%d)", err); | 5370 | BT_ERR("Wrong link type (%d)", err); |
5440 | 5371 | ||
5441 | rej.reason = l2cap_err_to_reason(err); | 5372 | rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); |
5442 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, | 5373 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, |
5443 | sizeof(rej), &rej); | 5374 | sizeof(rej), &rej); |
5444 | } | 5375 | } |
@@ -6446,8 +6377,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, | |||
6446 | if (hcon->type != ACL_LINK) | 6377 | if (hcon->type != ACL_LINK) |
6447 | goto drop; | 6378 | goto drop; |
6448 | 6379 | ||
6449 | chan = l2cap_global_chan_by_psm(0, psm, &conn->hcon->src, | 6380 | chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst); |
6450 | &conn->hcon->dst); | ||
6451 | if (!chan) | 6381 | if (!chan) |
6452 | goto drop; | 6382 | goto drop; |
6453 | 6383 | ||
@@ -6460,7 +6390,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, | |||
6460 | goto drop; | 6390 | goto drop; |
6461 | 6391 | ||
6462 | /* Store remote BD_ADDR and PSM for msg_name */ | 6392 | /* Store remote BD_ADDR and PSM for msg_name */ |
6463 | bacpy(&bt_cb(skb)->bdaddr, &conn->hcon->dst); | 6393 | bacpy(&bt_cb(skb)->bdaddr, &hcon->dst); |
6464 | bt_cb(skb)->psm = psm; | 6394 | bt_cb(skb)->psm = psm; |
6465 | 6395 | ||
6466 | if (!chan->ops->recv(chan, skb)) | 6396 | if (!chan->ops->recv(chan, skb)) |
@@ -6480,12 +6410,15 @@ static void l2cap_att_channel(struct l2cap_conn *conn, | |||
6480 | goto drop; | 6410 | goto drop; |
6481 | 6411 | ||
6482 | chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT, | 6412 | chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT, |
6483 | &conn->hcon->src, &conn->hcon->dst); | 6413 | &hcon->src, &hcon->dst); |
6484 | if (!chan) | 6414 | if (!chan) |
6485 | goto drop; | 6415 | goto drop; |
6486 | 6416 | ||
6487 | BT_DBG("chan %p, len %d", chan, skb->len); | 6417 | BT_DBG("chan %p, len %d", chan, skb->len); |
6488 | 6418 | ||
6419 | if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type)) | ||
6420 | goto drop; | ||
6421 | |||
6489 | if (chan->imtu < skb->len) | 6422 | if (chan->imtu < skb->len) |
6490 | goto drop; | 6423 | goto drop; |
6491 | 6424 | ||
@@ -6682,31 +6615,26 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
6682 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); | 6615 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
6683 | } | 6616 | } |
6684 | } else if (chan->state == BT_CONNECT2) { | 6617 | } else if (chan->state == BT_CONNECT2) { |
6685 | struct sock *sk = chan->sk; | ||
6686 | struct l2cap_conn_rsp rsp; | 6618 | struct l2cap_conn_rsp rsp; |
6687 | __u16 res, stat; | 6619 | __u16 res, stat; |
6688 | 6620 | ||
6689 | lock_sock(sk); | ||
6690 | |||
6691 | if (!status) { | 6621 | if (!status) { |
6692 | if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { | 6622 | if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { |
6693 | res = L2CAP_CR_PEND; | 6623 | res = L2CAP_CR_PEND; |
6694 | stat = L2CAP_CS_AUTHOR_PEND; | 6624 | stat = L2CAP_CS_AUTHOR_PEND; |
6695 | chan->ops->defer(chan); | 6625 | chan->ops->defer(chan); |
6696 | } else { | 6626 | } else { |
6697 | __l2cap_state_change(chan, BT_CONFIG); | 6627 | l2cap_state_change(chan, BT_CONFIG); |
6698 | res = L2CAP_CR_SUCCESS; | 6628 | res = L2CAP_CR_SUCCESS; |
6699 | stat = L2CAP_CS_NO_INFO; | 6629 | stat = L2CAP_CS_NO_INFO; |
6700 | } | 6630 | } |
6701 | } else { | 6631 | } else { |
6702 | __l2cap_state_change(chan, BT_DISCONN); | 6632 | l2cap_state_change(chan, BT_DISCONN); |
6703 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); | 6633 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
6704 | res = L2CAP_CR_SEC_BLOCK; | 6634 | res = L2CAP_CR_SEC_BLOCK; |
6705 | stat = L2CAP_CS_NO_INFO; | 6635 | stat = L2CAP_CS_NO_INFO; |
6706 | } | 6636 | } |
6707 | 6637 | ||
6708 | release_sock(sk); | ||
6709 | |||
6710 | rsp.scid = cpu_to_le16(chan->dcid); | 6638 | rsp.scid = cpu_to_le16(chan->dcid); |
6711 | rsp.dcid = cpu_to_le16(chan->scid); | 6639 | rsp.dcid = cpu_to_le16(chan->scid); |
6712 | rsp.result = cpu_to_le16(res); | 6640 | rsp.result = cpu_to_le16(res); |
@@ -6880,12 +6808,11 @@ int __init l2cap_init(void) | |||
6880 | if (err < 0) | 6808 | if (err < 0) |
6881 | return err; | 6809 | return err; |
6882 | 6810 | ||
6883 | if (bt_debugfs) { | 6811 | if (IS_ERR_OR_NULL(bt_debugfs)) |
6884 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs, | 6812 | return 0; |
6885 | NULL, &l2cap_debugfs_fops); | 6813 | |
6886 | if (!l2cap_debugfs) | 6814 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs, |
6887 | BT_ERR("Failed to create L2CAP debug file"); | 6815 | NULL, &l2cap_debugfs_fops); |
6888 | } | ||
6889 | 6816 | ||
6890 | return 0; | 6817 | return 0; |
6891 | } | 6818 | } |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 5ffd75e20bde..7cc24d263caa 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -72,6 +72,15 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | |||
72 | if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) | 72 | if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) |
73 | return -EINVAL; | 73 | return -EINVAL; |
74 | 74 | ||
75 | if (bdaddr_type_is_le(la.l2_bdaddr_type)) { | ||
76 | /* Connection oriented channels are not supported on LE */ | ||
77 | if (la.l2_psm) | ||
78 | return -EINVAL; | ||
79 | /* We only allow ATT user space socket */ | ||
80 | if (la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) | ||
81 | return -EINVAL; | ||
82 | } | ||
83 | |||
75 | lock_sock(sk); | 84 | lock_sock(sk); |
76 | 85 | ||
77 | if (sk->sk_state != BT_OPEN) { | 86 | if (sk->sk_state != BT_OPEN) { |
@@ -150,12 +159,44 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, | |||
150 | if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) | 159 | if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) |
151 | return -EINVAL; | 160 | return -EINVAL; |
152 | 161 | ||
153 | if (chan->src_type == BDADDR_BREDR && la.l2_bdaddr_type != BDADDR_BREDR) | 162 | /* Check that the socket wasn't bound to something that |
154 | return -EINVAL; | 163 | * conflicts with the address given to connect(). If chan->src |
164 | * is BDADDR_ANY it means bind() was never used, in which case | ||
165 | * chan->src_type and la.l2_bdaddr_type do not need to match. | ||
166 | */ | ||
167 | if (chan->src_type == BDADDR_BREDR && bacmp(&chan->src, BDADDR_ANY) && | ||
168 | bdaddr_type_is_le(la.l2_bdaddr_type)) { | ||
169 | /* Old user space versions will try to incorrectly bind | ||
170 | * the ATT socket using BDADDR_BREDR. We need to accept | ||
171 | * this and fix up the source address type only when | ||
172 | * both the source CID and destination CID indicate | ||
173 | * ATT. Anything else is an invalid combination. | ||
174 | */ | ||
175 | if (chan->scid != L2CAP_CID_ATT || | ||
176 | la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) | ||
177 | return -EINVAL; | ||
178 | |||
179 | /* We don't have the hdev available here to make a | ||
180 | * better decision on random vs public, but since all | ||
181 | * user space versions that exhibit this issue anyway do | ||
182 | * not support random local addresses assuming public | ||
183 | * here is good enough. | ||
184 | */ | ||
185 | chan->src_type = BDADDR_LE_PUBLIC; | ||
186 | } | ||
155 | 187 | ||
156 | if (chan->src_type != BDADDR_BREDR && la.l2_bdaddr_type == BDADDR_BREDR) | 188 | if (chan->src_type != BDADDR_BREDR && la.l2_bdaddr_type == BDADDR_BREDR) |
157 | return -EINVAL; | 189 | return -EINVAL; |
158 | 190 | ||
191 | if (bdaddr_type_is_le(la.l2_bdaddr_type)) { | ||
192 | /* Connection oriented channels are not supported on LE */ | ||
193 | if (la.l2_psm) | ||
194 | return -EINVAL; | ||
195 | /* We only allow ATT user space socket */ | ||
196 | if (la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) | ||
197 | return -EINVAL; | ||
198 | } | ||
199 | |||
159 | err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), | 200 | err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), |
160 | &la.l2_bdaddr, la.l2_bdaddr_type); | 201 | &la.l2_bdaddr, la.l2_bdaddr_type); |
161 | if (err) | 202 | if (err) |
@@ -879,6 +920,38 @@ static void l2cap_sock_kill(struct sock *sk) | |||
879 | sock_put(sk); | 920 | sock_put(sk); |
880 | } | 921 | } |
881 | 922 | ||
923 | static int __l2cap_wait_ack(struct sock *sk) | ||
924 | { | ||
925 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
926 | DECLARE_WAITQUEUE(wait, current); | ||
927 | int err = 0; | ||
928 | int timeo = HZ/5; | ||
929 | |||
930 | add_wait_queue(sk_sleep(sk), &wait); | ||
931 | set_current_state(TASK_INTERRUPTIBLE); | ||
932 | while (chan->unacked_frames > 0 && chan->conn) { | ||
933 | if (!timeo) | ||
934 | timeo = HZ/5; | ||
935 | |||
936 | if (signal_pending(current)) { | ||
937 | err = sock_intr_errno(timeo); | ||
938 | break; | ||
939 | } | ||
940 | |||
941 | release_sock(sk); | ||
942 | timeo = schedule_timeout(timeo); | ||
943 | lock_sock(sk); | ||
944 | set_current_state(TASK_INTERRUPTIBLE); | ||
945 | |||
946 | err = sock_error(sk); | ||
947 | if (err) | ||
948 | break; | ||
949 | } | ||
950 | set_current_state(TASK_RUNNING); | ||
951 | remove_wait_queue(sk_sleep(sk), &wait); | ||
952 | return err; | ||
953 | } | ||
954 | |||
882 | static int l2cap_sock_shutdown(struct socket *sock, int how) | 955 | static int l2cap_sock_shutdown(struct socket *sock, int how) |
883 | { | 956 | { |
884 | struct sock *sk = sock->sk; | 957 | struct sock *sk = sock->sk; |
@@ -969,6 +1042,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) | |||
969 | { | 1042 | { |
970 | struct sock *sk, *parent = chan->data; | 1043 | struct sock *sk, *parent = chan->data; |
971 | 1044 | ||
1045 | lock_sock(parent); | ||
1046 | |||
972 | /* Check for backlog size */ | 1047 | /* Check for backlog size */ |
973 | if (sk_acceptq_is_full(parent)) { | 1048 | if (sk_acceptq_is_full(parent)) { |
974 | BT_DBG("backlog full %d", parent->sk_ack_backlog); | 1049 | BT_DBG("backlog full %d", parent->sk_ack_backlog); |
@@ -986,6 +1061,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) | |||
986 | 1061 | ||
987 | bt_accept_enqueue(parent, sk); | 1062 | bt_accept_enqueue(parent, sk); |
988 | 1063 | ||
1064 | release_sock(parent); | ||
1065 | |||
989 | return l2cap_pi(sk)->chan; | 1066 | return l2cap_pi(sk)->chan; |
990 | } | 1067 | } |
991 | 1068 | ||
@@ -1072,26 +1149,33 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err) | |||
1072 | release_sock(sk); | 1149 | release_sock(sk); |
1073 | } | 1150 | } |
1074 | 1151 | ||
1075 | static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state) | 1152 | static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state, |
1153 | int err) | ||
1076 | { | 1154 | { |
1077 | struct sock *sk = chan->data; | 1155 | struct sock *sk = chan->data; |
1078 | 1156 | ||
1079 | sk->sk_state = state; | 1157 | sk->sk_state = state; |
1158 | |||
1159 | if (err) | ||
1160 | sk->sk_err = err; | ||
1080 | } | 1161 | } |
1081 | 1162 | ||
1082 | static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, | 1163 | static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, |
1083 | unsigned long len, int nb) | 1164 | unsigned long len, int nb) |
1084 | { | 1165 | { |
1166 | struct sock *sk = chan->data; | ||
1085 | struct sk_buff *skb; | 1167 | struct sk_buff *skb; |
1086 | int err; | 1168 | int err; |
1087 | 1169 | ||
1088 | l2cap_chan_unlock(chan); | 1170 | l2cap_chan_unlock(chan); |
1089 | skb = bt_skb_send_alloc(chan->sk, len, nb, &err); | 1171 | skb = bt_skb_send_alloc(sk, len, nb, &err); |
1090 | l2cap_chan_lock(chan); | 1172 | l2cap_chan_lock(chan); |
1091 | 1173 | ||
1092 | if (!skb) | 1174 | if (!skb) |
1093 | return ERR_PTR(err); | 1175 | return ERR_PTR(err); |
1094 | 1176 | ||
1177 | bt_cb(skb)->chan = chan; | ||
1178 | |||
1095 | return skb; | 1179 | return skb; |
1096 | } | 1180 | } |
1097 | 1181 | ||
@@ -1117,11 +1201,15 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan) | |||
1117 | 1201 | ||
1118 | static void l2cap_sock_defer_cb(struct l2cap_chan *chan) | 1202 | static void l2cap_sock_defer_cb(struct l2cap_chan *chan) |
1119 | { | 1203 | { |
1120 | struct sock *sk = chan->data; | 1204 | struct sock *parent, *sk = chan->data; |
1121 | struct sock *parent = bt_sk(sk)->parent; | 1205 | |
1206 | lock_sock(sk); | ||
1122 | 1207 | ||
1208 | parent = bt_sk(sk)->parent; | ||
1123 | if (parent) | 1209 | if (parent) |
1124 | parent->sk_data_ready(parent, 0); | 1210 | parent->sk_data_ready(parent, 0); |
1211 | |||
1212 | release_sock(sk); | ||
1125 | } | 1213 | } |
1126 | 1214 | ||
1127 | static void l2cap_sock_resume_cb(struct l2cap_chan *chan) | 1215 | static void l2cap_sock_resume_cb(struct l2cap_chan *chan) |
@@ -1132,6 +1220,22 @@ static void l2cap_sock_resume_cb(struct l2cap_chan *chan) | |||
1132 | sk->sk_state_change(sk); | 1220 | sk->sk_state_change(sk); |
1133 | } | 1221 | } |
1134 | 1222 | ||
1223 | static void l2cap_sock_set_shutdown_cb(struct l2cap_chan *chan) | ||
1224 | { | ||
1225 | struct sock *sk = chan->data; | ||
1226 | |||
1227 | lock_sock(sk); | ||
1228 | sk->sk_shutdown = SHUTDOWN_MASK; | ||
1229 | release_sock(sk); | ||
1230 | } | ||
1231 | |||
1232 | static long l2cap_sock_get_sndtimeo_cb(struct l2cap_chan *chan) | ||
1233 | { | ||
1234 | struct sock *sk = chan->data; | ||
1235 | |||
1236 | return sk->sk_sndtimeo; | ||
1237 | } | ||
1238 | |||
1135 | static struct l2cap_ops l2cap_chan_ops = { | 1239 | static struct l2cap_ops l2cap_chan_ops = { |
1136 | .name = "L2CAP Socket Interface", | 1240 | .name = "L2CAP Socket Interface", |
1137 | .new_connection = l2cap_sock_new_connection_cb, | 1241 | .new_connection = l2cap_sock_new_connection_cb, |
@@ -1142,6 +1246,8 @@ static struct l2cap_ops l2cap_chan_ops = { | |||
1142 | .ready = l2cap_sock_ready_cb, | 1246 | .ready = l2cap_sock_ready_cb, |
1143 | .defer = l2cap_sock_defer_cb, | 1247 | .defer = l2cap_sock_defer_cb, |
1144 | .resume = l2cap_sock_resume_cb, | 1248 | .resume = l2cap_sock_resume_cb, |
1249 | .set_shutdown = l2cap_sock_set_shutdown_cb, | ||
1250 | .get_sndtimeo = l2cap_sock_get_sndtimeo_cb, | ||
1145 | .alloc_skb = l2cap_sock_alloc_skb_cb, | 1251 | .alloc_skb = l2cap_sock_alloc_skb_cb, |
1146 | }; | 1252 | }; |
1147 | 1253 | ||
@@ -1268,8 +1374,6 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, | |||
1268 | 1374 | ||
1269 | l2cap_chan_hold(chan); | 1375 | l2cap_chan_hold(chan); |
1270 | 1376 | ||
1271 | chan->sk = sk; | ||
1272 | |||
1273 | l2cap_pi(sk)->chan = chan; | 1377 | l2cap_pi(sk)->chan = chan; |
1274 | 1378 | ||
1275 | return sk; | 1379 | return sk; |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 861e389f4b4c..074d83690a41 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -536,6 +536,156 @@ static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) | |||
536 | return ptr; | 536 | return ptr; |
537 | } | 537 | } |
538 | 538 | ||
539 | static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev) | ||
540 | { | ||
541 | struct pending_cmd *cmd; | ||
542 | |||
543 | list_for_each_entry(cmd, &hdev->mgmt_pending, list) { | ||
544 | if (cmd->opcode == opcode) | ||
545 | return cmd; | ||
546 | } | ||
547 | |||
548 | return NULL; | ||
549 | } | ||
550 | |||
551 | static u8 create_scan_rsp_data(struct hci_dev *hdev, u8 *ptr) | ||
552 | { | ||
553 | u8 ad_len = 0; | ||
554 | size_t name_len; | ||
555 | |||
556 | name_len = strlen(hdev->dev_name); | ||
557 | if (name_len > 0) { | ||
558 | size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2; | ||
559 | |||
560 | if (name_len > max_len) { | ||
561 | name_len = max_len; | ||
562 | ptr[1] = EIR_NAME_SHORT; | ||
563 | } else | ||
564 | ptr[1] = EIR_NAME_COMPLETE; | ||
565 | |||
566 | ptr[0] = name_len + 1; | ||
567 | |||
568 | memcpy(ptr + 2, hdev->dev_name, name_len); | ||
569 | |||
570 | ad_len += (name_len + 2); | ||
571 | ptr += (name_len + 2); | ||
572 | } | ||
573 | |||
574 | return ad_len; | ||
575 | } | ||
576 | |||
577 | static void update_scan_rsp_data(struct hci_request *req) | ||
578 | { | ||
579 | struct hci_dev *hdev = req->hdev; | ||
580 | struct hci_cp_le_set_scan_rsp_data cp; | ||
581 | u8 len; | ||
582 | |||
583 | if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) | ||
584 | return; | ||
585 | |||
586 | memset(&cp, 0, sizeof(cp)); | ||
587 | |||
588 | len = create_scan_rsp_data(hdev, cp.data); | ||
589 | |||
590 | if (hdev->scan_rsp_data_len == len && | ||
591 | memcmp(cp.data, hdev->scan_rsp_data, len) == 0) | ||
592 | return; | ||
593 | |||
594 | memcpy(hdev->scan_rsp_data, cp.data, sizeof(cp.data)); | ||
595 | hdev->scan_rsp_data_len = len; | ||
596 | |||
597 | cp.length = len; | ||
598 | |||
599 | hci_req_add(req, HCI_OP_LE_SET_SCAN_RSP_DATA, sizeof(cp), &cp); | ||
600 | } | ||
601 | |||
602 | static u8 get_adv_discov_flags(struct hci_dev *hdev) | ||
603 | { | ||
604 | struct pending_cmd *cmd; | ||
605 | |||
606 | /* If there's a pending mgmt command the flags will not yet have | ||
607 | * their final values, so check for this first. | ||
608 | */ | ||
609 | cmd = mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev); | ||
610 | if (cmd) { | ||
611 | struct mgmt_mode *cp = cmd->param; | ||
612 | if (cp->val == 0x01) | ||
613 | return LE_AD_GENERAL; | ||
614 | else if (cp->val == 0x02) | ||
615 | return LE_AD_LIMITED; | ||
616 | } else { | ||
617 | if (test_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags)) | ||
618 | return LE_AD_LIMITED; | ||
619 | else if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) | ||
620 | return LE_AD_GENERAL; | ||
621 | } | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static u8 create_adv_data(struct hci_dev *hdev, u8 *ptr) | ||
627 | { | ||
628 | u8 ad_len = 0, flags = 0; | ||
629 | |||
630 | flags |= get_adv_discov_flags(hdev); | ||
631 | |||
632 | if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { | ||
633 | if (lmp_le_br_capable(hdev)) | ||
634 | flags |= LE_AD_SIM_LE_BREDR_CTRL; | ||
635 | if (lmp_host_le_br_capable(hdev)) | ||
636 | flags |= LE_AD_SIM_LE_BREDR_HOST; | ||
637 | } else { | ||
638 | flags |= LE_AD_NO_BREDR; | ||
639 | } | ||
640 | |||
641 | if (flags) { | ||
642 | BT_DBG("adv flags 0x%02x", flags); | ||
643 | |||
644 | ptr[0] = 2; | ||
645 | ptr[1] = EIR_FLAGS; | ||
646 | ptr[2] = flags; | ||
647 | |||
648 | ad_len += 3; | ||
649 | ptr += 3; | ||
650 | } | ||
651 | |||
652 | if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) { | ||
653 | ptr[0] = 2; | ||
654 | ptr[1] = EIR_TX_POWER; | ||
655 | ptr[2] = (u8) hdev->adv_tx_power; | ||
656 | |||
657 | ad_len += 3; | ||
658 | ptr += 3; | ||
659 | } | ||
660 | |||
661 | return ad_len; | ||
662 | } | ||
663 | |||
664 | static void update_adv_data(struct hci_request *req) | ||
665 | { | ||
666 | struct hci_dev *hdev = req->hdev; | ||
667 | struct hci_cp_le_set_adv_data cp; | ||
668 | u8 len; | ||
669 | |||
670 | if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) | ||
671 | return; | ||
672 | |||
673 | memset(&cp, 0, sizeof(cp)); | ||
674 | |||
675 | len = create_adv_data(hdev, cp.data); | ||
676 | |||
677 | if (hdev->adv_data_len == len && | ||
678 | memcmp(cp.data, hdev->adv_data, len) == 0) | ||
679 | return; | ||
680 | |||
681 | memcpy(hdev->adv_data, cp.data, sizeof(cp.data)); | ||
682 | hdev->adv_data_len = len; | ||
683 | |||
684 | cp.length = len; | ||
685 | |||
686 | hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp); | ||
687 | } | ||
688 | |||
539 | static void create_eir(struct hci_dev *hdev, u8 *data) | 689 | static void create_eir(struct hci_dev *hdev, u8 *data) |
540 | { | 690 | { |
541 | u8 *ptr = data; | 691 | u8 *ptr = data; |
@@ -634,6 +784,9 @@ static void update_class(struct hci_request *req) | |||
634 | if (!hdev_is_powered(hdev)) | 784 | if (!hdev_is_powered(hdev)) |
635 | return; | 785 | return; |
636 | 786 | ||
787 | if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) | ||
788 | return; | ||
789 | |||
637 | if (test_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) | 790 | if (test_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) |
638 | return; | 791 | return; |
639 | 792 | ||
@@ -641,6 +794,9 @@ static void update_class(struct hci_request *req) | |||
641 | cod[1] = hdev->major_class; | 794 | cod[1] = hdev->major_class; |
642 | cod[2] = get_service_classes(hdev); | 795 | cod[2] = get_service_classes(hdev); |
643 | 796 | ||
797 | if (test_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags)) | ||
798 | cod[1] |= 0x20; | ||
799 | |||
644 | if (memcmp(cod, hdev->dev_class, 3) == 0) | 800 | if (memcmp(cod, hdev->dev_class, 3) == 0) |
645 | return; | 801 | return; |
646 | 802 | ||
@@ -765,18 +921,6 @@ static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, | |||
765 | } | 921 | } |
766 | } | 922 | } |
767 | 923 | ||
768 | static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev) | ||
769 | { | ||
770 | struct pending_cmd *cmd; | ||
771 | |||
772 | list_for_each_entry(cmd, &hdev->mgmt_pending, list) { | ||
773 | if (cmd->opcode == opcode) | ||
774 | return cmd; | ||
775 | } | ||
776 | |||
777 | return NULL; | ||
778 | } | ||
779 | |||
780 | static void mgmt_pending_remove(struct pending_cmd *cmd) | 924 | static void mgmt_pending_remove(struct pending_cmd *cmd) |
781 | { | 925 | { |
782 | list_del(&cmd->list); | 926 | list_del(&cmd->list); |
@@ -939,6 +1083,7 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status) | |||
939 | { | 1083 | { |
940 | struct pending_cmd *cmd; | 1084 | struct pending_cmd *cmd; |
941 | struct mgmt_mode *cp; | 1085 | struct mgmt_mode *cp; |
1086 | struct hci_request req; | ||
942 | bool changed; | 1087 | bool changed; |
943 | 1088 | ||
944 | BT_DBG("status 0x%02x", status); | 1089 | BT_DBG("status 0x%02x", status); |
@@ -952,22 +1097,38 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status) | |||
952 | if (status) { | 1097 | if (status) { |
953 | u8 mgmt_err = mgmt_status(status); | 1098 | u8 mgmt_err = mgmt_status(status); |
954 | cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); | 1099 | cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); |
1100 | clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); | ||
955 | goto remove_cmd; | 1101 | goto remove_cmd; |
956 | } | 1102 | } |
957 | 1103 | ||
958 | cp = cmd->param; | 1104 | cp = cmd->param; |
959 | if (cp->val) | 1105 | if (cp->val) { |
960 | changed = !test_and_set_bit(HCI_DISCOVERABLE, | 1106 | changed = !test_and_set_bit(HCI_DISCOVERABLE, |
961 | &hdev->dev_flags); | 1107 | &hdev->dev_flags); |
962 | else | 1108 | |
1109 | if (hdev->discov_timeout > 0) { | ||
1110 | int to = msecs_to_jiffies(hdev->discov_timeout * 1000); | ||
1111 | queue_delayed_work(hdev->workqueue, &hdev->discov_off, | ||
1112 | to); | ||
1113 | } | ||
1114 | } else { | ||
963 | changed = test_and_clear_bit(HCI_DISCOVERABLE, | 1115 | changed = test_and_clear_bit(HCI_DISCOVERABLE, |
964 | &hdev->dev_flags); | 1116 | &hdev->dev_flags); |
1117 | } | ||
965 | 1118 | ||
966 | send_settings_rsp(cmd->sk, MGMT_OP_SET_DISCOVERABLE, hdev); | 1119 | send_settings_rsp(cmd->sk, MGMT_OP_SET_DISCOVERABLE, hdev); |
967 | 1120 | ||
968 | if (changed) | 1121 | if (changed) |
969 | new_settings(hdev, cmd->sk); | 1122 | new_settings(hdev, cmd->sk); |
970 | 1123 | ||
1124 | /* When the discoverable mode gets changed, make sure | ||
1125 | * that class of device has the limited discoverable | ||
1126 | * bit correctly set. | ||
1127 | */ | ||
1128 | hci_req_init(&req, hdev); | ||
1129 | update_class(&req); | ||
1130 | hci_req_run(&req, NULL); | ||
1131 | |||
971 | remove_cmd: | 1132 | remove_cmd: |
972 | mgmt_pending_remove(cmd); | 1133 | mgmt_pending_remove(cmd); |
973 | 1134 | ||
@@ -982,22 +1143,27 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, | |||
982 | struct pending_cmd *cmd; | 1143 | struct pending_cmd *cmd; |
983 | struct hci_request req; | 1144 | struct hci_request req; |
984 | u16 timeout; | 1145 | u16 timeout; |
985 | u8 scan, status; | 1146 | u8 scan; |
986 | int err; | 1147 | int err; |
987 | 1148 | ||
988 | BT_DBG("request for %s", hdev->name); | 1149 | BT_DBG("request for %s", hdev->name); |
989 | 1150 | ||
990 | status = mgmt_bredr_support(hdev); | 1151 | if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags) && |
991 | if (status) | 1152 | !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) |
992 | return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, | 1153 | return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, |
993 | status); | 1154 | MGMT_STATUS_REJECTED); |
994 | 1155 | ||
995 | if (cp->val != 0x00 && cp->val != 0x01) | 1156 | if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02) |
996 | return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, | 1157 | return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, |
997 | MGMT_STATUS_INVALID_PARAMS); | 1158 | MGMT_STATUS_INVALID_PARAMS); |
998 | 1159 | ||
999 | timeout = __le16_to_cpu(cp->timeout); | 1160 | timeout = __le16_to_cpu(cp->timeout); |
1000 | if (!cp->val && timeout > 0) | 1161 | |
1162 | /* Disabling discoverable requires that no timeout is set, | ||
1163 | * and enabling limited discoverable requires a timeout. | ||
1164 | */ | ||
1165 | if ((cp->val == 0x00 && timeout > 0) || | ||
1166 | (cp->val == 0x02 && timeout == 0)) | ||
1001 | return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, | 1167 | return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, |
1002 | MGMT_STATUS_INVALID_PARAMS); | 1168 | MGMT_STATUS_INVALID_PARAMS); |
1003 | 1169 | ||
@@ -1025,6 +1191,10 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1025 | if (!hdev_is_powered(hdev)) { | 1191 | if (!hdev_is_powered(hdev)) { |
1026 | bool changed = false; | 1192 | bool changed = false; |
1027 | 1193 | ||
1194 | /* Setting limited discoverable when powered off is | ||
1195 | * not a valid operation since it requires a timeout | ||
1196 | * and so no need to check HCI_LIMITED_DISCOVERABLE. | ||
1197 | */ | ||
1028 | if (!!cp->val != test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) { | 1198 | if (!!cp->val != test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) { |
1029 | change_bit(HCI_DISCOVERABLE, &hdev->dev_flags); | 1199 | change_bit(HCI_DISCOVERABLE, &hdev->dev_flags); |
1030 | changed = true; | 1200 | changed = true; |
@@ -1040,16 +1210,20 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1040 | goto failed; | 1210 | goto failed; |
1041 | } | 1211 | } |
1042 | 1212 | ||
1043 | if (!!cp->val == test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) { | 1213 | /* If the current mode is the same, then just update the timeout |
1044 | if (hdev->discov_timeout > 0) { | 1214 | * value with the new value. And if only the timeout gets updated, |
1045 | cancel_delayed_work(&hdev->discov_off); | 1215 | * then no need for any HCI transactions. |
1046 | hdev->discov_timeout = 0; | 1216 | */ |
1047 | } | 1217 | if (!!cp->val == test_bit(HCI_DISCOVERABLE, &hdev->dev_flags) && |
1218 | (cp->val == 0x02) == test_bit(HCI_LIMITED_DISCOVERABLE, | ||
1219 | &hdev->dev_flags)) { | ||
1220 | cancel_delayed_work(&hdev->discov_off); | ||
1221 | hdev->discov_timeout = timeout; | ||
1048 | 1222 | ||
1049 | if (cp->val && timeout > 0) { | 1223 | if (cp->val && hdev->discov_timeout > 0) { |
1050 | hdev->discov_timeout = timeout; | 1224 | int to = msecs_to_jiffies(hdev->discov_timeout * 1000); |
1051 | queue_delayed_work(hdev->workqueue, &hdev->discov_off, | 1225 | queue_delayed_work(hdev->workqueue, &hdev->discov_off, |
1052 | msecs_to_jiffies(hdev->discov_timeout * 1000)); | 1226 | to); |
1053 | } | 1227 | } |
1054 | 1228 | ||
1055 | err = send_settings_rsp(sk, MGMT_OP_SET_DISCOVERABLE, hdev); | 1229 | err = send_settings_rsp(sk, MGMT_OP_SET_DISCOVERABLE, hdev); |
@@ -1062,24 +1236,66 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1062 | goto failed; | 1236 | goto failed; |
1063 | } | 1237 | } |
1064 | 1238 | ||
1239 | /* Cancel any potential discoverable timeout that might be | ||
1240 | * still active and store new timeout value. The arming of | ||
1241 | * the timeout happens in the complete handler. | ||
1242 | */ | ||
1243 | cancel_delayed_work(&hdev->discov_off); | ||
1244 | hdev->discov_timeout = timeout; | ||
1245 | |||
1246 | /* Limited discoverable mode */ | ||
1247 | if (cp->val == 0x02) | ||
1248 | set_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); | ||
1249 | else | ||
1250 | clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); | ||
1251 | |||
1065 | hci_req_init(&req, hdev); | 1252 | hci_req_init(&req, hdev); |
1066 | 1253 | ||
1254 | /* The procedure for LE-only controllers is much simpler - just | ||
1255 | * update the advertising data. | ||
1256 | */ | ||
1257 | if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) | ||
1258 | goto update_ad; | ||
1259 | |||
1067 | scan = SCAN_PAGE; | 1260 | scan = SCAN_PAGE; |
1068 | 1261 | ||
1069 | if (cp->val) | 1262 | if (cp->val) { |
1263 | struct hci_cp_write_current_iac_lap hci_cp; | ||
1264 | |||
1265 | if (cp->val == 0x02) { | ||
1266 | /* Limited discoverable mode */ | ||
1267 | hci_cp.num_iac = 2; | ||
1268 | hci_cp.iac_lap[0] = 0x00; /* LIAC */ | ||
1269 | hci_cp.iac_lap[1] = 0x8b; | ||
1270 | hci_cp.iac_lap[2] = 0x9e; | ||
1271 | hci_cp.iac_lap[3] = 0x33; /* GIAC */ | ||
1272 | hci_cp.iac_lap[4] = 0x8b; | ||
1273 | hci_cp.iac_lap[5] = 0x9e; | ||
1274 | } else { | ||
1275 | /* General discoverable mode */ | ||
1276 | hci_cp.num_iac = 1; | ||
1277 | hci_cp.iac_lap[0] = 0x33; /* GIAC */ | ||
1278 | hci_cp.iac_lap[1] = 0x8b; | ||
1279 | hci_cp.iac_lap[2] = 0x9e; | ||
1280 | } | ||
1281 | |||
1282 | hci_req_add(&req, HCI_OP_WRITE_CURRENT_IAC_LAP, | ||
1283 | (hci_cp.num_iac * 3) + 1, &hci_cp); | ||
1284 | |||
1070 | scan |= SCAN_INQUIRY; | 1285 | scan |= SCAN_INQUIRY; |
1071 | else | 1286 | } else { |
1072 | cancel_delayed_work(&hdev->discov_off); | 1287 | clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); |
1288 | } | ||
1073 | 1289 | ||
1074 | hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | 1290 | hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); |
1291 | |||
1292 | update_ad: | ||
1293 | update_adv_data(&req); | ||
1075 | 1294 | ||
1076 | err = hci_req_run(&req, set_discoverable_complete); | 1295 | err = hci_req_run(&req, set_discoverable_complete); |
1077 | if (err < 0) | 1296 | if (err < 0) |
1078 | mgmt_pending_remove(cmd); | 1297 | mgmt_pending_remove(cmd); |
1079 | 1298 | ||
1080 | if (cp->val) | ||
1081 | hdev->discov_timeout = timeout; | ||
1082 | |||
1083 | failed: | 1299 | failed: |
1084 | hci_dev_unlock(hdev); | 1300 | hci_dev_unlock(hdev); |
1085 | return err; | 1301 | return err; |
@@ -1091,6 +1307,9 @@ static void write_fast_connectable(struct hci_request *req, bool enable) | |||
1091 | struct hci_cp_write_page_scan_activity acp; | 1307 | struct hci_cp_write_page_scan_activity acp; |
1092 | u8 type; | 1308 | u8 type; |
1093 | 1309 | ||
1310 | if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) | ||
1311 | return; | ||
1312 | |||
1094 | if (hdev->hci_ver < BLUETOOTH_VER_1_2) | 1313 | if (hdev->hci_ver < BLUETOOTH_VER_1_2) |
1095 | return; | 1314 | return; |
1096 | 1315 | ||
@@ -1146,10 +1365,7 @@ static void enable_advertising(struct hci_request *req) | |||
1146 | cp.min_interval = __constant_cpu_to_le16(0x0800); | 1365 | cp.min_interval = __constant_cpu_to_le16(0x0800); |
1147 | cp.max_interval = __constant_cpu_to_le16(0x0800); | 1366 | cp.max_interval = __constant_cpu_to_le16(0x0800); |
1148 | cp.type = get_adv_type(hdev); | 1367 | cp.type = get_adv_type(hdev); |
1149 | if (bacmp(&hdev->bdaddr, BDADDR_ANY)) | 1368 | cp.own_address_type = hdev->own_addr_type; |
1150 | cp.own_address_type = ADDR_LE_DEV_PUBLIC; | ||
1151 | else | ||
1152 | cp.own_address_type = ADDR_LE_DEV_RANDOM; | ||
1153 | cp.channel_map = 0x07; | 1369 | cp.channel_map = 0x07; |
1154 | 1370 | ||
1155 | hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp); | 1371 | hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp); |
@@ -1202,6 +1418,32 @@ unlock: | |||
1202 | hci_dev_unlock(hdev); | 1418 | hci_dev_unlock(hdev); |
1203 | } | 1419 | } |
1204 | 1420 | ||
1421 | static int set_connectable_update_settings(struct hci_dev *hdev, | ||
1422 | struct sock *sk, u8 val) | ||
1423 | { | ||
1424 | bool changed = false; | ||
1425 | int err; | ||
1426 | |||
1427 | if (!!val != test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) | ||
1428 | changed = true; | ||
1429 | |||
1430 | if (val) { | ||
1431 | set_bit(HCI_CONNECTABLE, &hdev->dev_flags); | ||
1432 | } else { | ||
1433 | clear_bit(HCI_CONNECTABLE, &hdev->dev_flags); | ||
1434 | clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); | ||
1435 | } | ||
1436 | |||
1437 | err = send_settings_rsp(sk, MGMT_OP_SET_CONNECTABLE, hdev); | ||
1438 | if (err < 0) | ||
1439 | return err; | ||
1440 | |||
1441 | if (changed) | ||
1442 | return new_settings(hdev, sk); | ||
1443 | |||
1444 | return 0; | ||
1445 | } | ||
1446 | |||
1205 | static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, | 1447 | static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, |
1206 | u16 len) | 1448 | u16 len) |
1207 | { | 1449 | { |
@@ -1225,25 +1467,7 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1225 | hci_dev_lock(hdev); | 1467 | hci_dev_lock(hdev); |
1226 | 1468 | ||
1227 | if (!hdev_is_powered(hdev)) { | 1469 | if (!hdev_is_powered(hdev)) { |
1228 | bool changed = false; | 1470 | err = set_connectable_update_settings(hdev, sk, cp->val); |
1229 | |||
1230 | if (!!cp->val != test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) | ||
1231 | changed = true; | ||
1232 | |||
1233 | if (cp->val) { | ||
1234 | set_bit(HCI_CONNECTABLE, &hdev->dev_flags); | ||
1235 | } else { | ||
1236 | clear_bit(HCI_CONNECTABLE, &hdev->dev_flags); | ||
1237 | clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); | ||
1238 | } | ||
1239 | |||
1240 | err = send_settings_rsp(sk, MGMT_OP_SET_CONNECTABLE, hdev); | ||
1241 | if (err < 0) | ||
1242 | goto failed; | ||
1243 | |||
1244 | if (changed) | ||
1245 | err = new_settings(hdev, sk); | ||
1246 | |||
1247 | goto failed; | 1471 | goto failed; |
1248 | } | 1472 | } |
1249 | 1473 | ||
@@ -1262,16 +1486,24 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1262 | 1486 | ||
1263 | hci_req_init(&req, hdev); | 1487 | hci_req_init(&req, hdev); |
1264 | 1488 | ||
1265 | if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) && | 1489 | /* If BR/EDR is not enabled and we disable advertising as a |
1266 | cp->val != test_bit(HCI_PSCAN, &hdev->flags)) { | 1490 | * by-product of disabling connectable, we need to update the |
1267 | 1491 | * advertising flags. | |
1492 | */ | ||
1493 | if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { | ||
1494 | if (!cp->val) { | ||
1495 | clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); | ||
1496 | clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); | ||
1497 | } | ||
1498 | update_adv_data(&req); | ||
1499 | } else if (cp->val != test_bit(HCI_PSCAN, &hdev->flags)) { | ||
1268 | if (cp->val) { | 1500 | if (cp->val) { |
1269 | scan = SCAN_PAGE; | 1501 | scan = SCAN_PAGE; |
1270 | } else { | 1502 | } else { |
1271 | scan = 0; | 1503 | scan = 0; |
1272 | 1504 | ||
1273 | if (test_bit(HCI_ISCAN, &hdev->flags) && | 1505 | if (test_bit(HCI_ISCAN, &hdev->flags) && |
1274 | hdev->discov_timeout > 0) | 1506 | hdev->discov_timeout > 0) |
1275 | cancel_delayed_work(&hdev->discov_off); | 1507 | cancel_delayed_work(&hdev->discov_off); |
1276 | } | 1508 | } |
1277 | 1509 | ||
@@ -1297,8 +1529,8 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1297 | if (err < 0) { | 1529 | if (err < 0) { |
1298 | mgmt_pending_remove(cmd); | 1530 | mgmt_pending_remove(cmd); |
1299 | if (err == -ENODATA) | 1531 | if (err == -ENODATA) |
1300 | err = send_settings_rsp(sk, MGMT_OP_SET_CONNECTABLE, | 1532 | err = set_connectable_update_settings(hdev, sk, |
1301 | hdev); | 1533 | cp->val); |
1302 | goto failed; | 1534 | goto failed; |
1303 | } | 1535 | } |
1304 | 1536 | ||
@@ -1556,6 +1788,24 @@ static void le_enable_complete(struct hci_dev *hdev, u8 status) | |||
1556 | 1788 | ||
1557 | if (match.sk) | 1789 | if (match.sk) |
1558 | sock_put(match.sk); | 1790 | sock_put(match.sk); |
1791 | |||
1792 | /* Make sure the controller has a good default for | ||
1793 | * advertising data. Restrict the update to when LE | ||
1794 | * has actually been enabled. During power on, the | ||
1795 | * update in powered_update_hci will take care of it. | ||
1796 | */ | ||
1797 | if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { | ||
1798 | struct hci_request req; | ||
1799 | |||
1800 | hci_dev_lock(hdev); | ||
1801 | |||
1802 | hci_req_init(&req, hdev); | ||
1803 | update_adv_data(&req); | ||
1804 | update_scan_rsp_data(&req); | ||
1805 | hci_req_run(&req, NULL); | ||
1806 | |||
1807 | hci_dev_unlock(hdev); | ||
1808 | } | ||
1559 | } | 1809 | } |
1560 | 1810 | ||
1561 | static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | 1811 | static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) |
@@ -1623,18 +1873,18 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | |||
1623 | goto unlock; | 1873 | goto unlock; |
1624 | } | 1874 | } |
1625 | 1875 | ||
1876 | hci_req_init(&req, hdev); | ||
1877 | |||
1626 | memset(&hci_cp, 0, sizeof(hci_cp)); | 1878 | memset(&hci_cp, 0, sizeof(hci_cp)); |
1627 | 1879 | ||
1628 | if (val) { | 1880 | if (val) { |
1629 | hci_cp.le = val; | 1881 | hci_cp.le = val; |
1630 | hci_cp.simul = lmp_le_br_capable(hdev); | 1882 | hci_cp.simul = lmp_le_br_capable(hdev); |
1883 | } else { | ||
1884 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) | ||
1885 | disable_advertising(&req); | ||
1631 | } | 1886 | } |
1632 | 1887 | ||
1633 | hci_req_init(&req, hdev); | ||
1634 | |||
1635 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) && !val) | ||
1636 | disable_advertising(&req); | ||
1637 | |||
1638 | hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp), | 1888 | hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp), |
1639 | &hci_cp); | 1889 | &hci_cp); |
1640 | 1890 | ||
@@ -2772,8 +3022,11 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2772 | update_eir(&req); | 3022 | update_eir(&req); |
2773 | } | 3023 | } |
2774 | 3024 | ||
3025 | /* The name is stored in the scan response data and so | ||
3026 | * no need to udpate the advertising data here. | ||
3027 | */ | ||
2775 | if (lmp_le_capable(hdev)) | 3028 | if (lmp_le_capable(hdev)) |
2776 | hci_update_ad(&req); | 3029 | update_scan_rsp_data(&req); |
2777 | 3030 | ||
2778 | err = hci_req_run(&req, set_name_complete); | 3031 | err = hci_req_run(&req, set_name_complete); |
2779 | if (err < 0) | 3032 | if (err < 0) |
@@ -3038,10 +3291,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
3038 | param_cp.type = LE_SCAN_ACTIVE; | 3291 | param_cp.type = LE_SCAN_ACTIVE; |
3039 | param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT); | 3292 | param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT); |
3040 | param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN); | 3293 | param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN); |
3041 | if (bacmp(&hdev->bdaddr, BDADDR_ANY)) | 3294 | param_cp.own_address_type = hdev->own_addr_type; |
3042 | param_cp.own_address_type = ADDR_LE_DEV_PUBLIC; | ||
3043 | else | ||
3044 | param_cp.own_address_type = ADDR_LE_DEV_RANDOM; | ||
3045 | hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), | 3295 | hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), |
3046 | ¶m_cp); | 3296 | ¶m_cp); |
3047 | 3297 | ||
@@ -3725,7 +3975,7 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | |||
3725 | goto unlock; | 3975 | goto unlock; |
3726 | } | 3976 | } |
3727 | 3977 | ||
3728 | /* We need to flip the bit already here so that hci_update_ad | 3978 | /* We need to flip the bit already here so that update_adv_data |
3729 | * generates the correct flags. | 3979 | * generates the correct flags. |
3730 | */ | 3980 | */ |
3731 | set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); | 3981 | set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags); |
@@ -3735,7 +3985,10 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | |||
3735 | if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) | 3985 | if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) |
3736 | set_bredr_scan(&req); | 3986 | set_bredr_scan(&req); |
3737 | 3987 | ||
3738 | hci_update_ad(&req); | 3988 | /* Since only the advertising data flags will change, there |
3989 | * is no need to update the scan response data. | ||
3990 | */ | ||
3991 | update_adv_data(&req); | ||
3739 | 3992 | ||
3740 | err = hci_req_run(&req, set_bredr_complete); | 3993 | err = hci_req_run(&req, set_bredr_complete); |
3741 | if (err < 0) | 3994 | if (err < 0) |
@@ -4036,9 +4289,6 @@ static int powered_update_hci(struct hci_dev *hdev) | |||
4036 | cp.simul != lmp_host_le_br_capable(hdev)) | 4289 | cp.simul != lmp_host_le_br_capable(hdev)) |
4037 | hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, | 4290 | hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, |
4038 | sizeof(cp), &cp); | 4291 | sizeof(cp), &cp); |
4039 | |||
4040 | /* In case BR/EDR was toggled during the AUTO_OFF phase */ | ||
4041 | hci_update_ad(&req); | ||
4042 | } | 4292 | } |
4043 | 4293 | ||
4044 | if (lmp_le_capable(hdev)) { | 4294 | if (lmp_le_capable(hdev)) { |
@@ -4047,6 +4297,15 @@ static int powered_update_hci(struct hci_dev *hdev) | |||
4047 | hci_req_add(&req, HCI_OP_LE_SET_RANDOM_ADDR, 6, | 4297 | hci_req_add(&req, HCI_OP_LE_SET_RANDOM_ADDR, 6, |
4048 | &hdev->static_addr); | 4298 | &hdev->static_addr); |
4049 | 4299 | ||
4300 | /* Make sure the controller has a good default for | ||
4301 | * advertising data. This also applies to the case | ||
4302 | * where BR/EDR was toggled during the AUTO_OFF phase. | ||
4303 | */ | ||
4304 | if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { | ||
4305 | update_adv_data(&req); | ||
4306 | update_scan_rsp_data(&req); | ||
4307 | } | ||
4308 | |||
4050 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) | 4309 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) |
4051 | enable_advertising(&req); | 4310 | enable_advertising(&req); |
4052 | } | 4311 | } |
@@ -4121,59 +4380,91 @@ void mgmt_set_powered_failed(struct hci_dev *hdev, int err) | |||
4121 | mgmt_pending_remove(cmd); | 4380 | mgmt_pending_remove(cmd); |
4122 | } | 4381 | } |
4123 | 4382 | ||
4124 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) | 4383 | void mgmt_discoverable_timeout(struct hci_dev *hdev) |
4125 | { | 4384 | { |
4126 | bool changed = false; | 4385 | struct hci_request req; |
4127 | int err = 0; | 4386 | |
4387 | hci_dev_lock(hdev); | ||
4388 | |||
4389 | /* When discoverable timeout triggers, then just make sure | ||
4390 | * the limited discoverable flag is cleared. Even in the case | ||
4391 | * of a timeout triggered from general discoverable, it is | ||
4392 | * safe to unconditionally clear the flag. | ||
4393 | */ | ||
4394 | clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); | ||
4395 | clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); | ||
4396 | |||
4397 | hci_req_init(&req, hdev); | ||
4398 | if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { | ||
4399 | u8 scan = SCAN_PAGE; | ||
4400 | hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, | ||
4401 | sizeof(scan), &scan); | ||
4402 | } | ||
4403 | update_class(&req); | ||
4404 | update_adv_data(&req); | ||
4405 | hci_req_run(&req, NULL); | ||
4406 | |||
4407 | hdev->discov_timeout = 0; | ||
4408 | |||
4409 | new_settings(hdev, NULL); | ||
4410 | |||
4411 | hci_dev_unlock(hdev); | ||
4412 | } | ||
4413 | |||
4414 | void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) | ||
4415 | { | ||
4416 | bool changed; | ||
4128 | 4417 | ||
4129 | /* Nothing needed here if there's a pending command since that | 4418 | /* Nothing needed here if there's a pending command since that |
4130 | * commands request completion callback takes care of everything | 4419 | * commands request completion callback takes care of everything |
4131 | * necessary. | 4420 | * necessary. |
4132 | */ | 4421 | */ |
4133 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev)) | 4422 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev)) |
4134 | return 0; | 4423 | return; |
4135 | 4424 | ||
4136 | if (discoverable) { | 4425 | if (discoverable) { |
4137 | if (!test_and_set_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) | 4426 | changed = !test_and_set_bit(HCI_DISCOVERABLE, &hdev->dev_flags); |
4138 | changed = true; | ||
4139 | } else { | 4427 | } else { |
4140 | if (test_and_clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) | 4428 | clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags); |
4141 | changed = true; | 4429 | changed = test_and_clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags); |
4142 | } | 4430 | } |
4143 | 4431 | ||
4144 | if (changed) | 4432 | if (changed) { |
4145 | err = new_settings(hdev, NULL); | 4433 | struct hci_request req; |
4146 | 4434 | ||
4147 | return err; | 4435 | /* In case this change in discoverable was triggered by |
4436 | * a disabling of connectable there could be a need to | ||
4437 | * update the advertising flags. | ||
4438 | */ | ||
4439 | hci_req_init(&req, hdev); | ||
4440 | update_adv_data(&req); | ||
4441 | hci_req_run(&req, NULL); | ||
4442 | |||
4443 | new_settings(hdev, NULL); | ||
4444 | } | ||
4148 | } | 4445 | } |
4149 | 4446 | ||
4150 | int mgmt_connectable(struct hci_dev *hdev, u8 connectable) | 4447 | void mgmt_connectable(struct hci_dev *hdev, u8 connectable) |
4151 | { | 4448 | { |
4152 | bool changed = false; | 4449 | bool changed; |
4153 | int err = 0; | ||
4154 | 4450 | ||
4155 | /* Nothing needed here if there's a pending command since that | 4451 | /* Nothing needed here if there's a pending command since that |
4156 | * commands request completion callback takes care of everything | 4452 | * commands request completion callback takes care of everything |
4157 | * necessary. | 4453 | * necessary. |
4158 | */ | 4454 | */ |
4159 | if (mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) | 4455 | if (mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) |
4160 | return 0; | 4456 | return; |
4161 | 4457 | ||
4162 | if (connectable) { | 4458 | if (connectable) |
4163 | if (!test_and_set_bit(HCI_CONNECTABLE, &hdev->dev_flags)) | 4459 | changed = !test_and_set_bit(HCI_CONNECTABLE, &hdev->dev_flags); |
4164 | changed = true; | 4460 | else |
4165 | } else { | 4461 | changed = test_and_clear_bit(HCI_CONNECTABLE, &hdev->dev_flags); |
4166 | if (test_and_clear_bit(HCI_CONNECTABLE, &hdev->dev_flags)) | ||
4167 | changed = true; | ||
4168 | } | ||
4169 | 4462 | ||
4170 | if (changed) | 4463 | if (changed) |
4171 | err = new_settings(hdev, NULL); | 4464 | new_settings(hdev, NULL); |
4172 | |||
4173 | return err; | ||
4174 | } | 4465 | } |
4175 | 4466 | ||
4176 | int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status) | 4467 | void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status) |
4177 | { | 4468 | { |
4178 | u8 mgmt_err = mgmt_status(status); | 4469 | u8 mgmt_err = mgmt_status(status); |
4179 | 4470 | ||
@@ -4184,12 +4475,10 @@ int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status) | |||
4184 | if (scan & SCAN_INQUIRY) | 4475 | if (scan & SCAN_INQUIRY) |
4185 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, | 4476 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, |
4186 | cmd_status_rsp, &mgmt_err); | 4477 | cmd_status_rsp, &mgmt_err); |
4187 | |||
4188 | return 0; | ||
4189 | } | 4478 | } |
4190 | 4479 | ||
4191 | int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, | 4480 | void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, |
4192 | bool persistent) | 4481 | bool persistent) |
4193 | { | 4482 | { |
4194 | struct mgmt_ev_new_link_key ev; | 4483 | struct mgmt_ev_new_link_key ev; |
4195 | 4484 | ||
@@ -4202,10 +4491,10 @@ int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, | |||
4202 | memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE); | 4491 | memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE); |
4203 | ev.key.pin_len = key->pin_len; | 4492 | ev.key.pin_len = key->pin_len; |
4204 | 4493 | ||
4205 | return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); | 4494 | mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); |
4206 | } | 4495 | } |
4207 | 4496 | ||
4208 | int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent) | 4497 | void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent) |
4209 | { | 4498 | { |
4210 | struct mgmt_ev_new_long_term_key ev; | 4499 | struct mgmt_ev_new_long_term_key ev; |
4211 | 4500 | ||
@@ -4224,8 +4513,18 @@ int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent) | |||
4224 | memcpy(ev.key.rand, key->rand, sizeof(key->rand)); | 4513 | memcpy(ev.key.rand, key->rand, sizeof(key->rand)); |
4225 | memcpy(ev.key.val, key->val, sizeof(key->val)); | 4514 | memcpy(ev.key.val, key->val, sizeof(key->val)); |
4226 | 4515 | ||
4227 | return mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev, &ev, sizeof(ev), | 4516 | mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev, &ev, sizeof(ev), NULL); |
4228 | NULL); | 4517 | } |
4518 | |||
4519 | static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, | ||
4520 | u8 data_len) | ||
4521 | { | ||
4522 | eir[eir_len++] = sizeof(type) + data_len; | ||
4523 | eir[eir_len++] = type; | ||
4524 | memcpy(&eir[eir_len], data, data_len); | ||
4525 | eir_len += data_len; | ||
4526 | |||
4527 | return eir_len; | ||
4229 | } | 4528 | } |
4230 | 4529 | ||
4231 | void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 4530 | void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, |
@@ -4345,7 +4644,7 @@ void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
4345 | mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL); | 4644 | mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL); |
4346 | } | 4645 | } |
4347 | 4646 | ||
4348 | int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure) | 4647 | void mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure) |
4349 | { | 4648 | { |
4350 | struct mgmt_ev_pin_code_request ev; | 4649 | struct mgmt_ev_pin_code_request ev; |
4351 | 4650 | ||
@@ -4353,52 +4652,45 @@ int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure) | |||
4353 | ev.addr.type = BDADDR_BREDR; | 4652 | ev.addr.type = BDADDR_BREDR; |
4354 | ev.secure = secure; | 4653 | ev.secure = secure; |
4355 | 4654 | ||
4356 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, hdev, &ev, sizeof(ev), | 4655 | mgmt_event(MGMT_EV_PIN_CODE_REQUEST, hdev, &ev, sizeof(ev), NULL); |
4357 | NULL); | ||
4358 | } | 4656 | } |
4359 | 4657 | ||
4360 | int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | 4658 | void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
4361 | u8 status) | 4659 | u8 status) |
4362 | { | 4660 | { |
4363 | struct pending_cmd *cmd; | 4661 | struct pending_cmd *cmd; |
4364 | struct mgmt_rp_pin_code_reply rp; | 4662 | struct mgmt_rp_pin_code_reply rp; |
4365 | int err; | ||
4366 | 4663 | ||
4367 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev); | 4664 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev); |
4368 | if (!cmd) | 4665 | if (!cmd) |
4369 | return -ENOENT; | 4666 | return; |
4370 | 4667 | ||
4371 | bacpy(&rp.addr.bdaddr, bdaddr); | 4668 | bacpy(&rp.addr.bdaddr, bdaddr); |
4372 | rp.addr.type = BDADDR_BREDR; | 4669 | rp.addr.type = BDADDR_BREDR; |
4373 | 4670 | ||
4374 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, | 4671 | cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, |
4375 | mgmt_status(status), &rp, sizeof(rp)); | 4672 | mgmt_status(status), &rp, sizeof(rp)); |
4376 | 4673 | ||
4377 | mgmt_pending_remove(cmd); | 4674 | mgmt_pending_remove(cmd); |
4378 | |||
4379 | return err; | ||
4380 | } | 4675 | } |
4381 | 4676 | ||
4382 | int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | 4677 | void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
4383 | u8 status) | 4678 | u8 status) |
4384 | { | 4679 | { |
4385 | struct pending_cmd *cmd; | 4680 | struct pending_cmd *cmd; |
4386 | struct mgmt_rp_pin_code_reply rp; | 4681 | struct mgmt_rp_pin_code_reply rp; |
4387 | int err; | ||
4388 | 4682 | ||
4389 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev); | 4683 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev); |
4390 | if (!cmd) | 4684 | if (!cmd) |
4391 | return -ENOENT; | 4685 | return; |
4392 | 4686 | ||
4393 | bacpy(&rp.addr.bdaddr, bdaddr); | 4687 | bacpy(&rp.addr.bdaddr, bdaddr); |
4394 | rp.addr.type = BDADDR_BREDR; | 4688 | rp.addr.type = BDADDR_BREDR; |
4395 | 4689 | ||
4396 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, | 4690 | cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, |
4397 | mgmt_status(status), &rp, sizeof(rp)); | 4691 | mgmt_status(status), &rp, sizeof(rp)); |
4398 | 4692 | ||
4399 | mgmt_pending_remove(cmd); | 4693 | mgmt_pending_remove(cmd); |
4400 | |||
4401 | return err; | ||
4402 | } | 4694 | } |
4403 | 4695 | ||
4404 | int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, | 4696 | int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, |
@@ -4500,8 +4792,8 @@ int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
4500 | return mgmt_event(MGMT_EV_PASSKEY_NOTIFY, hdev, &ev, sizeof(ev), NULL); | 4792 | return mgmt_event(MGMT_EV_PASSKEY_NOTIFY, hdev, &ev, sizeof(ev), NULL); |
4501 | } | 4793 | } |
4502 | 4794 | ||
4503 | int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 4795 | void mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, |
4504 | u8 addr_type, u8 status) | 4796 | u8 addr_type, u8 status) |
4505 | { | 4797 | { |
4506 | struct mgmt_ev_auth_failed ev; | 4798 | struct mgmt_ev_auth_failed ev; |
4507 | 4799 | ||
@@ -4509,40 +4801,36 @@ int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
4509 | ev.addr.type = link_to_bdaddr(link_type, addr_type); | 4801 | ev.addr.type = link_to_bdaddr(link_type, addr_type); |
4510 | ev.status = mgmt_status(status); | 4802 | ev.status = mgmt_status(status); |
4511 | 4803 | ||
4512 | return mgmt_event(MGMT_EV_AUTH_FAILED, hdev, &ev, sizeof(ev), NULL); | 4804 | mgmt_event(MGMT_EV_AUTH_FAILED, hdev, &ev, sizeof(ev), NULL); |
4513 | } | 4805 | } |
4514 | 4806 | ||
4515 | int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) | 4807 | void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) |
4516 | { | 4808 | { |
4517 | struct cmd_lookup match = { NULL, hdev }; | 4809 | struct cmd_lookup match = { NULL, hdev }; |
4518 | bool changed = false; | 4810 | bool changed; |
4519 | int err = 0; | ||
4520 | 4811 | ||
4521 | if (status) { | 4812 | if (status) { |
4522 | u8 mgmt_err = mgmt_status(status); | 4813 | u8 mgmt_err = mgmt_status(status); |
4523 | mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, | 4814 | mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, |
4524 | cmd_status_rsp, &mgmt_err); | 4815 | cmd_status_rsp, &mgmt_err); |
4525 | return 0; | 4816 | return; |
4526 | } | 4817 | } |
4527 | 4818 | ||
4528 | if (test_bit(HCI_AUTH, &hdev->flags)) { | 4819 | if (test_bit(HCI_AUTH, &hdev->flags)) |
4529 | if (!test_and_set_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) | 4820 | changed = !test_and_set_bit(HCI_LINK_SECURITY, |
4530 | changed = true; | 4821 | &hdev->dev_flags); |
4531 | } else { | 4822 | else |
4532 | if (test_and_clear_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) | 4823 | changed = test_and_clear_bit(HCI_LINK_SECURITY, |
4533 | changed = true; | 4824 | &hdev->dev_flags); |
4534 | } | ||
4535 | 4825 | ||
4536 | mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp, | 4826 | mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp, |
4537 | &match); | 4827 | &match); |
4538 | 4828 | ||
4539 | if (changed) | 4829 | if (changed) |
4540 | err = new_settings(hdev, match.sk); | 4830 | new_settings(hdev, match.sk); |
4541 | 4831 | ||
4542 | if (match.sk) | 4832 | if (match.sk) |
4543 | sock_put(match.sk); | 4833 | sock_put(match.sk); |
4544 | |||
4545 | return err; | ||
4546 | } | 4834 | } |
4547 | 4835 | ||
4548 | static void clear_eir(struct hci_request *req) | 4836 | static void clear_eir(struct hci_request *req) |
@@ -4560,12 +4848,11 @@ static void clear_eir(struct hci_request *req) | |||
4560 | hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); | 4848 | hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp); |
4561 | } | 4849 | } |
4562 | 4850 | ||
4563 | int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status) | 4851 | void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status) |
4564 | { | 4852 | { |
4565 | struct cmd_lookup match = { NULL, hdev }; | 4853 | struct cmd_lookup match = { NULL, hdev }; |
4566 | struct hci_request req; | 4854 | struct hci_request req; |
4567 | bool changed = false; | 4855 | bool changed = false; |
4568 | int err = 0; | ||
4569 | 4856 | ||
4570 | if (status) { | 4857 | if (status) { |
4571 | u8 mgmt_err = mgmt_status(status); | 4858 | u8 mgmt_err = mgmt_status(status); |
@@ -4573,13 +4860,12 @@ int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status) | |||
4573 | if (enable && test_and_clear_bit(HCI_SSP_ENABLED, | 4860 | if (enable && test_and_clear_bit(HCI_SSP_ENABLED, |
4574 | &hdev->dev_flags)) { | 4861 | &hdev->dev_flags)) { |
4575 | clear_bit(HCI_HS_ENABLED, &hdev->dev_flags); | 4862 | clear_bit(HCI_HS_ENABLED, &hdev->dev_flags); |
4576 | err = new_settings(hdev, NULL); | 4863 | new_settings(hdev, NULL); |
4577 | } | 4864 | } |
4578 | 4865 | ||
4579 | mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp, | 4866 | mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp, |
4580 | &mgmt_err); | 4867 | &mgmt_err); |
4581 | 4868 | return; | |
4582 | return err; | ||
4583 | } | 4869 | } |
4584 | 4870 | ||
4585 | if (enable) { | 4871 | if (enable) { |
@@ -4596,7 +4882,7 @@ int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status) | |||
4596 | mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match); | 4882 | mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match); |
4597 | 4883 | ||
4598 | if (changed) | 4884 | if (changed) |
4599 | err = new_settings(hdev, match.sk); | 4885 | new_settings(hdev, match.sk); |
4600 | 4886 | ||
4601 | if (match.sk) | 4887 | if (match.sk) |
4602 | sock_put(match.sk); | 4888 | sock_put(match.sk); |
@@ -4609,8 +4895,6 @@ int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status) | |||
4609 | clear_eir(&req); | 4895 | clear_eir(&req); |
4610 | 4896 | ||
4611 | hci_req_run(&req, NULL); | 4897 | hci_req_run(&req, NULL); |
4612 | |||
4613 | return err; | ||
4614 | } | 4898 | } |
4615 | 4899 | ||
4616 | static void sk_lookup(struct pending_cmd *cmd, void *data) | 4900 | static void sk_lookup(struct pending_cmd *cmd, void *data) |
@@ -4623,33 +4907,30 @@ static void sk_lookup(struct pending_cmd *cmd, void *data) | |||
4623 | } | 4907 | } |
4624 | } | 4908 | } |
4625 | 4909 | ||
4626 | int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, | 4910 | void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, |
4627 | u8 status) | 4911 | u8 status) |
4628 | { | 4912 | { |
4629 | struct cmd_lookup match = { NULL, hdev, mgmt_status(status) }; | 4913 | struct cmd_lookup match = { NULL, hdev, mgmt_status(status) }; |
4630 | int err = 0; | ||
4631 | 4914 | ||
4632 | mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match); | 4915 | mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match); |
4633 | mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match); | 4916 | mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match); |
4634 | mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match); | 4917 | mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match); |
4635 | 4918 | ||
4636 | if (!status) | 4919 | if (!status) |
4637 | err = mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, | 4920 | mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, 3, |
4638 | 3, NULL); | 4921 | NULL); |
4639 | 4922 | ||
4640 | if (match.sk) | 4923 | if (match.sk) |
4641 | sock_put(match.sk); | 4924 | sock_put(match.sk); |
4642 | |||
4643 | return err; | ||
4644 | } | 4925 | } |
4645 | 4926 | ||
4646 | int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) | 4927 | void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) |
4647 | { | 4928 | { |
4648 | struct mgmt_cp_set_local_name ev; | 4929 | struct mgmt_cp_set_local_name ev; |
4649 | struct pending_cmd *cmd; | 4930 | struct pending_cmd *cmd; |
4650 | 4931 | ||
4651 | if (status) | 4932 | if (status) |
4652 | return 0; | 4933 | return; |
4653 | 4934 | ||
4654 | memset(&ev, 0, sizeof(ev)); | 4935 | memset(&ev, 0, sizeof(ev)); |
4655 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); | 4936 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); |
@@ -4663,42 +4944,38 @@ int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) | |||
4663 | * HCI dev don't send any mgmt signals. | 4944 | * HCI dev don't send any mgmt signals. |
4664 | */ | 4945 | */ |
4665 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) | 4946 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) |
4666 | return 0; | 4947 | return; |
4667 | } | 4948 | } |
4668 | 4949 | ||
4669 | return mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev), | 4950 | mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev), |
4670 | cmd ? cmd->sk : NULL); | 4951 | cmd ? cmd->sk : NULL); |
4671 | } | 4952 | } |
4672 | 4953 | ||
4673 | int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, | 4954 | void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, |
4674 | u8 *randomizer, u8 status) | 4955 | u8 *randomizer, u8 status) |
4675 | { | 4956 | { |
4676 | struct pending_cmd *cmd; | 4957 | struct pending_cmd *cmd; |
4677 | int err; | ||
4678 | 4958 | ||
4679 | BT_DBG("%s status %u", hdev->name, status); | 4959 | BT_DBG("%s status %u", hdev->name, status); |
4680 | 4960 | ||
4681 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev); | 4961 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev); |
4682 | if (!cmd) | 4962 | if (!cmd) |
4683 | return -ENOENT; | 4963 | return; |
4684 | 4964 | ||
4685 | if (status) { | 4965 | if (status) { |
4686 | err = cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, | 4966 | cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, |
4687 | mgmt_status(status)); | 4967 | mgmt_status(status)); |
4688 | } else { | 4968 | } else { |
4689 | struct mgmt_rp_read_local_oob_data rp; | 4969 | struct mgmt_rp_read_local_oob_data rp; |
4690 | 4970 | ||
4691 | memcpy(rp.hash, hash, sizeof(rp.hash)); | 4971 | memcpy(rp.hash, hash, sizeof(rp.hash)); |
4692 | memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); | 4972 | memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); |
4693 | 4973 | ||
4694 | err = cmd_complete(cmd->sk, hdev->id, | 4974 | cmd_complete(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, |
4695 | MGMT_OP_READ_LOCAL_OOB_DATA, 0, &rp, | 4975 | 0, &rp, sizeof(rp)); |
4696 | sizeof(rp)); | ||
4697 | } | 4976 | } |
4698 | 4977 | ||
4699 | mgmt_pending_remove(cmd); | 4978 | mgmt_pending_remove(cmd); |
4700 | |||
4701 | return err; | ||
4702 | } | 4979 | } |
4703 | 4980 | ||
4704 | void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 4981 | void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 27e936a7ddd9..94d06cbfbc18 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -2154,13 +2154,6 @@ static int __init rfcomm_init(void) | |||
2154 | goto unregister; | 2154 | goto unregister; |
2155 | } | 2155 | } |
2156 | 2156 | ||
2157 | if (bt_debugfs) { | ||
2158 | rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444, | ||
2159 | bt_debugfs, NULL, &rfcomm_dlc_debugfs_fops); | ||
2160 | if (!rfcomm_dlc_debugfs) | ||
2161 | BT_ERR("Failed to create RFCOMM debug file"); | ||
2162 | } | ||
2163 | |||
2164 | err = rfcomm_init_ttys(); | 2157 | err = rfcomm_init_ttys(); |
2165 | if (err < 0) | 2158 | if (err < 0) |
2166 | goto stop; | 2159 | goto stop; |
@@ -2171,6 +2164,13 @@ static int __init rfcomm_init(void) | |||
2171 | 2164 | ||
2172 | BT_INFO("RFCOMM ver %s", VERSION); | 2165 | BT_INFO("RFCOMM ver %s", VERSION); |
2173 | 2166 | ||
2167 | if (IS_ERR_OR_NULL(bt_debugfs)) | ||
2168 | return 0; | ||
2169 | |||
2170 | rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444, | ||
2171 | bt_debugfs, NULL, | ||
2172 | &rfcomm_dlc_debugfs_fops); | ||
2173 | |||
2174 | return 0; | 2174 | return 0; |
2175 | 2175 | ||
2176 | cleanup: | 2176 | cleanup: |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index df17276eb32b..c4d3d423f89b 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -1051,15 +1051,15 @@ int __init rfcomm_init_sockets(void) | |||
1051 | goto error; | 1051 | goto error; |
1052 | } | 1052 | } |
1053 | 1053 | ||
1054 | if (bt_debugfs) { | ||
1055 | rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444, | ||
1056 | bt_debugfs, NULL, &rfcomm_sock_debugfs_fops); | ||
1057 | if (!rfcomm_sock_debugfs) | ||
1058 | BT_ERR("Failed to create RFCOMM debug file"); | ||
1059 | } | ||
1060 | |||
1061 | BT_INFO("RFCOMM socket layer initialized"); | 1054 | BT_INFO("RFCOMM socket layer initialized"); |
1062 | 1055 | ||
1056 | if (IS_ERR_OR_NULL(bt_debugfs)) | ||
1057 | return 0; | ||
1058 | |||
1059 | rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444, | ||
1060 | bt_debugfs, NULL, | ||
1061 | &rfcomm_sock_debugfs_fops); | ||
1062 | |||
1063 | return 0; | 1063 | return 0; |
1064 | 1064 | ||
1065 | error: | 1065 | error: |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index a92aebac56ca..12a0e51e21e1 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -1177,15 +1177,14 @@ int __init sco_init(void) | |||
1177 | goto error; | 1177 | goto error; |
1178 | } | 1178 | } |
1179 | 1179 | ||
1180 | if (bt_debugfs) { | ||
1181 | sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs, | ||
1182 | NULL, &sco_debugfs_fops); | ||
1183 | if (!sco_debugfs) | ||
1184 | BT_ERR("Failed to create SCO debug file"); | ||
1185 | } | ||
1186 | |||
1187 | BT_INFO("SCO socket layer initialized"); | 1180 | BT_INFO("SCO socket layer initialized"); |
1188 | 1181 | ||
1182 | if (IS_ERR_OR_NULL(bt_debugfs)) | ||
1183 | return 0; | ||
1184 | |||
1185 | sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs, | ||
1186 | NULL, &sco_debugfs_fops); | ||
1187 | |||
1189 | return 0; | 1188 | return 0; |
1190 | 1189 | ||
1191 | error: | 1190 | error: |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 463e50c58716..85a2796cac61 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -856,7 +856,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | |||
856 | 856 | ||
857 | if (hcon->type != LE_LINK) { | 857 | if (hcon->type != LE_LINK) { |
858 | kfree_skb(skb); | 858 | kfree_skb(skb); |
859 | return -ENOTSUPP; | 859 | return 0; |
860 | } | 860 | } |
861 | 861 | ||
862 | if (skb->len < 1) { | 862 | if (skb->len < 1) { |
@@ -864,7 +864,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | |||
864 | return -EILSEQ; | 864 | return -EILSEQ; |
865 | } | 865 | } |
866 | 866 | ||
867 | if (!test_bit(HCI_LE_ENABLED, &conn->hcon->hdev->dev_flags)) { | 867 | if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) { |
868 | err = -ENOTSUPP; | 868 | err = -ENOTSUPP; |
869 | reason = SMP_PAIRING_NOTSUPP; | 869 | reason = SMP_PAIRING_NOTSUPP; |
870 | goto done; | 870 | goto done; |
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 62535fe9f570..97b5dcad5025 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -4,6 +4,7 @@ config MAC80211 | |||
4 | select CRYPTO | 4 | select CRYPTO |
5 | select CRYPTO_ARC4 | 5 | select CRYPTO_ARC4 |
6 | select CRYPTO_AES | 6 | select CRYPTO_AES |
7 | select CRYPTO_CCM | ||
7 | select CRC32 | 8 | select CRC32 |
8 | select AVERAGE | 9 | select AVERAGE |
9 | ---help--- | 10 | ---help--- |
@@ -258,6 +259,17 @@ config MAC80211_MESH_SYNC_DEBUG | |||
258 | 259 | ||
259 | Do not select this option. | 260 | Do not select this option. |
260 | 261 | ||
262 | config MAC80211_MESH_CSA_DEBUG | ||
263 | bool "Verbose mesh channel switch debugging" | ||
264 | depends on MAC80211_DEBUG_MENU | ||
265 | depends on MAC80211_MESH | ||
266 | ---help--- | ||
267 | Selecting this option causes mac80211 to print out very verbose mesh | ||
268 | channel switch debugging messages (when mac80211 is taking part in a | ||
269 | mesh network). | ||
270 | |||
271 | Do not select this option. | ||
272 | |||
261 | config MAC80211_MESH_PS_DEBUG | 273 | config MAC80211_MESH_PS_DEBUG |
262 | bool "Verbose mesh powersave debugging" | 274 | bool "Verbose mesh powersave debugging" |
263 | depends on MAC80211_DEBUG_MENU | 275 | depends on MAC80211_DEBUG_MENU |
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index be7614b9ed27..7c7df475a401 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c | |||
@@ -2,6 +2,8 @@ | |||
2 | * Copyright 2003-2004, Instant802 Networks, Inc. | 2 | * Copyright 2003-2004, Instant802 Networks, Inc. |
3 | * Copyright 2005-2006, Devicescape Software, Inc. | 3 | * Copyright 2005-2006, Devicescape Software, Inc. |
4 | * | 4 | * |
5 | * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org> | ||
6 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
7 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
@@ -17,134 +19,75 @@ | |||
17 | #include "key.h" | 19 | #include "key.h" |
18 | #include "aes_ccm.h" | 20 | #include "aes_ccm.h" |
19 | 21 | ||
20 | static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a) | 22 | void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, |
23 | u8 *data, size_t data_len, u8 *mic) | ||
21 | { | 24 | { |
22 | int i; | 25 | struct scatterlist assoc, pt, ct[2]; |
23 | u8 *b_0, *aad, *b, *s_0; | 26 | struct { |
24 | 27 | struct aead_request req; | |
25 | b_0 = scratch + 3 * AES_BLOCK_SIZE; | 28 | u8 priv[crypto_aead_reqsize(tfm)]; |
26 | aad = scratch + 4 * AES_BLOCK_SIZE; | 29 | } aead_req; |
27 | b = scratch; | ||
28 | s_0 = scratch + AES_BLOCK_SIZE; | ||
29 | |||
30 | crypto_cipher_encrypt_one(tfm, b, b_0); | ||
31 | 30 | ||
32 | /* Extra Authenticate-only data (always two AES blocks) */ | 31 | memset(&aead_req, 0, sizeof(aead_req)); |
33 | for (i = 0; i < AES_BLOCK_SIZE; i++) | ||
34 | aad[i] ^= b[i]; | ||
35 | crypto_cipher_encrypt_one(tfm, b, aad); | ||
36 | 32 | ||
37 | aad += AES_BLOCK_SIZE; | 33 | sg_init_one(&pt, data, data_len); |
34 | sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); | ||
35 | sg_init_table(ct, 2); | ||
36 | sg_set_buf(&ct[0], data, data_len); | ||
37 | sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN); | ||
38 | 38 | ||
39 | for (i = 0; i < AES_BLOCK_SIZE; i++) | 39 | aead_request_set_tfm(&aead_req.req, tfm); |
40 | aad[i] ^= b[i]; | 40 | aead_request_set_assoc(&aead_req.req, &assoc, assoc.length); |
41 | crypto_cipher_encrypt_one(tfm, a, aad); | 41 | aead_request_set_crypt(&aead_req.req, &pt, ct, data_len, b_0); |
42 | 42 | ||
43 | /* Mask out bits from auth-only-b_0 */ | 43 | crypto_aead_encrypt(&aead_req.req); |
44 | b_0[0] &= 0x07; | ||
45 | |||
46 | /* S_0 is used to encrypt T (= MIC) */ | ||
47 | b_0[14] = 0; | ||
48 | b_0[15] = 0; | ||
49 | crypto_cipher_encrypt_one(tfm, s_0, b_0); | ||
50 | } | 44 | } |
51 | 45 | ||
52 | 46 | int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, | |
53 | void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, | 47 | u8 *data, size_t data_len, u8 *mic) |
54 | u8 *data, size_t data_len, | ||
55 | u8 *cdata, u8 *mic) | ||
56 | { | 48 | { |
57 | int i, j, last_len, num_blocks; | 49 | struct scatterlist assoc, pt, ct[2]; |
58 | u8 *pos, *cpos, *b, *s_0, *e, *b_0; | 50 | struct { |
59 | 51 | struct aead_request req; | |
60 | b = scratch; | 52 | u8 priv[crypto_aead_reqsize(tfm)]; |
61 | s_0 = scratch + AES_BLOCK_SIZE; | 53 | } aead_req; |
62 | e = scratch + 2 * AES_BLOCK_SIZE; | 54 | |
63 | b_0 = scratch + 3 * AES_BLOCK_SIZE; | 55 | memset(&aead_req, 0, sizeof(aead_req)); |
64 | 56 | ||
65 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); | 57 | sg_init_one(&pt, data, data_len); |
66 | last_len = data_len % AES_BLOCK_SIZE; | 58 | sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); |
67 | aes_ccm_prepare(tfm, scratch, b); | 59 | sg_init_table(ct, 2); |
68 | 60 | sg_set_buf(&ct[0], data, data_len); | |
69 | /* Process payload blocks */ | 61 | sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN); |
70 | pos = data; | 62 | |
71 | cpos = cdata; | 63 | aead_request_set_tfm(&aead_req.req, tfm); |
72 | for (j = 1; j <= num_blocks; j++) { | 64 | aead_request_set_assoc(&aead_req.req, &assoc, assoc.length); |
73 | int blen = (j == num_blocks && last_len) ? | 65 | aead_request_set_crypt(&aead_req.req, ct, &pt, |
74 | last_len : AES_BLOCK_SIZE; | 66 | data_len + IEEE80211_CCMP_MIC_LEN, b_0); |
75 | 67 | ||
76 | /* Authentication followed by encryption */ | 68 | return crypto_aead_decrypt(&aead_req.req); |
77 | for (i = 0; i < blen; i++) | ||
78 | b[i] ^= pos[i]; | ||
79 | crypto_cipher_encrypt_one(tfm, b, b); | ||
80 | |||
81 | b_0[14] = (j >> 8) & 0xff; | ||
82 | b_0[15] = j & 0xff; | ||
83 | crypto_cipher_encrypt_one(tfm, e, b_0); | ||
84 | for (i = 0; i < blen; i++) | ||
85 | *cpos++ = *pos++ ^ e[i]; | ||
86 | } | ||
87 | |||
88 | for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) | ||
89 | mic[i] = b[i] ^ s_0[i]; | ||
90 | } | 69 | } |
91 | 70 | ||
92 | 71 | struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[]) | |
93 | int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, | ||
94 | u8 *cdata, size_t data_len, u8 *mic, u8 *data) | ||
95 | { | 72 | { |
96 | int i, j, last_len, num_blocks; | 73 | struct crypto_aead *tfm; |
97 | u8 *pos, *cpos, *b, *s_0, *a, *b_0; | 74 | int err; |
98 | |||
99 | b = scratch; | ||
100 | s_0 = scratch + AES_BLOCK_SIZE; | ||
101 | a = scratch + 2 * AES_BLOCK_SIZE; | ||
102 | b_0 = scratch + 3 * AES_BLOCK_SIZE; | ||
103 | |||
104 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); | ||
105 | last_len = data_len % AES_BLOCK_SIZE; | ||
106 | aes_ccm_prepare(tfm, scratch, a); | ||
107 | |||
108 | /* Process payload blocks */ | ||
109 | cpos = cdata; | ||
110 | pos = data; | ||
111 | for (j = 1; j <= num_blocks; j++) { | ||
112 | int blen = (j == num_blocks && last_len) ? | ||
113 | last_len : AES_BLOCK_SIZE; | ||
114 | |||
115 | /* Decryption followed by authentication */ | ||
116 | b_0[14] = (j >> 8) & 0xff; | ||
117 | b_0[15] = j & 0xff; | ||
118 | crypto_cipher_encrypt_one(tfm, b, b_0); | ||
119 | for (i = 0; i < blen; i++) { | ||
120 | *pos = *cpos++ ^ b[i]; | ||
121 | a[i] ^= *pos++; | ||
122 | } | ||
123 | crypto_cipher_encrypt_one(tfm, a, a); | ||
124 | } | ||
125 | |||
126 | for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) { | ||
127 | if ((mic[i] ^ s_0[i]) != a[i]) | ||
128 | return -1; | ||
129 | } | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | 75 | ||
76 | tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC); | ||
77 | if (IS_ERR(tfm)) | ||
78 | return tfm; | ||
134 | 79 | ||
135 | struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]) | 80 | err = crypto_aead_setkey(tfm, key, WLAN_KEY_LEN_CCMP); |
136 | { | 81 | if (!err) |
137 | struct crypto_cipher *tfm; | 82 | err = crypto_aead_setauthsize(tfm, IEEE80211_CCMP_MIC_LEN); |
83 | if (!err) | ||
84 | return tfm; | ||
138 | 85 | ||
139 | tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); | 86 | crypto_free_aead(tfm); |
140 | if (!IS_ERR(tfm)) | 87 | return ERR_PTR(err); |
141 | crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP); | ||
142 | |||
143 | return tfm; | ||
144 | } | 88 | } |
145 | 89 | ||
146 | 90 | void ieee80211_aes_key_free(struct crypto_aead *tfm) | |
147 | void ieee80211_aes_key_free(struct crypto_cipher *tfm) | ||
148 | { | 91 | { |
149 | crypto_free_cipher(tfm); | 92 | crypto_free_aead(tfm); |
150 | } | 93 | } |
diff --git a/net/mac80211/aes_ccm.h b/net/mac80211/aes_ccm.h index 5b7d744e2370..2c7ab1948a2e 100644 --- a/net/mac80211/aes_ccm.h +++ b/net/mac80211/aes_ccm.h | |||
@@ -12,13 +12,11 @@ | |||
12 | 12 | ||
13 | #include <linux/crypto.h> | 13 | #include <linux/crypto.h> |
14 | 14 | ||
15 | struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]); | 15 | struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[]); |
16 | void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, | 16 | void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, |
17 | u8 *data, size_t data_len, | 17 | u8 *data, size_t data_len, u8 *mic); |
18 | u8 *cdata, u8 *mic); | 18 | int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, |
19 | int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, | 19 | u8 *data, size_t data_len, u8 *mic); |
20 | u8 *cdata, size_t data_len, | 20 | void ieee80211_aes_key_free(struct crypto_aead *tfm); |
21 | u8 *mic, u8 *data); | ||
22 | void ieee80211_aes_key_free(struct crypto_cipher *tfm); | ||
23 | 21 | ||
24 | #endif /* AES_CCM_H */ | 22 | #endif /* AES_CCM_H */ |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index b0a651cc389f..95667b088c5b 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1059,6 +1059,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
1059 | /* abort any running channel switch */ | 1059 | /* abort any running channel switch */ |
1060 | sdata->vif.csa_active = false; | 1060 | sdata->vif.csa_active = false; |
1061 | cancel_work_sync(&sdata->csa_finalize_work); | 1061 | cancel_work_sync(&sdata->csa_finalize_work); |
1062 | cancel_work_sync(&sdata->u.ap.request_smps_work); | ||
1062 | 1063 | ||
1063 | /* turn off carrier for this interface and dependent VLANs */ | 1064 | /* turn off carrier for this interface and dependent VLANs */ |
1064 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | 1065 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) |
@@ -1342,8 +1343,8 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1342 | sta->plink_state = params->plink_state; | 1343 | sta->plink_state = params->plink_state; |
1343 | 1344 | ||
1344 | ieee80211_mps_sta_status_update(sta); | 1345 | ieee80211_mps_sta_status_update(sta); |
1345 | changed |= | 1346 | changed |= ieee80211_mps_set_sta_local_pm(sta, |
1346 | ieee80211_mps_local_status_update(sdata); | 1347 | NL80211_MESH_POWER_UNKNOWN); |
1347 | break; | 1348 | break; |
1348 | default: | 1349 | default: |
1349 | /* nothing */ | 1350 | /* nothing */ |
@@ -1553,6 +1554,20 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
1553 | 1554 | ||
1554 | mutex_unlock(&local->sta_mtx); | 1555 | mutex_unlock(&local->sta_mtx); |
1555 | 1556 | ||
1557 | if ((sdata->vif.type == NL80211_IFTYPE_AP || | ||
1558 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && | ||
1559 | sta->known_smps_mode != sta->sdata->bss->req_smps && | ||
1560 | test_sta_flag(sta, WLAN_STA_AUTHORIZED) && | ||
1561 | sta_info_tx_streams(sta) != 1) { | ||
1562 | ht_dbg(sta->sdata, | ||
1563 | "%pM just authorized and MIMO capable - update SMPS\n", | ||
1564 | sta->sta.addr); | ||
1565 | ieee80211_send_smps_action(sta->sdata, | ||
1566 | sta->sdata->bss->req_smps, | ||
1567 | sta->sta.addr, | ||
1568 | sta->sdata->vif.bss_conf.bssid); | ||
1569 | } | ||
1570 | |||
1556 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | 1571 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
1557 | params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { | 1572 | params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { |
1558 | ieee80211_recalc_ps(local, -1); | 1573 | ieee80211_recalc_ps(local, -1); |
@@ -2337,8 +2352,92 @@ static int ieee80211_testmode_dump(struct wiphy *wiphy, | |||
2337 | } | 2352 | } |
2338 | #endif | 2353 | #endif |
2339 | 2354 | ||
2340 | int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, | 2355 | int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata, |
2341 | enum ieee80211_smps_mode smps_mode) | 2356 | enum ieee80211_smps_mode smps_mode) |
2357 | { | ||
2358 | struct sta_info *sta; | ||
2359 | enum ieee80211_smps_mode old_req; | ||
2360 | int i; | ||
2361 | |||
2362 | if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP)) | ||
2363 | return -EINVAL; | ||
2364 | |||
2365 | if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) | ||
2366 | return 0; | ||
2367 | |||
2368 | old_req = sdata->u.ap.req_smps; | ||
2369 | sdata->u.ap.req_smps = smps_mode; | ||
2370 | |||
2371 | /* AUTOMATIC doesn't mean much for AP - don't allow it */ | ||
2372 | if (old_req == smps_mode || | ||
2373 | smps_mode == IEEE80211_SMPS_AUTOMATIC) | ||
2374 | return 0; | ||
2375 | |||
2376 | /* If no associated stations, there's no need to do anything */ | ||
2377 | if (!atomic_read(&sdata->u.ap.num_mcast_sta)) { | ||
2378 | sdata->smps_mode = smps_mode; | ||
2379 | ieee80211_queue_work(&sdata->local->hw, &sdata->recalc_smps); | ||
2380 | return 0; | ||
2381 | } | ||
2382 | |||
2383 | ht_dbg(sdata, | ||
2384 | "SMSP %d requested in AP mode, sending Action frame to %d stations\n", | ||
2385 | smps_mode, atomic_read(&sdata->u.ap.num_mcast_sta)); | ||
2386 | |||
2387 | mutex_lock(&sdata->local->sta_mtx); | ||
2388 | for (i = 0; i < STA_HASH_SIZE; i++) { | ||
2389 | for (sta = rcu_dereference_protected(sdata->local->sta_hash[i], | ||
2390 | lockdep_is_held(&sdata->local->sta_mtx)); | ||
2391 | sta; | ||
2392 | sta = rcu_dereference_protected(sta->hnext, | ||
2393 | lockdep_is_held(&sdata->local->sta_mtx))) { | ||
2394 | /* | ||
2395 | * Only stations associated to our AP and | ||
2396 | * associated VLANs | ||
2397 | */ | ||
2398 | if (sta->sdata->bss != &sdata->u.ap) | ||
2399 | continue; | ||
2400 | |||
2401 | /* This station doesn't support MIMO - skip it */ | ||
2402 | if (sta_info_tx_streams(sta) == 1) | ||
2403 | continue; | ||
2404 | |||
2405 | /* | ||
2406 | * Don't wake up a STA just to send the action frame | ||
2407 | * unless we are getting more restrictive. | ||
2408 | */ | ||
2409 | if (test_sta_flag(sta, WLAN_STA_PS_STA) && | ||
2410 | !ieee80211_smps_is_restrictive(sta->known_smps_mode, | ||
2411 | smps_mode)) { | ||
2412 | ht_dbg(sdata, | ||
2413 | "Won't send SMPS to sleeping STA %pM\n", | ||
2414 | sta->sta.addr); | ||
2415 | continue; | ||
2416 | } | ||
2417 | |||
2418 | /* | ||
2419 | * If the STA is not authorized, wait until it gets | ||
2420 | * authorized and the action frame will be sent then. | ||
2421 | */ | ||
2422 | if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED)) | ||
2423 | continue; | ||
2424 | |||
2425 | ht_dbg(sdata, "Sending SMPS to %pM\n", sta->sta.addr); | ||
2426 | ieee80211_send_smps_action(sdata, smps_mode, | ||
2427 | sta->sta.addr, | ||
2428 | sdata->vif.bss_conf.bssid); | ||
2429 | } | ||
2430 | } | ||
2431 | mutex_unlock(&sdata->local->sta_mtx); | ||
2432 | |||
2433 | sdata->smps_mode = smps_mode; | ||
2434 | ieee80211_queue_work(&sdata->local->hw, &sdata->recalc_smps); | ||
2435 | |||
2436 | return 0; | ||
2437 | } | ||
2438 | |||
2439 | int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata, | ||
2440 | enum ieee80211_smps_mode smps_mode) | ||
2342 | { | 2441 | { |
2343 | const u8 *ap; | 2442 | const u8 *ap; |
2344 | enum ieee80211_smps_mode old_req; | 2443 | enum ieee80211_smps_mode old_req; |
@@ -2346,6 +2445,9 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, | |||
2346 | 2445 | ||
2347 | lockdep_assert_held(&sdata->wdev.mtx); | 2446 | lockdep_assert_held(&sdata->wdev.mtx); |
2348 | 2447 | ||
2448 | if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION)) | ||
2449 | return -EINVAL; | ||
2450 | |||
2349 | old_req = sdata->u.mgd.req_smps; | 2451 | old_req = sdata->u.mgd.req_smps; |
2350 | sdata->u.mgd.req_smps = smps_mode; | 2452 | sdata->u.mgd.req_smps = smps_mode; |
2351 | 2453 | ||
@@ -2402,7 +2504,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
2402 | 2504 | ||
2403 | /* no change, but if automatic follow powersave */ | 2505 | /* no change, but if automatic follow powersave */ |
2404 | sdata_lock(sdata); | 2506 | sdata_lock(sdata); |
2405 | __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps); | 2507 | __ieee80211_request_smps_mgd(sdata, sdata->u.mgd.req_smps); |
2406 | sdata_unlock(sdata); | 2508 | sdata_unlock(sdata); |
2407 | 2509 | ||
2408 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) | 2510 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) |
@@ -2860,7 +2962,7 @@ void ieee80211_csa_finalize_work(struct work_struct *work) | |||
2860 | container_of(work, struct ieee80211_sub_if_data, | 2962 | container_of(work, struct ieee80211_sub_if_data, |
2861 | csa_finalize_work); | 2963 | csa_finalize_work); |
2862 | struct ieee80211_local *local = sdata->local; | 2964 | struct ieee80211_local *local = sdata->local; |
2863 | int err, changed; | 2965 | int err, changed = 0; |
2864 | 2966 | ||
2865 | if (!ieee80211_sdata_running(sdata)) | 2967 | if (!ieee80211_sdata_running(sdata)) |
2866 | return; | 2968 | return; |
@@ -2892,6 +2994,13 @@ void ieee80211_csa_finalize_work(struct work_struct *work) | |||
2892 | case NL80211_IFTYPE_ADHOC: | 2994 | case NL80211_IFTYPE_ADHOC: |
2893 | ieee80211_ibss_finish_csa(sdata); | 2995 | ieee80211_ibss_finish_csa(sdata); |
2894 | break; | 2996 | break; |
2997 | #ifdef CONFIG_MAC80211_MESH | ||
2998 | case NL80211_IFTYPE_MESH_POINT: | ||
2999 | err = ieee80211_mesh_finish_csa(sdata); | ||
3000 | if (err < 0) | ||
3001 | return; | ||
3002 | break; | ||
3003 | #endif | ||
2895 | default: | 3004 | default: |
2896 | WARN_ON(1); | 3005 | WARN_ON(1); |
2897 | return; | 3006 | return; |
@@ -2912,6 +3021,7 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, | |||
2912 | struct ieee80211_local *local = sdata->local; | 3021 | struct ieee80211_local *local = sdata->local; |
2913 | struct ieee80211_chanctx_conf *chanctx_conf; | 3022 | struct ieee80211_chanctx_conf *chanctx_conf; |
2914 | struct ieee80211_chanctx *chanctx; | 3023 | struct ieee80211_chanctx *chanctx; |
3024 | struct ieee80211_if_mesh __maybe_unused *ifmsh; | ||
2915 | int err, num_chanctx; | 3025 | int err, num_chanctx; |
2916 | 3026 | ||
2917 | if (!list_empty(&local->roc_list) || local->scanning) | 3027 | if (!list_empty(&local->roc_list) || local->scanning) |
@@ -2995,6 +3105,26 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, | |||
2995 | if (err < 0) | 3105 | if (err < 0) |
2996 | return err; | 3106 | return err; |
2997 | break; | 3107 | break; |
3108 | #ifdef CONFIG_MAC80211_MESH | ||
3109 | case NL80211_IFTYPE_MESH_POINT: | ||
3110 | ifmsh = &sdata->u.mesh; | ||
3111 | |||
3112 | if (!ifmsh->mesh_id) | ||
3113 | return -EINVAL; | ||
3114 | |||
3115 | if (params->chandef.width != sdata->vif.bss_conf.chandef.width) | ||
3116 | return -EINVAL; | ||
3117 | |||
3118 | /* changes into another band are not supported */ | ||
3119 | if (sdata->vif.bss_conf.chandef.chan->band != | ||
3120 | params->chandef.chan->band) | ||
3121 | return -EINVAL; | ||
3122 | |||
3123 | err = ieee80211_mesh_csa_beacon(sdata, params, true); | ||
3124 | if (err < 0) | ||
3125 | return err; | ||
3126 | break; | ||
3127 | #endif | ||
2998 | default: | 3128 | default: |
2999 | return -EOPNOTSUPP; | 3129 | return -EOPNOTSUPP; |
3000 | } | 3130 | } |
diff --git a/net/mac80211/debug.h b/net/mac80211/debug.h index 4ccc5ed6237d..493d68061f0c 100644 --- a/net/mac80211/debug.h +++ b/net/mac80211/debug.h | |||
@@ -44,6 +44,12 @@ | |||
44 | #define MAC80211_MESH_SYNC_DEBUG 0 | 44 | #define MAC80211_MESH_SYNC_DEBUG 0 |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #ifdef CONFIG_MAC80211_MESH_CSA_DEBUG | ||
48 | #define MAC80211_MESH_CSA_DEBUG 1 | ||
49 | #else | ||
50 | #define MAC80211_MESH_CSA_DEBUG 0 | ||
51 | #endif | ||
52 | |||
47 | #ifdef CONFIG_MAC80211_MESH_PS_DEBUG | 53 | #ifdef CONFIG_MAC80211_MESH_PS_DEBUG |
48 | #define MAC80211_MESH_PS_DEBUG 1 | 54 | #define MAC80211_MESH_PS_DEBUG 1 |
49 | #else | 55 | #else |
@@ -157,6 +163,10 @@ do { \ | |||
157 | _sdata_dbg(MAC80211_MESH_SYNC_DEBUG, \ | 163 | _sdata_dbg(MAC80211_MESH_SYNC_DEBUG, \ |
158 | sdata, fmt, ##__VA_ARGS__) | 164 | sdata, fmt, ##__VA_ARGS__) |
159 | 165 | ||
166 | #define mcsa_dbg(sdata, fmt, ...) \ | ||
167 | _sdata_dbg(MAC80211_MESH_CSA_DEBUG, \ | ||
168 | sdata, fmt, ##__VA_ARGS__) | ||
169 | |||
160 | #define mps_dbg(sdata, fmt, ...) \ | 170 | #define mps_dbg(sdata, fmt, ...) \ |
161 | _sdata_dbg(MAC80211_MESH_PS_DEBUG, \ | 171 | _sdata_dbg(MAC80211_MESH_PS_DEBUG, \ |
162 | sdata, fmt, ##__VA_ARGS__) | 172 | sdata, fmt, ##__VA_ARGS__) |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index cafe614ef93d..04b5a14c8a05 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -224,12 +224,15 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, | |||
224 | smps_mode == IEEE80211_SMPS_AUTOMATIC)) | 224 | smps_mode == IEEE80211_SMPS_AUTOMATIC)) |
225 | return -EINVAL; | 225 | return -EINVAL; |
226 | 226 | ||
227 | /* supported only on managed interfaces for now */ | 227 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
228 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 228 | sdata->vif.type != NL80211_IFTYPE_AP) |
229 | return -EOPNOTSUPP; | 229 | return -EOPNOTSUPP; |
230 | 230 | ||
231 | sdata_lock(sdata); | 231 | sdata_lock(sdata); |
232 | err = __ieee80211_request_smps(sdata, smps_mode); | 232 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
233 | err = __ieee80211_request_smps_mgd(sdata, smps_mode); | ||
234 | else | ||
235 | err = __ieee80211_request_smps_ap(sdata, smps_mode); | ||
233 | sdata_unlock(sdata); | 236 | sdata_unlock(sdata); |
234 | 237 | ||
235 | return err; | 238 | return err; |
@@ -245,12 +248,15 @@ static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = { | |||
245 | static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata, | 248 | static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata, |
246 | char *buf, int buflen) | 249 | char *buf, int buflen) |
247 | { | 250 | { |
248 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 251 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
249 | return -EOPNOTSUPP; | 252 | return snprintf(buf, buflen, "request: %s\nused: %s\n", |
250 | 253 | smps_modes[sdata->u.mgd.req_smps], | |
251 | return snprintf(buf, buflen, "request: %s\nused: %s\n", | 254 | smps_modes[sdata->smps_mode]); |
252 | smps_modes[sdata->u.mgd.req_smps], | 255 | if (sdata->vif.type == NL80211_IFTYPE_AP) |
253 | smps_modes[sdata->smps_mode]); | 256 | return snprintf(buf, buflen, "request: %s\nused: %s\n", |
257 | smps_modes[sdata->u.ap.req_smps], | ||
258 | smps_modes[sdata->smps_mode]); | ||
259 | return -EINVAL; | ||
254 | } | 260 | } |
255 | 261 | ||
256 | static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata, | 262 | static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata, |
@@ -563,6 +569,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) | |||
563 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) | 569 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) |
564 | { | 570 | { |
565 | DEBUGFS_ADD(num_mcast_sta); | 571 | DEBUGFS_ADD(num_mcast_sta); |
572 | DEBUGFS_ADD_MODE(smps, 0600); | ||
566 | DEBUGFS_ADD(num_sta_ps); | 573 | DEBUGFS_ADD(num_sta_ps); |
567 | DEBUGFS_ADD(dtim_count); | 574 | DEBUGFS_ADD(dtim_count); |
568 | DEBUGFS_ADD(num_buffered_multicast); | 575 | DEBUGFS_ADD(num_buffered_multicast); |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 529bf58bc145..9a8be8f69224 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -448,14 +448,25 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, | |||
448 | return 0; | 448 | return 0; |
449 | } | 449 | } |
450 | 450 | ||
451 | void ieee80211_request_smps_work(struct work_struct *work) | 451 | void ieee80211_request_smps_mgd_work(struct work_struct *work) |
452 | { | 452 | { |
453 | struct ieee80211_sub_if_data *sdata = | 453 | struct ieee80211_sub_if_data *sdata = |
454 | container_of(work, struct ieee80211_sub_if_data, | 454 | container_of(work, struct ieee80211_sub_if_data, |
455 | u.mgd.request_smps_work); | 455 | u.mgd.request_smps_work); |
456 | 456 | ||
457 | sdata_lock(sdata); | 457 | sdata_lock(sdata); |
458 | __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode); | 458 | __ieee80211_request_smps_mgd(sdata, sdata->u.mgd.driver_smps_mode); |
459 | sdata_unlock(sdata); | ||
460 | } | ||
461 | |||
462 | void ieee80211_request_smps_ap_work(struct work_struct *work) | ||
463 | { | ||
464 | struct ieee80211_sub_if_data *sdata = | ||
465 | container_of(work, struct ieee80211_sub_if_data, | ||
466 | u.ap.request_smps_work); | ||
467 | |||
468 | sdata_lock(sdata); | ||
469 | __ieee80211_request_smps_ap(sdata, sdata->u.ap.driver_smps_mode); | ||
459 | sdata_unlock(sdata); | 470 | sdata_unlock(sdata); |
460 | } | 471 | } |
461 | 472 | ||
@@ -464,19 +475,29 @@ void ieee80211_request_smps(struct ieee80211_vif *vif, | |||
464 | { | 475 | { |
465 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 476 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
466 | 477 | ||
467 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) | 478 | if (WARN_ON_ONCE(vif->type != NL80211_IFTYPE_STATION && |
479 | vif->type != NL80211_IFTYPE_AP)) | ||
468 | return; | 480 | return; |
469 | 481 | ||
470 | if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) | 482 | if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) |
471 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | 483 | smps_mode = IEEE80211_SMPS_AUTOMATIC; |
472 | 484 | ||
473 | if (sdata->u.mgd.driver_smps_mode == smps_mode) | 485 | if (vif->type == NL80211_IFTYPE_STATION) { |
474 | return; | 486 | if (sdata->u.mgd.driver_smps_mode == smps_mode) |
475 | 487 | return; | |
476 | sdata->u.mgd.driver_smps_mode = smps_mode; | 488 | sdata->u.mgd.driver_smps_mode = smps_mode; |
477 | 489 | ieee80211_queue_work(&sdata->local->hw, | |
478 | ieee80211_queue_work(&sdata->local->hw, | 490 | &sdata->u.mgd.request_smps_work); |
479 | &sdata->u.mgd.request_smps_work); | 491 | } else { |
492 | /* AUTOMATIC is meaningless in AP mode */ | ||
493 | if (WARN_ON_ONCE(smps_mode == IEEE80211_SMPS_AUTOMATIC)) | ||
494 | return; | ||
495 | if (sdata->u.ap.driver_smps_mode == smps_mode) | ||
496 | return; | ||
497 | sdata->u.ap.driver_smps_mode = smps_mode; | ||
498 | ieee80211_queue_work(&sdata->local->hw, | ||
499 | &sdata->u.ap.request_smps_work); | ||
500 | } | ||
480 | } | 501 | } |
481 | /* this might change ... don't want non-open drivers using it */ | 502 | /* this might change ... don't want non-open drivers using it */ |
482 | EXPORT_SYMBOL_GPL(ieee80211_request_smps); | 503 | EXPORT_SYMBOL_GPL(ieee80211_request_smps); |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 21a0b8835cb3..531be040b9ae 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -229,6 +229,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
229 | struct beacon_data *presp; | 229 | struct beacon_data *presp; |
230 | enum nl80211_bss_scan_width scan_width; | 230 | enum nl80211_bss_scan_width scan_width; |
231 | bool have_higher_than_11mbit; | 231 | bool have_higher_than_11mbit; |
232 | bool radar_required = false; | ||
232 | int err; | 233 | int err; |
233 | 234 | ||
234 | sdata_assert_lock(sdata); | 235 | sdata_assert_lock(sdata); |
@@ -273,6 +274,23 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
273 | } | 274 | } |
274 | chandef.width = NL80211_CHAN_WIDTH_20; | 275 | chandef.width = NL80211_CHAN_WIDTH_20; |
275 | chandef.center_freq1 = chan->center_freq; | 276 | chandef.center_freq1 = chan->center_freq; |
277 | /* check again for downgraded chandef */ | ||
278 | if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { | ||
279 | sdata_info(sdata, | ||
280 | "Failed to join IBSS, beacons forbidden\n"); | ||
281 | return; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy, | ||
286 | &chandef); | ||
287 | if (err > 0) { | ||
288 | if (!ifibss->userspace_handles_dfs) { | ||
289 | sdata_info(sdata, | ||
290 | "Failed to join IBSS, DFS channel without control program\n"); | ||
291 | return; | ||
292 | } | ||
293 | radar_required = true; | ||
276 | } | 294 | } |
277 | 295 | ||
278 | ieee80211_vif_release_channel(sdata); | 296 | ieee80211_vif_release_channel(sdata); |
@@ -297,6 +315,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
297 | rcu_assign_pointer(ifibss->presp, presp); | 315 | rcu_assign_pointer(ifibss->presp, presp); |
298 | mgmt = (void *)presp->head; | 316 | mgmt = (void *)presp->head; |
299 | 317 | ||
318 | sdata->radar_required = radar_required; | ||
300 | sdata->vif.bss_conf.enable_beacon = true; | 319 | sdata->vif.bss_conf.enable_beacon = true; |
301 | sdata->vif.bss_conf.beacon_int = beacon_int; | 320 | sdata->vif.bss_conf.beacon_int = beacon_int; |
302 | sdata->vif.bss_conf.basic_rates = basic_rates; | 321 | sdata->vif.bss_conf.basic_rates = basic_rates; |
@@ -445,60 +464,6 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
445 | tsf, false); | 464 | tsf, false); |
446 | } | 465 | } |
447 | 466 | ||
448 | static int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, | ||
449 | struct cfg80211_csa_settings *csa_settings) | ||
450 | { | ||
451 | struct sk_buff *skb; | ||
452 | struct ieee80211_mgmt *mgmt; | ||
453 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | ||
454 | struct ieee80211_local *local = sdata->local; | ||
455 | int freq; | ||
456 | int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.chan_switch) + | ||
457 | sizeof(mgmt->u.action.u.chan_switch); | ||
458 | u8 *pos; | ||
459 | |||
460 | skb = dev_alloc_skb(local->tx_headroom + hdr_len + | ||
461 | 5 + /* channel switch announcement element */ | ||
462 | 3); /* secondary channel offset element */ | ||
463 | if (!skb) | ||
464 | return -1; | ||
465 | |||
466 | skb_reserve(skb, local->tx_headroom); | ||
467 | mgmt = (struct ieee80211_mgmt *)skb_put(skb, hdr_len); | ||
468 | memset(mgmt, 0, hdr_len); | ||
469 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
470 | IEEE80211_STYPE_ACTION); | ||
471 | |||
472 | eth_broadcast_addr(mgmt->da); | ||
473 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | ||
474 | memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); | ||
475 | mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; | ||
476 | mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH; | ||
477 | pos = skb_put(skb, 5); | ||
478 | *pos++ = WLAN_EID_CHANNEL_SWITCH; /* EID */ | ||
479 | *pos++ = 3; /* IE length */ | ||
480 | *pos++ = csa_settings->block_tx ? 1 : 0; /* CSA mode */ | ||
481 | freq = csa_settings->chandef.chan->center_freq; | ||
482 | *pos++ = ieee80211_frequency_to_channel(freq); /* channel */ | ||
483 | *pos++ = csa_settings->count; /* count */ | ||
484 | |||
485 | if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_40) { | ||
486 | enum nl80211_channel_type ch_type; | ||
487 | |||
488 | skb_put(skb, 3); | ||
489 | *pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; /* EID */ | ||
490 | *pos++ = 1; /* IE length */ | ||
491 | ch_type = cfg80211_get_chandef_type(&csa_settings->chandef); | ||
492 | if (ch_type == NL80211_CHAN_HT40PLUS) | ||
493 | *pos++ = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
494 | else | ||
495 | *pos++ = IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
496 | } | ||
497 | |||
498 | ieee80211_tx_skb(sdata, skb); | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, | 467 | int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, |
503 | struct cfg80211_csa_settings *csa_settings) | 468 | struct cfg80211_csa_settings *csa_settings) |
504 | { | 469 | { |
@@ -796,19 +761,34 @@ static void ieee80211_csa_connection_drop_work(struct work_struct *work) | |||
796 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); | 761 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); |
797 | } | 762 | } |
798 | 763 | ||
764 | static void ieee80211_ibss_csa_mark_radar(struct ieee80211_sub_if_data *sdata) | ||
765 | { | ||
766 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | ||
767 | int err; | ||
768 | |||
769 | /* if the current channel is a DFS channel, mark the channel as | ||
770 | * unavailable. | ||
771 | */ | ||
772 | err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy, | ||
773 | &ifibss->chandef); | ||
774 | if (err > 0) | ||
775 | cfg80211_radar_event(sdata->local->hw.wiphy, &ifibss->chandef, | ||
776 | GFP_ATOMIC); | ||
777 | } | ||
778 | |||
799 | static bool | 779 | static bool |
800 | ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | 780 | ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, |
801 | struct ieee802_11_elems *elems, | 781 | struct ieee802_11_elems *elems, |
802 | bool beacon) | 782 | bool beacon) |
803 | { | 783 | { |
804 | struct cfg80211_csa_settings params; | 784 | struct cfg80211_csa_settings params; |
785 | struct ieee80211_csa_ie csa_ie; | ||
805 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 786 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
806 | struct ieee80211_chanctx_conf *chanctx_conf; | 787 | struct ieee80211_chanctx_conf *chanctx_conf; |
807 | struct ieee80211_chanctx *chanctx; | 788 | struct ieee80211_chanctx *chanctx; |
808 | enum nl80211_channel_type ch_type; | 789 | enum nl80211_channel_type ch_type; |
809 | int err, num_chanctx; | 790 | int err, num_chanctx; |
810 | u32 sta_flags; | 791 | u32 sta_flags; |
811 | u8 mode; | ||
812 | 792 | ||
813 | if (sdata->vif.csa_active) | 793 | if (sdata->vif.csa_active) |
814 | return true; | 794 | return true; |
@@ -831,12 +811,10 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
831 | } | 811 | } |
832 | 812 | ||
833 | memset(¶ms, 0, sizeof(params)); | 813 | memset(¶ms, 0, sizeof(params)); |
814 | memset(&csa_ie, 0, sizeof(csa_ie)); | ||
834 | err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, | 815 | err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, |
835 | ifibss->chandef.chan->band, | 816 | ifibss->chandef.chan->band, |
836 | sta_flags, ifibss->bssid, | 817 | sta_flags, ifibss->bssid, &csa_ie); |
837 | ¶ms.count, &mode, | ||
838 | ¶ms.chandef); | ||
839 | |||
840 | /* can't switch to destination channel, fail */ | 818 | /* can't switch to destination channel, fail */ |
841 | if (err < 0) | 819 | if (err < 0) |
842 | goto disconnect; | 820 | goto disconnect; |
@@ -845,6 +823,9 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
845 | if (err) | 823 | if (err) |
846 | return false; | 824 | return false; |
847 | 825 | ||
826 | params.count = csa_ie.count; | ||
827 | params.chandef = csa_ie.chandef; | ||
828 | |||
848 | if (ifibss->chandef.chan->band != params.chandef.chan->band) | 829 | if (ifibss->chandef.chan->band != params.chandef.chan->band) |
849 | goto disconnect; | 830 | goto disconnect; |
850 | 831 | ||
@@ -880,8 +861,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
880 | goto disconnect; | 861 | goto disconnect; |
881 | } | 862 | } |
882 | 863 | ||
883 | if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, ¶ms.chandef, | 864 | if (!cfg80211_reg_can_beacon(sdata->local->hw.wiphy, ¶ms.chandef)) { |
884 | IEEE80211_CHAN_DISABLED)) { | ||
885 | sdata_info(sdata, | 865 | sdata_info(sdata, |
886 | "IBSS %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n", | 866 | "IBSS %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n", |
887 | ifibss->bssid, | 867 | ifibss->bssid, |
@@ -897,10 +877,11 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
897 | if (err < 0) | 877 | if (err < 0) |
898 | goto disconnect; | 878 | goto disconnect; |
899 | if (err) { | 879 | if (err) { |
900 | params.radar_required = true; | 880 | /* IBSS-DFS only allowed with a control program */ |
881 | if (!ifibss->userspace_handles_dfs) | ||
882 | goto disconnect; | ||
901 | 883 | ||
902 | /* TODO: IBSS-DFS not (yet) supported, disconnect. */ | 884 | params.radar_required = true; |
903 | goto disconnect; | ||
904 | } | 885 | } |
905 | 886 | ||
906 | rcu_read_lock(); | 887 | rcu_read_lock(); |
@@ -931,7 +912,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
931 | "received channel switch announcement to go to channel %d MHz\n", | 912 | "received channel switch announcement to go to channel %d MHz\n", |
932 | params.chandef.chan->center_freq); | 913 | params.chandef.chan->center_freq); |
933 | 914 | ||
934 | params.block_tx = !!mode; | 915 | params.block_tx = !!csa_ie.mode; |
935 | 916 | ||
936 | ieee80211_ibss_csa_beacon(sdata, ¶ms); | 917 | ieee80211_ibss_csa_beacon(sdata, ¶ms); |
937 | sdata->csa_radar_required = params.radar_required; | 918 | sdata->csa_radar_required = params.radar_required; |
@@ -947,12 +928,16 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
947 | ieee80211_bss_info_change_notify(sdata, err); | 928 | ieee80211_bss_info_change_notify(sdata, err); |
948 | drv_channel_switch_beacon(sdata, ¶ms.chandef); | 929 | drv_channel_switch_beacon(sdata, ¶ms.chandef); |
949 | 930 | ||
931 | ieee80211_ibss_csa_mark_radar(sdata); | ||
932 | |||
950 | return true; | 933 | return true; |
951 | disconnect: | 934 | disconnect: |
952 | ibss_dbg(sdata, "Can't handle channel switch, disconnect\n"); | 935 | ibss_dbg(sdata, "Can't handle channel switch, disconnect\n"); |
953 | ieee80211_queue_work(&sdata->local->hw, | 936 | ieee80211_queue_work(&sdata->local->hw, |
954 | &ifibss->csa_connection_drop_work); | 937 | &ifibss->csa_connection_drop_work); |
955 | 938 | ||
939 | ieee80211_ibss_csa_mark_radar(sdata); | ||
940 | |||
956 | return true; | 941 | return true; |
957 | } | 942 | } |
958 | 943 | ||
@@ -1688,6 +1673,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1688 | 1673 | ||
1689 | sdata->u.ibss.privacy = params->privacy; | 1674 | sdata->u.ibss.privacy = params->privacy; |
1690 | sdata->u.ibss.control_port = params->control_port; | 1675 | sdata->u.ibss.control_port = params->control_port; |
1676 | sdata->u.ibss.userspace_handles_dfs = params->userspace_handles_dfs; | ||
1691 | sdata->u.ibss.basic_rates = params->basic_rates; | 1677 | sdata->u.ibss.basic_rates = params->basic_rates; |
1692 | 1678 | ||
1693 | /* fix basic_rates if channel does not support these rates */ | 1679 | /* fix basic_rates if channel does not support these rates */ |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index fe48b093d4dc..29dc505be125 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -262,6 +262,10 @@ struct ieee80211_if_ap { | |||
262 | 262 | ||
263 | struct ps_data ps; | 263 | struct ps_data ps; |
264 | atomic_t num_mcast_sta; /* number of stations receiving multicast */ | 264 | atomic_t num_mcast_sta; /* number of stations receiving multicast */ |
265 | enum ieee80211_smps_mode req_smps, /* requested smps mode */ | ||
266 | driver_smps_mode; /* smps mode request */ | ||
267 | |||
268 | struct work_struct request_smps_work; | ||
265 | }; | 269 | }; |
266 | 270 | ||
267 | struct ieee80211_if_wds { | 271 | struct ieee80211_if_wds { |
@@ -498,6 +502,7 @@ struct ieee80211_if_ibss { | |||
498 | bool privacy; | 502 | bool privacy; |
499 | 503 | ||
500 | bool control_port; | 504 | bool control_port; |
505 | bool userspace_handles_dfs; | ||
501 | 506 | ||
502 | u8 bssid[ETH_ALEN] __aligned(2); | 507 | u8 bssid[ETH_ALEN] __aligned(2); |
503 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 508 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
@@ -539,6 +544,11 @@ struct ieee80211_mesh_sync_ops { | |||
539 | /* add other framework functions here */ | 544 | /* add other framework functions here */ |
540 | }; | 545 | }; |
541 | 546 | ||
547 | struct mesh_csa_settings { | ||
548 | struct rcu_head rcu_head; | ||
549 | struct cfg80211_csa_settings settings; | ||
550 | }; | ||
551 | |||
542 | struct ieee80211_if_mesh { | 552 | struct ieee80211_if_mesh { |
543 | struct timer_list housekeeping_timer; | 553 | struct timer_list housekeeping_timer; |
544 | struct timer_list mesh_path_timer; | 554 | struct timer_list mesh_path_timer; |
@@ -599,6 +609,11 @@ struct ieee80211_if_mesh { | |||
599 | int ps_peers_light_sleep; | 609 | int ps_peers_light_sleep; |
600 | int ps_peers_deep_sleep; | 610 | int ps_peers_deep_sleep; |
601 | struct ps_data ps; | 611 | struct ps_data ps; |
612 | /* Channel Switching Support */ | ||
613 | struct mesh_csa_settings __rcu *csa; | ||
614 | bool chsw_init; | ||
615 | u8 chsw_ttl; | ||
616 | u16 pre_value; | ||
602 | }; | 617 | }; |
603 | 618 | ||
604 | #ifdef CONFIG_MAC80211_MESH | 619 | #ifdef CONFIG_MAC80211_MESH |
@@ -1207,6 +1222,14 @@ struct ieee80211_ra_tid { | |||
1207 | u16 tid; | 1222 | u16 tid; |
1208 | }; | 1223 | }; |
1209 | 1224 | ||
1225 | /* this struct holds the value parsing from channel switch IE */ | ||
1226 | struct ieee80211_csa_ie { | ||
1227 | struct cfg80211_chan_def chandef; | ||
1228 | u8 mode; | ||
1229 | u8 count; | ||
1230 | u8 ttl; | ||
1231 | }; | ||
1232 | |||
1210 | /* Parsed Information Elements */ | 1233 | /* Parsed Information Elements */ |
1211 | struct ieee802_11_elems { | 1234 | struct ieee802_11_elems { |
1212 | const u8 *ie_start; | 1235 | const u8 *ie_start; |
@@ -1243,6 +1266,7 @@ struct ieee802_11_elems { | |||
1243 | const struct ieee80211_timeout_interval_ie *timeout_int; | 1266 | const struct ieee80211_timeout_interval_ie *timeout_int; |
1244 | const u8 *opmode_notif; | 1267 | const u8 *opmode_notif; |
1245 | const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; | 1268 | const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; |
1269 | const struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie; | ||
1246 | 1270 | ||
1247 | /* length of them, respectively */ | 1271 | /* length of them, respectively */ |
1248 | u8 ssid_len; | 1272 | u8 ssid_len; |
@@ -1343,6 +1367,10 @@ void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata); | |||
1343 | void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata); | 1367 | void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata); |
1344 | void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | 1368 | void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, |
1345 | struct sk_buff *skb); | 1369 | struct sk_buff *skb); |
1370 | int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata, | ||
1371 | struct cfg80211_csa_settings *csa_settings, | ||
1372 | bool csa_action); | ||
1373 | int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata); | ||
1346 | 1374 | ||
1347 | /* scan/BSS handling */ | 1375 | /* scan/BSS handling */ |
1348 | void ieee80211_scan_work(struct work_struct *work); | 1376 | void ieee80211_scan_work(struct work_struct *work); |
@@ -1439,7 +1467,10 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, | |||
1439 | int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, | 1467 | int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, |
1440 | enum ieee80211_smps_mode smps, const u8 *da, | 1468 | enum ieee80211_smps_mode smps, const u8 *da, |
1441 | const u8 *bssid); | 1469 | const u8 *bssid); |
1442 | void ieee80211_request_smps_work(struct work_struct *work); | 1470 | void ieee80211_request_smps_ap_work(struct work_struct *work); |
1471 | void ieee80211_request_smps_mgd_work(struct work_struct *work); | ||
1472 | bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old, | ||
1473 | enum ieee80211_smps_mode smps_mode_new); | ||
1443 | 1474 | ||
1444 | void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 1475 | void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
1445 | u16 initiator, u16 reason, bool stop); | 1476 | u16 initiator, u16 reason, bool stop); |
@@ -1501,17 +1532,16 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, | |||
1501 | * %IEEE80211_STA_DISABLE_HT, %IEEE80211_STA_DISABLE_VHT, | 1532 | * %IEEE80211_STA_DISABLE_HT, %IEEE80211_STA_DISABLE_VHT, |
1502 | * %IEEE80211_STA_DISABLE_40MHZ, %IEEE80211_STA_DISABLE_80P80MHZ, | 1533 | * %IEEE80211_STA_DISABLE_40MHZ, %IEEE80211_STA_DISABLE_80P80MHZ, |
1503 | * %IEEE80211_STA_DISABLE_160MHZ. | 1534 | * %IEEE80211_STA_DISABLE_160MHZ. |
1504 | * @count: to be filled with the counter until the switch (on success only) | ||
1505 | * @bssid: the currently connected bssid (for reporting) | 1535 | * @bssid: the currently connected bssid (for reporting) |
1506 | * @mode: to be filled with CSA mode (on success only) | 1536 | * @csa_ie: parsed 802.11 csa elements on count, mode, chandef and mesh ttl. |
1507 | * @new_chandef: to be filled with destination chandef (on success only) | 1537 | All of them will be filled with if success only. |
1508 | * Return: 0 on success, <0 on error and >0 if there is nothing to parse. | 1538 | * Return: 0 on success, <0 on error and >0 if there is nothing to parse. |
1509 | */ | 1539 | */ |
1510 | int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | 1540 | int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, |
1511 | struct ieee802_11_elems *elems, bool beacon, | 1541 | struct ieee802_11_elems *elems, bool beacon, |
1512 | enum ieee80211_band current_band, | 1542 | enum ieee80211_band current_band, |
1513 | u32 sta_flags, u8 *bssid, u8 *count, u8 *mode, | 1543 | u32 sta_flags, u8 *bssid, |
1514 | struct cfg80211_chan_def *new_chandef); | 1544 | struct ieee80211_csa_ie *csa_ie); |
1515 | 1545 | ||
1516 | /* Suspend/resume and hw reconfiguration */ | 1546 | /* Suspend/resume and hw reconfiguration */ |
1517 | int ieee80211_reconfig(struct ieee80211_local *local); | 1547 | int ieee80211_reconfig(struct ieee80211_local *local); |
@@ -1657,8 +1687,10 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1657 | u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata, | 1687 | u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata, |
1658 | struct ieee802_11_elems *elems, | 1688 | struct ieee802_11_elems *elems, |
1659 | enum ieee80211_band band, u32 *basic_rates); | 1689 | enum ieee80211_band band, u32 *basic_rates); |
1660 | int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, | 1690 | int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata, |
1661 | enum ieee80211_smps_mode smps_mode); | 1691 | enum ieee80211_smps_mode smps_mode); |
1692 | int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata, | ||
1693 | enum ieee80211_smps_mode smps_mode); | ||
1662 | void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); | 1694 | void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); |
1663 | 1695 | ||
1664 | size_t ieee80211_ie_split(const u8 *ies, size_t ielen, | 1696 | size_t ieee80211_ie_split(const u8 *ies, size_t ielen, |
@@ -1714,6 +1746,8 @@ void ieee80211_dfs_cac_timer(unsigned long data); | |||
1714 | void ieee80211_dfs_cac_timer_work(struct work_struct *work); | 1746 | void ieee80211_dfs_cac_timer_work(struct work_struct *work); |
1715 | void ieee80211_dfs_cac_cancel(struct ieee80211_local *local); | 1747 | void ieee80211_dfs_cac_cancel(struct ieee80211_local *local); |
1716 | void ieee80211_dfs_radar_detected_work(struct work_struct *work); | 1748 | void ieee80211_dfs_radar_detected_work(struct work_struct *work); |
1749 | int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, | ||
1750 | struct cfg80211_csa_settings *csa_settings); | ||
1717 | 1751 | ||
1718 | #ifdef CONFIG_MAC80211_NOINLINE | 1752 | #ifdef CONFIG_MAC80211_NOINLINE |
1719 | #define debug_noinline noinline | 1753 | #define debug_noinline noinline |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index e48f103b9ade..ff101ea1d9ae 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -1293,7 +1293,10 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
1293 | case NL80211_IFTYPE_AP: | 1293 | case NL80211_IFTYPE_AP: |
1294 | skb_queue_head_init(&sdata->u.ap.ps.bc_buf); | 1294 | skb_queue_head_init(&sdata->u.ap.ps.bc_buf); |
1295 | INIT_LIST_HEAD(&sdata->u.ap.vlans); | 1295 | INIT_LIST_HEAD(&sdata->u.ap.vlans); |
1296 | INIT_WORK(&sdata->u.ap.request_smps_work, | ||
1297 | ieee80211_request_smps_ap_work); | ||
1296 | sdata->vif.bss_conf.bssid = sdata->vif.addr; | 1298 | sdata->vif.bss_conf.bssid = sdata->vif.addr; |
1299 | sdata->u.ap.req_smps = IEEE80211_SMPS_OFF; | ||
1297 | break; | 1300 | break; |
1298 | case NL80211_IFTYPE_P2P_CLIENT: | 1301 | case NL80211_IFTYPE_P2P_CLIENT: |
1299 | type = NL80211_IFTYPE_STATION; | 1302 | type = NL80211_IFTYPE_STATION; |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index 036d57e76a5e..aaae0ed37004 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -83,7 +83,7 @@ struct ieee80211_key { | |||
83 | * Management frames. | 83 | * Management frames. |
84 | */ | 84 | */ |
85 | u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; | 85 | u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; |
86 | struct crypto_cipher *tfm; | 86 | struct crypto_aead *tfm; |
87 | u32 replays; /* dot11RSNAStatsCCMPReplays */ | 87 | u32 replays; /* dot11RSNAStatsCCMPReplays */ |
88 | } ccmp; | 88 | } ccmp; |
89 | struct { | 89 | struct { |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 707ac61d63e5..896fe3bd599e 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/unaligned.h> | 12 | #include <asm/unaligned.h> |
13 | #include "ieee80211_i.h" | 13 | #include "ieee80211_i.h" |
14 | #include "mesh.h" | 14 | #include "mesh.h" |
15 | #include "driver-ops.h" | ||
15 | 16 | ||
16 | static int mesh_allocated; | 17 | static int mesh_allocated; |
17 | static struct kmem_cache *rm_cache; | 18 | static struct kmem_cache *rm_cache; |
@@ -610,6 +611,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) | |||
610 | struct sk_buff *skb; | 611 | struct sk_buff *skb; |
611 | struct ieee80211_mgmt *mgmt; | 612 | struct ieee80211_mgmt *mgmt; |
612 | struct ieee80211_chanctx_conf *chanctx_conf; | 613 | struct ieee80211_chanctx_conf *chanctx_conf; |
614 | struct mesh_csa_settings *csa; | ||
613 | enum ieee80211_band band; | 615 | enum ieee80211_band band; |
614 | u8 *pos; | 616 | u8 *pos; |
615 | struct ieee80211_sub_if_data *sdata; | 617 | struct ieee80211_sub_if_data *sdata; |
@@ -624,6 +626,10 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) | |||
624 | 626 | ||
625 | head_len = hdr_len + | 627 | head_len = hdr_len + |
626 | 2 + /* NULL SSID */ | 628 | 2 + /* NULL SSID */ |
629 | /* Channel Switch Announcement */ | ||
630 | 2 + sizeof(struct ieee80211_channel_sw_ie) + | ||
631 | /* Mesh Channel Swith Parameters */ | ||
632 | 2 + sizeof(struct ieee80211_mesh_chansw_params_ie) + | ||
627 | 2 + 8 + /* supported rates */ | 633 | 2 + 8 + /* supported rates */ |
628 | 2 + 3; /* DS params */ | 634 | 2 + 3; /* DS params */ |
629 | tail_len = 2 + (IEEE80211_MAX_SUPP_RATES - 8) + | 635 | tail_len = 2 + (IEEE80211_MAX_SUPP_RATES - 8) + |
@@ -665,6 +671,38 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) | |||
665 | *pos++ = WLAN_EID_SSID; | 671 | *pos++ = WLAN_EID_SSID; |
666 | *pos++ = 0x0; | 672 | *pos++ = 0x0; |
667 | 673 | ||
674 | rcu_read_lock(); | ||
675 | csa = rcu_dereference(ifmsh->csa); | ||
676 | if (csa) { | ||
677 | __le16 pre_value; | ||
678 | |||
679 | pos = skb_put(skb, 13); | ||
680 | memset(pos, 0, 13); | ||
681 | *pos++ = WLAN_EID_CHANNEL_SWITCH; | ||
682 | *pos++ = 3; | ||
683 | *pos++ = 0x0; | ||
684 | *pos++ = ieee80211_frequency_to_channel( | ||
685 | csa->settings.chandef.chan->center_freq); | ||
686 | sdata->csa_counter_offset_beacon = hdr_len + 6; | ||
687 | *pos++ = csa->settings.count; | ||
688 | *pos++ = WLAN_EID_CHAN_SWITCH_PARAM; | ||
689 | *pos++ = 6; | ||
690 | if (ifmsh->chsw_init) { | ||
691 | *pos++ = ifmsh->mshcfg.dot11MeshTTL; | ||
692 | *pos |= WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; | ||
693 | } else { | ||
694 | *pos++ = ifmsh->chsw_ttl; | ||
695 | } | ||
696 | *pos++ |= csa->settings.block_tx ? | ||
697 | WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; | ||
698 | put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); | ||
699 | pos += 2; | ||
700 | pre_value = cpu_to_le16(ifmsh->pre_value); | ||
701 | memcpy(pos, &pre_value, 2); | ||
702 | pos += 2; | ||
703 | } | ||
704 | rcu_read_unlock(); | ||
705 | |||
668 | if (ieee80211_add_srates_ie(sdata, skb, true, band) || | 706 | if (ieee80211_add_srates_ie(sdata, skb, true, band) || |
669 | mesh_add_ds_params_ie(sdata, skb)) | 707 | mesh_add_ds_params_ie(sdata, skb)) |
670 | goto out_free; | 708 | goto out_free; |
@@ -812,6 +850,127 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) | |||
812 | ieee80211_configure_filter(local); | 850 | ieee80211_configure_filter(local); |
813 | } | 851 | } |
814 | 852 | ||
853 | static bool | ||
854 | ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata, | ||
855 | struct ieee802_11_elems *elems, bool beacon) | ||
856 | { | ||
857 | struct cfg80211_csa_settings params; | ||
858 | struct ieee80211_csa_ie csa_ie; | ||
859 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
860 | struct ieee80211_chanctx *chanctx; | ||
861 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
862 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); | ||
863 | int err, num_chanctx; | ||
864 | u32 sta_flags; | ||
865 | |||
866 | if (sdata->vif.csa_active) | ||
867 | return true; | ||
868 | |||
869 | if (!ifmsh->mesh_id) | ||
870 | return false; | ||
871 | |||
872 | sta_flags = IEEE80211_STA_DISABLE_VHT; | ||
873 | switch (sdata->vif.bss_conf.chandef.width) { | ||
874 | case NL80211_CHAN_WIDTH_20_NOHT: | ||
875 | sta_flags |= IEEE80211_STA_DISABLE_HT; | ||
876 | case NL80211_CHAN_WIDTH_20: | ||
877 | sta_flags |= IEEE80211_STA_DISABLE_40MHZ; | ||
878 | break; | ||
879 | default: | ||
880 | break; | ||
881 | } | ||
882 | |||
883 | memset(¶ms, 0, sizeof(params)); | ||
884 | memset(&csa_ie, 0, sizeof(csa_ie)); | ||
885 | err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, band, | ||
886 | sta_flags, sdata->vif.addr, | ||
887 | &csa_ie); | ||
888 | if (err < 0) | ||
889 | return false; | ||
890 | if (err) | ||
891 | return false; | ||
892 | |||
893 | params.chandef = csa_ie.chandef; | ||
894 | params.count = csa_ie.count; | ||
895 | |||
896 | if (sdata->vif.bss_conf.chandef.chan->band != | ||
897 | params.chandef.chan->band) | ||
898 | return false; | ||
899 | |||
900 | if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, ¶ms.chandef, | ||
901 | IEEE80211_CHAN_DISABLED)) { | ||
902 | sdata_info(sdata, | ||
903 | "mesh STA %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), aborting\n", | ||
904 | sdata->vif.addr, | ||
905 | params.chandef.chan->center_freq, | ||
906 | params.chandef.width, | ||
907 | params.chandef.center_freq1, | ||
908 | params.chandef.center_freq2); | ||
909 | return false; | ||
910 | } | ||
911 | |||
912 | err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy, | ||
913 | ¶ms.chandef); | ||
914 | if (err < 0) | ||
915 | return false; | ||
916 | if (err) { | ||
917 | params.radar_required = true; | ||
918 | /* TODO: DFS not (yet) supported */ | ||
919 | return false; | ||
920 | } | ||
921 | |||
922 | rcu_read_lock(); | ||
923 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
924 | if (!chanctx_conf) | ||
925 | goto failed_chswitch; | ||
926 | |||
927 | /* don't handle for multi-VIF cases */ | ||
928 | chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf); | ||
929 | if (chanctx->refcount > 1) | ||
930 | goto failed_chswitch; | ||
931 | |||
932 | num_chanctx = 0; | ||
933 | list_for_each_entry_rcu(chanctx, &sdata->local->chanctx_list, list) | ||
934 | num_chanctx++; | ||
935 | |||
936 | if (num_chanctx > 1) | ||
937 | goto failed_chswitch; | ||
938 | |||
939 | rcu_read_unlock(); | ||
940 | |||
941 | mcsa_dbg(sdata, | ||
942 | "received channel switch announcement to go to channel %d MHz\n", | ||
943 | params.chandef.chan->center_freq); | ||
944 | |||
945 | params.block_tx = csa_ie.mode & WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT; | ||
946 | if (beacon) | ||
947 | ifmsh->chsw_ttl = csa_ie.ttl - 1; | ||
948 | else | ||
949 | ifmsh->chsw_ttl = 0; | ||
950 | |||
951 | if (ifmsh->chsw_ttl > 0) | ||
952 | if (ieee80211_mesh_csa_beacon(sdata, ¶ms, false) < 0) | ||
953 | return false; | ||
954 | |||
955 | sdata->csa_radar_required = params.radar_required; | ||
956 | |||
957 | if (params.block_tx) | ||
958 | ieee80211_stop_queues_by_reason(&sdata->local->hw, | ||
959 | IEEE80211_MAX_QUEUE_MAP, | ||
960 | IEEE80211_QUEUE_STOP_REASON_CSA); | ||
961 | |||
962 | sdata->local->csa_chandef = params.chandef; | ||
963 | sdata->vif.csa_active = true; | ||
964 | |||
965 | ieee80211_bss_info_change_notify(sdata, err); | ||
966 | drv_channel_switch_beacon(sdata, ¶ms.chandef); | ||
967 | |||
968 | return true; | ||
969 | failed_chswitch: | ||
970 | rcu_read_unlock(); | ||
971 | return false; | ||
972 | } | ||
973 | |||
815 | static void | 974 | static void |
816 | ieee80211_mesh_rx_probe_req(struct ieee80211_sub_if_data *sdata, | 975 | ieee80211_mesh_rx_probe_req(struct ieee80211_sub_if_data *sdata, |
817 | struct ieee80211_mgmt *mgmt, size_t len) | 976 | struct ieee80211_mgmt *mgmt, size_t len) |
@@ -918,6 +1077,142 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
918 | if (ifmsh->sync_ops) | 1077 | if (ifmsh->sync_ops) |
919 | ifmsh->sync_ops->rx_bcn_presp(sdata, | 1078 | ifmsh->sync_ops->rx_bcn_presp(sdata, |
920 | stype, mgmt, &elems, rx_status); | 1079 | stype, mgmt, &elems, rx_status); |
1080 | |||
1081 | if (!ifmsh->chsw_init) | ||
1082 | ieee80211_mesh_process_chnswitch(sdata, &elems, true); | ||
1083 | } | ||
1084 | |||
1085 | int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata) | ||
1086 | { | ||
1087 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
1088 | struct mesh_csa_settings *tmp_csa_settings; | ||
1089 | int ret = 0; | ||
1090 | |||
1091 | /* Reset the TTL value and Initiator flag */ | ||
1092 | ifmsh->chsw_init = false; | ||
1093 | ifmsh->chsw_ttl = 0; | ||
1094 | |||
1095 | /* Remove the CSA and MCSP elements from the beacon */ | ||
1096 | tmp_csa_settings = rcu_dereference(ifmsh->csa); | ||
1097 | rcu_assign_pointer(ifmsh->csa, NULL); | ||
1098 | kfree_rcu(tmp_csa_settings, rcu_head); | ||
1099 | ret = ieee80211_mesh_rebuild_beacon(sdata); | ||
1100 | if (ret) | ||
1101 | return -EINVAL; | ||
1102 | |||
1103 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); | ||
1104 | |||
1105 | mcsa_dbg(sdata, "complete switching to center freq %d MHz", | ||
1106 | sdata->vif.bss_conf.chandef.chan->center_freq); | ||
1107 | return 0; | ||
1108 | } | ||
1109 | |||
1110 | int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata, | ||
1111 | struct cfg80211_csa_settings *csa_settings, | ||
1112 | bool csa_action) | ||
1113 | { | ||
1114 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
1115 | struct mesh_csa_settings *tmp_csa_settings; | ||
1116 | int ret = 0; | ||
1117 | |||
1118 | tmp_csa_settings = kmalloc(sizeof(*tmp_csa_settings), | ||
1119 | GFP_ATOMIC); | ||
1120 | if (!tmp_csa_settings) | ||
1121 | return -ENOMEM; | ||
1122 | |||
1123 | memcpy(&tmp_csa_settings->settings, csa_settings, | ||
1124 | sizeof(struct cfg80211_csa_settings)); | ||
1125 | |||
1126 | rcu_assign_pointer(ifmsh->csa, tmp_csa_settings); | ||
1127 | |||
1128 | ret = ieee80211_mesh_rebuild_beacon(sdata); | ||
1129 | if (ret) { | ||
1130 | tmp_csa_settings = rcu_dereference(ifmsh->csa); | ||
1131 | rcu_assign_pointer(ifmsh->csa, NULL); | ||
1132 | kfree_rcu(tmp_csa_settings, rcu_head); | ||
1133 | return ret; | ||
1134 | } | ||
1135 | |||
1136 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); | ||
1137 | |||
1138 | if (csa_action) | ||
1139 | ieee80211_send_action_csa(sdata, csa_settings); | ||
1140 | |||
1141 | return 0; | ||
1142 | } | ||
1143 | |||
1144 | static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata, | ||
1145 | struct ieee80211_mgmt *mgmt, size_t len) | ||
1146 | { | ||
1147 | struct ieee80211_mgmt *mgmt_fwd; | ||
1148 | struct sk_buff *skb; | ||
1149 | struct ieee80211_local *local = sdata->local; | ||
1150 | u8 *pos = mgmt->u.action.u.chan_switch.variable; | ||
1151 | size_t offset_ttl; | ||
1152 | |||
1153 | skb = dev_alloc_skb(local->tx_headroom + len); | ||
1154 | if (!skb) | ||
1155 | return -ENOMEM; | ||
1156 | skb_reserve(skb, local->tx_headroom); | ||
1157 | mgmt_fwd = (struct ieee80211_mgmt *) skb_put(skb, len); | ||
1158 | |||
1159 | /* offset_ttl is based on whether the secondary channel | ||
1160 | * offset is available or not. Substract 1 from the mesh TTL | ||
1161 | * and disable the initiator flag before forwarding. | ||
1162 | */ | ||
1163 | offset_ttl = (len < 42) ? 7 : 10; | ||
1164 | *(pos + offset_ttl) -= 1; | ||
1165 | *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; | ||
1166 | sdata->u.mesh.chsw_ttl = *(pos + offset_ttl); | ||
1167 | |||
1168 | memcpy(mgmt_fwd, mgmt, len); | ||
1169 | eth_broadcast_addr(mgmt_fwd->da); | ||
1170 | memcpy(mgmt_fwd->sa, sdata->vif.addr, ETH_ALEN); | ||
1171 | memcpy(mgmt_fwd->bssid, sdata->vif.addr, ETH_ALEN); | ||
1172 | |||
1173 | ieee80211_tx_skb(sdata, skb); | ||
1174 | return 0; | ||
1175 | } | ||
1176 | |||
1177 | static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata, | ||
1178 | struct ieee80211_mgmt *mgmt, size_t len) | ||
1179 | { | ||
1180 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
1181 | struct ieee802_11_elems elems; | ||
1182 | u16 pre_value; | ||
1183 | bool fwd_csa = true; | ||
1184 | size_t baselen; | ||
1185 | u8 *pos, ttl; | ||
1186 | |||
1187 | if (mgmt->u.action.u.measurement.action_code != | ||
1188 | WLAN_ACTION_SPCT_CHL_SWITCH) | ||
1189 | return; | ||
1190 | |||
1191 | pos = mgmt->u.action.u.chan_switch.variable; | ||
1192 | baselen = offsetof(struct ieee80211_mgmt, | ||
1193 | u.action.u.chan_switch.variable); | ||
1194 | ieee802_11_parse_elems(pos, len - baselen, false, &elems); | ||
1195 | |||
1196 | ttl = elems.mesh_chansw_params_ie->mesh_ttl; | ||
1197 | if (!--ttl) | ||
1198 | fwd_csa = false; | ||
1199 | |||
1200 | pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value); | ||
1201 | if (ifmsh->pre_value >= pre_value) | ||
1202 | return; | ||
1203 | |||
1204 | ifmsh->pre_value = pre_value; | ||
1205 | |||
1206 | if (!ieee80211_mesh_process_chnswitch(sdata, &elems, false)) { | ||
1207 | mcsa_dbg(sdata, "Failed to process CSA action frame"); | ||
1208 | return; | ||
1209 | } | ||
1210 | |||
1211 | /* forward or re-broadcast the CSA frame */ | ||
1212 | if (fwd_csa) { | ||
1213 | if (mesh_fwd_csa_frame(sdata, mgmt, len) < 0) | ||
1214 | mcsa_dbg(sdata, "Failed to forward the CSA frame"); | ||
1215 | } | ||
921 | } | 1216 | } |
922 | 1217 | ||
923 | static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata, | 1218 | static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata, |
@@ -939,6 +1234,9 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata, | |||
939 | if (mesh_action_is_path_sel(mgmt)) | 1234 | if (mesh_action_is_path_sel(mgmt)) |
940 | mesh_rx_path_sel_frame(sdata, mgmt, len); | 1235 | mesh_rx_path_sel_frame(sdata, mgmt, len); |
941 | break; | 1236 | break; |
1237 | case WLAN_CATEGORY_SPECTRUM_MGMT: | ||
1238 | mesh_rx_csa_frame(sdata, mgmt, len); | ||
1239 | break; | ||
942 | } | 1240 | } |
943 | } | 1241 | } |
944 | 1242 | ||
@@ -1056,13 +1354,11 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) | |||
1056 | (unsigned long) sdata); | 1354 | (unsigned long) sdata); |
1057 | 1355 | ||
1058 | ifmsh->accepting_plinks = true; | 1356 | ifmsh->accepting_plinks = true; |
1059 | ifmsh->preq_id = 0; | ||
1060 | ifmsh->sn = 0; | ||
1061 | ifmsh->num_gates = 0; | ||
1062 | atomic_set(&ifmsh->mpaths, 0); | 1357 | atomic_set(&ifmsh->mpaths, 0); |
1063 | mesh_rmc_init(sdata); | 1358 | mesh_rmc_init(sdata); |
1064 | ifmsh->last_preq = jiffies; | 1359 | ifmsh->last_preq = jiffies; |
1065 | ifmsh->next_perr = jiffies; | 1360 | ifmsh->next_perr = jiffies; |
1361 | ifmsh->chsw_init = false; | ||
1066 | /* Allocate all mesh structures when creating the first mesh interface. */ | 1362 | /* Allocate all mesh structures when creating the first mesh interface. */ |
1067 | if (!mesh_allocated) | 1363 | if (!mesh_allocated) |
1068 | ieee80211s_init(); | 1364 | ieee80211s_init(); |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 6b65d5055f5b..4301aa5aa227 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -222,7 +222,8 @@ static u32 __mesh_plink_deactivate(struct sta_info *sta) | |||
222 | mesh_path_flush_by_nexthop(sta); | 222 | mesh_path_flush_by_nexthop(sta); |
223 | 223 | ||
224 | ieee80211_mps_sta_status_update(sta); | 224 | ieee80211_mps_sta_status_update(sta); |
225 | changed |= ieee80211_mps_local_status_update(sdata); | 225 | changed |= ieee80211_mps_set_sta_local_pm(sta, |
226 | NL80211_MESH_POWER_UNKNOWN); | ||
226 | 227 | ||
227 | return changed; | 228 | return changed; |
228 | } | 229 | } |
diff --git a/net/mac80211/mesh_ps.c b/net/mac80211/mesh_ps.c index 22290a929b94..0f79b78b5e86 100644 --- a/net/mac80211/mesh_ps.c +++ b/net/mac80211/mesh_ps.c | |||
@@ -152,6 +152,9 @@ u32 ieee80211_mps_set_sta_local_pm(struct sta_info *sta, | |||
152 | { | 152 | { |
153 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 153 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
154 | 154 | ||
155 | if (sta->local_pm == pm) | ||
156 | return 0; | ||
157 | |||
155 | mps_dbg(sdata, "local STA operates in mode %d with %pM\n", | 158 | mps_dbg(sdata, "local STA operates in mode %d with %pM\n", |
156 | pm, sta->sta.addr); | 159 | pm, sta->sta.addr); |
157 | 160 | ||
@@ -245,6 +248,14 @@ void ieee80211_mps_sta_status_update(struct sta_info *sta) | |||
245 | 248 | ||
246 | do_buffer = (pm != NL80211_MESH_POWER_ACTIVE); | 249 | do_buffer = (pm != NL80211_MESH_POWER_ACTIVE); |
247 | 250 | ||
251 | /* clear the MPSP flags for non-peers or active STA */ | ||
252 | if (sta->plink_state != NL80211_PLINK_ESTAB) { | ||
253 | clear_sta_flag(sta, WLAN_STA_MPSP_OWNER); | ||
254 | clear_sta_flag(sta, WLAN_STA_MPSP_RECIPIENT); | ||
255 | } else if (!do_buffer) { | ||
256 | clear_sta_flag(sta, WLAN_STA_MPSP_OWNER); | ||
257 | } | ||
258 | |||
248 | /* Don't let the same PS state be set twice */ | 259 | /* Don't let the same PS state be set twice */ |
249 | if (test_sta_flag(sta, WLAN_STA_PS_STA) == do_buffer) | 260 | if (test_sta_flag(sta, WLAN_STA_PS_STA) == do_buffer) |
250 | return; | 261 | return; |
@@ -257,14 +268,6 @@ void ieee80211_mps_sta_status_update(struct sta_info *sta) | |||
257 | } else { | 268 | } else { |
258 | ieee80211_sta_ps_deliver_wakeup(sta); | 269 | ieee80211_sta_ps_deliver_wakeup(sta); |
259 | } | 270 | } |
260 | |||
261 | /* clear the MPSP flags for non-peers or active STA */ | ||
262 | if (sta->plink_state != NL80211_PLINK_ESTAB) { | ||
263 | clear_sta_flag(sta, WLAN_STA_MPSP_OWNER); | ||
264 | clear_sta_flag(sta, WLAN_STA_MPSP_RECIPIENT); | ||
265 | } else if (!do_buffer) { | ||
266 | clear_sta_flag(sta, WLAN_STA_MPSP_OWNER); | ||
267 | } | ||
268 | } | 271 | } |
269 | 272 | ||
270 | static void mps_set_sta_peer_pm(struct sta_info *sta, | 273 | static void mps_set_sta_peer_pm(struct sta_info *sta, |
@@ -444,8 +447,7 @@ static void mpsp_qos_null_append(struct sta_info *sta, | |||
444 | */ | 447 | */ |
445 | static void mps_frame_deliver(struct sta_info *sta, int n_frames) | 448 | static void mps_frame_deliver(struct sta_info *sta, int n_frames) |
446 | { | 449 | { |
447 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 450 | struct ieee80211_local *local = sta->sdata->local; |
448 | struct ieee80211_local *local = sdata->local; | ||
449 | int ac; | 451 | int ac; |
450 | struct sk_buff_head frames; | 452 | struct sk_buff_head frames; |
451 | struct sk_buff *skb; | 453 | struct sk_buff *skb; |
@@ -558,10 +560,10 @@ void ieee80211_mpsp_trigger_process(u8 *qc, struct sta_info *sta, | |||
558 | } | 560 | } |
559 | 561 | ||
560 | /** | 562 | /** |
561 | * ieee80211_mps_frame_release - release buffered frames in response to beacon | 563 | * ieee80211_mps_frame_release - release frames buffered due to mesh power save |
562 | * | 564 | * |
563 | * @sta: mesh STA | 565 | * @sta: mesh STA |
564 | * @elems: beacon IEs | 566 | * @elems: IEs of beacon or probe response |
565 | * | 567 | * |
566 | * For peers if we have individually-addressed frames buffered or the peer | 568 | * For peers if we have individually-addressed frames buffered or the peer |
567 | * indicates buffered frames, send a corresponding MPSP trigger frame. Since | 569 | * indicates buffered frames, send a corresponding MPSP trigger frame. Since |
@@ -588,9 +590,10 @@ void ieee80211_mps_frame_release(struct sta_info *sta, | |||
588 | (!elems->awake_window || !le16_to_cpu(*elems->awake_window))) | 590 | (!elems->awake_window || !le16_to_cpu(*elems->awake_window))) |
589 | return; | 591 | return; |
590 | 592 | ||
591 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 593 | if (!test_sta_flag(sta, WLAN_STA_MPSP_OWNER)) |
592 | buffer_local += skb_queue_len(&sta->ps_tx_buf[ac]) + | 594 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
593 | skb_queue_len(&sta->tx_filtered[ac]); | 595 | buffer_local += skb_queue_len(&sta->ps_tx_buf[ac]) + |
596 | skb_queue_len(&sta->tx_filtered[ac]); | ||
594 | 597 | ||
595 | if (!has_buffered && !buffer_local) | 598 | if (!has_buffered && !buffer_local) |
596 | return; | 599 | return; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d7bdc4b97dde..d7504ab61a34 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -958,9 +958,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
958 | struct cfg80211_bss *cbss = ifmgd->associated; | 958 | struct cfg80211_bss *cbss = ifmgd->associated; |
959 | struct ieee80211_chanctx *chanctx; | 959 | struct ieee80211_chanctx *chanctx; |
960 | enum ieee80211_band current_band; | 960 | enum ieee80211_band current_band; |
961 | u8 count; | 961 | struct ieee80211_csa_ie csa_ie; |
962 | u8 mode; | ||
963 | struct cfg80211_chan_def new_chandef = {}; | ||
964 | int res; | 962 | int res; |
965 | 963 | ||
966 | sdata_assert_lock(sdata); | 964 | sdata_assert_lock(sdata); |
@@ -976,24 +974,24 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
976 | return; | 974 | return; |
977 | 975 | ||
978 | current_band = cbss->channel->band; | 976 | current_band = cbss->channel->band; |
977 | memset(&csa_ie, 0, sizeof(csa_ie)); | ||
979 | res = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, current_band, | 978 | res = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, current_band, |
980 | ifmgd->flags, | 979 | ifmgd->flags, |
981 | ifmgd->associated->bssid, &count, | 980 | ifmgd->associated->bssid, &csa_ie); |
982 | &mode, &new_chandef); | ||
983 | if (res < 0) | 981 | if (res < 0) |
984 | ieee80211_queue_work(&local->hw, | 982 | ieee80211_queue_work(&local->hw, |
985 | &ifmgd->csa_connection_drop_work); | 983 | &ifmgd->csa_connection_drop_work); |
986 | if (res) | 984 | if (res) |
987 | return; | 985 | return; |
988 | 986 | ||
989 | if (!cfg80211_chandef_usable(local->hw.wiphy, &new_chandef, | 987 | if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef, |
990 | IEEE80211_CHAN_DISABLED)) { | 988 | IEEE80211_CHAN_DISABLED)) { |
991 | sdata_info(sdata, | 989 | sdata_info(sdata, |
992 | "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n", | 990 | "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n", |
993 | ifmgd->associated->bssid, | 991 | ifmgd->associated->bssid, |
994 | new_chandef.chan->center_freq, | 992 | csa_ie.chandef.chan->center_freq, |
995 | new_chandef.width, new_chandef.center_freq1, | 993 | csa_ie.chandef.width, csa_ie.chandef.center_freq1, |
996 | new_chandef.center_freq2); | 994 | csa_ie.chandef.center_freq2); |
997 | ieee80211_queue_work(&local->hw, | 995 | ieee80211_queue_work(&local->hw, |
998 | &ifmgd->csa_connection_drop_work); | 996 | &ifmgd->csa_connection_drop_work); |
999 | return; | 997 | return; |
@@ -1037,9 +1035,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1037 | } | 1035 | } |
1038 | mutex_unlock(&local->chanctx_mtx); | 1036 | mutex_unlock(&local->chanctx_mtx); |
1039 | 1037 | ||
1040 | local->csa_chandef = new_chandef; | 1038 | local->csa_chandef = csa_ie.chandef; |
1041 | 1039 | ||
1042 | if (mode) | 1040 | if (csa_ie.mode) |
1043 | ieee80211_stop_queues_by_reason(&local->hw, | 1041 | ieee80211_stop_queues_by_reason(&local->hw, |
1044 | IEEE80211_MAX_QUEUE_MAP, | 1042 | IEEE80211_MAX_QUEUE_MAP, |
1045 | IEEE80211_QUEUE_STOP_REASON_CSA); | 1043 | IEEE80211_QUEUE_STOP_REASON_CSA); |
@@ -1048,9 +1046,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1048 | /* use driver's channel switch callback */ | 1046 | /* use driver's channel switch callback */ |
1049 | struct ieee80211_channel_switch ch_switch = { | 1047 | struct ieee80211_channel_switch ch_switch = { |
1050 | .timestamp = timestamp, | 1048 | .timestamp = timestamp, |
1051 | .block_tx = mode, | 1049 | .block_tx = csa_ie.mode, |
1052 | .chandef = new_chandef, | 1050 | .chandef = csa_ie.chandef, |
1053 | .count = count, | 1051 | .count = csa_ie.count, |
1054 | }; | 1052 | }; |
1055 | 1053 | ||
1056 | drv_channel_switch(local, &ch_switch); | 1054 | drv_channel_switch(local, &ch_switch); |
@@ -1058,11 +1056,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1058 | } | 1056 | } |
1059 | 1057 | ||
1060 | /* channel switch handled in software */ | 1058 | /* channel switch handled in software */ |
1061 | if (count <= 1) | 1059 | if (csa_ie.count <= 1) |
1062 | ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work); | 1060 | ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work); |
1063 | else | 1061 | else |
1064 | mod_timer(&ifmgd->chswitch_timer, | 1062 | mod_timer(&ifmgd->chswitch_timer, |
1065 | TU_TO_EXP_TIME(count * cbss->beacon_interval)); | 1063 | TU_TO_EXP_TIME(csa_ie.count * cbss->beacon_interval)); |
1066 | } | 1064 | } |
1067 | 1065 | ||
1068 | static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, | 1066 | static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, |
@@ -3500,7 +3498,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
3500 | ieee80211_beacon_connection_loss_work); | 3498 | ieee80211_beacon_connection_loss_work); |
3501 | INIT_WORK(&ifmgd->csa_connection_drop_work, | 3499 | INIT_WORK(&ifmgd->csa_connection_drop_work, |
3502 | ieee80211_csa_connection_drop_work); | 3500 | ieee80211_csa_connection_drop_work); |
3503 | INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_work); | 3501 | INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_mgd_work); |
3504 | setup_timer(&ifmgd->timer, ieee80211_sta_timer, | 3502 | setup_timer(&ifmgd->timer, ieee80211_sta_timer, |
3505 | (unsigned long) sdata); | 3503 | (unsigned long) sdata); |
3506 | setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, | 3504 | setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 0011ac815097..caecef870c0e 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -2593,13 +2593,16 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2593 | break; | 2593 | break; |
2594 | 2594 | ||
2595 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 2595 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
2596 | sdata->vif.type != NL80211_IFTYPE_ADHOC) | 2596 | sdata->vif.type != NL80211_IFTYPE_ADHOC && |
2597 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT) | ||
2597 | break; | 2598 | break; |
2598 | 2599 | ||
2599 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 2600 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
2600 | bssid = sdata->u.mgd.bssid; | 2601 | bssid = sdata->u.mgd.bssid; |
2601 | else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 2602 | else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
2602 | bssid = sdata->u.ibss.bssid; | 2603 | bssid = sdata->u.ibss.bssid; |
2604 | else if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | ||
2605 | bssid = mgmt->sa; | ||
2603 | else | 2606 | else |
2604 | break; | 2607 | break; |
2605 | 2608 | ||
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index 921597e279a3..a40da20b32e0 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c | |||
@@ -24,8 +24,8 @@ | |||
24 | int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | 24 | int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, |
25 | struct ieee802_11_elems *elems, bool beacon, | 25 | struct ieee802_11_elems *elems, bool beacon, |
26 | enum ieee80211_band current_band, | 26 | enum ieee80211_band current_band, |
27 | u32 sta_flags, u8 *bssid, u8 *count, u8 *mode, | 27 | u32 sta_flags, u8 *bssid, |
28 | struct cfg80211_chan_def *new_chandef) | 28 | struct ieee80211_csa_ie *csa_ie) |
29 | { | 29 | { |
30 | enum ieee80211_band new_band; | 30 | enum ieee80211_band new_band; |
31 | int new_freq; | 31 | int new_freq; |
@@ -62,18 +62,24 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | |||
62 | return -EINVAL; | 62 | return -EINVAL; |
63 | } | 63 | } |
64 | new_chan_no = elems->ext_chansw_ie->new_ch_num; | 64 | new_chan_no = elems->ext_chansw_ie->new_ch_num; |
65 | *count = elems->ext_chansw_ie->count; | 65 | csa_ie->count = elems->ext_chansw_ie->count; |
66 | *mode = elems->ext_chansw_ie->mode; | 66 | csa_ie->mode = elems->ext_chansw_ie->mode; |
67 | } else if (elems->ch_switch_ie) { | 67 | } else if (elems->ch_switch_ie) { |
68 | new_band = current_band; | 68 | new_band = current_band; |
69 | new_chan_no = elems->ch_switch_ie->new_ch_num; | 69 | new_chan_no = elems->ch_switch_ie->new_ch_num; |
70 | *count = elems->ch_switch_ie->count; | 70 | csa_ie->count = elems->ch_switch_ie->count; |
71 | *mode = elems->ch_switch_ie->mode; | 71 | csa_ie->mode = elems->ch_switch_ie->mode; |
72 | } else { | 72 | } else { |
73 | /* nothing here we understand */ | 73 | /* nothing here we understand */ |
74 | return 1; | 74 | return 1; |
75 | } | 75 | } |
76 | 76 | ||
77 | /* Mesh Channel Switch Parameters Element */ | ||
78 | if (elems->mesh_chansw_params_ie) { | ||
79 | csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl; | ||
80 | csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags; | ||
81 | } | ||
82 | |||
77 | new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band); | 83 | new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band); |
78 | new_chan = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq); | 84 | new_chan = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq); |
79 | if (!new_chan || new_chan->flags & IEEE80211_CHAN_DISABLED) { | 85 | if (!new_chan || new_chan->flags & IEEE80211_CHAN_DISABLED) { |
@@ -103,25 +109,26 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | |||
103 | default: | 109 | default: |
104 | /* secondary_channel_offset was present but is invalid */ | 110 | /* secondary_channel_offset was present but is invalid */ |
105 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: | 111 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: |
106 | cfg80211_chandef_create(new_chandef, new_chan, | 112 | cfg80211_chandef_create(&csa_ie->chandef, new_chan, |
107 | NL80211_CHAN_HT20); | 113 | NL80211_CHAN_HT20); |
108 | break; | 114 | break; |
109 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 115 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
110 | cfg80211_chandef_create(new_chandef, new_chan, | 116 | cfg80211_chandef_create(&csa_ie->chandef, new_chan, |
111 | NL80211_CHAN_HT40PLUS); | 117 | NL80211_CHAN_HT40PLUS); |
112 | break; | 118 | break; |
113 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | 119 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: |
114 | cfg80211_chandef_create(new_chandef, new_chan, | 120 | cfg80211_chandef_create(&csa_ie->chandef, new_chan, |
115 | NL80211_CHAN_HT40MINUS); | 121 | NL80211_CHAN_HT40MINUS); |
116 | break; | 122 | break; |
117 | case -1: | 123 | case -1: |
118 | cfg80211_chandef_create(new_chandef, new_chan, | 124 | cfg80211_chandef_create(&csa_ie->chandef, new_chan, |
119 | NL80211_CHAN_NO_HT); | 125 | NL80211_CHAN_NO_HT); |
120 | /* keep width for 5/10 MHz channels */ | 126 | /* keep width for 5/10 MHz channels */ |
121 | switch (sdata->vif.bss_conf.chandef.width) { | 127 | switch (sdata->vif.bss_conf.chandef.width) { |
122 | case NL80211_CHAN_WIDTH_5: | 128 | case NL80211_CHAN_WIDTH_5: |
123 | case NL80211_CHAN_WIDTH_10: | 129 | case NL80211_CHAN_WIDTH_10: |
124 | new_chandef->width = sdata->vif.bss_conf.chandef.width; | 130 | csa_ie->chandef.width = |
131 | sdata->vif.bss_conf.chandef.width; | ||
125 | break; | 132 | break; |
126 | default: | 133 | default: |
127 | break; | 134 | break; |
@@ -171,13 +178,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | |||
171 | /* if VHT data is there validate & use it */ | 178 | /* if VHT data is there validate & use it */ |
172 | if (new_vht_chandef.chan) { | 179 | if (new_vht_chandef.chan) { |
173 | if (!cfg80211_chandef_compatible(&new_vht_chandef, | 180 | if (!cfg80211_chandef_compatible(&new_vht_chandef, |
174 | new_chandef)) { | 181 | &csa_ie->chandef)) { |
175 | sdata_info(sdata, | 182 | sdata_info(sdata, |
176 | "BSS %pM: CSA has inconsistent channel data, disconnecting\n", | 183 | "BSS %pM: CSA has inconsistent channel data, disconnecting\n", |
177 | bssid); | 184 | bssid); |
178 | return -EINVAL; | 185 | return -EINVAL; |
179 | } | 186 | } |
180 | *new_chandef = new_vht_chandef; | 187 | csa_ie->chandef = new_vht_chandef; |
181 | } | 188 | } |
182 | 189 | ||
183 | return 0; | 190 | return 0; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index aeb967a0aeed..1eb66e26e49d 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -385,6 +385,30 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
385 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); | 385 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); |
386 | 386 | ||
387 | sta->sta.smps_mode = IEEE80211_SMPS_OFF; | 387 | sta->sta.smps_mode = IEEE80211_SMPS_OFF; |
388 | if (sdata->vif.type == NL80211_IFTYPE_AP || | ||
389 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { | ||
390 | struct ieee80211_supported_band *sband = | ||
391 | local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; | ||
392 | u8 smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> | ||
393 | IEEE80211_HT_CAP_SM_PS_SHIFT; | ||
394 | /* | ||
395 | * Assume that hostapd advertises our caps in the beacon and | ||
396 | * this is the known_smps_mode for a station that just assciated | ||
397 | */ | ||
398 | switch (smps) { | ||
399 | case WLAN_HT_SMPS_CONTROL_DISABLED: | ||
400 | sta->known_smps_mode = IEEE80211_SMPS_OFF; | ||
401 | break; | ||
402 | case WLAN_HT_SMPS_CONTROL_STATIC: | ||
403 | sta->known_smps_mode = IEEE80211_SMPS_STATIC; | ||
404 | break; | ||
405 | case WLAN_HT_SMPS_CONTROL_DYNAMIC: | ||
406 | sta->known_smps_mode = IEEE80211_SMPS_DYNAMIC; | ||
407 | break; | ||
408 | default: | ||
409 | WARN_ON(1); | ||
410 | } | ||
411 | } | ||
388 | 412 | ||
389 | sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); | 413 | sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); |
390 | 414 | ||
@@ -1069,6 +1093,19 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
1069 | 1093 | ||
1070 | ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta); | 1094 | ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta); |
1071 | 1095 | ||
1096 | /* This station just woke up and isn't aware of our SMPS state */ | ||
1097 | if (!ieee80211_smps_is_restrictive(sta->known_smps_mode, | ||
1098 | sdata->smps_mode) && | ||
1099 | sta->known_smps_mode != sdata->bss->req_smps && | ||
1100 | sta_info_tx_streams(sta) != 1) { | ||
1101 | ht_dbg(sdata, | ||
1102 | "%pM just woke up and MIMO capable - update SMPS\n", | ||
1103 | sta->sta.addr); | ||
1104 | ieee80211_send_smps_action(sdata, sdata->bss->req_smps, | ||
1105 | sta->sta.addr, | ||
1106 | sdata->vif.bss_conf.bssid); | ||
1107 | } | ||
1108 | |||
1072 | local->total_ps_buffered -= buffered; | 1109 | local->total_ps_buffered -= buffered; |
1073 | 1110 | ||
1074 | sta_info_recalc_tim(sta); | 1111 | sta_info_recalc_tim(sta); |
@@ -1520,3 +1557,38 @@ int sta_info_move_state(struct sta_info *sta, | |||
1520 | 1557 | ||
1521 | return 0; | 1558 | return 0; |
1522 | } | 1559 | } |
1560 | |||
1561 | u8 sta_info_tx_streams(struct sta_info *sta) | ||
1562 | { | ||
1563 | struct ieee80211_sta_ht_cap *ht_cap = &sta->sta.ht_cap; | ||
1564 | u8 rx_streams; | ||
1565 | |||
1566 | if (!sta->sta.ht_cap.ht_supported) | ||
1567 | return 1; | ||
1568 | |||
1569 | if (sta->sta.vht_cap.vht_supported) { | ||
1570 | int i; | ||
1571 | u16 tx_mcs_map = | ||
1572 | le16_to_cpu(sta->sta.vht_cap.vht_mcs.tx_mcs_map); | ||
1573 | |||
1574 | for (i = 7; i >= 0; i--) | ||
1575 | if ((tx_mcs_map & (0x3 << (i * 2))) != | ||
1576 | IEEE80211_VHT_MCS_NOT_SUPPORTED) | ||
1577 | return i + 1; | ||
1578 | } | ||
1579 | |||
1580 | if (ht_cap->mcs.rx_mask[3]) | ||
1581 | rx_streams = 4; | ||
1582 | else if (ht_cap->mcs.rx_mask[2]) | ||
1583 | rx_streams = 3; | ||
1584 | else if (ht_cap->mcs.rx_mask[1]) | ||
1585 | rx_streams = 2; | ||
1586 | else | ||
1587 | rx_streams = 1; | ||
1588 | |||
1589 | if (!(ht_cap->mcs.tx_params & IEEE80211_HT_MCS_TX_RX_DIFF)) | ||
1590 | return rx_streams; | ||
1591 | |||
1592 | return ((ht_cap->mcs.tx_params & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) | ||
1593 | >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1; | ||
1594 | } | ||
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 4208dbd5861f..3ef06a26b9cb 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -301,6 +301,8 @@ struct sta_ampdu_mlme { | |||
301 | * @chains: chains ever used for RX from this station | 301 | * @chains: chains ever used for RX from this station |
302 | * @chain_signal_last: last signal (per chain) | 302 | * @chain_signal_last: last signal (per chain) |
303 | * @chain_signal_avg: signal average (per chain) | 303 | * @chain_signal_avg: signal average (per chain) |
304 | * @known_smps_mode: the smps_mode the client thinks we are in. Relevant for | ||
305 | * AP only. | ||
304 | */ | 306 | */ |
305 | struct sta_info { | 307 | struct sta_info { |
306 | /* General information, mostly static */ | 308 | /* General information, mostly static */ |
@@ -411,6 +413,8 @@ struct sta_info { | |||
411 | unsigned int lost_packets; | 413 | unsigned int lost_packets; |
412 | unsigned int beacon_loss_count; | 414 | unsigned int beacon_loss_count; |
413 | 415 | ||
416 | enum ieee80211_smps_mode known_smps_mode; | ||
417 | |||
414 | /* keep last! */ | 418 | /* keep last! */ |
415 | struct ieee80211_sta sta; | 419 | struct ieee80211_sta sta; |
416 | }; | 420 | }; |
@@ -613,6 +617,7 @@ void sta_set_rate_info_rx(struct sta_info *sta, | |||
613 | struct rate_info *rinfo); | 617 | struct rate_info *rinfo); |
614 | void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | 618 | void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, |
615 | unsigned long exp_time); | 619 | unsigned long exp_time); |
620 | u8 sta_info_tx_streams(struct sta_info *sta); | ||
616 | 621 | ||
617 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta); | 622 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta); |
618 | void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta); | 623 | void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta); |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 78dc2e99027e..52a152b01b06 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -194,29 +194,36 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) | |||
194 | if (ieee80211_is_action(mgmt->frame_control) && | 194 | if (ieee80211_is_action(mgmt->frame_control) && |
195 | mgmt->u.action.category == WLAN_CATEGORY_HT && | 195 | mgmt->u.action.category == WLAN_CATEGORY_HT && |
196 | mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS && | 196 | mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS && |
197 | sdata->vif.type == NL80211_IFTYPE_STATION && | ||
198 | ieee80211_sdata_running(sdata)) { | 197 | ieee80211_sdata_running(sdata)) { |
199 | /* | 198 | enum ieee80211_smps_mode smps_mode; |
200 | * This update looks racy, but isn't -- if we come | 199 | |
201 | * here we've definitely got a station that we're | ||
202 | * talking to, and on a managed interface that can | ||
203 | * only be the AP. And the only other place updating | ||
204 | * this variable in managed mode is before association. | ||
205 | */ | ||
206 | switch (mgmt->u.action.u.ht_smps.smps_control) { | 200 | switch (mgmt->u.action.u.ht_smps.smps_control) { |
207 | case WLAN_HT_SMPS_CONTROL_DYNAMIC: | 201 | case WLAN_HT_SMPS_CONTROL_DYNAMIC: |
208 | sdata->smps_mode = IEEE80211_SMPS_DYNAMIC; | 202 | smps_mode = IEEE80211_SMPS_DYNAMIC; |
209 | break; | 203 | break; |
210 | case WLAN_HT_SMPS_CONTROL_STATIC: | 204 | case WLAN_HT_SMPS_CONTROL_STATIC: |
211 | sdata->smps_mode = IEEE80211_SMPS_STATIC; | 205 | smps_mode = IEEE80211_SMPS_STATIC; |
212 | break; | 206 | break; |
213 | case WLAN_HT_SMPS_CONTROL_DISABLED: | 207 | case WLAN_HT_SMPS_CONTROL_DISABLED: |
214 | default: /* shouldn't happen since we don't send that */ | 208 | default: /* shouldn't happen since we don't send that */ |
215 | sdata->smps_mode = IEEE80211_SMPS_OFF; | 209 | smps_mode = IEEE80211_SMPS_OFF; |
216 | break; | 210 | break; |
217 | } | 211 | } |
218 | 212 | ||
219 | ieee80211_queue_work(&local->hw, &sdata->recalc_smps); | 213 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
214 | /* | ||
215 | * This update looks racy, but isn't -- if we come | ||
216 | * here we've definitely got a station that we're | ||
217 | * talking to, and on a managed interface that can | ||
218 | * only be the AP. And the only other place updating | ||
219 | * this variable in managed mode is before association. | ||
220 | */ | ||
221 | sdata->smps_mode = smps_mode; | ||
222 | ieee80211_queue_work(&local->hw, &sdata->recalc_smps); | ||
223 | } else if (sdata->vif.type == NL80211_IFTYPE_AP || | ||
224 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { | ||
225 | sta->known_smps_mode = smps_mode; | ||
226 | } | ||
220 | } | 227 | } |
221 | } | 228 | } |
222 | 229 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 9993fcb19ecd..c558b246ef00 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1367,6 +1367,35 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1367 | return 0; | 1367 | return 0; |
1368 | } | 1368 | } |
1369 | 1369 | ||
1370 | bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw, | ||
1371 | struct ieee80211_vif *vif, struct sk_buff *skb, | ||
1372 | int band, struct ieee80211_sta **sta) | ||
1373 | { | ||
1374 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
1375 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1376 | struct ieee80211_tx_data tx; | ||
1377 | |||
1378 | if (ieee80211_tx_prepare(sdata, &tx, skb) == TX_DROP) | ||
1379 | return false; | ||
1380 | |||
1381 | info->band = band; | ||
1382 | info->control.vif = vif; | ||
1383 | info->hw_queue = vif->hw_queue[skb_get_queue_mapping(skb)]; | ||
1384 | |||
1385 | if (invoke_tx_handlers(&tx)) | ||
1386 | return false; | ||
1387 | |||
1388 | if (sta) { | ||
1389 | if (tx.sta) | ||
1390 | *sta = &tx.sta->sta; | ||
1391 | else | ||
1392 | *sta = NULL; | ||
1393 | } | ||
1394 | |||
1395 | return true; | ||
1396 | } | ||
1397 | EXPORT_SYMBOL(ieee80211_tx_prepare_skb); | ||
1398 | |||
1370 | /* | 1399 | /* |
1371 | * Returns false if the frame couldn't be transmitted but was queued instead. | 1400 | * Returns false if the frame couldn't be transmitted but was queued instead. |
1372 | */ | 1401 | */ |
@@ -2370,6 +2399,10 @@ static void ieee80211_update_csa(struct ieee80211_sub_if_data *sdata, | |||
2370 | beacon_data = beacon->head; | 2399 | beacon_data = beacon->head; |
2371 | beacon_data_len = beacon->head_len; | 2400 | beacon_data_len = beacon->head_len; |
2372 | break; | 2401 | break; |
2402 | case NL80211_IFTYPE_MESH_POINT: | ||
2403 | beacon_data = beacon->head; | ||
2404 | beacon_data_len = beacon->head_len; | ||
2405 | break; | ||
2373 | default: | 2406 | default: |
2374 | return; | 2407 | return; |
2375 | } | 2408 | } |
@@ -2426,6 +2459,15 @@ bool ieee80211_csa_is_complete(struct ieee80211_vif *vif) | |||
2426 | 2459 | ||
2427 | beacon_data = beacon->head; | 2460 | beacon_data = beacon->head; |
2428 | beacon_data_len = beacon->head_len; | 2461 | beacon_data_len = beacon->head_len; |
2462 | } else if (vif->type == NL80211_IFTYPE_MESH_POINT) { | ||
2463 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
2464 | |||
2465 | beacon = rcu_dereference(ifmsh->beacon); | ||
2466 | if (!beacon) | ||
2467 | goto out; | ||
2468 | |||
2469 | beacon_data = beacon->head; | ||
2470 | beacon_data_len = beacon->head_len; | ||
2429 | } else { | 2471 | } else { |
2430 | WARN_ON(1); | 2472 | WARN_ON(1); |
2431 | goto out; | 2473 | goto out; |
@@ -2531,6 +2573,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2531 | if (!bcn) | 2573 | if (!bcn) |
2532 | goto out; | 2574 | goto out; |
2533 | 2575 | ||
2576 | if (sdata->vif.csa_active) | ||
2577 | ieee80211_update_csa(sdata, bcn); | ||
2578 | |||
2534 | if (ifmsh->sync_ops) | 2579 | if (ifmsh->sync_ops) |
2535 | ifmsh->sync_ops->adjust_tbtt( | 2580 | ifmsh->sync_ops->adjust_tbtt( |
2536 | sdata); | 2581 | sdata); |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index aefb9d5b9620..592a18171f95 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -300,9 +300,6 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) | |||
300 | if (!sdata->dev) | 300 | if (!sdata->dev) |
301 | continue; | 301 | continue; |
302 | 302 | ||
303 | if (test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) | ||
304 | continue; | ||
305 | |||
306 | if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE && | 303 | if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE && |
307 | local->queue_stop_reasons[sdata->vif.cab_queue] != 0) | 304 | local->queue_stop_reasons[sdata->vif.cab_queue] != 0) |
308 | continue; | 305 | continue; |
@@ -743,6 +740,7 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, | |||
743 | case WLAN_EID_TIMEOUT_INTERVAL: | 740 | case WLAN_EID_TIMEOUT_INTERVAL: |
744 | case WLAN_EID_SECONDARY_CHANNEL_OFFSET: | 741 | case WLAN_EID_SECONDARY_CHANNEL_OFFSET: |
745 | case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: | 742 | case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: |
743 | case WLAN_EID_CHAN_SWITCH_PARAM: | ||
746 | /* | 744 | /* |
747 | * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible | 745 | * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible |
748 | * that if the content gets bigger it might be needed more than once | 746 | * that if the content gets bigger it might be needed more than once |
@@ -908,6 +906,14 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, | |||
908 | } | 906 | } |
909 | elems->sec_chan_offs = (void *)pos; | 907 | elems->sec_chan_offs = (void *)pos; |
910 | break; | 908 | break; |
909 | case WLAN_EID_CHAN_SWITCH_PARAM: | ||
910 | if (elen != | ||
911 | sizeof(*elems->mesh_chansw_params_ie)) { | ||
912 | elem_parse_failed = true; | ||
913 | break; | ||
914 | } | ||
915 | elems->mesh_chansw_params_ie = (void *)pos; | ||
916 | break; | ||
911 | case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: | 917 | case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: |
912 | if (!action || | 918 | if (!action || |
913 | elen != sizeof(*elems->wide_bw_chansw_ie)) { | 919 | elen != sizeof(*elems->wide_bw_chansw_ie)) { |
@@ -2354,3 +2360,115 @@ u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c) | |||
2354 | 2360 | ||
2355 | return ret; | 2361 | return ret; |
2356 | } | 2362 | } |
2363 | |||
2364 | /* | ||
2365 | * Returns true if smps_mode_new is strictly more restrictive than | ||
2366 | * smps_mode_old. | ||
2367 | */ | ||
2368 | bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old, | ||
2369 | enum ieee80211_smps_mode smps_mode_new) | ||
2370 | { | ||
2371 | if (WARN_ON_ONCE(smps_mode_old == IEEE80211_SMPS_AUTOMATIC || | ||
2372 | smps_mode_new == IEEE80211_SMPS_AUTOMATIC)) | ||
2373 | return false; | ||
2374 | |||
2375 | switch (smps_mode_old) { | ||
2376 | case IEEE80211_SMPS_STATIC: | ||
2377 | return false; | ||
2378 | case IEEE80211_SMPS_DYNAMIC: | ||
2379 | return smps_mode_new == IEEE80211_SMPS_STATIC; | ||
2380 | case IEEE80211_SMPS_OFF: | ||
2381 | return smps_mode_new != IEEE80211_SMPS_OFF; | ||
2382 | default: | ||
2383 | WARN_ON(1); | ||
2384 | } | ||
2385 | |||
2386 | return false; | ||
2387 | } | ||
2388 | |||
2389 | int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, | ||
2390 | struct cfg80211_csa_settings *csa_settings) | ||
2391 | { | ||
2392 | struct sk_buff *skb; | ||
2393 | struct ieee80211_mgmt *mgmt; | ||
2394 | struct ieee80211_local *local = sdata->local; | ||
2395 | int freq; | ||
2396 | int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.chan_switch) + | ||
2397 | sizeof(mgmt->u.action.u.chan_switch); | ||
2398 | u8 *pos; | ||
2399 | |||
2400 | if (sdata->vif.type != NL80211_IFTYPE_ADHOC && | ||
2401 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT) | ||
2402 | return -EOPNOTSUPP; | ||
2403 | |||
2404 | skb = dev_alloc_skb(local->tx_headroom + hdr_len + | ||
2405 | 5 + /* channel switch announcement element */ | ||
2406 | 3 + /* secondary channel offset element */ | ||
2407 | 8); /* mesh channel switch parameters element */ | ||
2408 | if (!skb) | ||
2409 | return -ENOMEM; | ||
2410 | |||
2411 | skb_reserve(skb, local->tx_headroom); | ||
2412 | mgmt = (struct ieee80211_mgmt *)skb_put(skb, hdr_len); | ||
2413 | memset(mgmt, 0, hdr_len); | ||
2414 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
2415 | IEEE80211_STYPE_ACTION); | ||
2416 | |||
2417 | eth_broadcast_addr(mgmt->da); | ||
2418 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | ||
2419 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
2420 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); | ||
2421 | } else { | ||
2422 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | ||
2423 | memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); | ||
2424 | } | ||
2425 | mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; | ||
2426 | mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH; | ||
2427 | pos = skb_put(skb, 5); | ||
2428 | *pos++ = WLAN_EID_CHANNEL_SWITCH; /* EID */ | ||
2429 | *pos++ = 3; /* IE length */ | ||
2430 | *pos++ = csa_settings->block_tx ? 1 : 0; /* CSA mode */ | ||
2431 | freq = csa_settings->chandef.chan->center_freq; | ||
2432 | *pos++ = ieee80211_frequency_to_channel(freq); /* channel */ | ||
2433 | *pos++ = csa_settings->count; /* count */ | ||
2434 | |||
2435 | if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_40) { | ||
2436 | enum nl80211_channel_type ch_type; | ||
2437 | |||
2438 | skb_put(skb, 3); | ||
2439 | *pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; /* EID */ | ||
2440 | *pos++ = 1; /* IE length */ | ||
2441 | ch_type = cfg80211_get_chandef_type(&csa_settings->chandef); | ||
2442 | if (ch_type == NL80211_CHAN_HT40PLUS) | ||
2443 | *pos++ = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
2444 | else | ||
2445 | *pos++ = IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
2446 | } | ||
2447 | |||
2448 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
2449 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
2450 | __le16 pre_value; | ||
2451 | |||
2452 | skb_put(skb, 8); | ||
2453 | *pos++ = WLAN_EID_CHAN_SWITCH_PARAM; /* EID */ | ||
2454 | *pos++ = 6; /* IE length */ | ||
2455 | *pos++ = sdata->u.mesh.mshcfg.dot11MeshTTL; /* Mesh TTL */ | ||
2456 | *pos = 0x00; /* Mesh Flag: Tx Restrict, Initiator, Reason */ | ||
2457 | *pos |= WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; | ||
2458 | *pos++ |= csa_settings->block_tx ? | ||
2459 | WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; | ||
2460 | put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */ | ||
2461 | pos += 2; | ||
2462 | if (!ifmsh->pre_value) | ||
2463 | ifmsh->pre_value = 1; | ||
2464 | else | ||
2465 | ifmsh->pre_value++; | ||
2466 | pre_value = cpu_to_le16(ifmsh->pre_value); | ||
2467 | memcpy(pos, &pre_value, 2); /* Precedence Value */ | ||
2468 | pos += 2; | ||
2469 | ifmsh->chsw_init = true; | ||
2470 | } | ||
2471 | |||
2472 | ieee80211_tx_skb(sdata, skb); | ||
2473 | return 0; | ||
2474 | } | ||
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index c9edfcb7a13b..d65728220763 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -301,22 +301,16 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
301 | } | 301 | } |
302 | 302 | ||
303 | 303 | ||
304 | static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, | 304 | static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, |
305 | int encrypted) | 305 | int encrypted) |
306 | { | 306 | { |
307 | __le16 mask_fc; | 307 | __le16 mask_fc; |
308 | int a4_included, mgmt; | 308 | int a4_included, mgmt; |
309 | u8 qos_tid; | 309 | u8 qos_tid; |
310 | u8 *b_0, *aad; | 310 | u16 len_a; |
311 | u16 data_len, len_a; | ||
312 | unsigned int hdrlen; | 311 | unsigned int hdrlen; |
313 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 312 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
314 | 313 | ||
315 | memset(scratch, 0, 6 * AES_BLOCK_SIZE); | ||
316 | |||
317 | b_0 = scratch + 3 * AES_BLOCK_SIZE; | ||
318 | aad = scratch + 4 * AES_BLOCK_SIZE; | ||
319 | |||
320 | /* | 314 | /* |
321 | * Mask FC: zero subtype b4 b5 b6 (if not mgmt) | 315 | * Mask FC: zero subtype b4 b5 b6 (if not mgmt) |
322 | * Retry, PwrMgt, MoreData; set Protected | 316 | * Retry, PwrMgt, MoreData; set Protected |
@@ -338,20 +332,21 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, | |||
338 | else | 332 | else |
339 | qos_tid = 0; | 333 | qos_tid = 0; |
340 | 334 | ||
341 | data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN; | 335 | /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC |
342 | if (encrypted) | 336 | * mode authentication are not allowed to collide, yet both are derived |
343 | data_len -= IEEE80211_CCMP_MIC_LEN; | 337 | * from this vector b_0. We only set L := 1 here to indicate that the |
338 | * data size can be represented in (L+1) bytes. The CCM layer will take | ||
339 | * care of storing the data length in the top (L+1) bytes and setting | ||
340 | * and clearing the other bits as is required to derive the two IVs. | ||
341 | */ | ||
342 | b_0[0] = 0x1; | ||
344 | 343 | ||
345 | /* First block, b_0 */ | ||
346 | b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ | ||
347 | /* Nonce: Nonce Flags | A2 | PN | 344 | /* Nonce: Nonce Flags | A2 | PN |
348 | * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) | 345 | * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) |
349 | */ | 346 | */ |
350 | b_0[1] = qos_tid | (mgmt << 4); | 347 | b_0[1] = qos_tid | (mgmt << 4); |
351 | memcpy(&b_0[2], hdr->addr2, ETH_ALEN); | 348 | memcpy(&b_0[2], hdr->addr2, ETH_ALEN); |
352 | memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); | 349 | memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); |
353 | /* l(m) */ | ||
354 | put_unaligned_be16(data_len, &b_0[14]); | ||
355 | 350 | ||
356 | /* AAD (extra authenticate-only data) / masked 802.11 header | 351 | /* AAD (extra authenticate-only data) / masked 802.11 header |
357 | * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ | 352 | * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ |
@@ -407,7 +402,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
407 | u8 *pos; | 402 | u8 *pos; |
408 | u8 pn[6]; | 403 | u8 pn[6]; |
409 | u64 pn64; | 404 | u64 pn64; |
410 | u8 scratch[6 * AES_BLOCK_SIZE]; | 405 | u8 aad[2 * AES_BLOCK_SIZE]; |
406 | u8 b_0[AES_BLOCK_SIZE]; | ||
411 | 407 | ||
412 | if (info->control.hw_key && | 408 | if (info->control.hw_key && |
413 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) && | 409 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) && |
@@ -460,9 +456,9 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
460 | return 0; | 456 | return 0; |
461 | 457 | ||
462 | pos += IEEE80211_CCMP_HDR_LEN; | 458 | pos += IEEE80211_CCMP_HDR_LEN; |
463 | ccmp_special_blocks(skb, pn, scratch, 0); | 459 | ccmp_special_blocks(skb, pn, b_0, aad, 0); |
464 | ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len, | 460 | ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, |
465 | pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN)); | 461 | skb_put(skb, IEEE80211_CCMP_MIC_LEN)); |
466 | 462 | ||
467 | return 0; | 463 | return 0; |
468 | } | 464 | } |
@@ -525,16 +521,16 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
525 | } | 521 | } |
526 | 522 | ||
527 | if (!(status->flag & RX_FLAG_DECRYPTED)) { | 523 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
528 | u8 scratch[6 * AES_BLOCK_SIZE]; | 524 | u8 aad[2 * AES_BLOCK_SIZE]; |
525 | u8 b_0[AES_BLOCK_SIZE]; | ||
529 | /* hardware didn't decrypt/verify MIC */ | 526 | /* hardware didn't decrypt/verify MIC */ |
530 | ccmp_special_blocks(skb, pn, scratch, 1); | 527 | ccmp_special_blocks(skb, pn, b_0, aad, 1); |
531 | 528 | ||
532 | if (ieee80211_aes_ccm_decrypt( | 529 | if (ieee80211_aes_ccm_decrypt( |
533 | key->u.ccmp.tfm, scratch, | 530 | key->u.ccmp.tfm, b_0, aad, |
534 | skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, | 531 | skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, |
535 | data_len, | 532 | data_len, |
536 | skb->data + skb->len - IEEE80211_CCMP_MIC_LEN, | 533 | skb->data + skb->len - IEEE80211_CCMP_MIC_LEN)) |
537 | skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN)) | ||
538 | return RX_DROP_UNUSABLE; | 534 | return RX_DROP_UNUSABLE; |
539 | } | 535 | } |
540 | 536 | ||
diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig index 78efe895b663..4c10e7e6c9f6 100644 --- a/net/rfkill/Kconfig +++ b/net/rfkill/Kconfig | |||
@@ -36,7 +36,7 @@ config RFKILL_REGULATOR | |||
36 | 36 | ||
37 | config RFKILL_GPIO | 37 | config RFKILL_GPIO |
38 | tristate "GPIO RFKILL driver" | 38 | tristate "GPIO RFKILL driver" |
39 | depends on RFKILL && GPIOLIB && HAVE_CLK | 39 | depends on RFKILL && GPIOLIB |
40 | default n | 40 | default n |
41 | help | 41 | help |
42 | If you say yes here you get support of a generic gpio RFKILL | 42 | If you say yes here you get support of a generic gpio RFKILL |
diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c index fb076cd6f808..5620d3c07479 100644 --- a/net/rfkill/rfkill-gpio.c +++ b/net/rfkill/rfkill-gpio.c | |||
@@ -24,27 +24,23 @@ | |||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/acpi.h> | ||
28 | #include <linux/acpi_gpio.h> | ||
27 | 29 | ||
28 | #include <linux/rfkill-gpio.h> | 30 | #include <linux/rfkill-gpio.h> |
29 | 31 | ||
30 | enum rfkill_gpio_clk_state { | 32 | struct rfkill_gpio_data { |
31 | UNSPECIFIED = 0, | 33 | const char *name; |
32 | PWR_ENABLED, | 34 | enum rfkill_type type; |
33 | PWR_DISABLED | 35 | int reset_gpio; |
34 | }; | 36 | int shutdown_gpio; |
35 | 37 | ||
36 | #define PWR_CLK_SET(_RF, _EN) \ | 38 | struct rfkill *rfkill_dev; |
37 | ((_RF)->pwr_clk_enabled = (!(_EN) ? PWR_ENABLED : PWR_DISABLED)) | 39 | char *reset_name; |
38 | #define PWR_CLK_ENABLED(_RF) ((_RF)->pwr_clk_enabled == PWR_ENABLED) | 40 | char *shutdown_name; |
39 | #define PWR_CLK_DISABLED(_RF) ((_RF)->pwr_clk_enabled != PWR_ENABLED) | 41 | struct clk *clk; |
40 | 42 | ||
41 | struct rfkill_gpio_data { | 43 | bool clk_enabled; |
42 | struct rfkill_gpio_platform_data *pdata; | ||
43 | struct rfkill *rfkill_dev; | ||
44 | char *reset_name; | ||
45 | char *shutdown_name; | ||
46 | enum rfkill_gpio_clk_state pwr_clk_enabled; | ||
47 | struct clk *pwr_clk; | ||
48 | }; | 44 | }; |
49 | 45 | ||
50 | static int rfkill_gpio_set_power(void *data, bool blocked) | 46 | static int rfkill_gpio_set_power(void *data, bool blocked) |
@@ -52,23 +48,22 @@ static int rfkill_gpio_set_power(void *data, bool blocked) | |||
52 | struct rfkill_gpio_data *rfkill = data; | 48 | struct rfkill_gpio_data *rfkill = data; |
53 | 49 | ||
54 | if (blocked) { | 50 | if (blocked) { |
55 | if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) | 51 | if (gpio_is_valid(rfkill->shutdown_gpio)) |
56 | gpio_direction_output(rfkill->pdata->shutdown_gpio, 0); | 52 | gpio_set_value(rfkill->shutdown_gpio, 0); |
57 | if (gpio_is_valid(rfkill->pdata->reset_gpio)) | 53 | if (gpio_is_valid(rfkill->reset_gpio)) |
58 | gpio_direction_output(rfkill->pdata->reset_gpio, 0); | 54 | gpio_set_value(rfkill->reset_gpio, 0); |
59 | if (rfkill->pwr_clk && PWR_CLK_ENABLED(rfkill)) | 55 | if (!IS_ERR(rfkill->clk) && rfkill->clk_enabled) |
60 | clk_disable(rfkill->pwr_clk); | 56 | clk_disable(rfkill->clk); |
61 | } else { | 57 | } else { |
62 | if (rfkill->pwr_clk && PWR_CLK_DISABLED(rfkill)) | 58 | if (!IS_ERR(rfkill->clk) && !rfkill->clk_enabled) |
63 | clk_enable(rfkill->pwr_clk); | 59 | clk_enable(rfkill->clk); |
64 | if (gpio_is_valid(rfkill->pdata->reset_gpio)) | 60 | if (gpio_is_valid(rfkill->reset_gpio)) |
65 | gpio_direction_output(rfkill->pdata->reset_gpio, 1); | 61 | gpio_set_value(rfkill->reset_gpio, 1); |
66 | if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) | 62 | if (gpio_is_valid(rfkill->shutdown_gpio)) |
67 | gpio_direction_output(rfkill->pdata->shutdown_gpio, 1); | 63 | gpio_set_value(rfkill->shutdown_gpio, 1); |
68 | } | 64 | } |
69 | 65 | ||
70 | if (rfkill->pwr_clk) | 66 | rfkill->clk_enabled = blocked; |
71 | PWR_CLK_SET(rfkill, blocked); | ||
72 | 67 | ||
73 | return 0; | 68 | return 0; |
74 | } | 69 | } |
@@ -77,117 +72,112 @@ static const struct rfkill_ops rfkill_gpio_ops = { | |||
77 | .set_block = rfkill_gpio_set_power, | 72 | .set_block = rfkill_gpio_set_power, |
78 | }; | 73 | }; |
79 | 74 | ||
75 | static int rfkill_gpio_acpi_probe(struct device *dev, | ||
76 | struct rfkill_gpio_data *rfkill) | ||
77 | { | ||
78 | const struct acpi_device_id *id; | ||
79 | |||
80 | id = acpi_match_device(dev->driver->acpi_match_table, dev); | ||
81 | if (!id) | ||
82 | return -ENODEV; | ||
83 | |||
84 | rfkill->name = dev_name(dev); | ||
85 | rfkill->type = (unsigned)id->driver_data; | ||
86 | rfkill->reset_gpio = acpi_get_gpio_by_index(dev, 0, NULL); | ||
87 | rfkill->shutdown_gpio = acpi_get_gpio_by_index(dev, 1, NULL); | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
80 | static int rfkill_gpio_probe(struct platform_device *pdev) | 92 | static int rfkill_gpio_probe(struct platform_device *pdev) |
81 | { | 93 | { |
82 | struct rfkill_gpio_data *rfkill; | ||
83 | struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data; | 94 | struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data; |
95 | struct rfkill_gpio_data *rfkill; | ||
96 | const char *clk_name = NULL; | ||
84 | int ret = 0; | 97 | int ret = 0; |
85 | int len = 0; | 98 | int len = 0; |
86 | 99 | ||
87 | if (!pdata) { | 100 | rfkill = devm_kzalloc(&pdev->dev, sizeof(*rfkill), GFP_KERNEL); |
88 | pr_warn("%s: No platform data specified\n", __func__); | 101 | if (!rfkill) |
89 | return -EINVAL; | 102 | return -ENOMEM; |
103 | |||
104 | if (ACPI_HANDLE(&pdev->dev)) { | ||
105 | ret = rfkill_gpio_acpi_probe(&pdev->dev, rfkill); | ||
106 | if (ret) | ||
107 | return ret; | ||
108 | } else if (pdata) { | ||
109 | clk_name = pdata->power_clk_name; | ||
110 | rfkill->name = pdata->name; | ||
111 | rfkill->type = pdata->type; | ||
112 | rfkill->reset_gpio = pdata->reset_gpio; | ||
113 | rfkill->shutdown_gpio = pdata->shutdown_gpio; | ||
114 | } else { | ||
115 | return -ENODEV; | ||
90 | } | 116 | } |
91 | 117 | ||
92 | /* make sure at-least one of the GPIO is defined and that | 118 | /* make sure at-least one of the GPIO is defined and that |
93 | * a name is specified for this instance */ | 119 | * a name is specified for this instance */ |
94 | if (!pdata->name || (!gpio_is_valid(pdata->reset_gpio) && | 120 | if ((!gpio_is_valid(rfkill->reset_gpio) && |
95 | !gpio_is_valid(pdata->shutdown_gpio))) { | 121 | !gpio_is_valid(rfkill->shutdown_gpio)) || !rfkill->name) { |
96 | pr_warn("%s: invalid platform data\n", __func__); | 122 | pr_warn("%s: invalid platform data\n", __func__); |
97 | return -EINVAL; | 123 | return -EINVAL; |
98 | } | 124 | } |
99 | 125 | ||
100 | rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL); | 126 | if (pdata && pdata->gpio_runtime_setup) { |
101 | if (!rfkill) | ||
102 | return -ENOMEM; | ||
103 | |||
104 | if (pdata->gpio_runtime_setup) { | ||
105 | ret = pdata->gpio_runtime_setup(pdev); | 127 | ret = pdata->gpio_runtime_setup(pdev); |
106 | if (ret) { | 128 | if (ret) { |
107 | pr_warn("%s: can't set up gpio\n", __func__); | 129 | pr_warn("%s: can't set up gpio\n", __func__); |
108 | goto fail_alloc; | 130 | return ret; |
109 | } | 131 | } |
110 | } | 132 | } |
111 | 133 | ||
112 | rfkill->pdata = pdata; | 134 | len = strlen(rfkill->name); |
113 | 135 | rfkill->reset_name = devm_kzalloc(&pdev->dev, len + 7, GFP_KERNEL); | |
114 | len = strlen(pdata->name); | 136 | if (!rfkill->reset_name) |
115 | rfkill->reset_name = kzalloc(len + 7, GFP_KERNEL); | 137 | return -ENOMEM; |
116 | if (!rfkill->reset_name) { | ||
117 | ret = -ENOMEM; | ||
118 | goto fail_alloc; | ||
119 | } | ||
120 | 138 | ||
121 | rfkill->shutdown_name = kzalloc(len + 10, GFP_KERNEL); | 139 | rfkill->shutdown_name = devm_kzalloc(&pdev->dev, len + 10, GFP_KERNEL); |
122 | if (!rfkill->shutdown_name) { | 140 | if (!rfkill->shutdown_name) |
123 | ret = -ENOMEM; | 141 | return -ENOMEM; |
124 | goto fail_reset_name; | ||
125 | } | ||
126 | 142 | ||
127 | snprintf(rfkill->reset_name, len + 6 , "%s_reset", pdata->name); | 143 | snprintf(rfkill->reset_name, len + 6 , "%s_reset", rfkill->name); |
128 | snprintf(rfkill->shutdown_name, len + 9, "%s_shutdown", pdata->name); | 144 | snprintf(rfkill->shutdown_name, len + 9, "%s_shutdown", rfkill->name); |
129 | 145 | ||
130 | if (pdata->power_clk_name) { | 146 | rfkill->clk = devm_clk_get(&pdev->dev, clk_name); |
131 | rfkill->pwr_clk = clk_get(&pdev->dev, pdata->power_clk_name); | ||
132 | if (IS_ERR(rfkill->pwr_clk)) { | ||
133 | pr_warn("%s: can't find pwr_clk.\n", __func__); | ||
134 | ret = PTR_ERR(rfkill->pwr_clk); | ||
135 | goto fail_shutdown_name; | ||
136 | } | ||
137 | } | ||
138 | 147 | ||
139 | if (gpio_is_valid(pdata->reset_gpio)) { | 148 | if (gpio_is_valid(rfkill->reset_gpio)) { |
140 | ret = gpio_request(pdata->reset_gpio, rfkill->reset_name); | 149 | ret = devm_gpio_request_one(&pdev->dev, rfkill->reset_gpio, |
150 | 0, rfkill->reset_name); | ||
141 | if (ret) { | 151 | if (ret) { |
142 | pr_warn("%s: failed to get reset gpio.\n", __func__); | 152 | pr_warn("%s: failed to get reset gpio.\n", __func__); |
143 | goto fail_clock; | 153 | return ret; |
144 | } | 154 | } |
145 | } | 155 | } |
146 | 156 | ||
147 | if (gpio_is_valid(pdata->shutdown_gpio)) { | 157 | if (gpio_is_valid(rfkill->shutdown_gpio)) { |
148 | ret = gpio_request(pdata->shutdown_gpio, rfkill->shutdown_name); | 158 | ret = devm_gpio_request_one(&pdev->dev, rfkill->shutdown_gpio, |
159 | 0, rfkill->shutdown_name); | ||
149 | if (ret) { | 160 | if (ret) { |
150 | pr_warn("%s: failed to get shutdown gpio.\n", __func__); | 161 | pr_warn("%s: failed to get shutdown gpio.\n", __func__); |
151 | goto fail_reset; | 162 | return ret; |
152 | } | 163 | } |
153 | } | 164 | } |
154 | 165 | ||
155 | rfkill->rfkill_dev = rfkill_alloc(pdata->name, &pdev->dev, pdata->type, | 166 | rfkill->rfkill_dev = rfkill_alloc(rfkill->name, &pdev->dev, |
156 | &rfkill_gpio_ops, rfkill); | 167 | rfkill->type, &rfkill_gpio_ops, |
157 | if (!rfkill->rfkill_dev) { | 168 | rfkill); |
158 | ret = -ENOMEM; | 169 | if (!rfkill->rfkill_dev) |
159 | goto fail_shutdown; | 170 | return -ENOMEM; |
160 | } | ||
161 | 171 | ||
162 | ret = rfkill_register(rfkill->rfkill_dev); | 172 | ret = rfkill_register(rfkill->rfkill_dev); |
163 | if (ret < 0) | 173 | if (ret < 0) |
164 | goto fail_rfkill; | 174 | return ret; |
165 | 175 | ||
166 | platform_set_drvdata(pdev, rfkill); | 176 | platform_set_drvdata(pdev, rfkill); |
167 | 177 | ||
168 | dev_info(&pdev->dev, "%s device registered.\n", pdata->name); | 178 | dev_info(&pdev->dev, "%s device registered.\n", rfkill->name); |
169 | 179 | ||
170 | return 0; | 180 | return 0; |
171 | |||
172 | fail_rfkill: | ||
173 | rfkill_destroy(rfkill->rfkill_dev); | ||
174 | fail_shutdown: | ||
175 | if (gpio_is_valid(pdata->shutdown_gpio)) | ||
176 | gpio_free(pdata->shutdown_gpio); | ||
177 | fail_reset: | ||
178 | if (gpio_is_valid(pdata->reset_gpio)) | ||
179 | gpio_free(pdata->reset_gpio); | ||
180 | fail_clock: | ||
181 | if (rfkill->pwr_clk) | ||
182 | clk_put(rfkill->pwr_clk); | ||
183 | fail_shutdown_name: | ||
184 | kfree(rfkill->shutdown_name); | ||
185 | fail_reset_name: | ||
186 | kfree(rfkill->reset_name); | ||
187 | fail_alloc: | ||
188 | kfree(rfkill); | ||
189 | |||
190 | return ret; | ||
191 | } | 181 | } |
192 | 182 | ||
193 | static int rfkill_gpio_remove(struct platform_device *pdev) | 183 | static int rfkill_gpio_remove(struct platform_device *pdev) |
@@ -195,31 +185,26 @@ static int rfkill_gpio_remove(struct platform_device *pdev) | |||
195 | struct rfkill_gpio_data *rfkill = platform_get_drvdata(pdev); | 185 | struct rfkill_gpio_data *rfkill = platform_get_drvdata(pdev); |
196 | struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data; | 186 | struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data; |
197 | 187 | ||
198 | if (pdata->gpio_runtime_close) | 188 | if (pdata && pdata->gpio_runtime_close) |
199 | pdata->gpio_runtime_close(pdev); | 189 | pdata->gpio_runtime_close(pdev); |
200 | rfkill_unregister(rfkill->rfkill_dev); | 190 | rfkill_unregister(rfkill->rfkill_dev); |
201 | rfkill_destroy(rfkill->rfkill_dev); | 191 | rfkill_destroy(rfkill->rfkill_dev); |
202 | if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) | ||
203 | gpio_free(rfkill->pdata->shutdown_gpio); | ||
204 | if (gpio_is_valid(rfkill->pdata->reset_gpio)) | ||
205 | gpio_free(rfkill->pdata->reset_gpio); | ||
206 | if (rfkill->pwr_clk && PWR_CLK_ENABLED(rfkill)) | ||
207 | clk_disable(rfkill->pwr_clk); | ||
208 | if (rfkill->pwr_clk) | ||
209 | clk_put(rfkill->pwr_clk); | ||
210 | kfree(rfkill->shutdown_name); | ||
211 | kfree(rfkill->reset_name); | ||
212 | kfree(rfkill); | ||
213 | 192 | ||
214 | return 0; | 193 | return 0; |
215 | } | 194 | } |
216 | 195 | ||
196 | static const struct acpi_device_id rfkill_acpi_match[] = { | ||
197 | { "BCM4752", RFKILL_TYPE_GPS }, | ||
198 | { }, | ||
199 | }; | ||
200 | |||
217 | static struct platform_driver rfkill_gpio_driver = { | 201 | static struct platform_driver rfkill_gpio_driver = { |
218 | .probe = rfkill_gpio_probe, | 202 | .probe = rfkill_gpio_probe, |
219 | .remove = rfkill_gpio_remove, | 203 | .remove = rfkill_gpio_remove, |
220 | .driver = { | 204 | .driver = { |
221 | .name = "rfkill_gpio", | 205 | .name = "rfkill_gpio", |
222 | .owner = THIS_MODULE, | 206 | .owner = THIS_MODULE, |
207 | .acpi_match_table = ACPI_PTR(rfkill_acpi_match), | ||
223 | }, | 208 | }, |
224 | }; | 209 | }; |
225 | 210 | ||
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 16f3c3a7b2c1..9b8cc877eb19 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -504,7 +504,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, | |||
504 | case NL80211_IFTYPE_ADHOC: | 504 | case NL80211_IFTYPE_ADHOC: |
505 | if (wdev->current_bss) { | 505 | if (wdev->current_bss) { |
506 | *chan = wdev->current_bss->pub.channel; | 506 | *chan = wdev->current_bss->pub.channel; |
507 | *chanmode = wdev->ibss_fixed | 507 | *chanmode = (wdev->ibss_fixed && |
508 | !wdev->ibss_dfs_possible) | ||
508 | ? CHAN_MODE_SHARED | 509 | ? CHAN_MODE_SHARED |
509 | : CHAN_MODE_EXCLUSIVE; | 510 | : CHAN_MODE_EXCLUSIVE; |
510 | return; | 511 | return; |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 403fe29c024d..9d797df56649 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -83,6 +83,8 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
83 | struct cfg80211_cached_keys *connkeys) | 83 | struct cfg80211_cached_keys *connkeys) |
84 | { | 84 | { |
85 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 85 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
86 | struct ieee80211_channel *check_chan; | ||
87 | u8 radar_detect_width = 0; | ||
86 | int err; | 88 | int err; |
87 | 89 | ||
88 | ASSERT_WDEV_LOCK(wdev); | 90 | ASSERT_WDEV_LOCK(wdev); |
@@ -114,14 +116,28 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
114 | wdev->connect_keys = connkeys; | 116 | wdev->connect_keys = connkeys; |
115 | 117 | ||
116 | wdev->ibss_fixed = params->channel_fixed; | 118 | wdev->ibss_fixed = params->channel_fixed; |
119 | wdev->ibss_dfs_possible = params->userspace_handles_dfs; | ||
117 | #ifdef CONFIG_CFG80211_WEXT | 120 | #ifdef CONFIG_CFG80211_WEXT |
118 | wdev->wext.ibss.chandef = params->chandef; | 121 | wdev->wext.ibss.chandef = params->chandef; |
119 | #endif | 122 | #endif |
123 | check_chan = params->chandef.chan; | ||
124 | if (params->userspace_handles_dfs) { | ||
125 | /* use channel NULL to check for radar even if the current | ||
126 | * channel is not a radar channel - it might decide to change | ||
127 | * to DFS channel later. | ||
128 | */ | ||
129 | radar_detect_width = BIT(params->chandef.width); | ||
130 | check_chan = NULL; | ||
131 | } | ||
132 | |||
133 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, | ||
134 | check_chan, | ||
135 | (params->channel_fixed && | ||
136 | !radar_detect_width) | ||
137 | ? CHAN_MODE_SHARED | ||
138 | : CHAN_MODE_EXCLUSIVE, | ||
139 | radar_detect_width); | ||
120 | 140 | ||
121 | err = cfg80211_can_use_chan(rdev, wdev, params->chandef.chan, | ||
122 | params->channel_fixed | ||
123 | ? CHAN_MODE_SHARED | ||
124 | : CHAN_MODE_EXCLUSIVE); | ||
125 | if (err) { | 141 | if (err) { |
126 | wdev->connect_keys = NULL; | 142 | wdev->connect_keys = NULL; |
127 | return err; | 143 | return err; |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 8d49c1ce3dea..6a6b1c8e907d 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -707,11 +707,13 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work) | |||
707 | if (c->dfs_state != NL80211_DFS_UNAVAILABLE) | 707 | if (c->dfs_state != NL80211_DFS_UNAVAILABLE) |
708 | continue; | 708 | continue; |
709 | 709 | ||
710 | timeout = c->dfs_state_entered + | 710 | timeout = c->dfs_state_entered + msecs_to_jiffies( |
711 | IEEE80211_DFS_MIN_NOP_TIME_MS; | 711 | IEEE80211_DFS_MIN_NOP_TIME_MS); |
712 | 712 | ||
713 | if (time_after_eq(jiffies, timeout)) { | 713 | if (time_after_eq(jiffies, timeout)) { |
714 | c->dfs_state = NL80211_DFS_USABLE; | 714 | c->dfs_state = NL80211_DFS_USABLE; |
715 | c->dfs_state_entered = jiffies; | ||
716 | |||
715 | cfg80211_chandef_create(&chandef, c, | 717 | cfg80211_chandef_create(&chandef, c, |
716 | NL80211_CHAN_NO_HT); | 718 | NL80211_CHAN_NO_HT); |
717 | 719 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cbbef88a8ebd..a7f4e7902104 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -354,6 +354,9 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
354 | [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED }, | 354 | [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED }, |
355 | [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 }, | 355 | [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 }, |
356 | [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 }, | 356 | [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 }, |
357 | [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY }, | ||
358 | [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY }, | ||
359 | [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG }, | ||
357 | }; | 360 | }; |
358 | 361 | ||
359 | /* policy for the key attributes */ | 362 | /* policy for the key attributes */ |
@@ -3896,9 +3899,45 @@ static int nl80211_parse_sta_wme(struct genl_info *info, | |||
3896 | return 0; | 3899 | return 0; |
3897 | } | 3900 | } |
3898 | 3901 | ||
3902 | static int nl80211_parse_sta_channel_info(struct genl_info *info, | ||
3903 | struct station_parameters *params) | ||
3904 | { | ||
3905 | if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) { | ||
3906 | params->supported_channels = | ||
3907 | nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]); | ||
3908 | params->supported_channels_len = | ||
3909 | nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]); | ||
3910 | /* | ||
3911 | * Need to include at least one (first channel, number of | ||
3912 | * channels) tuple for each subband, and must have proper | ||
3913 | * tuples for the rest of the data as well. | ||
3914 | */ | ||
3915 | if (params->supported_channels_len < 2) | ||
3916 | return -EINVAL; | ||
3917 | if (params->supported_channels_len % 2) | ||
3918 | return -EINVAL; | ||
3919 | } | ||
3920 | |||
3921 | if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) { | ||
3922 | params->supported_oper_classes = | ||
3923 | nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]); | ||
3924 | params->supported_oper_classes_len = | ||
3925 | nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]); | ||
3926 | /* | ||
3927 | * The value of the Length field of the Supported Operating | ||
3928 | * Classes element is between 2 and 253. | ||
3929 | */ | ||
3930 | if (params->supported_oper_classes_len < 2 || | ||
3931 | params->supported_oper_classes_len > 253) | ||
3932 | return -EINVAL; | ||
3933 | } | ||
3934 | return 0; | ||
3935 | } | ||
3936 | |||
3899 | static int nl80211_set_station_tdls(struct genl_info *info, | 3937 | static int nl80211_set_station_tdls(struct genl_info *info, |
3900 | struct station_parameters *params) | 3938 | struct station_parameters *params) |
3901 | { | 3939 | { |
3940 | int err; | ||
3902 | /* Dummy STA entry gets updated once the peer capabilities are known */ | 3941 | /* Dummy STA entry gets updated once the peer capabilities are known */ |
3903 | if (info->attrs[NL80211_ATTR_PEER_AID]) | 3942 | if (info->attrs[NL80211_ATTR_PEER_AID]) |
3904 | params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]); | 3943 | params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]); |
@@ -3909,6 +3948,10 @@ static int nl80211_set_station_tdls(struct genl_info *info, | |||
3909 | params->vht_capa = | 3948 | params->vht_capa = |
3910 | nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]); | 3949 | nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]); |
3911 | 3950 | ||
3951 | err = nl80211_parse_sta_channel_info(info, params); | ||
3952 | if (err) | ||
3953 | return err; | ||
3954 | |||
3912 | return nl80211_parse_sta_wme(info, params); | 3955 | return nl80211_parse_sta_wme(info, params); |
3913 | } | 3956 | } |
3914 | 3957 | ||
@@ -4089,6 +4132,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
4089 | return -EINVAL; | 4132 | return -EINVAL; |
4090 | } | 4133 | } |
4091 | 4134 | ||
4135 | err = nl80211_parse_sta_channel_info(info, ¶ms); | ||
4136 | if (err) | ||
4137 | return err; | ||
4138 | |||
4092 | err = nl80211_parse_sta_wme(info, ¶ms); | 4139 | err = nl80211_parse_sta_wme(info, ¶ms); |
4093 | if (err) | 4140 | if (err) |
4094 | return err; | 4141 | return err; |
@@ -5653,6 +5700,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) | |||
5653 | return -EINVAL; | 5700 | return -EINVAL; |
5654 | break; | 5701 | break; |
5655 | case NL80211_IFTYPE_ADHOC: | 5702 | case NL80211_IFTYPE_ADHOC: |
5703 | case NL80211_IFTYPE_MESH_POINT: | ||
5656 | break; | 5704 | break; |
5657 | default: | 5705 | default: |
5658 | return -EOPNOTSUPP; | 5706 | return -EOPNOTSUPP; |
@@ -5665,9 +5713,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) | |||
5665 | return -EINVAL; | 5713 | return -EINVAL; |
5666 | 5714 | ||
5667 | /* only important for AP, IBSS and mesh create IEs internally */ | 5715 | /* only important for AP, IBSS and mesh create IEs internally */ |
5668 | if (need_new_beacon && | 5716 | if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES]) |
5669 | (!info->attrs[NL80211_ATTR_CSA_IES] || | ||
5670 | !info->attrs[NL80211_ATTR_CSA_C_OFF_BEACON])) | ||
5671 | return -EINVAL; | 5717 | return -EINVAL; |
5672 | 5718 | ||
5673 | params.count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]); | 5719 | params.count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]); |
@@ -5722,9 +5768,9 @@ skip_beacons: | |||
5722 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef)) | 5768 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef)) |
5723 | return -EINVAL; | 5769 | return -EINVAL; |
5724 | 5770 | ||
5725 | /* DFS channels are only supported for AP/P2P GO ... for now. */ | ||
5726 | if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP || | 5771 | if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP || |
5727 | dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO) { | 5772 | dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO || |
5773 | dev->ieee80211_ptr->iftype == NL80211_IFTYPE_ADHOC) { | ||
5728 | err = cfg80211_chandef_dfs_required(wdev->wiphy, | 5774 | err = cfg80211_chandef_dfs_required(wdev->wiphy, |
5729 | ¶ms.chandef); | 5775 | ¶ms.chandef); |
5730 | if (err < 0) { | 5776 | if (err < 0) { |
@@ -6556,6 +6602,9 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
6556 | ibss.control_port = | 6602 | ibss.control_port = |
6557 | nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]); | 6603 | nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]); |
6558 | 6604 | ||
6605 | ibss.userspace_handles_dfs = | ||
6606 | nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]); | ||
6607 | |||
6559 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); | 6608 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); |
6560 | if (err) | 6609 | if (err) |
6561 | kfree(connkeys); | 6610 | kfree(connkeys); |
@@ -10762,7 +10811,8 @@ void cfg80211_ch_switch_notify(struct net_device *dev, | |||
10762 | 10811 | ||
10763 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && | 10812 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && |
10764 | wdev->iftype != NL80211_IFTYPE_P2P_GO && | 10813 | wdev->iftype != NL80211_IFTYPE_P2P_GO && |
10765 | wdev->iftype != NL80211_IFTYPE_ADHOC)) | 10814 | wdev->iftype != NL80211_IFTYPE_ADHOC && |
10815 | wdev->iftype != NL80211_IFTYPE_MESH_POINT)) | ||
10766 | goto out; | 10816 | goto out; |
10767 | 10817 | ||
10768 | wdev->channel = chandef->chan; | 10818 | wdev->channel = chandef->chan; |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index a0ec143ba3dc..7da67fd0b418 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -787,7 +787,6 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator) | |||
787 | EXPORT_SYMBOL(reg_initiator_name); | 787 | EXPORT_SYMBOL(reg_initiator_name); |
788 | 788 | ||
789 | #ifdef CONFIG_CFG80211_REG_DEBUG | 789 | #ifdef CONFIG_CFG80211_REG_DEBUG |
790 | |||
791 | static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, | 790 | static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, |
792 | const struct ieee80211_reg_rule *reg_rule) | 791 | const struct ieee80211_reg_rule *reg_rule) |
793 | { | 792 | { |
@@ -974,6 +973,13 @@ static bool reg_dev_ignore_cell_hint(struct wiphy *wiphy) | |||
974 | } | 973 | } |
975 | #endif | 974 | #endif |
976 | 975 | ||
976 | static bool wiphy_strict_alpha2_regd(struct wiphy *wiphy) | ||
977 | { | ||
978 | if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && | ||
979 | !(wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY)) | ||
980 | return true; | ||
981 | return false; | ||
982 | } | ||
977 | 983 | ||
978 | static bool ignore_reg_update(struct wiphy *wiphy, | 984 | static bool ignore_reg_update(struct wiphy *wiphy, |
979 | enum nl80211_reg_initiator initiator) | 985 | enum nl80211_reg_initiator initiator) |
@@ -1000,7 +1006,7 @@ static bool ignore_reg_update(struct wiphy *wiphy, | |||
1000 | * wiphy->regd will be set once the device has its own | 1006 | * wiphy->regd will be set once the device has its own |
1001 | * desired regulatory domain set | 1007 | * desired regulatory domain set |
1002 | */ | 1008 | */ |
1003 | if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd && | 1009 | if (wiphy_strict_alpha2_regd(wiphy) && !wiphy->regd && |
1004 | initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && | 1010 | initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && |
1005 | !is_world_regdom(lr->alpha2)) { | 1011 | !is_world_regdom(lr->alpha2)) { |
1006 | REG_DBG_PRINT("Ignoring regulatory request set by %s " | 1012 | REG_DBG_PRINT("Ignoring regulatory request set by %s " |
@@ -1706,8 +1712,8 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2) | |||
1706 | } | 1712 | } |
1707 | EXPORT_SYMBOL(regulatory_hint); | 1713 | EXPORT_SYMBOL(regulatory_hint); |
1708 | 1714 | ||
1709 | void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band, | 1715 | void regulatory_hint_country_ie(struct wiphy *wiphy, enum ieee80211_band band, |
1710 | const u8 *country_ie, u8 country_ie_len) | 1716 | const u8 *country_ie, u8 country_ie_len) |
1711 | { | 1717 | { |
1712 | char alpha2[2]; | 1718 | char alpha2[2]; |
1713 | enum environment_cap env = ENVIRON_ANY; | 1719 | enum environment_cap env = ENVIRON_ANY; |
diff --git a/net/wireless/reg.h b/net/wireless/reg.h index af2d5f8a5d82..9677e3c13da9 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h | |||
@@ -58,7 +58,7 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy, | |||
58 | gfp_t gfp); | 58 | gfp_t gfp); |
59 | 59 | ||
60 | /** | 60 | /** |
61 | * regulatory_hint_11d - hints a country IE as a regulatory domain | 61 | * regulatory_hint_country_ie - hints a country IE as a regulatory domain |
62 | * @wiphy: the wireless device giving the hint (used only for reporting | 62 | * @wiphy: the wireless device giving the hint (used only for reporting |
63 | * conflicts) | 63 | * conflicts) |
64 | * @band: the band on which the country IE was received on. This determines | 64 | * @band: the band on which the country IE was received on. This determines |
@@ -78,7 +78,7 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy, | |||
78 | * not observed. For this reason if a triplet is seen with channel | 78 | * not observed. For this reason if a triplet is seen with channel |
79 | * information for a band the BSS is not present in it will be ignored. | 79 | * information for a band the BSS is not present in it will be ignored. |
80 | */ | 80 | */ |
81 | void regulatory_hint_11d(struct wiphy *wiphy, | 81 | void regulatory_hint_country_ie(struct wiphy *wiphy, |
82 | enum ieee80211_band band, | 82 | enum ieee80211_band band, |
83 | const u8 *country_ie, | 83 | const u8 *country_ie, |
84 | u8 country_ie_len); | 84 | u8 country_ie_len); |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index eeb71480f1af..d4397eba5408 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -254,10 +254,10 @@ void __cfg80211_sched_scan_results(struct work_struct *wk) | |||
254 | rdev = container_of(wk, struct cfg80211_registered_device, | 254 | rdev = container_of(wk, struct cfg80211_registered_device, |
255 | sched_scan_results_wk); | 255 | sched_scan_results_wk); |
256 | 256 | ||
257 | request = rdev->sched_scan_req; | ||
258 | |||
259 | rtnl_lock(); | 257 | rtnl_lock(); |
260 | 258 | ||
259 | request = rdev->sched_scan_req; | ||
260 | |||
261 | /* we don't have sched_scan_req anymore if the scan is stopping */ | 261 | /* we don't have sched_scan_req anymore if the scan is stopping */ |
262 | if (request) { | 262 | if (request) { |
263 | if (request->flags & NL80211_SCAN_FLAG_FLUSH) { | 263 | if (request->flags & NL80211_SCAN_FLAG_FLUSH) { |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 20e86a95dc4e..65f800890d70 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -682,8 +682,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
682 | * - country_ie + 2, the start of the country ie data, and | 682 | * - country_ie + 2, the start of the country ie data, and |
683 | * - and country_ie[1] which is the IE length | 683 | * - and country_ie[1] which is the IE length |
684 | */ | 684 | */ |
685 | regulatory_hint_11d(wdev->wiphy, bss->channel->band, | 685 | regulatory_hint_country_ie(wdev->wiphy, bss->channel->band, |
686 | country_ie + 2, country_ie[1]); | 686 | country_ie + 2, country_ie[1]); |
687 | kfree(country_ie); | 687 | kfree(country_ie); |
688 | } | 688 | } |
689 | 689 | ||
diff --git a/net/wireless/util.c b/net/wireless/util.c index 3c8be6104ba4..935dea9485da 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -1249,7 +1249,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1249 | enum cfg80211_chan_mode chmode; | 1249 | enum cfg80211_chan_mode chmode; |
1250 | int num_different_channels = 0; | 1250 | int num_different_channels = 0; |
1251 | int total = 1; | 1251 | int total = 1; |
1252 | bool radar_required; | 1252 | bool radar_required = false; |
1253 | int i, j; | 1253 | int i, j; |
1254 | 1254 | ||
1255 | ASSERT_RTNL(); | 1255 | ASSERT_RTNL(); |
@@ -1264,14 +1264,20 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1264 | case NL80211_IFTYPE_MESH_POINT: | 1264 | case NL80211_IFTYPE_MESH_POINT: |
1265 | case NL80211_IFTYPE_P2P_GO: | 1265 | case NL80211_IFTYPE_P2P_GO: |
1266 | case NL80211_IFTYPE_WDS: | 1266 | case NL80211_IFTYPE_WDS: |
1267 | radar_required = !!(chan && | 1267 | /* if the interface could potentially choose a DFS channel, |
1268 | (chan->flags & IEEE80211_CHAN_RADAR)); | 1268 | * then mark DFS as required. |
1269 | */ | ||
1270 | if (!chan) { | ||
1271 | if (chanmode != CHAN_MODE_UNDEFINED && radar_detect) | ||
1272 | radar_required = true; | ||
1273 | break; | ||
1274 | } | ||
1275 | radar_required = !!(chan->flags & IEEE80211_CHAN_RADAR); | ||
1269 | break; | 1276 | break; |
1270 | case NL80211_IFTYPE_P2P_CLIENT: | 1277 | case NL80211_IFTYPE_P2P_CLIENT: |
1271 | case NL80211_IFTYPE_STATION: | 1278 | case NL80211_IFTYPE_STATION: |
1272 | case NL80211_IFTYPE_P2P_DEVICE: | 1279 | case NL80211_IFTYPE_P2P_DEVICE: |
1273 | case NL80211_IFTYPE_MONITOR: | 1280 | case NL80211_IFTYPE_MONITOR: |
1274 | radar_required = false; | ||
1275 | break; | 1281 | break; |
1276 | case NUM_NL80211_IFTYPES: | 1282 | case NUM_NL80211_IFTYPES: |
1277 | case NL80211_IFTYPE_UNSPECIFIED: | 1283 | case NL80211_IFTYPE_UNSPECIFIED: |