aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 7e38858a9280..ca170b417da6 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -18,7 +18,6 @@
18#include <linux/skbuff.h> 18#include <linux/skbuff.h>
19#include <linux/etherdevice.h> 19#include <linux/etherdevice.h>
20#include <linux/if_arp.h> 20#include <linux/if_arp.h>
21#include <linux/wireless.h>
22#include <linux/bitmap.h> 21#include <linux/bitmap.h>
23#include <linux/crc32.h> 22#include <linux/crc32.h>
24#include <net/net_namespace.h> 23#include <net/net_namespace.h>
@@ -269,6 +268,7 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
269 enum queue_stop_reason reason) 268 enum queue_stop_reason reason)
270{ 269{
271 struct ieee80211_local *local = hw_to_local(hw); 270 struct ieee80211_local *local = hw_to_local(hw);
271 struct ieee80211_sub_if_data *sdata;
272 272
273 if (WARN_ON(queue >= hw->queues)) 273 if (WARN_ON(queue >= hw->queues))
274 return; 274 return;
@@ -281,6 +281,11 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
281 281
282 if (!skb_queue_empty(&local->pending[queue])) 282 if (!skb_queue_empty(&local->pending[queue]))
283 tasklet_schedule(&local->tx_pending_tasklet); 283 tasklet_schedule(&local->tx_pending_tasklet);
284
285 rcu_read_lock();
286 list_for_each_entry_rcu(sdata, &local->interfaces, list)
287 netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
288 rcu_read_unlock();
284} 289}
285 290
286void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 291void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -305,11 +310,17 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
305 enum queue_stop_reason reason) 310 enum queue_stop_reason reason)
306{ 311{
307 struct ieee80211_local *local = hw_to_local(hw); 312 struct ieee80211_local *local = hw_to_local(hw);
313 struct ieee80211_sub_if_data *sdata;
308 314
309 if (WARN_ON(queue >= hw->queues)) 315 if (WARN_ON(queue >= hw->queues))
310 return; 316 return;
311 317
312 __set_bit(reason, &local->queue_stop_reasons[queue]); 318 __set_bit(reason, &local->queue_stop_reasons[queue]);
319
320 rcu_read_lock();
321 list_for_each_entry_rcu(sdata, &local->interfaces, list)
322 netif_tx_stop_queue(netdev_get_tx_queue(sdata->dev, queue));
323 rcu_read_unlock();
313} 324}
314 325
315void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, 326void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -781,6 +792,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
781 break; 792 break;
782 } 793 }
783 794
795 qparam.uapsd = false;
796
784 drv_conf_tx(local, queue, &qparam); 797 drv_conf_tx(local, queue, &qparam);
785 } 798 }
786} 799}
@@ -989,40 +1002,33 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
989 struct ieee80211_local *local = sdata->local; 1002 struct ieee80211_local *local = sdata->local;
990 struct sk_buff *skb; 1003 struct sk_buff *skb;
991 struct ieee80211_mgmt *mgmt; 1004 struct ieee80211_mgmt *mgmt;
992 u8 *pos; 1005 size_t buf_len;
993 1006 u8 *buf;
994 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 + 1007
995 ie_len); 1008 /* FIXME: come up with a proper value */
996 if (!skb) { 1009 buf = kmalloc(200 + ie_len, GFP_KERNEL);
997 printk(KERN_DEBUG "%s: failed to allocate buffer for probe " 1010 if (!buf) {
998 "request\n", sdata->name); 1011 printk(KERN_DEBUG "%s: failed to allocate temporary IE "
1012 "buffer\n", sdata->name);
999 return; 1013 return;
1000 } 1014 }
1001 skb_reserve(skb, local->hw.extra_tx_headroom);
1002 1015
1003 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 1016 buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len,
1004 memset(mgmt, 0, 24); 1017 local->hw.conf.channel->band);
1005 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 1018
1006 IEEE80211_STYPE_PROBE_REQ); 1019 skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
1007 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 1020 ssid, ssid_len,
1021 buf, buf_len);
1022
1008 if (dst) { 1023 if (dst) {
1024 mgmt = (struct ieee80211_mgmt *) skb->data;
1009 memcpy(mgmt->da, dst, ETH_ALEN); 1025 memcpy(mgmt->da, dst, ETH_ALEN);
1010 memcpy(mgmt->bssid, dst, ETH_ALEN); 1026 memcpy(mgmt->bssid, dst, ETH_ALEN);
1011 } else {
1012 memset(mgmt->da, 0xff, ETH_ALEN);
1013 memset(mgmt->bssid, 0xff, ETH_ALEN);
1014 } 1027 }
1015 pos = skb_put(skb, 2 + ssid_len);
1016 *pos++ = WLAN_EID_SSID;
1017 *pos++ = ssid_len;
1018 memcpy(pos, ssid, ssid_len);
1019 pos += ssid_len;
1020
1021 skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len,
1022 local->hw.conf.channel->band));
1023 1028
1024 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 1029 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
1025 ieee80211_tx_skb(sdata, skb); 1030 ieee80211_tx_skb(sdata, skb);
1031 kfree(buf);
1026} 1032}
1027 1033
1028u32 ieee80211_sta_get_rates(struct ieee80211_local *local, 1034u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
@@ -1066,9 +1072,9 @@ void ieee80211_stop_device(struct ieee80211_local *local)
1066 ieee80211_led_radio(local, false); 1072 ieee80211_led_radio(local, false);
1067 1073
1068 cancel_work_sync(&local->reconfig_filter); 1074 cancel_work_sync(&local->reconfig_filter);
1069 drv_stop(local);
1070 1075
1071 flush_workqueue(local->workqueue); 1076 flush_workqueue(local->workqueue);
1077 drv_stop(local);
1072} 1078}
1073 1079
1074int ieee80211_reconfig(struct ieee80211_local *local) 1080int ieee80211_reconfig(struct ieee80211_local *local)
@@ -1094,7 +1100,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1094 if (res) { 1100 if (res) {
1095 WARN(local->suspended, "Harware became unavailable " 1101 WARN(local->suspended, "Harware became unavailable "
1096 "upon resume. This is could be a software issue" 1102 "upon resume. This is could be a software issue"
1097 "prior to suspend or a harware issue\n"); 1103 "prior to suspend or a hardware issue\n");
1098 return res; 1104 return res;
1099 } 1105 }
1100 1106