diff options
29 files changed, 520 insertions, 400 deletions
diff --git a/drivers/bluetooth/btmrvl_debugfs.c b/drivers/bluetooth/btmrvl_debugfs.c index 428dbb7574bd..db2c3c305df8 100644 --- a/drivers/bluetooth/btmrvl_debugfs.c +++ b/drivers/bluetooth/btmrvl_debugfs.c | |||
@@ -29,20 +29,6 @@ | |||
29 | struct btmrvl_debugfs_data { | 29 | struct btmrvl_debugfs_data { |
30 | struct dentry *config_dir; | 30 | struct dentry *config_dir; |
31 | struct dentry *status_dir; | 31 | struct dentry *status_dir; |
32 | |||
33 | /* config */ | ||
34 | struct dentry *psmode; | ||
35 | struct dentry *pscmd; | ||
36 | struct dentry *hsmode; | ||
37 | struct dentry *hscmd; | ||
38 | struct dentry *gpiogap; | ||
39 | struct dentry *hscfgcmd; | ||
40 | |||
41 | /* status */ | ||
42 | struct dentry *curpsmode; | ||
43 | struct dentry *hsstate; | ||
44 | struct dentry *psstate; | ||
45 | struct dentry *txdnldready; | ||
46 | }; | 32 | }; |
47 | 33 | ||
48 | static ssize_t btmrvl_hscfgcmd_write(struct file *file, | 34 | static ssize_t btmrvl_hscfgcmd_write(struct file *file, |
@@ -91,47 +77,6 @@ static const struct file_operations btmrvl_hscfgcmd_fops = { | |||
91 | .llseek = default_llseek, | 77 | .llseek = default_llseek, |
92 | }; | 78 | }; |
93 | 79 | ||
94 | static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf, | ||
95 | size_t count, loff_t *ppos) | ||
96 | { | ||
97 | struct btmrvl_private *priv = file->private_data; | ||
98 | char buf[16]; | ||
99 | long result, ret; | ||
100 | |||
101 | memset(buf, 0, sizeof(buf)); | ||
102 | |||
103 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
104 | return -EFAULT; | ||
105 | |||
106 | ret = strict_strtol(buf, 10, &result); | ||
107 | if (ret) | ||
108 | return ret; | ||
109 | |||
110 | priv->btmrvl_dev.psmode = result; | ||
111 | |||
112 | return count; | ||
113 | } | ||
114 | |||
115 | static ssize_t btmrvl_psmode_read(struct file *file, char __user *userbuf, | ||
116 | size_t count, loff_t *ppos) | ||
117 | { | ||
118 | struct btmrvl_private *priv = file->private_data; | ||
119 | char buf[16]; | ||
120 | int ret; | ||
121 | |||
122 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", | ||
123 | priv->btmrvl_dev.psmode); | ||
124 | |||
125 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | ||
126 | } | ||
127 | |||
128 | static const struct file_operations btmrvl_psmode_fops = { | ||
129 | .read = btmrvl_psmode_read, | ||
130 | .write = btmrvl_psmode_write, | ||
131 | .open = simple_open, | ||
132 | .llseek = default_llseek, | ||
133 | }; | ||
134 | |||
135 | static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf, | 80 | static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf, |
136 | size_t count, loff_t *ppos) | 81 | size_t count, loff_t *ppos) |
137 | { | 82 | { |
@@ -178,47 +123,6 @@ static const struct file_operations btmrvl_pscmd_fops = { | |||
178 | .llseek = default_llseek, | 123 | .llseek = default_llseek, |
179 | }; | 124 | }; |
180 | 125 | ||
181 | static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf, | ||
182 | size_t count, loff_t *ppos) | ||
183 | { | ||
184 | struct btmrvl_private *priv = file->private_data; | ||
185 | char buf[16]; | ||
186 | long result, ret; | ||
187 | |||
188 | memset(buf, 0, sizeof(buf)); | ||
189 | |||
190 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
191 | return -EFAULT; | ||
192 | |||
193 | ret = strict_strtol(buf, 16, &result); | ||
194 | if (ret) | ||
195 | return ret; | ||
196 | |||
197 | priv->btmrvl_dev.gpio_gap = result; | ||
198 | |||
199 | return count; | ||
200 | } | ||
201 | |||
202 | static ssize_t btmrvl_gpiogap_read(struct file *file, char __user *userbuf, | ||
203 | size_t count, loff_t *ppos) | ||
204 | { | ||
205 | struct btmrvl_private *priv = file->private_data; | ||
206 | char buf[16]; | ||
207 | int ret; | ||
208 | |||
209 | ret = snprintf(buf, sizeof(buf) - 1, "0x%x\n", | ||
210 | priv->btmrvl_dev.gpio_gap); | ||
211 | |||
212 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | ||
213 | } | ||
214 | |||
215 | static const struct file_operations btmrvl_gpiogap_fops = { | ||
216 | .read = btmrvl_gpiogap_read, | ||
217 | .write = btmrvl_gpiogap_write, | ||
218 | .open = simple_open, | ||
219 | .llseek = default_llseek, | ||
220 | }; | ||
221 | |||
222 | static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf, | 126 | static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf, |
223 | size_t count, loff_t *ppos) | 127 | size_t count, loff_t *ppos) |
224 | { | 128 | { |
@@ -263,119 +167,6 @@ static const struct file_operations btmrvl_hscmd_fops = { | |||
263 | .llseek = default_llseek, | 167 | .llseek = default_llseek, |
264 | }; | 168 | }; |
265 | 169 | ||
266 | static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf, | ||
267 | size_t count, loff_t *ppos) | ||
268 | { | ||
269 | struct btmrvl_private *priv = file->private_data; | ||
270 | char buf[16]; | ||
271 | long result, ret; | ||
272 | |||
273 | memset(buf, 0, sizeof(buf)); | ||
274 | |||
275 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
276 | return -EFAULT; | ||
277 | |||
278 | ret = strict_strtol(buf, 10, &result); | ||
279 | if (ret) | ||
280 | return ret; | ||
281 | |||
282 | priv->btmrvl_dev.hsmode = result; | ||
283 | |||
284 | return count; | ||
285 | } | ||
286 | |||
287 | static ssize_t btmrvl_hsmode_read(struct file *file, char __user * userbuf, | ||
288 | size_t count, loff_t *ppos) | ||
289 | { | ||
290 | struct btmrvl_private *priv = file->private_data; | ||
291 | char buf[16]; | ||
292 | int ret; | ||
293 | |||
294 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hsmode); | ||
295 | |||
296 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | ||
297 | } | ||
298 | |||
299 | static const struct file_operations btmrvl_hsmode_fops = { | ||
300 | .read = btmrvl_hsmode_read, | ||
301 | .write = btmrvl_hsmode_write, | ||
302 | .open = simple_open, | ||
303 | .llseek = default_llseek, | ||
304 | }; | ||
305 | |||
306 | static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf, | ||
307 | size_t count, loff_t *ppos) | ||
308 | { | ||
309 | struct btmrvl_private *priv = file->private_data; | ||
310 | char buf[16]; | ||
311 | int ret; | ||
312 | |||
313 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->psmode); | ||
314 | |||
315 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | ||
316 | } | ||
317 | |||
318 | static const struct file_operations btmrvl_curpsmode_fops = { | ||
319 | .read = btmrvl_curpsmode_read, | ||
320 | .open = simple_open, | ||
321 | .llseek = default_llseek, | ||
322 | }; | ||
323 | |||
324 | static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf, | ||
325 | size_t count, loff_t *ppos) | ||
326 | { | ||
327 | struct btmrvl_private *priv = file->private_data; | ||
328 | char buf[16]; | ||
329 | int ret; | ||
330 | |||
331 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->ps_state); | ||
332 | |||
333 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | ||
334 | } | ||
335 | |||
336 | static const struct file_operations btmrvl_psstate_fops = { | ||
337 | .read = btmrvl_psstate_read, | ||
338 | .open = simple_open, | ||
339 | .llseek = default_llseek, | ||
340 | }; | ||
341 | |||
342 | static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf, | ||
343 | size_t count, loff_t *ppos) | ||
344 | { | ||
345 | struct btmrvl_private *priv = file->private_data; | ||
346 | char buf[16]; | ||
347 | int ret; | ||
348 | |||
349 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->hs_state); | ||
350 | |||
351 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | ||
352 | } | ||
353 | |||
354 | static const struct file_operations btmrvl_hsstate_fops = { | ||
355 | .read = btmrvl_hsstate_read, | ||
356 | .open = simple_open, | ||
357 | .llseek = default_llseek, | ||
358 | }; | ||
359 | |||
360 | static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf, | ||
361 | size_t count, loff_t *ppos) | ||
362 | { | ||
363 | struct btmrvl_private *priv = file->private_data; | ||
364 | char buf[16]; | ||
365 | int ret; | ||
366 | |||
367 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", | ||
368 | priv->btmrvl_dev.tx_dnld_rdy); | ||
369 | |||
370 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | ||
371 | } | ||
372 | |||
373 | static const struct file_operations btmrvl_txdnldready_fops = { | ||
374 | .read = btmrvl_txdnldready_read, | ||
375 | .open = simple_open, | ||
376 | .llseek = default_llseek, | ||
377 | }; | ||
378 | |||
379 | void btmrvl_debugfs_init(struct hci_dev *hdev) | 170 | void btmrvl_debugfs_init(struct hci_dev *hdev) |
380 | { | 171 | { |
381 | struct btmrvl_private *priv = hci_get_drvdata(hdev); | 172 | struct btmrvl_private *priv = hci_get_drvdata(hdev); |
@@ -394,30 +185,28 @@ void btmrvl_debugfs_init(struct hci_dev *hdev) | |||
394 | 185 | ||
395 | dbg->config_dir = debugfs_create_dir("config", hdev->debugfs); | 186 | dbg->config_dir = debugfs_create_dir("config", hdev->debugfs); |
396 | 187 | ||
397 | dbg->psmode = debugfs_create_file("psmode", 0644, dbg->config_dir, | 188 | debugfs_create_u8("psmode", 0644, dbg->config_dir, |
398 | priv, &btmrvl_psmode_fops); | 189 | &priv->btmrvl_dev.psmode); |
399 | dbg->pscmd = debugfs_create_file("pscmd", 0644, dbg->config_dir, | 190 | debugfs_create_file("pscmd", 0644, dbg->config_dir, |
400 | priv, &btmrvl_pscmd_fops); | 191 | priv, &btmrvl_pscmd_fops); |
401 | dbg->gpiogap = debugfs_create_file("gpiogap", 0644, dbg->config_dir, | 192 | debugfs_create_x16("gpiogap", 0644, dbg->config_dir, |
402 | priv, &btmrvl_gpiogap_fops); | 193 | &priv->btmrvl_dev.gpio_gap); |
403 | dbg->hsmode = debugfs_create_file("hsmode", 0644, dbg->config_dir, | 194 | debugfs_create_u8("hsmode", 0644, dbg->config_dir, |
404 | priv, &btmrvl_hsmode_fops); | 195 | &priv->btmrvl_dev.hsmode); |
405 | dbg->hscmd = debugfs_create_file("hscmd", 0644, dbg->config_dir, | 196 | debugfs_create_file("hscmd", 0644, dbg->config_dir, |
406 | priv, &btmrvl_hscmd_fops); | 197 | priv, &btmrvl_hscmd_fops); |
407 | dbg->hscfgcmd = debugfs_create_file("hscfgcmd", 0644, dbg->config_dir, | 198 | debugfs_create_file("hscfgcmd", 0644, dbg->config_dir, |
408 | priv, &btmrvl_hscfgcmd_fops); | 199 | priv, &btmrvl_hscfgcmd_fops); |
409 | 200 | ||
410 | dbg->status_dir = debugfs_create_dir("status", hdev->debugfs); | 201 | dbg->status_dir = debugfs_create_dir("status", hdev->debugfs); |
411 | dbg->curpsmode = debugfs_create_file("curpsmode", 0444, | 202 | debugfs_create_u8("curpsmode", 0444, dbg->status_dir, |
412 | dbg->status_dir, priv, | 203 | &priv->adapter->psmode); |
413 | &btmrvl_curpsmode_fops); | 204 | debugfs_create_u8("psstate", 0444, dbg->status_dir, |
414 | dbg->psstate = debugfs_create_file("psstate", 0444, dbg->status_dir, | 205 | &priv->adapter->ps_state); |
415 | priv, &btmrvl_psstate_fops); | 206 | debugfs_create_u8("hsstate", 0444, dbg->status_dir, |
416 | dbg->hsstate = debugfs_create_file("hsstate", 0444, dbg->status_dir, | 207 | &priv->adapter->hs_state); |
417 | priv, &btmrvl_hsstate_fops); | 208 | debugfs_create_u8("txdnldready", 0444, dbg->status_dir, |
418 | dbg->txdnldready = debugfs_create_file("txdnldready", 0444, | 209 | &priv->btmrvl_dev.tx_dnld_rdy); |
419 | dbg->status_dir, priv, | ||
420 | &btmrvl_txdnldready_fops); | ||
421 | } | 210 | } |
422 | 211 | ||
423 | void btmrvl_debugfs_remove(struct hci_dev *hdev) | 212 | void btmrvl_debugfs_remove(struct hci_dev *hdev) |
@@ -428,19 +217,8 @@ void btmrvl_debugfs_remove(struct hci_dev *hdev) | |||
428 | if (!dbg) | 217 | if (!dbg) |
429 | return; | 218 | return; |
430 | 219 | ||
431 | debugfs_remove(dbg->psmode); | 220 | debugfs_remove_recursive(dbg->config_dir); |
432 | debugfs_remove(dbg->pscmd); | 221 | debugfs_remove_recursive(dbg->status_dir); |
433 | debugfs_remove(dbg->gpiogap); | ||
434 | debugfs_remove(dbg->hsmode); | ||
435 | debugfs_remove(dbg->hscmd); | ||
436 | debugfs_remove(dbg->hscfgcmd); | ||
437 | debugfs_remove(dbg->config_dir); | ||
438 | |||
439 | debugfs_remove(dbg->curpsmode); | ||
440 | debugfs_remove(dbg->psstate); | ||
441 | debugfs_remove(dbg->hsstate); | ||
442 | debugfs_remove(dbg->txdnldready); | ||
443 | debugfs_remove(dbg->status_dir); | ||
444 | 222 | ||
445 | kfree(dbg); | 223 | kfree(dbg); |
446 | } | 224 | } |
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 1cb51839912d..c63488c54f4a 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c | |||
@@ -228,24 +228,24 @@ failed: | |||
228 | static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card, | 228 | static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card, |
229 | int pollnum) | 229 | int pollnum) |
230 | { | 230 | { |
231 | int ret = -ETIMEDOUT; | ||
232 | u16 firmwarestat; | 231 | u16 firmwarestat; |
233 | unsigned int tries; | 232 | int tries, ret; |
234 | 233 | ||
235 | /* Wait for firmware to become ready */ | 234 | /* Wait for firmware to become ready */ |
236 | for (tries = 0; tries < pollnum; tries++) { | 235 | for (tries = 0; tries < pollnum; tries++) { |
237 | if (btmrvl_sdio_read_fw_status(card, &firmwarestat) < 0) | 236 | sdio_claim_host(card->func); |
237 | ret = btmrvl_sdio_read_fw_status(card, &firmwarestat); | ||
238 | sdio_release_host(card->func); | ||
239 | if (ret < 0) | ||
238 | continue; | 240 | continue; |
239 | 241 | ||
240 | if (firmwarestat == FIRMWARE_READY) { | 242 | if (firmwarestat == FIRMWARE_READY) |
241 | ret = 0; | 243 | return 0; |
242 | break; | 244 | |
243 | } else { | 245 | msleep(10); |
244 | msleep(10); | ||
245 | } | ||
246 | } | 246 | } |
247 | 247 | ||
248 | return ret; | 248 | return -ETIMEDOUT; |
249 | } | 249 | } |
250 | 250 | ||
251 | static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) | 251 | static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) |
@@ -874,7 +874,7 @@ exit: | |||
874 | 874 | ||
875 | static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) | 875 | static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) |
876 | { | 876 | { |
877 | int ret = 0; | 877 | int ret; |
878 | u8 fws0; | 878 | u8 fws0; |
879 | int pollnum = MAX_POLL_TRIES; | 879 | int pollnum = MAX_POLL_TRIES; |
880 | 880 | ||
@@ -882,13 +882,14 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) | |||
882 | BT_ERR("card or function is NULL!"); | 882 | BT_ERR("card or function is NULL!"); |
883 | return -EINVAL; | 883 | return -EINVAL; |
884 | } | 884 | } |
885 | sdio_claim_host(card->func); | ||
886 | 885 | ||
887 | if (!btmrvl_sdio_verify_fw_download(card, 1)) { | 886 | if (!btmrvl_sdio_verify_fw_download(card, 1)) { |
888 | BT_DBG("Firmware already downloaded!"); | 887 | BT_DBG("Firmware already downloaded!"); |
889 | goto done; | 888 | return 0; |
890 | } | 889 | } |
891 | 890 | ||
891 | sdio_claim_host(card->func); | ||
892 | |||
892 | /* Check if other function driver is downloading the firmware */ | 893 | /* Check if other function driver is downloading the firmware */ |
893 | fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); | 894 | fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); |
894 | if (ret) { | 895 | if (ret) { |
@@ -918,15 +919,21 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) | |||
918 | } | 919 | } |
919 | } | 920 | } |
920 | 921 | ||
922 | sdio_release_host(card->func); | ||
923 | |||
924 | /* | ||
925 | * winner or not, with this test the FW synchronizes when the | ||
926 | * module can continue its initialization | ||
927 | */ | ||
921 | if (btmrvl_sdio_verify_fw_download(card, pollnum)) { | 928 | if (btmrvl_sdio_verify_fw_download(card, pollnum)) { |
922 | BT_ERR("FW failed to be active in time!"); | 929 | BT_ERR("FW failed to be active in time!"); |
923 | ret = -ETIMEDOUT; | 930 | return -ETIMEDOUT; |
924 | goto done; | ||
925 | } | 931 | } |
926 | 932 | ||
933 | return 0; | ||
934 | |||
927 | done: | 935 | done: |
928 | sdio_release_host(card->func); | 936 | sdio_release_host(card->func); |
929 | |||
930 | return ret; | 937 | return ret; |
931 | } | 938 | } |
932 | 939 | ||
@@ -989,8 +996,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func, | |||
989 | goto unreg_dev; | 996 | goto unreg_dev; |
990 | } | 997 | } |
991 | 998 | ||
992 | msleep(100); | ||
993 | |||
994 | btmrvl_sdio_enable_host_int(card); | 999 | btmrvl_sdio_enable_host_int(card); |
995 | 1000 | ||
996 | priv = btmrvl_add_card(card); | 1001 | priv = btmrvl_add_card(card); |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 3d684d20b584..7a7e5f8ecadc 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/usb.h> | 25 | #include <linux/usb.h> |
26 | #include <linux/firmware.h> | ||
26 | 27 | ||
27 | #include <net/bluetooth/bluetooth.h> | 28 | #include <net/bluetooth/bluetooth.h> |
28 | #include <net/bluetooth/hci_core.h> | 29 | #include <net/bluetooth/hci_core.h> |
@@ -47,6 +48,7 @@ static struct usb_driver btusb_driver; | |||
47 | #define BTUSB_BROKEN_ISOC 0x20 | 48 | #define BTUSB_BROKEN_ISOC 0x20 |
48 | #define BTUSB_WRONG_SCO_MTU 0x40 | 49 | #define BTUSB_WRONG_SCO_MTU 0x40 |
49 | #define BTUSB_ATH3012 0x80 | 50 | #define BTUSB_ATH3012 0x80 |
51 | #define BTUSB_INTEL 0x100 | ||
50 | 52 | ||
51 | static struct usb_device_id btusb_table[] = { | 53 | static struct usb_device_id btusb_table[] = { |
52 | /* Generic Bluetooth USB device */ | 54 | /* Generic Bluetooth USB device */ |
@@ -207,6 +209,9 @@ static struct usb_device_id blacklist_table[] = { | |||
207 | /* Frontline ComProbe Bluetooth Sniffer */ | 209 | /* Frontline ComProbe Bluetooth Sniffer */ |
208 | { USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER }, | 210 | { USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER }, |
209 | 211 | ||
212 | /* Intel Bluetooth device */ | ||
213 | { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL }, | ||
214 | |||
210 | { } /* Terminating entry */ | 215 | { } /* Terminating entry */ |
211 | }; | 216 | }; |
212 | 217 | ||
@@ -943,6 +948,375 @@ static int btusb_setup_bcm92035(struct hci_dev *hdev) | |||
943 | return 0; | 948 | return 0; |
944 | } | 949 | } |
945 | 950 | ||
951 | struct intel_version { | ||
952 | u8 status; | ||
953 | u8 hw_platform; | ||
954 | u8 hw_variant; | ||
955 | u8 hw_revision; | ||
956 | u8 fw_variant; | ||
957 | u8 fw_revision; | ||
958 | u8 fw_build_num; | ||
959 | u8 fw_build_ww; | ||
960 | u8 fw_build_yy; | ||
961 | u8 fw_patch_num; | ||
962 | } __packed; | ||
963 | |||
964 | static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev, | ||
965 | struct intel_version *ver) | ||
966 | { | ||
967 | const struct firmware *fw; | ||
968 | char fwname[64]; | ||
969 | int ret; | ||
970 | |||
971 | snprintf(fwname, sizeof(fwname), | ||
972 | "intel/ibt-hw-%x.%x.%x-fw-%x.%x.%x.%x.%x.bseq", | ||
973 | ver->hw_platform, ver->hw_variant, ver->hw_revision, | ||
974 | ver->fw_variant, ver->fw_revision, ver->fw_build_num, | ||
975 | ver->fw_build_ww, ver->fw_build_yy); | ||
976 | |||
977 | ret = request_firmware(&fw, fwname, &hdev->dev); | ||
978 | if (ret < 0) { | ||
979 | if (ret == -EINVAL) { | ||
980 | BT_ERR("%s Intel firmware file request failed (%d)", | ||
981 | hdev->name, ret); | ||
982 | return NULL; | ||
983 | } | ||
984 | |||
985 | BT_ERR("%s failed to open Intel firmware file: %s(%d)", | ||
986 | hdev->name, fwname, ret); | ||
987 | |||
988 | /* If the correct firmware patch file is not found, use the | ||
989 | * default firmware patch file instead | ||
990 | */ | ||
991 | snprintf(fwname, sizeof(fwname), "intel/ibt-hw-%x.%x.bseq", | ||
992 | ver->hw_platform, ver->hw_variant); | ||
993 | if (request_firmware(&fw, fwname, &hdev->dev) < 0) { | ||
994 | BT_ERR("%s failed to open default Intel fw file: %s", | ||
995 | hdev->name, fwname); | ||
996 | return NULL; | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | BT_INFO("%s: Intel Bluetooth firmware file: %s", hdev->name, fwname); | ||
1001 | |||
1002 | return fw; | ||
1003 | } | ||
1004 | |||
1005 | static int btusb_setup_intel_patching(struct hci_dev *hdev, | ||
1006 | const struct firmware *fw, | ||
1007 | const u8 **fw_ptr, int *disable_patch) | ||
1008 | { | ||
1009 | struct sk_buff *skb; | ||
1010 | struct hci_command_hdr *cmd; | ||
1011 | const u8 *cmd_param; | ||
1012 | struct hci_event_hdr *evt = NULL; | ||
1013 | const u8 *evt_param = NULL; | ||
1014 | int remain = fw->size - (*fw_ptr - fw->data); | ||
1015 | |||
1016 | /* The first byte indicates the types of the patch command or event. | ||
1017 | * 0x01 means HCI command and 0x02 is HCI event. If the first bytes | ||
1018 | * in the current firmware buffer doesn't start with 0x01 or | ||
1019 | * the size of remain buffer is smaller than HCI command header, | ||
1020 | * the firmware file is corrupted and it should stop the patching | ||
1021 | * process. | ||
1022 | */ | ||
1023 | if (remain > HCI_COMMAND_HDR_SIZE && *fw_ptr[0] != 0x01) { | ||
1024 | BT_ERR("%s Intel fw corrupted: invalid cmd read", hdev->name); | ||
1025 | return -EINVAL; | ||
1026 | } | ||
1027 | (*fw_ptr)++; | ||
1028 | remain--; | ||
1029 | |||
1030 | cmd = (struct hci_command_hdr *)(*fw_ptr); | ||
1031 | *fw_ptr += sizeof(*cmd); | ||
1032 | remain -= sizeof(*cmd); | ||
1033 | |||
1034 | /* Ensure that the remain firmware data is long enough than the length | ||
1035 | * of command parameter. If not, the firmware file is corrupted. | ||
1036 | */ | ||
1037 | if (remain < cmd->plen) { | ||
1038 | BT_ERR("%s Intel fw corrupted: invalid cmd len", hdev->name); | ||
1039 | return -EFAULT; | ||
1040 | } | ||
1041 | |||
1042 | /* If there is a command that loads a patch in the firmware | ||
1043 | * file, then enable the patch upon success, otherwise just | ||
1044 | * disable the manufacturer mode, for example patch activation | ||
1045 | * is not required when the default firmware patch file is used | ||
1046 | * because there are no patch data to load. | ||
1047 | */ | ||
1048 | if (*disable_patch && le16_to_cpu(cmd->opcode) == 0xfc8e) | ||
1049 | *disable_patch = 0; | ||
1050 | |||
1051 | cmd_param = *fw_ptr; | ||
1052 | *fw_ptr += cmd->plen; | ||
1053 | remain -= cmd->plen; | ||
1054 | |||
1055 | /* This reads the expected events when the above command is sent to the | ||
1056 | * device. Some vendor commands expects more than one events, for | ||
1057 | * example command status event followed by vendor specific event. | ||
1058 | * For this case, it only keeps the last expected event. so the command | ||
1059 | * can be sent with __hci_cmd_sync_ev() which returns the sk_buff of | ||
1060 | * last expected event. | ||
1061 | */ | ||
1062 | while (remain > HCI_EVENT_HDR_SIZE && *fw_ptr[0] == 0x02) { | ||
1063 | (*fw_ptr)++; | ||
1064 | remain--; | ||
1065 | |||
1066 | evt = (struct hci_event_hdr *)(*fw_ptr); | ||
1067 | *fw_ptr += sizeof(*evt); | ||
1068 | remain -= sizeof(*evt); | ||
1069 | |||
1070 | if (remain < evt->plen) { | ||
1071 | BT_ERR("%s Intel fw corrupted: invalid evt len", | ||
1072 | hdev->name); | ||
1073 | return -EFAULT; | ||
1074 | } | ||
1075 | |||
1076 | evt_param = *fw_ptr; | ||
1077 | *fw_ptr += evt->plen; | ||
1078 | remain -= evt->plen; | ||
1079 | } | ||
1080 | |||
1081 | /* Every HCI commands in the firmware file has its correspond event. | ||
1082 | * If event is not found or remain is smaller than zero, the firmware | ||
1083 | * file is corrupted. | ||
1084 | */ | ||
1085 | if (!evt || !evt_param || remain < 0) { | ||
1086 | BT_ERR("%s Intel fw corrupted: invalid evt read", hdev->name); | ||
1087 | return -EFAULT; | ||
1088 | } | ||
1089 | |||
1090 | skb = __hci_cmd_sync_ev(hdev, le16_to_cpu(cmd->opcode), cmd->plen, | ||
1091 | cmd_param, evt->evt, HCI_INIT_TIMEOUT); | ||
1092 | if (IS_ERR(skb)) { | ||
1093 | BT_ERR("%s sending Intel patch command (0x%4.4x) failed (%ld)", | ||
1094 | hdev->name, cmd->opcode, PTR_ERR(skb)); | ||
1095 | return -PTR_ERR(skb); | ||
1096 | } | ||
1097 | |||
1098 | /* It ensures that the returned event matches the event data read from | ||
1099 | * the firmware file. At fist, it checks the length and then | ||
1100 | * the contents of the event. | ||
1101 | */ | ||
1102 | if (skb->len != evt->plen) { | ||
1103 | BT_ERR("%s mismatch event length (opcode 0x%4.4x)", hdev->name, | ||
1104 | le16_to_cpu(cmd->opcode)); | ||
1105 | kfree_skb(skb); | ||
1106 | return -EFAULT; | ||
1107 | } | ||
1108 | |||
1109 | if (memcmp(skb->data, evt_param, evt->plen)) { | ||
1110 | BT_ERR("%s mismatch event parameter (opcode 0x%4.4x)", | ||
1111 | hdev->name, le16_to_cpu(cmd->opcode)); | ||
1112 | kfree_skb(skb); | ||
1113 | return -EFAULT; | ||
1114 | } | ||
1115 | kfree_skb(skb); | ||
1116 | |||
1117 | return 0; | ||
1118 | } | ||
1119 | |||
1120 | static int btusb_setup_intel(struct hci_dev *hdev) | ||
1121 | { | ||
1122 | struct sk_buff *skb; | ||
1123 | const struct firmware *fw; | ||
1124 | const u8 *fw_ptr; | ||
1125 | int disable_patch; | ||
1126 | struct intel_version *ver; | ||
1127 | |||
1128 | const u8 mfg_enable[] = { 0x01, 0x00 }; | ||
1129 | const u8 mfg_disable[] = { 0x00, 0x00 }; | ||
1130 | const u8 mfg_reset_deactivate[] = { 0x00, 0x01 }; | ||
1131 | const u8 mfg_reset_activate[] = { 0x00, 0x02 }; | ||
1132 | |||
1133 | BT_DBG("%s", hdev->name); | ||
1134 | |||
1135 | /* The controller has a bug with the first HCI command sent to it | ||
1136 | * returning number of completed commands as zero. This would stall the | ||
1137 | * command processing in the Bluetooth core. | ||
1138 | * | ||
1139 | * As a workaround, send HCI Reset command first which will reset the | ||
1140 | * number of completed commands and allow normal command processing | ||
1141 | * from now on. | ||
1142 | */ | ||
1143 | skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT); | ||
1144 | if (IS_ERR(skb)) { | ||
1145 | BT_ERR("%s sending initial HCI reset command failed (%ld)", | ||
1146 | hdev->name, PTR_ERR(skb)); | ||
1147 | return -PTR_ERR(skb); | ||
1148 | } | ||
1149 | kfree_skb(skb); | ||
1150 | |||
1151 | /* Read Intel specific controller version first to allow selection of | ||
1152 | * which firmware file to load. | ||
1153 | * | ||
1154 | * The returned information are hardware variant and revision plus | ||
1155 | * firmware variant, revision and build number. | ||
1156 | */ | ||
1157 | skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT); | ||
1158 | if (IS_ERR(skb)) { | ||
1159 | BT_ERR("%s reading Intel fw version command failed (%ld)", | ||
1160 | hdev->name, PTR_ERR(skb)); | ||
1161 | return -PTR_ERR(skb); | ||
1162 | } | ||
1163 | |||
1164 | if (skb->len != sizeof(*ver)) { | ||
1165 | BT_ERR("%s Intel version event length mismatch", hdev->name); | ||
1166 | kfree_skb(skb); | ||
1167 | return -EIO; | ||
1168 | } | ||
1169 | |||
1170 | ver = (struct intel_version *)skb->data; | ||
1171 | if (ver->status) { | ||
1172 | BT_ERR("%s Intel fw version event failed (%02x)", hdev->name, | ||
1173 | ver->status); | ||
1174 | kfree_skb(skb); | ||
1175 | return -bt_to_errno(ver->status); | ||
1176 | } | ||
1177 | |||
1178 | BT_INFO("%s: read Intel version: %02x%02x%02x%02x%02x%02x%02x%02x%02x", | ||
1179 | hdev->name, ver->hw_platform, ver->hw_variant, | ||
1180 | ver->hw_revision, ver->fw_variant, ver->fw_revision, | ||
1181 | ver->fw_build_num, ver->fw_build_ww, ver->fw_build_yy, | ||
1182 | ver->fw_patch_num); | ||
1183 | |||
1184 | /* fw_patch_num indicates the version of patch the device currently | ||
1185 | * have. If there is no patch data in the device, it is always 0x00. | ||
1186 | * So, if it is other than 0x00, no need to patch the deivce again. | ||
1187 | */ | ||
1188 | if (ver->fw_patch_num) { | ||
1189 | BT_INFO("%s: Intel device is already patched. patch num: %02x", | ||
1190 | hdev->name, ver->fw_patch_num); | ||
1191 | kfree_skb(skb); | ||
1192 | return 0; | ||
1193 | } | ||
1194 | |||
1195 | /* Opens the firmware patch file based on the firmware version read | ||
1196 | * from the controller. If it fails to open the matching firmware | ||
1197 | * patch file, it tries to open the default firmware patch file. | ||
1198 | * If no patch file is found, allow the device to operate without | ||
1199 | * a patch. | ||
1200 | */ | ||
1201 | fw = btusb_setup_intel_get_fw(hdev, ver); | ||
1202 | if (!fw) { | ||
1203 | kfree_skb(skb); | ||
1204 | return 0; | ||
1205 | } | ||
1206 | fw_ptr = fw->data; | ||
1207 | |||
1208 | /* This Intel specific command enables the manufacturer mode of the | ||
1209 | * controller. | ||
1210 | * | ||
1211 | * Only while this mode is enabled, the driver can download the | ||
1212 | * firmware patch data and configuration parameters. | ||
1213 | */ | ||
1214 | skb = __hci_cmd_sync(hdev, 0xfc11, 2, mfg_enable, HCI_INIT_TIMEOUT); | ||
1215 | if (IS_ERR(skb)) { | ||
1216 | BT_ERR("%s entering Intel manufacturer mode failed (%ld)", | ||
1217 | hdev->name, PTR_ERR(skb)); | ||
1218 | release_firmware(fw); | ||
1219 | return -PTR_ERR(skb); | ||
1220 | } | ||
1221 | |||
1222 | if (skb->data[0]) { | ||
1223 | u8 evt_status = skb->data[0]; | ||
1224 | BT_ERR("%s enable Intel manufacturer mode event failed (%02x)", | ||
1225 | hdev->name, evt_status); | ||
1226 | kfree_skb(skb); | ||
1227 | release_firmware(fw); | ||
1228 | return -bt_to_errno(evt_status); | ||
1229 | } | ||
1230 | kfree_skb(skb); | ||
1231 | |||
1232 | disable_patch = 1; | ||
1233 | |||
1234 | /* The firmware data file consists of list of Intel specific HCI | ||
1235 | * commands and its expected events. The first byte indicates the | ||
1236 | * type of the message, either HCI command or HCI event. | ||
1237 | * | ||
1238 | * It reads the command and its expected event from the firmware file, | ||
1239 | * and send to the controller. Once __hci_cmd_sync_ev() returns, | ||
1240 | * the returned event is compared with the event read from the firmware | ||
1241 | * file and it will continue until all the messages are downloaded to | ||
1242 | * the controller. | ||
1243 | * | ||
1244 | * Once the firmware patching is completed successfully, | ||
1245 | * the manufacturer mode is disabled with reset and activating the | ||
1246 | * downloaded patch. | ||
1247 | * | ||
1248 | * If the firmware patching fails, the manufacturer mode is | ||
1249 | * disabled with reset and deactivating the patch. | ||
1250 | * | ||
1251 | * If the default patch file is used, no reset is done when disabling | ||
1252 | * the manufacturer. | ||
1253 | */ | ||
1254 | while (fw->size > fw_ptr - fw->data) { | ||
1255 | int ret; | ||
1256 | |||
1257 | ret = btusb_setup_intel_patching(hdev, fw, &fw_ptr, | ||
1258 | &disable_patch); | ||
1259 | if (ret < 0) | ||
1260 | goto exit_mfg_deactivate; | ||
1261 | } | ||
1262 | |||
1263 | release_firmware(fw); | ||
1264 | |||
1265 | if (disable_patch) | ||
1266 | goto exit_mfg_disable; | ||
1267 | |||
1268 | /* Patching completed successfully and disable the manufacturer mode | ||
1269 | * with reset and activate the downloaded firmware patches. | ||
1270 | */ | ||
1271 | skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_activate), | ||
1272 | mfg_reset_activate, HCI_INIT_TIMEOUT); | ||
1273 | if (IS_ERR(skb)) { | ||
1274 | BT_ERR("%s exiting Intel manufacturer mode failed (%ld)", | ||
1275 | hdev->name, PTR_ERR(skb)); | ||
1276 | return -PTR_ERR(skb); | ||
1277 | } | ||
1278 | kfree_skb(skb); | ||
1279 | |||
1280 | BT_INFO("%s: Intel Bluetooth firmware patch completed and activated", | ||
1281 | hdev->name); | ||
1282 | |||
1283 | return 0; | ||
1284 | |||
1285 | exit_mfg_disable: | ||
1286 | /* Disable the manufacturer mode without reset */ | ||
1287 | skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_disable), mfg_disable, | ||
1288 | HCI_INIT_TIMEOUT); | ||
1289 | if (IS_ERR(skb)) { | ||
1290 | BT_ERR("%s exiting Intel manufacturer mode failed (%ld)", | ||
1291 | hdev->name, PTR_ERR(skb)); | ||
1292 | return -PTR_ERR(skb); | ||
1293 | } | ||
1294 | kfree_skb(skb); | ||
1295 | |||
1296 | BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name); | ||
1297 | return 0; | ||
1298 | |||
1299 | exit_mfg_deactivate: | ||
1300 | release_firmware(fw); | ||
1301 | |||
1302 | /* Patching failed. Disable the manufacturer mode with reset and | ||
1303 | * deactivate the downloaded firmware patches. | ||
1304 | */ | ||
1305 | skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_deactivate), | ||
1306 | mfg_reset_deactivate, HCI_INIT_TIMEOUT); | ||
1307 | if (IS_ERR(skb)) { | ||
1308 | BT_ERR("%s exiting Intel manufacturer mode failed (%ld)", | ||
1309 | hdev->name, PTR_ERR(skb)); | ||
1310 | return -PTR_ERR(skb); | ||
1311 | } | ||
1312 | kfree_skb(skb); | ||
1313 | |||
1314 | BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated", | ||
1315 | hdev->name); | ||
1316 | |||
1317 | return 0; | ||
1318 | } | ||
1319 | |||
946 | static int btusb_probe(struct usb_interface *intf, | 1320 | static int btusb_probe(struct usb_interface *intf, |
947 | const struct usb_device_id *id) | 1321 | const struct usb_device_id *id) |
948 | { | 1322 | { |
@@ -1048,6 +1422,9 @@ static int btusb_probe(struct usb_interface *intf, | |||
1048 | if (id->driver_info & BTUSB_BCM92035) | 1422 | if (id->driver_info & BTUSB_BCM92035) |
1049 | hdev->setup = btusb_setup_bcm92035; | 1423 | hdev->setup = btusb_setup_bcm92035; |
1050 | 1424 | ||
1425 | if (id->driver_info & BTUSB_INTEL) | ||
1426 | hdev->setup = btusb_setup_intel; | ||
1427 | |||
1051 | /* Interface numbers are hardcoded in the specification */ | 1428 | /* Interface numbers are hardcoded in the specification */ |
1052 | data->isoc = usb_ifnum_to_if(data->udev, 1); | 1429 | data->isoc = usb_ifnum_to_if(data->udev, 1); |
1053 | 1430 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 2346821667e6..3a6544710c8a 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -336,6 +336,7 @@ static void brcms_remove(struct bcma_device *pdev) | |||
336 | struct brcms_info *wl = hw->priv; | 336 | struct brcms_info *wl = hw->priv; |
337 | 337 | ||
338 | if (wl->wlc) { | 338 | if (wl->wlc) { |
339 | brcms_led_unregister(wl); | ||
339 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); | 340 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); |
340 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | 341 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); |
341 | ieee80211_unregister_hw(hw); | 342 | ieee80211_unregister_hw(hw); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index e575b9b0cda8..48545ab00311 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h | |||
@@ -172,7 +172,7 @@ int iwl_calib_set(struct iwl_priv *priv, | |||
172 | const struct iwl_calib_hdr *cmd, int len); | 172 | const struct iwl_calib_hdr *cmd, int len); |
173 | void iwl_calib_free_results(struct iwl_priv *priv); | 173 | void iwl_calib_free_results(struct iwl_priv *priv); |
174 | int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | 174 | int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, |
175 | char **buf, bool display); | 175 | char **buf); |
176 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); | 176 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); |
177 | 177 | ||
178 | /* lib */ | 178 | /* lib */ |
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 7b8178be119f..d5329489245a 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c | |||
@@ -2237,15 +2237,13 @@ static ssize_t iwl_dbgfs_log_event_read(struct file *file, | |||
2237 | size_t count, loff_t *ppos) | 2237 | size_t count, loff_t *ppos) |
2238 | { | 2238 | { |
2239 | struct iwl_priv *priv = file->private_data; | 2239 | struct iwl_priv *priv = file->private_data; |
2240 | char *buf; | 2240 | char *buf = NULL; |
2241 | int pos = 0; | 2241 | ssize_t ret; |
2242 | ssize_t ret = -ENOMEM; | ||
2243 | 2242 | ||
2244 | ret = pos = iwl_dump_nic_event_log(priv, true, &buf, true); | 2243 | ret = iwl_dump_nic_event_log(priv, true, &buf); |
2245 | if (buf) { | 2244 | if (ret > 0) |
2246 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 2245 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); |
2247 | kfree(buf); | 2246 | kfree(buf); |
2248 | } | ||
2249 | return ret; | 2247 | return ret; |
2250 | } | 2248 | } |
2251 | 2249 | ||
@@ -2269,7 +2267,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, | |||
2269 | if (sscanf(buf, "%d", &event_log_flag) != 1) | 2267 | if (sscanf(buf, "%d", &event_log_flag) != 1) |
2270 | return -EFAULT; | 2268 | return -EFAULT; |
2271 | if (event_log_flag == 1) | 2269 | if (event_log_flag == 1) |
2272 | iwl_dump_nic_event_log(priv, true, NULL, false); | 2270 | iwl_dump_nic_event_log(priv, true, NULL); |
2273 | 2271 | ||
2274 | return count; | 2272 | return count; |
2275 | } | 2273 | } |
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index b9e3517652d6..74d7572e7091 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
@@ -1795,7 +1795,7 @@ static int iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | |||
1795 | #define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) | 1795 | #define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) |
1796 | 1796 | ||
1797 | int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | 1797 | int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, |
1798 | char **buf, bool display) | 1798 | char **buf) |
1799 | { | 1799 | { |
1800 | u32 base; /* SRAM byte address of event log header */ | 1800 | u32 base; /* SRAM byte address of event log header */ |
1801 | u32 capacity; /* event log capacity in # entries */ | 1801 | u32 capacity; /* event log capacity in # entries */ |
@@ -1866,7 +1866,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | |||
1866 | size); | 1866 | size); |
1867 | 1867 | ||
1868 | #ifdef CONFIG_IWLWIFI_DEBUG | 1868 | #ifdef CONFIG_IWLWIFI_DEBUG |
1869 | if (display) { | 1869 | if (buf) { |
1870 | if (full_log) | 1870 | if (full_log) |
1871 | bufsz = capacity * 48; | 1871 | bufsz = capacity * 48; |
1872 | else | 1872 | else |
@@ -1962,7 +1962,7 @@ static void iwl_nic_error(struct iwl_op_mode *op_mode) | |||
1962 | priv->fw->fw_version); | 1962 | priv->fw->fw_version); |
1963 | 1963 | ||
1964 | iwl_dump_nic_error_log(priv); | 1964 | iwl_dump_nic_error_log(priv); |
1965 | iwl_dump_nic_event_log(priv, false, NULL, false); | 1965 | iwl_dump_nic_event_log(priv, false, NULL); |
1966 | 1966 | ||
1967 | iwlagn_fw_error(priv, false); | 1967 | iwlagn_fw_error(priv, false); |
1968 | } | 1968 | } |
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index b775769f8322..db183b44e038 100644 --- a/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c | |||
@@ -695,6 +695,7 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, | |||
695 | void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | 695 | void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) |
696 | { | 696 | { |
697 | struct iwl_addsta_cmd sta_cmd; | 697 | struct iwl_addsta_cmd sta_cmd; |
698 | static const struct iwl_link_quality_cmd zero_lq = {}; | ||
698 | struct iwl_link_quality_cmd lq; | 699 | struct iwl_link_quality_cmd lq; |
699 | int i; | 700 | int i; |
700 | bool found = false; | 701 | bool found = false; |
@@ -733,7 +734,9 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
733 | else | 734 | else |
734 | memcpy(&lq, priv->stations[i].lq, | 735 | memcpy(&lq, priv->stations[i].lq, |
735 | sizeof(struct iwl_link_quality_cmd)); | 736 | sizeof(struct iwl_link_quality_cmd)); |
736 | send_lq = true; | 737 | |
738 | if (!memcmp(&lq, &zero_lq, sizeof(lq))) | ||
739 | send_lq = true; | ||
737 | } | 740 | } |
738 | spin_unlock_bh(&priv->sta_lock); | 741 | spin_unlock_bh(&priv->sta_lock); |
739 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 742 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index fe031608fd91..dd158ec571fb 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -207,7 +207,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
207 | 207 | ||
208 | hw->wiphy->hw_version = mvm->trans->hw_id; | 208 | hw->wiphy->hw_version = mvm->trans->hw_id; |
209 | 209 | ||
210 | if (iwlwifi_mod_params.power_save) | 210 | if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) |
211 | hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; | 211 | hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; |
212 | else | 212 | else |
213 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 213 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c index 0f0b44eabd93..a28a1d1f23eb 100644 --- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c | |||
@@ -153,11 +153,6 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm, | |||
153 | cmd->ci.ctrl_pos = iwl_mvm_get_ctrl_pos(chandef); | 153 | cmd->ci.ctrl_pos = iwl_mvm_get_ctrl_pos(chandef); |
154 | 154 | ||
155 | /* Set rx the chains */ | 155 | /* Set rx the chains */ |
156 | |||
157 | /* TODO: | ||
158 | * Need to add on chain noise calibration limitations, and | ||
159 | * BT coex considerations. | ||
160 | */ | ||
161 | idle_cnt = chains_static; | 156 | idle_cnt = chains_static; |
162 | active_cnt = chains_dynamic; | 157 | active_cnt = chains_dynamic; |
163 | 158 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 9395ab2a1af2..ed77e437aac4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
@@ -111,8 +111,7 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
111 | */ | 111 | */ |
112 | cmd->keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC; | 112 | cmd->keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC; |
113 | 113 | ||
114 | if ((iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) || | 114 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) |
115 | !iwlwifi_mod_params.power_save) | ||
116 | return; | 115 | return; |
117 | 116 | ||
118 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); | 117 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); |
@@ -146,14 +145,8 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
146 | keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); | 145 | keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); |
147 | cmd->keep_alive_seconds = keep_alive; | 146 | cmd->keep_alive_seconds = keep_alive; |
148 | 147 | ||
149 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) { | 148 | cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); |
150 | /* TODO: Also for D3 (device sleep / WoWLAN) */ | 149 | cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); |
151 | cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); | ||
152 | cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC); | ||
153 | } else { | ||
154 | cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); | ||
155 | cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); | ||
156 | } | ||
157 | } | 150 | } |
158 | 151 | ||
159 | int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 152 | int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
@@ -177,8 +170,7 @@ int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
177 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) | 170 | if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) |
178 | return 0; | 171 | return 0; |
179 | 172 | ||
180 | if ((iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) && | 173 | if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) |
181 | iwlwifi_mod_params.power_save) | ||
182 | cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); | 174 | cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); |
183 | 175 | ||
184 | iwl_mvm_power_log(mvm, &cmd); | 176 | iwl_mvm_power_log(mvm, &cmd); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 0cc8d8c0d393..687b34e387ac 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
@@ -253,8 +253,9 @@ int iwl_mvm_rx_fw_error(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | |||
253 | u8 first_antenna(u8 mask) | 253 | u8 first_antenna(u8 mask) |
254 | { | 254 | { |
255 | BUILD_BUG_ON(ANT_A != BIT(0)); /* using ffs is wrong if not */ | 255 | BUILD_BUG_ON(ANT_A != BIT(0)); /* using ffs is wrong if not */ |
256 | WARN_ON_ONCE(!mask); /* ffs will return 0 if mask is zeroed */ | 256 | if (WARN_ON_ONCE(!mask)) /* ffs will return 0 if mask is zeroed */ |
257 | return (u8)(BIT(ffs(mask))); | 257 | return BIT(0); |
258 | return BIT(ffs(mask) - 1); | ||
258 | } | 259 | } |
259 | 260 | ||
260 | /* | 261 | /* |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 0016bb24b3d7..8cb53ec2b77b 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
@@ -256,6 +256,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
256 | 256 | ||
257 | /* 7000 Series */ | 257 | /* 7000 Series */ |
258 | {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)}, | 258 | {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)}, |
259 | {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_2ac_cfg)}, | ||
259 | {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)}, | 260 | {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)}, |
260 | {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_ac_cfg)}, | 261 | {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_ac_cfg)}, |
261 | {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_ac_cfg)}, | 262 | {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_ac_cfg)}, |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 80f282c0bd4d..20c9c4c7b0b2 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
@@ -861,9 +861,8 @@ static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) | |||
861 | 861 | ||
862 | if (card && card->cmd_buf) { | 862 | if (card && card->cmd_buf) { |
863 | MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa); | 863 | MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa); |
864 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_SIZE_OF_CMD_BUFFER, | 864 | pci_unmap_single(card->dev, buf_pa, card->cmd_buf->len, |
865 | PCI_DMA_TODEVICE); | 865 | PCI_DMA_TODEVICE); |
866 | dev_kfree_skb_any(card->cmd_buf); | ||
867 | } | 866 | } |
868 | return 0; | 867 | return 0; |
869 | } | 868 | } |
@@ -1573,7 +1572,7 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter, | |||
1573 | skb_tmp = card->cmd_buf; | 1572 | skb_tmp = card->cmd_buf; |
1574 | if (skb_tmp) { | 1573 | if (skb_tmp) { |
1575 | MWIFIEX_SKB_PACB(skb_tmp, &buf_pa); | 1574 | MWIFIEX_SKB_PACB(skb_tmp, &buf_pa); |
1576 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, | 1575 | pci_unmap_single(card->dev, buf_pa, skb_tmp->len, |
1577 | PCI_DMA_FROMDEVICE); | 1576 | PCI_DMA_FROMDEVICE); |
1578 | card->cmd_buf = NULL; | 1577 | card->cmd_buf = NULL; |
1579 | } | 1578 | } |
@@ -2294,9 +2293,9 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter) | |||
2294 | if (pdev) { | 2293 | if (pdev) { |
2295 | pci_iounmap(pdev, card->pci_mmap); | 2294 | pci_iounmap(pdev, card->pci_mmap); |
2296 | pci_iounmap(pdev, card->pci_mmap1); | 2295 | pci_iounmap(pdev, card->pci_mmap1); |
2297 | |||
2298 | pci_release_regions(pdev); | ||
2299 | pci_disable_device(pdev); | 2296 | pci_disable_device(pdev); |
2297 | pci_release_region(pdev, 2); | ||
2298 | pci_release_region(pdev, 0); | ||
2300 | pci_set_drvdata(pdev, NULL); | 2299 | pci_set_drvdata(pdev, NULL); |
2301 | } | 2300 | } |
2302 | } | 2301 | } |
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 83915dcd0e58..76732b0cd221 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
@@ -521,6 +521,9 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, | |||
521 | rtlpriv->link_info.num_rx_inperiod++; | 521 | rtlpriv->link_info.num_rx_inperiod++; |
522 | } | 522 | } |
523 | 523 | ||
524 | /* static bcn for roaming */ | ||
525 | rtl_beacon_statistic(hw, skb); | ||
526 | |||
524 | if (likely(rtl_action_proc(hw, skb, false))) | 527 | if (likely(rtl_action_proc(hw, skb, false))) |
525 | ieee80211_rx(hw, skb); | 528 | ieee80211_rx(hw, skb); |
526 | else | 529 | else |
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index 23c5dbfea115..1173a091b402 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c | |||
@@ -687,8 +687,23 @@ void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid) | |||
687 | pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD; | 687 | pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD; |
688 | break; | 688 | break; |
689 | case 43222: | 689 | case 43222: |
690 | /* TODO: BCM43222 requires updating PLLs too */ | 690 | if (spuravoid == 1) { |
691 | return; | 691 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11500008); |
692 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x0C000C06); | ||
693 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x0F600a08); | ||
694 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL3, 0x00000000); | ||
695 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL4, 0x2001E920); | ||
696 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888815); | ||
697 | } else { | ||
698 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100008); | ||
699 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x0c000c06); | ||
700 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x03000a08); | ||
701 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL3, 0x00000000); | ||
702 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL4, 0x200005c0); | ||
703 | ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888855); | ||
704 | } | ||
705 | pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD; | ||
706 | break; | ||
692 | default: | 707 | default: |
693 | ssb_printk(KERN_ERR PFX | 708 | ssb_printk(KERN_ERR PFX |
694 | "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n", | 709 | "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n", |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 80d718a9b31f..35a57cd1704c 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -1081,17 +1081,19 @@ struct hci_request { | |||
1081 | 1081 | ||
1082 | void hci_req_init(struct hci_request *req, struct hci_dev *hdev); | 1082 | void hci_req_init(struct hci_request *req, struct hci_dev *hdev); |
1083 | int hci_req_run(struct hci_request *req, hci_req_complete_t complete); | 1083 | int hci_req_run(struct hci_request *req, hci_req_complete_t complete); |
1084 | void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param); | 1084 | void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, |
1085 | void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void *param, | 1085 | const void *param); |
1086 | u8 event); | 1086 | void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, |
1087 | const void *param, u8 event); | ||
1087 | void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); | 1088 | void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); |
1088 | 1089 | ||
1089 | struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, | 1090 | struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, |
1090 | void *param, u32 timeout); | 1091 | const void *param, u32 timeout); |
1091 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, | 1092 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, |
1092 | void *param, u8 event, u32 timeout); | 1093 | const void *param, u8 event, u32 timeout); |
1093 | 1094 | ||
1094 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); | 1095 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, |
1096 | const void *param); | ||
1095 | void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); | 1097 | void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); |
1096 | void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); | 1098 | void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); |
1097 | 1099 | ||
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ce82265f5619..33843c5c4939 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -79,7 +79,8 @@ static void hci_req_cancel(struct hci_dev *hdev, int err) | |||
79 | } | 79 | } |
80 | } | 80 | } |
81 | 81 | ||
82 | struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 event) | 82 | static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, |
83 | u8 event) | ||
83 | { | 84 | { |
84 | struct hci_ev_cmd_complete *ev; | 85 | struct hci_ev_cmd_complete *ev; |
85 | struct hci_event_hdr *hdr; | 86 | struct hci_event_hdr *hdr; |
@@ -134,7 +135,7 @@ failed: | |||
134 | } | 135 | } |
135 | 136 | ||
136 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, | 137 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, |
137 | void *param, u8 event, u32 timeout) | 138 | const void *param, u8 event, u32 timeout) |
138 | { | 139 | { |
139 | DECLARE_WAITQUEUE(wait, current); | 140 | DECLARE_WAITQUEUE(wait, current); |
140 | struct hci_request req; | 141 | struct hci_request req; |
@@ -188,7 +189,7 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, | |||
188 | EXPORT_SYMBOL(__hci_cmd_sync_ev); | 189 | EXPORT_SYMBOL(__hci_cmd_sync_ev); |
189 | 190 | ||
190 | struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, | 191 | struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, |
191 | void *param, u32 timeout) | 192 | const void *param, u32 timeout) |
192 | { | 193 | { |
193 | return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); | 194 | return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout); |
194 | } | 195 | } |
@@ -377,6 +378,8 @@ static void bredr_setup(struct hci_request *req) | |||
377 | 378 | ||
378 | static void le_setup(struct hci_request *req) | 379 | static void le_setup(struct hci_request *req) |
379 | { | 380 | { |
381 | struct hci_dev *hdev = req->hdev; | ||
382 | |||
380 | /* Read LE Buffer Size */ | 383 | /* Read LE Buffer Size */ |
381 | hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); | 384 | hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); |
382 | 385 | ||
@@ -391,6 +394,10 @@ static void le_setup(struct hci_request *req) | |||
391 | 394 | ||
392 | /* Read LE Supported States */ | 395 | /* Read LE Supported States */ |
393 | hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); | 396 | hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL); |
397 | |||
398 | /* LE-only controllers have LE implicitly enabled */ | ||
399 | if (!lmp_bredr_capable(hdev)) | ||
400 | set_bit(HCI_LE_ENABLED, &hdev->dev_flags); | ||
394 | } | 401 | } |
395 | 402 | ||
396 | static u8 hci_get_inquiry_mode(struct hci_dev *hdev) | 403 | static u8 hci_get_inquiry_mode(struct hci_dev *hdev) |
@@ -574,6 +581,10 @@ static void hci_set_le_support(struct hci_request *req) | |||
574 | struct hci_dev *hdev = req->hdev; | 581 | struct hci_dev *hdev = req->hdev; |
575 | struct hci_cp_write_le_host_supported cp; | 582 | struct hci_cp_write_le_host_supported cp; |
576 | 583 | ||
584 | /* LE-only devices do not support explicit enablement */ | ||
585 | if (!lmp_bredr_capable(hdev)) | ||
586 | return; | ||
587 | |||
577 | memset(&cp, 0, sizeof(cp)); | 588 | memset(&cp, 0, sizeof(cp)); |
578 | 589 | ||
579 | if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { | 590 | if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { |
@@ -2602,7 +2613,7 @@ int hci_req_run(struct hci_request *req, hci_req_complete_t complete) | |||
2602 | } | 2613 | } |
2603 | 2614 | ||
2604 | static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, | 2615 | static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, |
2605 | u32 plen, void *param) | 2616 | u32 plen, const void *param) |
2606 | { | 2617 | { |
2607 | int len = HCI_COMMAND_HDR_SIZE + plen; | 2618 | int len = HCI_COMMAND_HDR_SIZE + plen; |
2608 | struct hci_command_hdr *hdr; | 2619 | struct hci_command_hdr *hdr; |
@@ -2628,7 +2639,8 @@ static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, | |||
2628 | } | 2639 | } |
2629 | 2640 | ||
2630 | /* Send HCI command */ | 2641 | /* Send HCI command */ |
2631 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) | 2642 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, |
2643 | const void *param) | ||
2632 | { | 2644 | { |
2633 | struct sk_buff *skb; | 2645 | struct sk_buff *skb; |
2634 | 2646 | ||
@@ -2652,8 +2664,8 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) | |||
2652 | } | 2664 | } |
2653 | 2665 | ||
2654 | /* Queue a command to an asynchronous HCI request */ | 2666 | /* Queue a command to an asynchronous HCI request */ |
2655 | void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void *param, | 2667 | void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, |
2656 | u8 event) | 2668 | const void *param, u8 event) |
2657 | { | 2669 | { |
2658 | struct hci_dev *hdev = req->hdev; | 2670 | struct hci_dev *hdev = req->hdev; |
2659 | struct sk_buff *skb; | 2671 | struct sk_buff *skb; |
@@ -2682,7 +2694,8 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void *param, | |||
2682 | skb_queue_tail(&req->cmd_q, skb); | 2694 | skb_queue_tail(&req->cmd_q, skb); |
2683 | } | 2695 | } |
2684 | 2696 | ||
2685 | void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param) | 2697 | void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, |
2698 | const void *param) | ||
2686 | { | 2699 | { |
2687 | hci_req_add_ev(req, opcode, plen, param, 0); | 2700 | hci_req_add_ev(req, opcode, plen, param, 0); |
2688 | } | 2701 | } |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index eae1d9f90b68..a76d1ac0321b 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -6314,12 +6314,13 @@ drop: | |||
6314 | kfree_skb(skb); | 6314 | kfree_skb(skb); |
6315 | } | 6315 | } |
6316 | 6316 | ||
6317 | static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid, | 6317 | static void l2cap_att_channel(struct l2cap_conn *conn, |
6318 | struct sk_buff *skb) | 6318 | struct sk_buff *skb) |
6319 | { | 6319 | { |
6320 | struct l2cap_chan *chan; | 6320 | struct l2cap_chan *chan; |
6321 | 6321 | ||
6322 | chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst); | 6322 | chan = l2cap_global_chan_by_scid(0, L2CAP_CID_LE_DATA, |
6323 | conn->src, conn->dst); | ||
6323 | if (!chan) | 6324 | if (!chan) |
6324 | goto drop; | 6325 | goto drop; |
6325 | 6326 | ||
@@ -6368,7 +6369,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
6368 | break; | 6369 | break; |
6369 | 6370 | ||
6370 | case L2CAP_CID_LE_DATA: | 6371 | case L2CAP_CID_LE_DATA: |
6371 | l2cap_att_channel(conn, cid, skb); | 6372 | l2cap_att_channel(conn, skb); |
6372 | break; | 6373 | break; |
6373 | 6374 | ||
6374 | case L2CAP_CID_SMP: | 6375 | case L2CAP_CID_SMP: |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 4c830c62ef74..35fef22703e9 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -1351,6 +1351,11 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | |||
1351 | return cmd_status(sk, hdev->id, MGMT_OP_SET_LE, | 1351 | return cmd_status(sk, hdev->id, MGMT_OP_SET_LE, |
1352 | MGMT_STATUS_INVALID_PARAMS); | 1352 | MGMT_STATUS_INVALID_PARAMS); |
1353 | 1353 | ||
1354 | /* LE-only devices do not allow toggling LE on/off */ | ||
1355 | if (!lmp_bredr_capable(hdev)) | ||
1356 | return cmd_status(sk, hdev->id, MGMT_OP_SET_LE, | ||
1357 | MGMT_STATUS_REJECTED); | ||
1358 | |||
1354 | hci_dev_lock(hdev); | 1359 | hci_dev_lock(hdev); |
1355 | 1360 | ||
1356 | val = !!cp->val; | 1361 | val = !!cp->val; |
@@ -3347,7 +3352,8 @@ static int powered_update_hci(struct hci_dev *hdev) | |||
3347 | hci_req_add(&req, HCI_OP_WRITE_SSP_MODE, 1, &ssp); | 3352 | hci_req_add(&req, HCI_OP_WRITE_SSP_MODE, 1, &ssp); |
3348 | } | 3353 | } |
3349 | 3354 | ||
3350 | if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { | 3355 | if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags) && |
3356 | lmp_bredr_capable(hdev)) { | ||
3351 | struct hci_cp_write_le_host_supported cp; | 3357 | struct hci_cp_write_le_host_supported cp; |
3352 | 3358 | ||
3353 | cp.le = 1; | 3359 | cp.le = 1; |
diff --git a/net/nfc/Kconfig b/net/nfc/Kconfig index 60c3bbb63e8e..5948b2fc72f6 100644 --- a/net/nfc/Kconfig +++ b/net/nfc/Kconfig | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | menuconfig NFC | 5 | menuconfig NFC |
6 | depends on NET | 6 | depends on NET |
7 | depends on RFKILL || !RFKILL | ||
7 | tristate "NFC subsystem support" | 8 | tristate "NFC subsystem support" |
8 | default n | 9 | default n |
9 | help | 10 | help |
@@ -15,6 +16,5 @@ menuconfig NFC | |||
15 | 16 | ||
16 | source "net/nfc/nci/Kconfig" | 17 | source "net/nfc/nci/Kconfig" |
17 | source "net/nfc/hci/Kconfig" | 18 | source "net/nfc/hci/Kconfig" |
18 | source "net/nfc/llcp/Kconfig" | ||
19 | 19 | ||
20 | source "drivers/nfc/Kconfig" | 20 | source "drivers/nfc/Kconfig" |
diff --git a/net/nfc/Makefile b/net/nfc/Makefile index d1a117c2c401..fb799deaed4f 100644 --- a/net/nfc/Makefile +++ b/net/nfc/Makefile | |||
@@ -5,6 +5,8 @@ | |||
5 | obj-$(CONFIG_NFC) += nfc.o | 5 | obj-$(CONFIG_NFC) += nfc.o |
6 | obj-$(CONFIG_NFC_NCI) += nci/ | 6 | obj-$(CONFIG_NFC_NCI) += nci/ |
7 | obj-$(CONFIG_NFC_HCI) += hci/ | 7 | obj-$(CONFIG_NFC_HCI) += hci/ |
8 | #obj-$(CONFIG_NFC_LLCP) += llcp/ | ||
9 | |||
10 | nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \ | ||
11 | llcp_sock.o | ||
8 | 12 | ||
9 | nfc-objs := core.o netlink.o af_nfc.o rawsock.o | ||
10 | nfc-$(CONFIG_NFC_LLCP) += llcp/llcp.o llcp/commands.o llcp/sock.o | ||
diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp.h index ff8c434f7df8..ff8c434f7df8 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp.h | |||
diff --git a/net/nfc/llcp/Kconfig b/net/nfc/llcp/Kconfig deleted file mode 100644 index a1a41cd68255..000000000000 --- a/net/nfc/llcp/Kconfig +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | config NFC_LLCP | ||
2 | depends on NFC | ||
3 | bool "NFC LLCP support" | ||
4 | default n | ||
5 | help | ||
6 | Say Y here if you want to build support for a kernel NFC LLCP | ||
7 | implementation. \ No newline at end of file | ||
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp_commands.c index 094f7e27e910..c1b23eef83ca 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp_commands.c | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | #include <net/nfc/nfc.h> | 27 | #include <net/nfc/nfc.h> |
28 | 28 | ||
29 | #include "../nfc.h" | 29 | #include "nfc.h" |
30 | #include "llcp.h" | 30 | #include "llcp.h" |
31 | 31 | ||
32 | static u8 llcp_tlv_length[LLCP_TLV_MAX] = { | 32 | static u8 llcp_tlv_length[LLCP_TLV_MAX] = { |
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp_core.c index 9e483c8e52f8..158bdbf668cc 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp_core.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
25 | #include <linux/nfc.h> | 25 | #include <linux/nfc.h> |
26 | 26 | ||
27 | #include "../nfc.h" | 27 | #include "nfc.h" |
28 | #include "llcp.h" | 28 | #include "llcp.h" |
29 | 29 | ||
30 | static u8 llcp_magic[3] = {0x46, 0x66, 0x6d}; | 30 | static u8 llcp_magic[3] = {0x46, 0x66, 0x6d}; |
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp_sock.c index d6faa47c9bba..38f08c31cdd8 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp_sock.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/nfc.h> | 25 | #include <linux/nfc.h> |
26 | 26 | ||
27 | #include "../nfc.h" | 27 | #include "nfc.h" |
28 | #include "llcp.h" | 28 | #include "llcp.h" |
29 | 29 | ||
30 | static int sock_wait_state(struct sock *sk, int state, unsigned long timeo) | 30 | static int sock_wait_state(struct sock *sk, int state, unsigned long timeo) |
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 73fd51098f4d..f0c4d61f37c0 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c | |||
@@ -28,8 +28,7 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | 29 | ||
30 | #include "nfc.h" | 30 | #include "nfc.h" |
31 | 31 | #include "llcp.h" | |
32 | #include "llcp/llcp.h" | ||
33 | 32 | ||
34 | static struct genl_multicast_group nfc_genl_event_mcgrp = { | 33 | static struct genl_multicast_group nfc_genl_event_mcgrp = { |
35 | .name = NFC_GENL_MCAST_EVENT_NAME, | 34 | .name = NFC_GENL_MCAST_EVENT_NAME, |
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index 94bfe19ba678..afa1f84ba040 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h | |||
@@ -48,8 +48,6 @@ struct nfc_rawsock { | |||
48 | 48 | ||
49 | struct nfc_llcp_sdp_tlv; | 49 | struct nfc_llcp_sdp_tlv; |
50 | 50 | ||
51 | #ifdef CONFIG_NFC_LLCP | ||
52 | |||
53 | void nfc_llcp_mac_is_down(struct nfc_dev *dev); | 51 | void nfc_llcp_mac_is_down(struct nfc_dev *dev); |
54 | void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, | 52 | void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, |
55 | u8 comm_mode, u8 rf_mode); | 53 | u8 comm_mode, u8 rf_mode); |
@@ -64,68 +62,6 @@ void nfc_llcp_exit(void); | |||
64 | void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp); | 62 | void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp); |
65 | void nfc_llcp_free_sdp_tlv_list(struct hlist_head *head); | 63 | void nfc_llcp_free_sdp_tlv_list(struct hlist_head *head); |
66 | 64 | ||
67 | #else | ||
68 | |||
69 | static inline void nfc_llcp_mac_is_down(struct nfc_dev *dev) | ||
70 | { | ||
71 | } | ||
72 | |||
73 | static inline void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, | ||
74 | u8 comm_mode, u8 rf_mode) | ||
75 | { | ||
76 | } | ||
77 | |||
78 | static inline int nfc_llcp_register_device(struct nfc_dev *dev) | ||
79 | { | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static inline void nfc_llcp_unregister_device(struct nfc_dev *dev) | ||
84 | { | ||
85 | } | ||
86 | |||
87 | static inline int nfc_llcp_set_remote_gb(struct nfc_dev *dev, | ||
88 | u8 *gb, u8 gb_len) | ||
89 | { | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static inline u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *gb_len) | ||
94 | { | ||
95 | *gb_len = 0; | ||
96 | return NULL; | ||
97 | } | ||
98 | |||
99 | static inline int nfc_llcp_data_received(struct nfc_dev *dev, | ||
100 | struct sk_buff *skb) | ||
101 | { | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static inline struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev) | ||
106 | { | ||
107 | return NULL; | ||
108 | } | ||
109 | |||
110 | static inline int nfc_llcp_init(void) | ||
111 | { | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static inline void nfc_llcp_exit(void) | ||
116 | { | ||
117 | } | ||
118 | |||
119 | static inline void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp) | ||
120 | { | ||
121 | } | ||
122 | |||
123 | static inline void nfc_llcp_free_sdp_tlv_list(struct hlist_head *sdp_head) | ||
124 | { | ||
125 | } | ||
126 | |||
127 | #endif | ||
128 | |||
129 | int __init rawsock_init(void); | 65 | int __init rawsock_init(void); |
130 | void rawsock_exit(void); | 66 | void rawsock_exit(void); |
131 | 67 | ||