diff options
| author | John W. Linville <linville@tuxdriver.com> | 2011-07-08 11:01:31 -0400 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2011-07-08 11:01:31 -0400 |
| commit | 8a98d935c4b8b3515d1403d150e282f95b9f558d (patch) | |
| tree | e891deb720a12aa2cf52ad9efc025e12bdcde787 | |
| parent | f8d9605243280f1870dd2c6c37a735b925c15f3c (diff) | |
| parent | 34459512ffa7236c849466e3bd604801389734e1 (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into for-davem
| -rw-r--r-- | drivers/net/wireless/ath/ath5k/pci.c | 7 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath5k/sysfs.c | 9 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 3 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/carl9170/usb.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 1 | ||||
| -rw-r--r-- | drivers/ssb/driver_pcicore.c | 18 | ||||
| -rw-r--r-- | net/bluetooth/hci_conn.c | 3 | ||||
| -rw-r--r-- | net/bluetooth/hidp/core.c | 18 | ||||
| -rw-r--r-- | net/bluetooth/hidp/hidp.h | 1 | ||||
| -rw-r--r-- | net/bluetooth/l2cap_core.c | 5 | ||||
| -rw-r--r-- | net/mac80211/scan.c | 3 | ||||
| -rw-r--r-- | net/mac80211/wpa.c | 16 | ||||
| -rw-r--r-- | net/wireless/core.c | 12 | ||||
| -rw-r--r-- | net/wireless/core.h | 2 | ||||
| -rw-r--r-- | net/wireless/nl80211.c | 24 | ||||
| -rw-r--r-- | net/wireless/scan.c | 10 |
16 files changed, 92 insertions, 42 deletions
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 296c316a8341..f2c0c236392f 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c | |||
| @@ -297,7 +297,9 @@ ath5k_pci_remove(struct pci_dev *pdev) | |||
| 297 | #ifdef CONFIG_PM_SLEEP | 297 | #ifdef CONFIG_PM_SLEEP |
| 298 | static int ath5k_pci_suspend(struct device *dev) | 298 | static int ath5k_pci_suspend(struct device *dev) |
| 299 | { | 299 | { |
| 300 | struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); | 300 | struct pci_dev *pdev = to_pci_dev(dev); |
| 301 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
| 302 | struct ath5k_softc *sc = hw->priv; | ||
| 301 | 303 | ||
| 302 | ath5k_led_off(sc); | 304 | ath5k_led_off(sc); |
| 303 | return 0; | 305 | return 0; |
| @@ -306,7 +308,8 @@ static int ath5k_pci_suspend(struct device *dev) | |||
| 306 | static int ath5k_pci_resume(struct device *dev) | 308 | static int ath5k_pci_resume(struct device *dev) |
| 307 | { | 309 | { |
| 308 | struct pci_dev *pdev = to_pci_dev(dev); | 310 | struct pci_dev *pdev = to_pci_dev(dev); |
| 309 | struct ath5k_softc *sc = pci_get_drvdata(pdev); | 311 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
| 312 | struct ath5k_softc *sc = hw->priv; | ||
| 310 | 313 | ||
| 311 | /* | 314 | /* |
| 312 | * Suspend/Resume resets the PCI configuration space, so we have to | 315 | * Suspend/Resume resets the PCI configuration space, so we have to |
diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c index 929c68cdf8ab..a073cdce1f15 100644 --- a/drivers/net/wireless/ath/ath5k/sysfs.c +++ b/drivers/net/wireless/ath/ath5k/sysfs.c | |||
| @@ -10,7 +10,8 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \ | |||
| 10 | struct device_attribute *attr, \ | 10 | struct device_attribute *attr, \ |
| 11 | char *buf) \ | 11 | char *buf) \ |
| 12 | { \ | 12 | { \ |
| 13 | struct ath5k_softc *sc = dev_get_drvdata(dev); \ | 13 | struct ieee80211_hw *hw = dev_get_drvdata(dev); \ |
| 14 | struct ath5k_softc *sc = hw->priv; \ | ||
| 14 | return snprintf(buf, PAGE_SIZE, "%d\n", get); \ | 15 | return snprintf(buf, PAGE_SIZE, "%d\n", get); \ |
| 15 | } \ | 16 | } \ |
| 16 | \ | 17 | \ |
| @@ -18,7 +19,8 @@ static ssize_t ath5k_attr_store_##name(struct device *dev, \ | |||
| 18 | struct device_attribute *attr, \ | 19 | struct device_attribute *attr, \ |
| 19 | const char *buf, size_t count) \ | 20 | const char *buf, size_t count) \ |
| 20 | { \ | 21 | { \ |
| 21 | struct ath5k_softc *sc = dev_get_drvdata(dev); \ | 22 | struct ieee80211_hw *hw = dev_get_drvdata(dev); \ |
| 23 | struct ath5k_softc *sc = hw->priv; \ | ||
| 22 | int val; \ | 24 | int val; \ |
| 23 | \ | 25 | \ |
| 24 | val = (int)simple_strtoul(buf, NULL, 10); \ | 26 | val = (int)simple_strtoul(buf, NULL, 10); \ |
| @@ -33,7 +35,8 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \ | |||
| 33 | struct device_attribute *attr, \ | 35 | struct device_attribute *attr, \ |
| 34 | char *buf) \ | 36 | char *buf) \ |
| 35 | { \ | 37 | { \ |
| 36 | struct ath5k_softc *sc = dev_get_drvdata(dev); \ | 38 | struct ieee80211_hw *hw = dev_get_drvdata(dev); \ |
| 39 | struct ath5k_softc *sc = hw->priv; \ | ||
| 37 | return snprintf(buf, PAGE_SIZE, "%d\n", get); \ | 40 | return snprintf(buf, PAGE_SIZE, "%d\n", get); \ |
| 38 | } \ | 41 | } \ |
| 39 | static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL) | 42 | static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL) |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 3779b8977d47..33443bcaa8d9 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -671,7 +671,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
| 671 | * TODO - this could be improved to be dependent on the rate. | 671 | * TODO - this could be improved to be dependent on the rate. |
| 672 | * The hardware can keep up at lower rates, but not higher rates | 672 | * The hardware can keep up at lower rates, but not higher rates |
| 673 | */ | 673 | */ |
| 674 | if (fi->keyix != ATH9K_TXKEYIX_INVALID) | 674 | if ((fi->keyix != ATH9K_TXKEYIX_INVALID) && |
| 675 | !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) | ||
| 675 | ndelim += ATH_AGGR_ENCRYPTDELIM; | 676 | ndelim += ATH_AGGR_ENCRYPTDELIM; |
| 676 | 677 | ||
| 677 | /* | 678 | /* |
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 2fb53d067512..333b69ef2ae2 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c | |||
| @@ -112,6 +112,8 @@ static struct usb_device_id carl9170_usb_ids[] = { | |||
| 112 | { USB_DEVICE(0x04bb, 0x093f) }, | 112 | { USB_DEVICE(0x04bb, 0x093f) }, |
| 113 | /* NEC WL300NU-G */ | 113 | /* NEC WL300NU-G */ |
| 114 | { USB_DEVICE(0x0409, 0x0249) }, | 114 | { USB_DEVICE(0x0409, 0x0249) }, |
| 115 | /* NEC WL300NU-AG */ | ||
| 116 | { USB_DEVICE(0x0409, 0x02b4) }, | ||
| 115 | /* AVM FRITZ!WLAN USB Stick N */ | 117 | /* AVM FRITZ!WLAN USB Stick N */ |
| 116 | { USB_DEVICE(0x057c, 0x8401) }, | 118 | { USB_DEVICE(0x057c, 0x8401) }, |
| 117 | /* AVM FRITZ!WLAN USB Stick N 2.4 */ | 119 | /* AVM FRITZ!WLAN USB Stick N 2.4 */ |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 092e342c19df..942f7a3969a7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | |||
| @@ -298,6 +298,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
| 298 | {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ | 298 | {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ |
| 299 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ | 299 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ |
| 300 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ | 300 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ |
| 301 | {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ | ||
| 301 | {RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ | 302 | {RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ |
| 302 | {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ | 303 | {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ |
| 303 | /* HP - Lite-On ,8188CUS Slim Combo */ | 304 | /* HP - Lite-On ,8188CUS Slim Combo */ |
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 2a20dabec76d..d6620ad309ce 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c | |||
| @@ -516,8 +516,17 @@ static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc) | |||
| 516 | 516 | ||
| 517 | static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) | 517 | static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) |
| 518 | { | 518 | { |
| 519 | ssb_pcicore_fix_sprom_core_index(pc); | ||
| 520 | |||
| 519 | /* Disable PCI interrupts. */ | 521 | /* Disable PCI interrupts. */ |
| 520 | ssb_write32(pc->dev, SSB_INTVEC, 0); | 522 | ssb_write32(pc->dev, SSB_INTVEC, 0); |
| 523 | |||
| 524 | /* Additional PCIe always once-executed workarounds */ | ||
| 525 | if (pc->dev->id.coreid == SSB_DEV_PCIE) { | ||
| 526 | ssb_pcicore_serdes_workaround(pc); | ||
| 527 | /* TODO: ASPM */ | ||
| 528 | /* TODO: Clock Request Update */ | ||
| 529 | } | ||
| 521 | } | 530 | } |
| 522 | 531 | ||
| 523 | void ssb_pcicore_init(struct ssb_pcicore *pc) | 532 | void ssb_pcicore_init(struct ssb_pcicore *pc) |
| @@ -529,8 +538,6 @@ void ssb_pcicore_init(struct ssb_pcicore *pc) | |||
| 529 | if (!ssb_device_is_enabled(dev)) | 538 | if (!ssb_device_is_enabled(dev)) |
| 530 | ssb_device_enable(dev, 0); | 539 | ssb_device_enable(dev, 0); |
| 531 | 540 | ||
| 532 | ssb_pcicore_fix_sprom_core_index(pc); | ||
| 533 | |||
| 534 | #ifdef CONFIG_SSB_PCICORE_HOSTMODE | 541 | #ifdef CONFIG_SSB_PCICORE_HOSTMODE |
| 535 | pc->hostmode = pcicore_is_in_hostmode(pc); | 542 | pc->hostmode = pcicore_is_in_hostmode(pc); |
| 536 | if (pc->hostmode) | 543 | if (pc->hostmode) |
| @@ -538,13 +545,6 @@ void ssb_pcicore_init(struct ssb_pcicore *pc) | |||
| 538 | #endif /* CONFIG_SSB_PCICORE_HOSTMODE */ | 545 | #endif /* CONFIG_SSB_PCICORE_HOSTMODE */ |
| 539 | if (!pc->hostmode) | 546 | if (!pc->hostmode) |
| 540 | ssb_pcicore_init_clientmode(pc); | 547 | ssb_pcicore_init_clientmode(pc); |
| 541 | |||
| 542 | /* Additional PCIe always once-executed workarounds */ | ||
| 543 | if (dev->id.coreid == SSB_DEV_PCIE) { | ||
| 544 | ssb_pcicore_serdes_workaround(pc); | ||
| 545 | /* TODO: ASPM */ | ||
| 546 | /* TODO: Clock Request Update */ | ||
| 547 | } | ||
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address) | 550 | static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address) |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index d3a05b9ade7a..bcd158f40bb9 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
| @@ -393,6 +393,9 @@ int hci_conn_del(struct hci_conn *conn) | |||
| 393 | 393 | ||
| 394 | hci_dev_put(hdev); | 394 | hci_dev_put(hdev); |
| 395 | 395 | ||
| 396 | if (conn->handle == 0) | ||
| 397 | kfree(conn); | ||
| 398 | |||
| 396 | return 0; | 399 | return 0; |
| 397 | } | 400 | } |
| 398 | 401 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index c405a954a603..43b4c2deb7cc 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
| @@ -464,7 +464,8 @@ static void hidp_idle_timeout(unsigned long arg) | |||
| 464 | { | 464 | { |
| 465 | struct hidp_session *session = (struct hidp_session *) arg; | 465 | struct hidp_session *session = (struct hidp_session *) arg; |
| 466 | 466 | ||
| 467 | kthread_stop(session->task); | 467 | atomic_inc(&session->terminate); |
| 468 | wake_up_process(session->task); | ||
| 468 | } | 469 | } |
| 469 | 470 | ||
| 470 | static void hidp_set_timer(struct hidp_session *session) | 471 | static void hidp_set_timer(struct hidp_session *session) |
| @@ -535,7 +536,8 @@ static void hidp_process_hid_control(struct hidp_session *session, | |||
| 535 | skb_queue_purge(&session->ctrl_transmit); | 536 | skb_queue_purge(&session->ctrl_transmit); |
| 536 | skb_queue_purge(&session->intr_transmit); | 537 | skb_queue_purge(&session->intr_transmit); |
| 537 | 538 | ||
| 538 | kthread_stop(session->task); | 539 | atomic_inc(&session->terminate); |
| 540 | wake_up_process(current); | ||
| 539 | } | 541 | } |
| 540 | } | 542 | } |
| 541 | 543 | ||
| @@ -706,9 +708,8 @@ static int hidp_session(void *arg) | |||
| 706 | add_wait_queue(sk_sleep(intr_sk), &intr_wait); | 708 | add_wait_queue(sk_sleep(intr_sk), &intr_wait); |
| 707 | session->waiting_for_startup = 0; | 709 | session->waiting_for_startup = 0; |
| 708 | wake_up_interruptible(&session->startup_queue); | 710 | wake_up_interruptible(&session->startup_queue); |
| 709 | while (!kthread_should_stop()) { | 711 | set_current_state(TASK_INTERRUPTIBLE); |
| 710 | set_current_state(TASK_INTERRUPTIBLE); | 712 | while (!atomic_read(&session->terminate)) { |
| 711 | |||
| 712 | if (ctrl_sk->sk_state != BT_CONNECTED || | 713 | if (ctrl_sk->sk_state != BT_CONNECTED || |
| 713 | intr_sk->sk_state != BT_CONNECTED) | 714 | intr_sk->sk_state != BT_CONNECTED) |
| 714 | break; | 715 | break; |
| @@ -726,6 +727,7 @@ static int hidp_session(void *arg) | |||
| 726 | hidp_process_transmit(session); | 727 | hidp_process_transmit(session); |
| 727 | 728 | ||
| 728 | schedule(); | 729 | schedule(); |
| 730 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 729 | } | 731 | } |
| 730 | set_current_state(TASK_RUNNING); | 732 | set_current_state(TASK_RUNNING); |
| 731 | remove_wait_queue(sk_sleep(intr_sk), &intr_wait); | 733 | remove_wait_queue(sk_sleep(intr_sk), &intr_wait); |
| @@ -1060,7 +1062,8 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
| 1060 | err_add_device: | 1062 | err_add_device: |
| 1061 | hid_destroy_device(session->hid); | 1063 | hid_destroy_device(session->hid); |
| 1062 | session->hid = NULL; | 1064 | session->hid = NULL; |
| 1063 | kthread_stop(session->task); | 1065 | atomic_inc(&session->terminate); |
| 1066 | wake_up_process(session->task); | ||
| 1064 | 1067 | ||
| 1065 | unlink: | 1068 | unlink: |
| 1066 | hidp_del_timer(session); | 1069 | hidp_del_timer(session); |
| @@ -1111,7 +1114,8 @@ int hidp_del_connection(struct hidp_conndel_req *req) | |||
| 1111 | skb_queue_purge(&session->ctrl_transmit); | 1114 | skb_queue_purge(&session->ctrl_transmit); |
| 1112 | skb_queue_purge(&session->intr_transmit); | 1115 | skb_queue_purge(&session->intr_transmit); |
| 1113 | 1116 | ||
| 1114 | kthread_stop(session->task); | 1117 | atomic_inc(&session->terminate); |
| 1118 | wake_up_process(session->task); | ||
| 1115 | } | 1119 | } |
| 1116 | } else | 1120 | } else |
| 1117 | err = -ENOENT; | 1121 | err = -ENOENT; |
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index 19e95004b286..af1bcc823f26 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h | |||
| @@ -142,6 +142,7 @@ struct hidp_session { | |||
| 142 | uint ctrl_mtu; | 142 | uint ctrl_mtu; |
| 143 | uint intr_mtu; | 143 | uint intr_mtu; |
| 144 | 144 | ||
| 145 | atomic_t terminate; | ||
| 145 | struct task_struct *task; | 146 | struct task_struct *task; |
| 146 | 147 | ||
| 147 | unsigned char keys[8]; | 148 | unsigned char keys[8]; |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 56fdd9162da9..ebff14c69078 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
| @@ -2323,7 +2323,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
| 2323 | 2323 | ||
| 2324 | sk = chan->sk; | 2324 | sk = chan->sk; |
| 2325 | 2325 | ||
| 2326 | if (sk->sk_state != BT_CONFIG) { | 2326 | if ((bt_sk(sk)->defer_setup && sk->sk_state != BT_CONNECT2) || |
| 2327 | (!bt_sk(sk)->defer_setup && sk->sk_state != BT_CONFIG)) { | ||
| 2327 | struct l2cap_cmd_rej rej; | 2328 | struct l2cap_cmd_rej rej; |
| 2328 | 2329 | ||
| 2329 | rej.reason = cpu_to_le16(0x0002); | 2330 | rej.reason = cpu_to_le16(0x0002); |
| @@ -2334,7 +2335,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
| 2334 | 2335 | ||
| 2335 | /* Reject if config buffer is too small. */ | 2336 | /* Reject if config buffer is too small. */ |
| 2336 | len = cmd_len - sizeof(*req); | 2337 | len = cmd_len - sizeof(*req); |
| 2337 | if (chan->conf_len + len > sizeof(chan->conf_req)) { | 2338 | if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) { |
| 2338 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 2339 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
| 2339 | l2cap_build_conf_rsp(chan, rsp, | 2340 | l2cap_build_conf_rsp(chan, rsp, |
| 2340 | L2CAP_CONF_REJECT, flags), rsp); | 2341 | L2CAP_CONF_REJECT, flags), rsp); |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 58ffa7d069c7..669d2e32efb6 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
| @@ -877,7 +877,8 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
| 877 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | 877 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
| 878 | local->sched_scan_ies.ie[i] = kzalloc(2 + | 878 | local->sched_scan_ies.ie[i] = kzalloc(2 + |
| 879 | IEEE80211_MAX_SSID_LEN + | 879 | IEEE80211_MAX_SSID_LEN + |
| 880 | local->scan_ies_len, | 880 | local->scan_ies_len + |
| 881 | req->ie_len, | ||
| 881 | GFP_KERNEL); | 882 | GFP_KERNEL); |
| 882 | if (!local->sched_scan_ies.ie[i]) { | 883 | if (!local->sched_scan_ies.ie[i]) { |
| 883 | ret = -ENOMEM; | 884 | ret = -ENOMEM; |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index d91c1a26630d..8f6a302d2ac3 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
| @@ -86,6 +86,11 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
| 86 | struct sk_buff *skb = rx->skb; | 86 | struct sk_buff *skb = rx->skb; |
| 87 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 87 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
| 88 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 88 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 89 | int queue = rx->queue; | ||
| 90 | |||
| 91 | /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */ | ||
| 92 | if (rx->queue == NUM_RX_DATA_QUEUES - 1) | ||
| 93 | queue = 0; | ||
| 89 | 94 | ||
| 90 | /* | 95 | /* |
| 91 | * it makes no sense to check for MIC errors on anything other | 96 | * it makes no sense to check for MIC errors on anything other |
| @@ -148,8 +153,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
| 148 | 153 | ||
| 149 | update_iv: | 154 | update_iv: |
| 150 | /* update IV in key information to be able to detect replays */ | 155 | /* update IV in key information to be able to detect replays */ |
| 151 | rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32; | 156 | rx->key->u.tkip.rx[queue].iv32 = rx->tkip_iv32; |
| 152 | rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16; | 157 | rx->key->u.tkip.rx[queue].iv16 = rx->tkip_iv16; |
| 153 | 158 | ||
| 154 | return RX_CONTINUE; | 159 | return RX_CONTINUE; |
| 155 | 160 | ||
| @@ -241,6 +246,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
| 241 | struct ieee80211_key *key = rx->key; | 246 | struct ieee80211_key *key = rx->key; |
| 242 | struct sk_buff *skb = rx->skb; | 247 | struct sk_buff *skb = rx->skb; |
| 243 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 248 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
| 249 | int queue = rx->queue; | ||
| 250 | |||
| 251 | /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */ | ||
| 252 | if (rx->queue == NUM_RX_DATA_QUEUES - 1) | ||
| 253 | queue = 0; | ||
| 244 | 254 | ||
| 245 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 255 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 246 | 256 | ||
| @@ -261,7 +271,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
| 261 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, | 271 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, |
| 262 | key, skb->data + hdrlen, | 272 | key, skb->data + hdrlen, |
| 263 | skb->len - hdrlen, rx->sta->sta.addr, | 273 | skb->len - hdrlen, rx->sta->sta.addr, |
| 264 | hdr->addr1, hwaccel, rx->queue, | 274 | hdr->addr1, hwaccel, queue, |
| 265 | &rx->tkip_iv32, | 275 | &rx->tkip_iv32, |
| 266 | &rx->tkip_iv16); | 276 | &rx->tkip_iv16); |
| 267 | if (res != TKIP_DECRYPT_OK) | 277 | if (res != TKIP_DECRYPT_OK) |
diff --git a/net/wireless/core.c b/net/wireless/core.c index c22ef3492ee6..880dbe2e6f94 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
| @@ -366,6 +366,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
| 366 | 366 | ||
| 367 | mutex_init(&rdev->mtx); | 367 | mutex_init(&rdev->mtx); |
| 368 | mutex_init(&rdev->devlist_mtx); | 368 | mutex_init(&rdev->devlist_mtx); |
| 369 | mutex_init(&rdev->sched_scan_mtx); | ||
| 369 | INIT_LIST_HEAD(&rdev->netdev_list); | 370 | INIT_LIST_HEAD(&rdev->netdev_list); |
| 370 | spin_lock_init(&rdev->bss_lock); | 371 | spin_lock_init(&rdev->bss_lock); |
| 371 | INIT_LIST_HEAD(&rdev->bss_list); | 372 | INIT_LIST_HEAD(&rdev->bss_list); |
| @@ -701,6 +702,7 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev) | |||
| 701 | rfkill_destroy(rdev->rfkill); | 702 | rfkill_destroy(rdev->rfkill); |
| 702 | mutex_destroy(&rdev->mtx); | 703 | mutex_destroy(&rdev->mtx); |
| 703 | mutex_destroy(&rdev->devlist_mtx); | 704 | mutex_destroy(&rdev->devlist_mtx); |
| 705 | mutex_destroy(&rdev->sched_scan_mtx); | ||
| 704 | list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) | 706 | list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) |
| 705 | cfg80211_put_bss(&scan->pub); | 707 | cfg80211_put_bss(&scan->pub); |
| 706 | cfg80211_rdev_free_wowlan(rdev); | 708 | cfg80211_rdev_free_wowlan(rdev); |
| @@ -737,12 +739,16 @@ static void wdev_cleanup_work(struct work_struct *work) | |||
| 737 | ___cfg80211_scan_done(rdev, true); | 739 | ___cfg80211_scan_done(rdev, true); |
| 738 | } | 740 | } |
| 739 | 741 | ||
| 742 | cfg80211_unlock_rdev(rdev); | ||
| 743 | |||
| 744 | mutex_lock(&rdev->sched_scan_mtx); | ||
| 745 | |||
| 740 | if (WARN_ON(rdev->sched_scan_req && | 746 | if (WARN_ON(rdev->sched_scan_req && |
| 741 | rdev->sched_scan_req->dev == wdev->netdev)) { | 747 | rdev->sched_scan_req->dev == wdev->netdev)) { |
| 742 | __cfg80211_stop_sched_scan(rdev, false); | 748 | __cfg80211_stop_sched_scan(rdev, false); |
| 743 | } | 749 | } |
| 744 | 750 | ||
| 745 | cfg80211_unlock_rdev(rdev); | 751 | mutex_unlock(&rdev->sched_scan_mtx); |
| 746 | 752 | ||
| 747 | mutex_lock(&rdev->devlist_mtx); | 753 | mutex_lock(&rdev->devlist_mtx); |
| 748 | rdev->opencount--; | 754 | rdev->opencount--; |
| @@ -830,9 +836,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, | |||
| 830 | break; | 836 | break; |
| 831 | case NL80211_IFTYPE_P2P_CLIENT: | 837 | case NL80211_IFTYPE_P2P_CLIENT: |
| 832 | case NL80211_IFTYPE_STATION: | 838 | case NL80211_IFTYPE_STATION: |
| 833 | cfg80211_lock_rdev(rdev); | 839 | mutex_lock(&rdev->sched_scan_mtx); |
| 834 | __cfg80211_stop_sched_scan(rdev, false); | 840 | __cfg80211_stop_sched_scan(rdev, false); |
| 835 | cfg80211_unlock_rdev(rdev); | 841 | mutex_unlock(&rdev->sched_scan_mtx); |
| 836 | 842 | ||
| 837 | wdev_lock(wdev); | 843 | wdev_lock(wdev); |
| 838 | #ifdef CONFIG_CFG80211_WEXT | 844 | #ifdef CONFIG_CFG80211_WEXT |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 3dce1f167eba..a570ff9214ec 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
| @@ -65,6 +65,8 @@ struct cfg80211_registered_device { | |||
| 65 | struct work_struct scan_done_wk; | 65 | struct work_struct scan_done_wk; |
| 66 | struct work_struct sched_scan_results_wk; | 66 | struct work_struct sched_scan_results_wk; |
| 67 | 67 | ||
| 68 | struct mutex sched_scan_mtx; | ||
| 69 | |||
| 68 | #ifdef CONFIG_NL80211_TESTMODE | 70 | #ifdef CONFIG_NL80211_TESTMODE |
| 69 | struct genl_info *testmode_info; | 71 | struct genl_info *testmode_info; |
| 70 | #endif | 72 | #endif |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f07602d7bf68..cea338150d05 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -3461,9 +3461,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
| 3461 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3461 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
| 3462 | return -EINVAL; | 3462 | return -EINVAL; |
| 3463 | 3463 | ||
| 3464 | if (rdev->sched_scan_req) | ||
| 3465 | return -EINPROGRESS; | ||
| 3466 | |||
| 3467 | if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]) | 3464 | if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]) |
| 3468 | return -EINVAL; | 3465 | return -EINVAL; |
| 3469 | 3466 | ||
| @@ -3502,12 +3499,21 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
| 3502 | if (ie_len > wiphy->max_scan_ie_len) | 3499 | if (ie_len > wiphy->max_scan_ie_len) |
| 3503 | return -EINVAL; | 3500 | return -EINVAL; |
| 3504 | 3501 | ||
| 3502 | mutex_lock(&rdev->sched_scan_mtx); | ||
| 3503 | |||
| 3504 | if (rdev->sched_scan_req) { | ||
| 3505 | err = -EINPROGRESS; | ||
| 3506 | goto out; | ||
| 3507 | } | ||
| 3508 | |||
| 3505 | request = kzalloc(sizeof(*request) | 3509 | request = kzalloc(sizeof(*request) |
| 3506 | + sizeof(*request->ssids) * n_ssids | 3510 | + sizeof(*request->ssids) * n_ssids |
| 3507 | + sizeof(*request->channels) * n_channels | 3511 | + sizeof(*request->channels) * n_channels |
| 3508 | + ie_len, GFP_KERNEL); | 3512 | + ie_len, GFP_KERNEL); |
| 3509 | if (!request) | 3513 | if (!request) { |
| 3510 | return -ENOMEM; | 3514 | err = -ENOMEM; |
| 3515 | goto out; | ||
| 3516 | } | ||
| 3511 | 3517 | ||
| 3512 | if (n_ssids) | 3518 | if (n_ssids) |
| 3513 | request->ssids = (void *)&request->channels[n_channels]; | 3519 | request->ssids = (void *)&request->channels[n_channels]; |
| @@ -3605,6 +3611,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
| 3605 | out_free: | 3611 | out_free: |
| 3606 | kfree(request); | 3612 | kfree(request); |
| 3607 | out: | 3613 | out: |
| 3614 | mutex_unlock(&rdev->sched_scan_mtx); | ||
| 3608 | return err; | 3615 | return err; |
| 3609 | } | 3616 | } |
| 3610 | 3617 | ||
| @@ -3612,12 +3619,17 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb, | |||
| 3612 | struct genl_info *info) | 3619 | struct genl_info *info) |
| 3613 | { | 3620 | { |
| 3614 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3621 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
| 3622 | int err; | ||
| 3615 | 3623 | ||
| 3616 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || | 3624 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || |
| 3617 | !rdev->ops->sched_scan_stop) | 3625 | !rdev->ops->sched_scan_stop) |
| 3618 | return -EOPNOTSUPP; | 3626 | return -EOPNOTSUPP; |
| 3619 | 3627 | ||
| 3620 | return __cfg80211_stop_sched_scan(rdev, false); | 3628 | mutex_lock(&rdev->sched_scan_mtx); |
| 3629 | err = __cfg80211_stop_sched_scan(rdev, false); | ||
| 3630 | mutex_unlock(&rdev->sched_scan_mtx); | ||
| 3631 | |||
| 3632 | return err; | ||
| 3621 | } | 3633 | } |
| 3622 | 3634 | ||
| 3623 | static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, | 3635 | static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 7a6c67667d70..ae0c2256ba3b 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
| @@ -100,14 +100,14 @@ void __cfg80211_sched_scan_results(struct work_struct *wk) | |||
| 100 | rdev = container_of(wk, struct cfg80211_registered_device, | 100 | rdev = container_of(wk, struct cfg80211_registered_device, |
| 101 | sched_scan_results_wk); | 101 | sched_scan_results_wk); |
| 102 | 102 | ||
| 103 | cfg80211_lock_rdev(rdev); | 103 | mutex_lock(&rdev->sched_scan_mtx); |
| 104 | 104 | ||
| 105 | /* we don't have sched_scan_req anymore if the scan is stopping */ | 105 | /* we don't have sched_scan_req anymore if the scan is stopping */ |
| 106 | if (rdev->sched_scan_req) | 106 | if (rdev->sched_scan_req) |
| 107 | nl80211_send_sched_scan_results(rdev, | 107 | nl80211_send_sched_scan_results(rdev, |
| 108 | rdev->sched_scan_req->dev); | 108 | rdev->sched_scan_req->dev); |
| 109 | 109 | ||
| 110 | cfg80211_unlock_rdev(rdev); | 110 | mutex_unlock(&rdev->sched_scan_mtx); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | void cfg80211_sched_scan_results(struct wiphy *wiphy) | 113 | void cfg80211_sched_scan_results(struct wiphy *wiphy) |
| @@ -123,9 +123,9 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy) | |||
| 123 | { | 123 | { |
| 124 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 124 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
| 125 | 125 | ||
| 126 | cfg80211_lock_rdev(rdev); | 126 | mutex_lock(&rdev->sched_scan_mtx); |
| 127 | __cfg80211_stop_sched_scan(rdev, true); | 127 | __cfg80211_stop_sched_scan(rdev, true); |
| 128 | cfg80211_unlock_rdev(rdev); | 128 | mutex_unlock(&rdev->sched_scan_mtx); |
| 129 | } | 129 | } |
| 130 | EXPORT_SYMBOL(cfg80211_sched_scan_stopped); | 130 | EXPORT_SYMBOL(cfg80211_sched_scan_stopped); |
| 131 | 131 | ||
| @@ -135,7 +135,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | |||
| 135 | int err; | 135 | int err; |
| 136 | struct net_device *dev; | 136 | struct net_device *dev; |
| 137 | 137 | ||
| 138 | ASSERT_RDEV_LOCK(rdev); | 138 | lockdep_assert_held(&rdev->sched_scan_mtx); |
| 139 | 139 | ||
| 140 | if (!rdev->sched_scan_req) | 140 | if (!rdev->sched_scan_req) |
| 141 | return 0; | 141 | return 0; |
