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.c130
1 files changed, 86 insertions, 44 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 915e77769312..dd6564321369 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -31,6 +31,7 @@
31#include "mesh.h" 31#include "mesh.h"
32#include "wme.h" 32#include "wme.h"
33#include "led.h" 33#include "led.h"
34#include "wep.h"
34 35
35/* privid for wiphys to determine whether they belong to us or not */ 36/* privid for wiphys to determine whether they belong to us or not */
36void *mac80211_wiphy_privid = &mac80211_wiphy_privid; 37void *mac80211_wiphy_privid = &mac80211_wiphy_privid;
@@ -274,16 +275,12 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
274 275
275 __clear_bit(reason, &local->queue_stop_reasons[queue]); 276 __clear_bit(reason, &local->queue_stop_reasons[queue]);
276 277
277 if (!skb_queue_empty(&local->pending[queue]) &&
278 local->queue_stop_reasons[queue] ==
279 BIT(IEEE80211_QUEUE_STOP_REASON_PENDING))
280 tasklet_schedule(&local->tx_pending_tasklet);
281
282 if (local->queue_stop_reasons[queue] != 0) 278 if (local->queue_stop_reasons[queue] != 0)
283 /* someone still has this queue stopped */ 279 /* someone still has this queue stopped */
284 return; 280 return;
285 281
286 netif_wake_subqueue(local->mdev, queue); 282 if (!skb_queue_empty(&local->pending[queue]))
283 tasklet_schedule(&local->tx_pending_tasklet);
287} 284}
288 285
289void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 286void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -312,14 +309,6 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
312 if (WARN_ON(queue >= hw->queues)) 309 if (WARN_ON(queue >= hw->queues))
313 return; 310 return;
314 311
315 /*
316 * Only stop if it was previously running, this is necessary
317 * for correct pending packets handling because there we may
318 * start (but not wake) the queue and rely on that.
319 */
320 if (!local->queue_stop_reasons[queue])
321 netif_stop_subqueue(local->mdev, queue);
322
323 __set_bit(reason, &local->queue_stop_reasons[queue]); 312 __set_bit(reason, &local->queue_stop_reasons[queue]);
324} 313}
325 314
@@ -347,11 +336,16 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
347 struct ieee80211_hw *hw = &local->hw; 336 struct ieee80211_hw *hw = &local->hw;
348 unsigned long flags; 337 unsigned long flags;
349 int queue = skb_get_queue_mapping(skb); 338 int queue = skb_get_queue_mapping(skb);
339 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
340
341 if (WARN_ON(!info->control.vif)) {
342 kfree(skb);
343 return;
344 }
350 345
351 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 346 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
352 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 347 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
353 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_PENDING); 348 __skb_queue_tail(&local->pending[queue], skb);
354 skb_queue_tail(&local->pending[queue], skb);
355 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 349 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
356 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 350 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
357} 351}
@@ -370,18 +364,21 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
370 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 364 IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
371 365
372 while ((skb = skb_dequeue(skbs))) { 366 while ((skb = skb_dequeue(skbs))) {
367 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
368
369 if (WARN_ON(!info->control.vif)) {
370 kfree(skb);
371 continue;
372 }
373
373 ret++; 374 ret++;
374 queue = skb_get_queue_mapping(skb); 375 queue = skb_get_queue_mapping(skb);
375 skb_queue_tail(&local->pending[queue], skb); 376 __skb_queue_tail(&local->pending[queue], skb);
376 } 377 }
377 378
378 for (i = 0; i < hw->queues; i++) { 379 for (i = 0; i < hw->queues; i++)
379 if (ret)
380 __ieee80211_stop_queue(hw, i,
381 IEEE80211_QUEUE_STOP_REASON_PENDING);
382 __ieee80211_wake_queue(hw, i, 380 __ieee80211_wake_queue(hw, i,
383 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 381 IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
384 }
385 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 382 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
386 383
387 return ret; 384 return ret;
@@ -412,11 +409,16 @@ EXPORT_SYMBOL(ieee80211_stop_queues);
412int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) 409int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
413{ 410{
414 struct ieee80211_local *local = hw_to_local(hw); 411 struct ieee80211_local *local = hw_to_local(hw);
412 unsigned long flags;
413 int ret;
415 414
416 if (WARN_ON(queue >= hw->queues)) 415 if (WARN_ON(queue >= hw->queues))
417 return true; 416 return true;
418 417
419 return __netif_subqueue_stopped(local->mdev, queue); 418 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
419 ret = !!local->queue_stop_reasons[queue];
420 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
421 return ret;
420} 422}
421EXPORT_SYMBOL(ieee80211_queue_stopped); 423EXPORT_SYMBOL(ieee80211_queue_stopped);
422 424
@@ -509,6 +511,46 @@ void ieee80211_iterate_active_interfaces_atomic(
509} 511}
510EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); 512EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
511 513
514/*
515 * Nothing should have been stuffed into the workqueue during
516 * the suspend->resume cycle. If this WARN is seen then there
517 * is a bug with either the driver suspend or something in
518 * mac80211 stuffing into the workqueue which we haven't yet
519 * cleared during mac80211's suspend cycle.
520 */
521static bool ieee80211_can_queue_work(struct ieee80211_local *local)
522{
523 if (WARN(local->suspended, "queueing ieee80211 work while "
524 "going to suspend\n"))
525 return false;
526
527 return true;
528}
529
530void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work)
531{
532 struct ieee80211_local *local = hw_to_local(hw);
533
534 if (!ieee80211_can_queue_work(local))
535 return;
536
537 queue_work(local->workqueue, work);
538}
539EXPORT_SYMBOL(ieee80211_queue_work);
540
541void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
542 struct delayed_work *dwork,
543 unsigned long delay)
544{
545 struct ieee80211_local *local = hw_to_local(hw);
546
547 if (!ieee80211_can_queue_work(local))
548 return;
549
550 queue_delayed_work(local->workqueue, dwork, delay);
551}
552EXPORT_SYMBOL(ieee80211_queue_delayed_work);
553
512void ieee802_11_parse_elems(u8 *start, size_t len, 554void ieee802_11_parse_elems(u8 *start, size_t len,
513 struct ieee802_11_elems *elems) 555 struct ieee802_11_elems *elems)
514{ 556{
@@ -760,20 +802,6 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
760 ieee80211_set_wmm_default(sdata); 802 ieee80211_set_wmm_default(sdata);
761} 803}
762 804
763void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
764 int encrypt)
765{
766 skb->dev = sdata->local->mdev;
767 skb_set_mac_header(skb, 0);
768 skb_set_network_header(skb, 0);
769 skb_set_transport_header(skb, 0);
770
771 skb->iif = sdata->dev->ifindex;
772 skb->do_not_encrypt = !encrypt;
773
774 dev_queue_xmit(skb);
775}
776
777u32 ieee80211_mandatory_rates(struct ieee80211_local *local, 805u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
778 enum ieee80211_band band) 806 enum ieee80211_band band)
779{ 807{
@@ -804,12 +832,13 @@ u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
804 832
805void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 833void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
806 u16 transaction, u16 auth_alg, 834 u16 transaction, u16 auth_alg,
807 u8 *extra, size_t extra_len, 835 u8 *extra, size_t extra_len, const u8 *bssid,
808 const u8 *bssid, int encrypt) 836 const u8 *key, u8 key_len, u8 key_idx)
809{ 837{
810 struct ieee80211_local *local = sdata->local; 838 struct ieee80211_local *local = sdata->local;
811 struct sk_buff *skb; 839 struct sk_buff *skb;
812 struct ieee80211_mgmt *mgmt; 840 struct ieee80211_mgmt *mgmt;
841 int err;
813 842
814 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 843 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
815 sizeof(*mgmt) + 6 + extra_len); 844 sizeof(*mgmt) + 6 + extra_len);
@@ -824,8 +853,6 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
824 memset(mgmt, 0, 24 + 6); 853 memset(mgmt, 0, 24 + 6);
825 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 854 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
826 IEEE80211_STYPE_AUTH); 855 IEEE80211_STYPE_AUTH);
827 if (encrypt)
828 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
829 memcpy(mgmt->da, bssid, ETH_ALEN); 856 memcpy(mgmt->da, bssid, ETH_ALEN);
830 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 857 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
831 memcpy(mgmt->bssid, bssid, ETH_ALEN); 858 memcpy(mgmt->bssid, bssid, ETH_ALEN);
@@ -835,7 +862,13 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
835 if (extra) 862 if (extra)
836 memcpy(skb_put(skb, extra_len), extra, extra_len); 863 memcpy(skb_put(skb, extra_len), extra, extra_len);
837 864
838 ieee80211_tx_skb(sdata, skb, encrypt); 865 if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
866 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
867 err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx);
868 WARN_ON(err);
869 }
870
871 ieee80211_tx_skb(sdata, skb, 0);
839} 872}
840 873
841int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 874int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
@@ -974,6 +1007,16 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
974 return supp_rates; 1007 return supp_rates;
975} 1008}
976 1009
1010void ieee80211_stop_device(struct ieee80211_local *local)
1011{
1012 ieee80211_led_radio(local, false);
1013
1014 cancel_work_sync(&local->reconfig_filter);
1015 drv_stop(local);
1016
1017 flush_workqueue(local->workqueue);
1018}
1019
977int ieee80211_reconfig(struct ieee80211_local *local) 1020int ieee80211_reconfig(struct ieee80211_local *local)
978{ 1021{
979 struct ieee80211_hw *hw = &local->hw; 1022 struct ieee80211_hw *hw = &local->hw;
@@ -1043,9 +1086,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1043 /* reconfigure hardware */ 1086 /* reconfigure hardware */
1044 ieee80211_hw_config(local, ~0); 1087 ieee80211_hw_config(local, ~0);
1045 1088
1046 netif_addr_lock_bh(local->mdev);
1047 ieee80211_configure_filter(local); 1089 ieee80211_configure_filter(local);
1048 netif_addr_unlock_bh(local->mdev);
1049 1090
1050 /* Finally also reconfigure all the BSS information */ 1091 /* Finally also reconfigure all the BSS information */
1051 list_for_each_entry(sdata, &local->interfaces, list) { 1092 list_for_each_entry(sdata, &local->interfaces, list) {
@@ -1121,3 +1162,4 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1121#endif 1162#endif
1122 return 0; 1163 return 0;
1123} 1164}
1165