diff options
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 60 |
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 | ||
286 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, | 291 | void 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 | ||
315 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | 326 | void 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 | ||
1028 | u32 ieee80211_sta_get_rates(struct ieee80211_local *local, | 1034 | u32 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 | ||
1074 | int ieee80211_reconfig(struct ieee80211_local *local) | 1080 | int 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 | ||