aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-07-08 12:33:34 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-08 12:33:34 -0400
commit3f97fae9482dac1dbdd870a25c89033d3a0b35dc (patch)
treec98fb21da14bf22ab7ea23098945e31bef6558fc /net
parent06b8fc5d308b15e853a68c3d4854fb2ac33db867 (diff)
parent8a98d935c4b8b3515d1403d150e282f95b9f558d (diff)
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_conn.c3
-rw-r--r--net/bluetooth/hidp/core.c18
-rw-r--r--net/bluetooth/hidp/hidp.h1
-rw-r--r--net/bluetooth/l2cap_core.c5
-rw-r--r--net/mac80211/scan.c3
-rw-r--r--net/mac80211/wpa.c16
-rw-r--r--net/wireless/core.c12
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/nl80211.c24
-rw-r--r--net/wireless/scan.c10
10 files changed, 67 insertions, 27 deletions
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
470static void hidp_set_timer(struct hidp_session *session) 471static 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,
1060err_add_device: 1062err_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
1065unlink: 1068unlink:
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
149update_iv: 154update_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,
3605out_free: 3611out_free:
3606 kfree(request); 3612 kfree(request);
3607out: 3613out:
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
3623static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, 3635static 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
113void cfg80211_sched_scan_results(struct wiphy *wiphy) 113void 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}
130EXPORT_SYMBOL(cfg80211_sched_scan_stopped); 130EXPORT_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;