diff options
author | David S. Miller <davem@davemloft.net> | 2009-07-30 22:26:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-30 22:26:55 -0400 |
commit | 2f6d7c1b34403b97fa57473edcb6749d1db5ace3 (patch) | |
tree | 97da33c077b08b72a361ff5a4542b86d190b0164 /net/mac80211 | |
parent | df597efb5737063497f1a4f7c996cc9aec294230 (diff) | |
parent | 1e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/Kconfig | 1 | ||||
-rw-r--r-- | net/mac80211/Makefile | 1 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 14 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 45 | ||||
-rw-r--r-- | net/mac80211/iface.c | 22 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 2 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 35 | ||||
-rw-r--r-- | net/mac80211/rx.c | 21 | ||||
-rw-r--r-- | net/mac80211/scan.c | 304 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 13 | ||||
-rw-r--r-- | net/mac80211/tx.c | 109 | ||||
-rw-r--r-- | net/mac80211/util.c | 13 | ||||
-rw-r--r-- | net/mac80211/wext.c | 235 |
15 files changed, 376 insertions, 444 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 19a4c66e143e..7dd77b6d4c9a 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -6,7 +6,6 @@ config MAC80211 | |||
6 | select CRYPTO_ARC4 | 6 | select CRYPTO_ARC4 |
7 | select CRYPTO_AES | 7 | select CRYPTO_AES |
8 | select CRC32 | 8 | select CRC32 |
9 | select WIRELESS_EXT | ||
10 | ---help--- | 9 | ---help--- |
11 | This option enables the hardware independent IEEE 802.11 | 10 | This option enables the hardware independent IEEE 802.11 |
12 | networking stack. | 11 | networking stack. |
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 91284a74ff91..9f3cf7129324 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -3,7 +3,6 @@ obj-$(CONFIG_MAC80211) += mac80211.o | |||
3 | # mac80211 objects | 3 | # mac80211 objects |
4 | mac80211-y := \ | 4 | mac80211-y := \ |
5 | main.o \ | 5 | main.o \ |
6 | wext.o \ | ||
7 | sta_info.o \ | 6 | sta_info.o \ |
8 | wep.o \ | 7 | wep.o \ |
9 | wpa.o \ | 8 | wpa.o \ |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 52928ad90570..4bbf5007799b 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -57,19 +57,9 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name, | |||
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
59 | 59 | ||
60 | static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) | 60 | static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev) |
61 | { | 61 | { |
62 | struct net_device *dev; | 62 | ieee80211_if_remove(IEEE80211_DEV_TO_SUB_IF(dev)); |
63 | struct ieee80211_sub_if_data *sdata; | ||
64 | |||
65 | /* we're under RTNL */ | ||
66 | dev = __dev_get_by_index(&init_net, ifindex); | ||
67 | if (!dev) | ||
68 | return -ENODEV; | ||
69 | |||
70 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
71 | |||
72 | ieee80211_if_remove(sdata); | ||
73 | 63 | ||
74 | return 0; | 64 | return 0; |
75 | } | 65 | } |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 8e2220000e5c..6e3cca65c460 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -742,7 +742,7 @@ static void ieee80211_ibss_work(struct work_struct *work) | |||
742 | if (!netif_running(sdata->dev)) | 742 | if (!netif_running(sdata->dev)) |
743 | return; | 743 | return; |
744 | 744 | ||
745 | if (local->sw_scanning || local->hw_scanning) | 745 | if (local->scanning) |
746 | return; | 746 | return; |
747 | 747 | ||
748 | if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_ADHOC)) | 748 | if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_ADHOC)) |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6a0177137dd5..aec6853cb435 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
26 | #include <net/cfg80211.h> | 26 | #include <net/cfg80211.h> |
27 | #include <net/iw_handler.h> | ||
28 | #include <net/mac80211.h> | 27 | #include <net/mac80211.h> |
29 | #include "key.h" | 28 | #include "key.h" |
30 | #include "sta_info.h" | 29 | #include "sta_info.h" |
@@ -570,6 +569,43 @@ enum queue_stop_reason { | |||
570 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD, | 569 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD, |
571 | }; | 570 | }; |
572 | 571 | ||
572 | /** | ||
573 | * mac80211 scan flags - currently active scan mode | ||
574 | * | ||
575 | * @SCAN_SW_SCANNING: We're currently in the process of scanning but may as | ||
576 | * well be on the operating channel | ||
577 | * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to | ||
578 | * determine if we are on the operating channel or not | ||
579 | * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning, | ||
580 | * gets only set in conjunction with SCAN_SW_SCANNING | ||
581 | */ | ||
582 | enum { | ||
583 | SCAN_SW_SCANNING, | ||
584 | SCAN_HW_SCANNING, | ||
585 | SCAN_OFF_CHANNEL, | ||
586 | }; | ||
587 | |||
588 | /** | ||
589 | * enum mac80211_scan_state - scan state machine states | ||
590 | * | ||
591 | * @SCAN_DECISION: Main entry point to the scan state machine, this state | ||
592 | * determines if we should keep on scanning or switch back to the | ||
593 | * operating channel | ||
594 | * @SCAN_SET_CHANNEL: Set the next channel to be scanned | ||
595 | * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses | ||
596 | * @SCAN_LEAVE_OPER_CHANNEL: Leave the operating channel, notify the AP | ||
597 | * about us leaving the channel and stop all associated STA interfaces | ||
598 | * @SCAN_ENTER_OPER_CHANNEL: Enter the operating channel again, notify the | ||
599 | * AP about us being back and restart all associated STA interfaces | ||
600 | */ | ||
601 | enum mac80211_scan_state { | ||
602 | SCAN_DECISION, | ||
603 | SCAN_SET_CHANNEL, | ||
604 | SCAN_SEND_PROBE, | ||
605 | SCAN_LEAVE_OPER_CHANNEL, | ||
606 | SCAN_ENTER_OPER_CHANNEL, | ||
607 | }; | ||
608 | |||
573 | struct ieee80211_local { | 609 | struct ieee80211_local { |
574 | /* embed the driver visible part. | 610 | /* embed the driver visible part. |
575 | * don't cast (use the static inlines below), but we keep | 611 | * don't cast (use the static inlines below), but we keep |
@@ -668,7 +704,7 @@ struct ieee80211_local { | |||
668 | 704 | ||
669 | /* Scanning and BSS list */ | 705 | /* Scanning and BSS list */ |
670 | struct mutex scan_mtx; | 706 | struct mutex scan_mtx; |
671 | bool sw_scanning, hw_scanning; | 707 | unsigned long scanning; |
672 | struct cfg80211_ssid scan_ssid; | 708 | struct cfg80211_ssid scan_ssid; |
673 | struct cfg80211_scan_request int_scan_req; | 709 | struct cfg80211_scan_request int_scan_req; |
674 | struct cfg80211_scan_request *scan_req; | 710 | struct cfg80211_scan_request *scan_req; |
@@ -678,7 +714,7 @@ struct ieee80211_local { | |||
678 | int scan_channel_idx; | 714 | int scan_channel_idx; |
679 | int scan_ies_len; | 715 | int scan_ies_len; |
680 | 716 | ||
681 | enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; | 717 | enum mac80211_scan_state next_scan_state; |
682 | struct delayed_work scan_work; | 718 | struct delayed_work scan_work; |
683 | struct ieee80211_sub_if_data *scan_sdata; | 719 | struct ieee80211_sub_if_data *scan_sdata; |
684 | enum nl80211_channel_type oper_channel_type; | 720 | enum nl80211_channel_type oper_channel_type; |
@@ -914,9 +950,6 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
914 | void ieee80211_configure_filter(struct ieee80211_local *local); | 950 | void ieee80211_configure_filter(struct ieee80211_local *local); |
915 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); | 951 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); |
916 | 952 | ||
917 | /* wireless extensions */ | ||
918 | extern const struct iw_handler_def ieee80211_iw_handler_def; | ||
919 | |||
920 | /* STA code */ | 953 | /* STA code */ |
921 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); | 954 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); |
922 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | 955 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 2f797a86ced5..6c655b6547fb 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -335,7 +335,10 @@ static int ieee80211_stop(struct net_device *dev) | |||
335 | struct ieee80211_local *local = sdata->local; | 335 | struct ieee80211_local *local = sdata->local; |
336 | struct ieee80211_if_init_conf conf; | 336 | struct ieee80211_if_init_conf conf; |
337 | struct sta_info *sta; | 337 | struct sta_info *sta; |
338 | unsigned long flags; | ||
339 | struct sk_buff *skb, *tmp; | ||
338 | u32 hw_reconf_flags = 0; | 340 | u32 hw_reconf_flags = 0; |
341 | int i; | ||
339 | 342 | ||
340 | /* | 343 | /* |
341 | * Stop TX on this interface first. | 344 | * Stop TX on this interface first. |
@@ -515,7 +518,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
515 | * the scan_sdata is NULL already don't send out a | 518 | * the scan_sdata is NULL already don't send out a |
516 | * scan event to userspace -- the scan is incomplete. | 519 | * scan event to userspace -- the scan is incomplete. |
517 | */ | 520 | */ |
518 | if (local->sw_scanning) | 521 | if (test_bit(SCAN_SW_SCANNING, &local->scanning)) |
519 | ieee80211_scan_completed(&local->hw, true); | 522 | ieee80211_scan_completed(&local->hw, true); |
520 | } | 523 | } |
521 | 524 | ||
@@ -551,6 +554,18 @@ static int ieee80211_stop(struct net_device *dev) | |||
551 | if (hw_reconf_flags) | 554 | if (hw_reconf_flags) |
552 | ieee80211_hw_config(local, hw_reconf_flags); | 555 | ieee80211_hw_config(local, hw_reconf_flags); |
553 | 556 | ||
557 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
558 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { | ||
559 | skb_queue_walk_safe(&local->pending[i], skb, tmp) { | ||
560 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
561 | if (info->control.vif == &sdata->vif) { | ||
562 | __skb_unlink(skb, &local->pending[i]); | ||
563 | dev_kfree_skb_irq(skb); | ||
564 | } | ||
565 | } | ||
566 | } | ||
567 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
568 | |||
554 | return 0; | 569 | return 0; |
555 | } | 570 | } |
556 | 571 | ||
@@ -669,7 +684,6 @@ static void ieee80211_if_setup(struct net_device *dev) | |||
669 | { | 684 | { |
670 | ether_setup(dev); | 685 | ether_setup(dev); |
671 | dev->netdev_ops = &ieee80211_dataif_ops; | 686 | dev->netdev_ops = &ieee80211_dataif_ops; |
672 | dev->wireless_handlers = &ieee80211_iw_handler_def; | ||
673 | dev->destructor = free_netdev; | 687 | dev->destructor = free_netdev; |
674 | } | 688 | } |
675 | 689 | ||
@@ -772,6 +786,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
772 | name, ieee80211_if_setup); | 786 | name, ieee80211_if_setup); |
773 | if (!ndev) | 787 | if (!ndev) |
774 | return -ENOMEM; | 788 | return -ENOMEM; |
789 | dev_net_set(ndev, wiphy_net(local->hw.wiphy)); | ||
775 | 790 | ||
776 | ndev->needed_headroom = local->tx_headroom + | 791 | ndev->needed_headroom = local->tx_headroom + |
777 | 4*6 /* four MAC addresses */ | 792 | 4*6 /* four MAC addresses */ |
@@ -788,7 +803,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
788 | 803 | ||
789 | memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); | 804 | memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); |
790 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); | 805 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); |
791 | ndev->features |= NETIF_F_NETNS_LOCAL; | ||
792 | 806 | ||
793 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ | 807 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ |
794 | sdata = netdev_priv(ndev); | 808 | sdata = netdev_priv(ndev); |
@@ -905,7 +919,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
905 | struct ieee80211_sub_if_data *sdata; | 919 | struct ieee80211_sub_if_data *sdata; |
906 | int count = 0; | 920 | int count = 0; |
907 | 921 | ||
908 | if (local->hw_scanning || local->sw_scanning) | 922 | if (local->scanning) |
909 | return ieee80211_idle_off(local, "scanning"); | 923 | return ieee80211_idle_off(local, "scanning"); |
910 | 924 | ||
911 | list_for_each_entry(sdata, &local->interfaces, list) { | 925 | list_for_each_entry(sdata, &local->interfaces, list) { |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 3234f3751d22..c1a799194fff 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -198,7 +198,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
198 | } | 198 | } |
199 | 199 | ||
200 | if (changed & BSS_CHANGED_BEACON_ENABLED) { | 200 | if (changed & BSS_CHANGED_BEACON_ENABLED) { |
201 | if (local->sw_scanning) { | 201 | if (test_bit(SCAN_SW_SCANNING, &local->scanning)) { |
202 | sdata->vif.bss_conf.enable_beacon = false; | 202 | sdata->vif.bss_conf.enable_beacon = false; |
203 | } else { | 203 | } else { |
204 | /* | 204 | /* |
@@ -620,6 +620,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
620 | if (!wiphy) | 620 | if (!wiphy) |
621 | return NULL; | 621 | return NULL; |
622 | 622 | ||
623 | wiphy->netnsok = true; | ||
623 | wiphy->privid = mac80211_wiphy_privid; | 624 | wiphy->privid = mac80211_wiphy_privid; |
624 | 625 | ||
625 | /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ | 626 | /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 8a97b1423088..9a3826978b1c 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -597,7 +597,7 @@ static void ieee80211_mesh_work(struct work_struct *work) | |||
597 | if (!netif_running(sdata->dev)) | 597 | if (!netif_running(sdata->dev)) |
598 | return; | 598 | return; |
599 | 599 | ||
600 | if (local->sw_scanning || local->hw_scanning) | 600 | if (local->scanning) |
601 | return; | 601 | return; |
602 | 602 | ||
603 | while ((skb = skb_dequeue(&ifmsh->skb_queue))) | 603 | while ((skb = skb_dequeue(&ifmsh->skb_queue))) |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0b3551da8f43..ee83125ed179 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -581,7 +581,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
581 | if (!ifmgd->associated) | 581 | if (!ifmgd->associated) |
582 | return; | 582 | return; |
583 | 583 | ||
584 | if (sdata->local->sw_scanning || sdata->local->hw_scanning) | 584 | if (sdata->local->scanning) |
585 | return; | 585 | return; |
586 | 586 | ||
587 | /* Disregard subsequent beacons if we are already running a timer | 587 | /* Disregard subsequent beacons if we are already running a timer |
@@ -639,7 +639,7 @@ static void ieee80211_enable_ps(struct ieee80211_local *local, | |||
639 | * If we are scanning right now then the parameters will | 639 | * If we are scanning right now then the parameters will |
640 | * take effect when scan finishes. | 640 | * take effect when scan finishes. |
641 | */ | 641 | */ |
642 | if (local->hw_scanning || local->sw_scanning) | 642 | if (local->scanning) |
643 | return; | 643 | return; |
644 | 644 | ||
645 | if (conf->dynamic_ps_timeout > 0 && | 645 | if (conf->dynamic_ps_timeout > 0 && |
@@ -1166,6 +1166,9 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
1166 | if (!netif_running(sdata->dev)) | 1166 | if (!netif_running(sdata->dev)) |
1167 | return; | 1167 | return; |
1168 | 1168 | ||
1169 | if (sdata->local->scanning) | ||
1170 | return; | ||
1171 | |||
1169 | mutex_lock(&ifmgd->mtx); | 1172 | mutex_lock(&ifmgd->mtx); |
1170 | 1173 | ||
1171 | if (!ifmgd->associated) | 1174 | if (!ifmgd->associated) |
@@ -2000,6 +2003,9 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
2000 | case RX_MGMT_CFG80211_ASSOC: | 2003 | case RX_MGMT_CFG80211_ASSOC: |
2001 | cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len); | 2004 | cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len); |
2002 | break; | 2005 | break; |
2006 | case RX_MGMT_CFG80211_DEAUTH: | ||
2007 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, NULL); | ||
2008 | break; | ||
2003 | default: | 2009 | default: |
2004 | WARN(1, "unexpected: %d", rma); | 2010 | WARN(1, "unexpected: %d", rma); |
2005 | } | 2011 | } |
@@ -2038,7 +2044,7 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2038 | if (!netif_running(sdata->dev)) | 2044 | if (!netif_running(sdata->dev)) |
2039 | return; | 2045 | return; |
2040 | 2046 | ||
2041 | if (local->sw_scanning || local->hw_scanning) | 2047 | if (local->scanning) |
2042 | return; | 2048 | return; |
2043 | 2049 | ||
2044 | if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) | 2050 | if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) |
@@ -2213,9 +2219,6 @@ static void ieee80211_sta_monitor_work(struct work_struct *work) | |||
2213 | container_of(work, struct ieee80211_sub_if_data, | 2219 | container_of(work, struct ieee80211_sub_if_data, |
2214 | u.mgd.monitor_work); | 2220 | u.mgd.monitor_work); |
2215 | 2221 | ||
2216 | if (sdata->local->sw_scanning || sdata->local->hw_scanning) | ||
2217 | return; | ||
2218 | |||
2219 | ieee80211_mgd_probe_ap(sdata, false); | 2222 | ieee80211_mgd_probe_ap(sdata, false); |
2220 | } | 2223 | } |
2221 | 2224 | ||
@@ -2377,6 +2380,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
2377 | 2380 | ||
2378 | wk->state = IEEE80211_MGD_STATE_PROBE; | 2381 | wk->state = IEEE80211_MGD_STATE_PROBE; |
2379 | wk->auth_alg = auth_alg; | 2382 | wk->auth_alg = auth_alg; |
2383 | wk->timeout = jiffies; /* run right away */ | ||
2380 | 2384 | ||
2381 | /* | 2385 | /* |
2382 | * XXX: if still associated need to tell AP that we're going | 2386 | * XXX: if still associated need to tell AP that we're going |
@@ -2448,6 +2452,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2448 | 2452 | ||
2449 | wk->state = IEEE80211_MGD_STATE_ASSOC; | 2453 | wk->state = IEEE80211_MGD_STATE_ASSOC; |
2450 | wk->tries = 0; | 2454 | wk->tries = 0; |
2455 | wk->timeout = jiffies; /* run right away */ | ||
2451 | 2456 | ||
2452 | if (req->use_mfp) { | 2457 | if (req->use_mfp) { |
2453 | ifmgd->mfp = IEEE80211_MFP_REQUIRED; | 2458 | ifmgd->mfp = IEEE80211_MFP_REQUIRED; |
@@ -2496,8 +2501,13 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2496 | } | 2501 | } |
2497 | } | 2502 | } |
2498 | 2503 | ||
2499 | /* cfg80211 should catch this... */ | 2504 | /* |
2500 | if (WARN_ON(!bssid)) { | 2505 | * cfg80211 should catch this ... but it's racy since |
2506 | * we can receive a deauth frame, process it, hand it | ||
2507 | * to cfg80211 while that's in a locked section already | ||
2508 | * trying to tell us that the user wants to disconnect. | ||
2509 | */ | ||
2510 | if (!bssid) { | ||
2501 | mutex_unlock(&ifmgd->mtx); | 2511 | mutex_unlock(&ifmgd->mtx); |
2502 | return -ENOLINK; | 2512 | return -ENOLINK; |
2503 | } | 2513 | } |
@@ -2522,8 +2532,13 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2522 | 2532 | ||
2523 | mutex_lock(&ifmgd->mtx); | 2533 | mutex_lock(&ifmgd->mtx); |
2524 | 2534 | ||
2525 | /* cfg80211 should catch that */ | 2535 | /* |
2526 | if (WARN_ON(&ifmgd->associated->cbss != req->bss)) { | 2536 | * cfg80211 should catch this ... but it's racy since |
2537 | * we can receive a disassoc frame, process it, hand it | ||
2538 | * to cfg80211 while that's in a locked section already | ||
2539 | * trying to tell us that the user wants to disconnect. | ||
2540 | */ | ||
2541 | if (&ifmgd->associated->cbss != req->bss) { | ||
2527 | mutex_unlock(&ifmgd->mtx); | 2542 | mutex_unlock(&ifmgd->mtx); |
2528 | return -ENOLINK; | 2543 | return -ENOLINK; |
2529 | } | 2544 | } |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b6ddde3848fb..25a669c86e14 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -418,10 +418,11 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | |||
418 | struct ieee80211_local *local = rx->local; | 418 | struct ieee80211_local *local = rx->local; |
419 | struct sk_buff *skb = rx->skb; | 419 | struct sk_buff *skb = rx->skb; |
420 | 420 | ||
421 | if (unlikely(local->hw_scanning)) | 421 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning))) |
422 | return ieee80211_scan_rx(rx->sdata, skb); | 422 | return ieee80211_scan_rx(rx->sdata, skb); |
423 | 423 | ||
424 | if (unlikely(local->sw_scanning)) { | 424 | if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning) && |
425 | (rx->flags & IEEE80211_RX_IN_SCAN))) { | ||
425 | /* drop all the other packets during a software scan anyway */ | 426 | /* drop all the other packets during a software scan anyway */ |
426 | if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED) | 427 | if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED) |
427 | dev_kfree_skb(skb); | 428 | dev_kfree_skb(skb); |
@@ -782,7 +783,7 @@ static void ap_sta_ps_start(struct sta_info *sta) | |||
782 | struct ieee80211_local *local = sdata->local; | 783 | struct ieee80211_local *local = sdata->local; |
783 | 784 | ||
784 | atomic_inc(&sdata->bss->num_sta_ps); | 785 | atomic_inc(&sdata->bss->num_sta_ps); |
785 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); | 786 | set_sta_flags(sta, WLAN_STA_PS); |
786 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta); | 787 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta); |
787 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 788 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
788 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", | 789 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", |
@@ -798,7 +799,7 @@ static int ap_sta_ps_end(struct sta_info *sta) | |||
798 | 799 | ||
799 | atomic_dec(&sdata->bss->num_sta_ps); | 800 | atomic_dec(&sdata->bss->num_sta_ps); |
800 | 801 | ||
801 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); | 802 | clear_sta_flags(sta, WLAN_STA_PS); |
802 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta); | 803 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta); |
803 | 804 | ||
804 | if (!skb_queue_empty(&sta->ps_tx_buf)) | 805 | if (!skb_queue_empty(&sta->ps_tx_buf)) |
@@ -1116,14 +1117,15 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1116 | skb_queue_empty(&rx->sta->ps_tx_buf); | 1117 | skb_queue_empty(&rx->sta->ps_tx_buf); |
1117 | 1118 | ||
1118 | if (skb) { | 1119 | if (skb) { |
1120 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1119 | struct ieee80211_hdr *hdr = | 1121 | struct ieee80211_hdr *hdr = |
1120 | (struct ieee80211_hdr *) skb->data; | 1122 | (struct ieee80211_hdr *) skb->data; |
1121 | 1123 | ||
1122 | /* | 1124 | /* |
1123 | * Tell TX path to send one frame even though the STA may | 1125 | * Tell TX path to send this frame even though the STA may |
1124 | * still remain is PS mode after this frame exchange. | 1126 | * still remain is PS mode after this frame exchange. |
1125 | */ | 1127 | */ |
1126 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); | 1128 | info->flags |= IEEE80211_TX_CTL_PSPOLL_RESPONSE; |
1127 | 1129 | ||
1128 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1130 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
1129 | printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n", | 1131 | printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n", |
@@ -1138,7 +1140,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1138 | else | 1140 | else |
1139 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 1141 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); |
1140 | 1142 | ||
1141 | dev_queue_xmit(skb); | 1143 | ieee80211_add_pending_skb(rx->local, skb); |
1142 | 1144 | ||
1143 | if (no_pending_pkts) | 1145 | if (no_pending_pkts) |
1144 | sta_info_clear_tim_bit(rx->sta); | 1146 | sta_info_clear_tim_bit(rx->sta); |
@@ -1539,7 +1541,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1539 | info = IEEE80211_SKB_CB(fwd_skb); | 1541 | info = IEEE80211_SKB_CB(fwd_skb); |
1540 | memset(info, 0, sizeof(*info)); | 1542 | memset(info, 0, sizeof(*info)); |
1541 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1543 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1542 | fwd_skb->iif = rx->dev->ifindex; | 1544 | info->control.vif = &rx->sdata->vif; |
1543 | ieee80211_select_queue(local, fwd_skb); | 1545 | ieee80211_select_queue(local, fwd_skb); |
1544 | if (is_multicast_ether_addr(fwd_hdr->addr3)) | 1546 | if (is_multicast_ether_addr(fwd_hdr->addr3)) |
1545 | memcpy(fwd_hdr->addr1, fwd_hdr->addr3, | 1547 | memcpy(fwd_hdr->addr1, fwd_hdr->addr3, |
@@ -2136,7 +2138,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2136 | return; | 2138 | return; |
2137 | } | 2139 | } |
2138 | 2140 | ||
2139 | if (unlikely(local->sw_scanning || local->hw_scanning)) | 2141 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || |
2142 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) | ||
2140 | rx.flags |= IEEE80211_RX_IN_SCAN; | 2143 | rx.flags |= IEEE80211_RX_IN_SCAN; |
2141 | 2144 | ||
2142 | ieee80211_parse_qos(&rx); | 2145 | ieee80211_parse_qos(&rx); |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 74820656dc89..45731000eb8d 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/if_arp.h> | 18 | #include <linux/if_arp.h> |
19 | #include <linux/rtnetlink.h> | 19 | #include <linux/rtnetlink.h> |
20 | #include <net/mac80211.h> | 20 | #include <net/mac80211.h> |
21 | #include <net/iw_handler.h> | ||
22 | 21 | ||
23 | #include "ieee80211_i.h" | 22 | #include "ieee80211_i.h" |
24 | #include "driver-ops.h" | 23 | #include "driver-ops.h" |
@@ -265,7 +264,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
265 | 264 | ||
266 | mutex_lock(&local->scan_mtx); | 265 | mutex_lock(&local->scan_mtx); |
267 | 266 | ||
268 | if (WARN_ON(!local->hw_scanning && !local->sw_scanning)) { | 267 | if (WARN_ON(!local->scanning)) { |
269 | mutex_unlock(&local->scan_mtx); | 268 | mutex_unlock(&local->scan_mtx); |
270 | return; | 269 | return; |
271 | } | 270 | } |
@@ -275,16 +274,15 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
275 | return; | 274 | return; |
276 | } | 275 | } |
277 | 276 | ||
278 | if (local->hw_scanning) | 277 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) |
279 | ieee80211_restore_scan_ies(local); | 278 | ieee80211_restore_scan_ies(local); |
280 | 279 | ||
281 | if (local->scan_req != &local->int_scan_req) | 280 | if (local->scan_req != &local->int_scan_req) |
282 | cfg80211_scan_done(local->scan_req, aborted); | 281 | cfg80211_scan_done(local->scan_req, aborted); |
283 | local->scan_req = NULL; | 282 | local->scan_req = NULL; |
284 | 283 | ||
285 | was_hw_scan = local->hw_scanning; | 284 | was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning); |
286 | local->hw_scanning = false; | 285 | local->scanning = 0; |
287 | local->sw_scanning = false; | ||
288 | local->scan_channel = NULL; | 286 | local->scan_channel = NULL; |
289 | 287 | ||
290 | /* we only have to protect scan_req and hw/sw scan */ | 288 | /* we only have to protect scan_req and hw/sw scan */ |
@@ -366,17 +364,16 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
366 | ieee80211_bss_info_change_notify( | 364 | ieee80211_bss_info_change_notify( |
367 | sdata, BSS_CHANGED_BEACON_ENABLED); | 365 | sdata, BSS_CHANGED_BEACON_ENABLED); |
368 | 366 | ||
369 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 367 | /* |
370 | if (sdata->u.mgd.associated) { | 368 | * only handle non-STA interfaces here, STA interfaces |
371 | netif_tx_stop_all_queues(sdata->dev); | 369 | * are handled in the scan state machine |
372 | ieee80211_scan_ps_enable(sdata); | 370 | */ |
373 | } | 371 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
374 | } else | ||
375 | netif_tx_stop_all_queues(sdata->dev); | 372 | netif_tx_stop_all_queues(sdata->dev); |
376 | } | 373 | } |
377 | mutex_unlock(&local->iflist_mtx); | 374 | mutex_unlock(&local->iflist_mtx); |
378 | 375 | ||
379 | local->scan_state = SCAN_SET_CHANNEL; | 376 | local->next_scan_state = SCAN_DECISION; |
380 | local->scan_channel_idx = 0; | 377 | local->scan_channel_idx = 0; |
381 | 378 | ||
382 | spin_lock_bh(&local->filter_lock); | 379 | spin_lock_bh(&local->filter_lock); |
@@ -434,9 +431,9 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
434 | } | 431 | } |
435 | 432 | ||
436 | if (local->ops->hw_scan) | 433 | if (local->ops->hw_scan) |
437 | local->hw_scanning = true; | 434 | __set_bit(SCAN_HW_SCANNING, &local->scanning); |
438 | else | 435 | else |
439 | local->sw_scanning = true; | 436 | __set_bit(SCAN_SW_SCANNING, &local->scanning); |
440 | /* | 437 | /* |
441 | * Kicking off the scan need not be protected, | 438 | * Kicking off the scan need not be protected, |
442 | * only the scan variable stuff, since now | 439 | * only the scan variable stuff, since now |
@@ -459,11 +456,9 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
459 | mutex_lock(&local->scan_mtx); | 456 | mutex_lock(&local->scan_mtx); |
460 | 457 | ||
461 | if (rc) { | 458 | if (rc) { |
462 | if (local->ops->hw_scan) { | 459 | if (local->ops->hw_scan) |
463 | local->hw_scanning = false; | ||
464 | ieee80211_restore_scan_ies(local); | 460 | ieee80211_restore_scan_ies(local); |
465 | } else | 461 | local->scanning = 0; |
466 | local->sw_scanning = false; | ||
467 | 462 | ||
468 | ieee80211_recalc_idle(local); | 463 | ieee80211_recalc_idle(local); |
469 | 464 | ||
@@ -474,13 +469,195 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
474 | return rc; | 469 | return rc; |
475 | } | 470 | } |
476 | 471 | ||
472 | static int ieee80211_scan_state_decision(struct ieee80211_local *local, | ||
473 | unsigned long *next_delay) | ||
474 | { | ||
475 | bool associated = false; | ||
476 | struct ieee80211_sub_if_data *sdata; | ||
477 | |||
478 | /* if no more bands/channels left, complete scan and advance to the idle state */ | ||
479 | if (local->scan_channel_idx >= local->scan_req->n_channels) { | ||
480 | ieee80211_scan_completed(&local->hw, false); | ||
481 | return 1; | ||
482 | } | ||
483 | |||
484 | /* check if at least one STA interface is associated */ | ||
485 | mutex_lock(&local->iflist_mtx); | ||
486 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
487 | if (!netif_running(sdata->dev)) | ||
488 | continue; | ||
489 | |||
490 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
491 | if (sdata->u.mgd.associated) { | ||
492 | associated = true; | ||
493 | break; | ||
494 | } | ||
495 | } | ||
496 | } | ||
497 | mutex_unlock(&local->iflist_mtx); | ||
498 | |||
499 | if (local->scan_channel) { | ||
500 | /* | ||
501 | * we're currently scanning a different channel, let's | ||
502 | * switch back to the operating channel now if at least | ||
503 | * one interface is associated. Otherwise just scan the | ||
504 | * next channel | ||
505 | */ | ||
506 | if (associated) | ||
507 | local->next_scan_state = SCAN_ENTER_OPER_CHANNEL; | ||
508 | else | ||
509 | local->next_scan_state = SCAN_SET_CHANNEL; | ||
510 | } else { | ||
511 | /* | ||
512 | * we're on the operating channel currently, let's | ||
513 | * leave that channel now to scan another one | ||
514 | */ | ||
515 | local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL; | ||
516 | } | ||
517 | |||
518 | *next_delay = 0; | ||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, | ||
523 | unsigned long *next_delay) | ||
524 | { | ||
525 | struct ieee80211_sub_if_data *sdata; | ||
526 | |||
527 | /* | ||
528 | * notify the AP about us leaving the channel and stop all STA interfaces | ||
529 | */ | ||
530 | mutex_lock(&local->iflist_mtx); | ||
531 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
532 | if (!netif_running(sdata->dev)) | ||
533 | continue; | ||
534 | |||
535 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
536 | netif_tx_stop_all_queues(sdata->dev); | ||
537 | if (sdata->u.mgd.associated) | ||
538 | ieee80211_scan_ps_enable(sdata); | ||
539 | } | ||
540 | } | ||
541 | mutex_unlock(&local->iflist_mtx); | ||
542 | |||
543 | __set_bit(SCAN_OFF_CHANNEL, &local->scanning); | ||
544 | |||
545 | /* advance to the next channel to be scanned */ | ||
546 | *next_delay = HZ / 10; | ||
547 | local->next_scan_state = SCAN_SET_CHANNEL; | ||
548 | } | ||
549 | |||
550 | static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *local, | ||
551 | unsigned long *next_delay) | ||
552 | { | ||
553 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | ||
554 | |||
555 | /* switch back to the operating channel */ | ||
556 | local->scan_channel = NULL; | ||
557 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
558 | |||
559 | /* | ||
560 | * notify the AP about us being back and restart all STA interfaces | ||
561 | */ | ||
562 | mutex_lock(&local->iflist_mtx); | ||
563 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
564 | if (!netif_running(sdata->dev)) | ||
565 | continue; | ||
566 | |||
567 | /* Tell AP we're back */ | ||
568 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
569 | if (sdata->u.mgd.associated) | ||
570 | ieee80211_scan_ps_disable(sdata); | ||
571 | netif_tx_wake_all_queues(sdata->dev); | ||
572 | } | ||
573 | } | ||
574 | mutex_unlock(&local->iflist_mtx); | ||
575 | |||
576 | __clear_bit(SCAN_OFF_CHANNEL, &local->scanning); | ||
577 | |||
578 | *next_delay = HZ / 5; | ||
579 | local->next_scan_state = SCAN_DECISION; | ||
580 | } | ||
581 | |||
582 | static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, | ||
583 | unsigned long *next_delay) | ||
584 | { | ||
585 | int skip; | ||
586 | struct ieee80211_channel *chan; | ||
587 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | ||
588 | |||
589 | skip = 0; | ||
590 | chan = local->scan_req->channels[local->scan_channel_idx]; | ||
591 | |||
592 | if (chan->flags & IEEE80211_CHAN_DISABLED || | ||
593 | (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
594 | chan->flags & IEEE80211_CHAN_NO_IBSS)) | ||
595 | skip = 1; | ||
596 | |||
597 | if (!skip) { | ||
598 | local->scan_channel = chan; | ||
599 | if (ieee80211_hw_config(local, | ||
600 | IEEE80211_CONF_CHANGE_CHANNEL)) | ||
601 | skip = 1; | ||
602 | } | ||
603 | |||
604 | /* advance state machine to next channel/band */ | ||
605 | local->scan_channel_idx++; | ||
606 | |||
607 | if (skip) { | ||
608 | /* if we skip this channel return to the decision state */ | ||
609 | local->next_scan_state = SCAN_DECISION; | ||
610 | return; | ||
611 | } | ||
612 | |||
613 | /* | ||
614 | * Probe delay is used to update the NAV, cf. 11.1.3.2.2 | ||
615 | * (which unfortunately doesn't say _why_ step a) is done, | ||
616 | * but it waits for the probe delay or until a frame is | ||
617 | * received - and the received frame would update the NAV). | ||
618 | * For now, we do not support waiting until a frame is | ||
619 | * received. | ||
620 | * | ||
621 | * In any case, it is not necessary for a passive scan. | ||
622 | */ | ||
623 | if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || | ||
624 | !local->scan_req->n_ssids) { | ||
625 | *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; | ||
626 | local->next_scan_state = SCAN_DECISION; | ||
627 | return; | ||
628 | } | ||
629 | |||
630 | /* active scan, send probes */ | ||
631 | *next_delay = IEEE80211_PROBE_DELAY; | ||
632 | local->next_scan_state = SCAN_SEND_PROBE; | ||
633 | } | ||
634 | |||
635 | static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | ||
636 | unsigned long *next_delay) | ||
637 | { | ||
638 | int i; | ||
639 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | ||
640 | |||
641 | for (i = 0; i < local->scan_req->n_ssids; i++) | ||
642 | ieee80211_send_probe_req( | ||
643 | sdata, NULL, | ||
644 | local->scan_req->ssids[i].ssid, | ||
645 | local->scan_req->ssids[i].ssid_len, | ||
646 | local->scan_req->ie, local->scan_req->ie_len); | ||
647 | |||
648 | /* | ||
649 | * After sending probe requests, wait for probe responses | ||
650 | * on the channel. | ||
651 | */ | ||
652 | *next_delay = IEEE80211_CHANNEL_TIME; | ||
653 | local->next_scan_state = SCAN_DECISION; | ||
654 | } | ||
655 | |||
477 | void ieee80211_scan_work(struct work_struct *work) | 656 | void ieee80211_scan_work(struct work_struct *work) |
478 | { | 657 | { |
479 | struct ieee80211_local *local = | 658 | struct ieee80211_local *local = |
480 | container_of(work, struct ieee80211_local, scan_work.work); | 659 | container_of(work, struct ieee80211_local, scan_work.work); |
481 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | 660 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; |
482 | struct ieee80211_channel *chan; | ||
483 | int skip, i; | ||
484 | unsigned long next_delay = 0; | 661 | unsigned long next_delay = 0; |
485 | 662 | ||
486 | mutex_lock(&local->scan_mtx); | 663 | mutex_lock(&local->scan_mtx); |
@@ -489,7 +666,7 @@ void ieee80211_scan_work(struct work_struct *work) | |||
489 | return; | 666 | return; |
490 | } | 667 | } |
491 | 668 | ||
492 | if (local->scan_req && !(local->sw_scanning || local->hw_scanning)) { | 669 | if (local->scan_req && !local->scanning) { |
493 | struct cfg80211_scan_request *req = local->scan_req; | 670 | struct cfg80211_scan_request *req = local->scan_req; |
494 | int rc; | 671 | int rc; |
495 | 672 | ||
@@ -513,69 +690,30 @@ void ieee80211_scan_work(struct work_struct *work) | |||
513 | return; | 690 | return; |
514 | } | 691 | } |
515 | 692 | ||
516 | switch (local->scan_state) { | 693 | /* |
517 | case SCAN_SET_CHANNEL: | 694 | * as long as no delay is required advance immediately |
518 | /* if no more bands/channels left, complete scan */ | 695 | * without scheduling a new work |
519 | if (local->scan_channel_idx >= local->scan_req->n_channels) { | 696 | */ |
520 | ieee80211_scan_completed(&local->hw, false); | 697 | do { |
521 | return; | 698 | switch (local->next_scan_state) { |
522 | } | 699 | case SCAN_DECISION: |
523 | skip = 0; | 700 | if (ieee80211_scan_state_decision(local, &next_delay)) |
524 | chan = local->scan_req->channels[local->scan_channel_idx]; | 701 | return; |
525 | |||
526 | if (chan->flags & IEEE80211_CHAN_DISABLED || | ||
527 | (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
528 | chan->flags & IEEE80211_CHAN_NO_IBSS)) | ||
529 | skip = 1; | ||
530 | |||
531 | if (!skip) { | ||
532 | local->scan_channel = chan; | ||
533 | if (ieee80211_hw_config(local, | ||
534 | IEEE80211_CONF_CHANGE_CHANNEL)) | ||
535 | skip = 1; | ||
536 | } | ||
537 | |||
538 | /* advance state machine to next channel/band */ | ||
539 | local->scan_channel_idx++; | ||
540 | |||
541 | if (skip) | ||
542 | break; | 702 | break; |
543 | 703 | case SCAN_SET_CHANNEL: | |
544 | /* | 704 | ieee80211_scan_state_set_channel(local, &next_delay); |
545 | * Probe delay is used to update the NAV, cf. 11.1.3.2.2 | 705 | break; |
546 | * (which unfortunately doesn't say _why_ step a) is done, | 706 | case SCAN_SEND_PROBE: |
547 | * but it waits for the probe delay or until a frame is | 707 | ieee80211_scan_state_send_probe(local, &next_delay); |
548 | * received - and the received frame would update the NAV). | 708 | break; |
549 | * For now, we do not support waiting until a frame is | 709 | case SCAN_LEAVE_OPER_CHANNEL: |
550 | * received. | 710 | ieee80211_scan_state_leave_oper_channel(local, &next_delay); |
551 | * | 711 | break; |
552 | * In any case, it is not necessary for a passive scan. | 712 | case SCAN_ENTER_OPER_CHANNEL: |
553 | */ | 713 | ieee80211_scan_state_enter_oper_channel(local, &next_delay); |
554 | if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || | ||
555 | !local->scan_req->n_ssids) { | ||
556 | next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; | ||
557 | break; | 714 | break; |
558 | } | 715 | } |
559 | 716 | } while (next_delay == 0); | |
560 | next_delay = IEEE80211_PROBE_DELAY; | ||
561 | local->scan_state = SCAN_SEND_PROBE; | ||
562 | break; | ||
563 | case SCAN_SEND_PROBE: | ||
564 | for (i = 0; i < local->scan_req->n_ssids; i++) | ||
565 | ieee80211_send_probe_req( | ||
566 | sdata, NULL, | ||
567 | local->scan_req->ssids[i].ssid, | ||
568 | local->scan_req->ssids[i].ssid_len, | ||
569 | local->scan_req->ie, local->scan_req->ie_len); | ||
570 | |||
571 | /* | ||
572 | * After sending probe requests, wait for probe responses | ||
573 | * on the channel. | ||
574 | */ | ||
575 | next_delay = IEEE80211_CHANNEL_TIME; | ||
576 | local->scan_state = SCAN_SET_CHANNEL; | ||
577 | break; | ||
578 | } | ||
579 | 717 | ||
580 | queue_delayed_work(local->hw.workqueue, &local->scan_work, | 718 | queue_delayed_work(local->hw.workqueue, &local->scan_work, |
581 | next_delay); | 719 | next_delay); |
@@ -625,7 +763,7 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) | |||
625 | * queued -- mostly at suspend under RTNL. | 763 | * queued -- mostly at suspend under RTNL. |
626 | */ | 764 | */ |
627 | mutex_lock(&local->scan_mtx); | 765 | mutex_lock(&local->scan_mtx); |
628 | swscan = local->sw_scanning; | 766 | swscan = test_bit(SCAN_SW_SCANNING, &local->scanning); |
629 | mutex_unlock(&local->scan_mtx); | 767 | mutex_unlock(&local->scan_mtx); |
630 | 768 | ||
631 | if (swscan) | 769 | if (swscan) |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 4ecf10a9bd00..ccc3adf962c7 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -30,7 +30,6 @@ | |||
30 | * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP. | 30 | * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP. |
31 | * @WLAN_STA_WME: Station is a QoS-STA. | 31 | * @WLAN_STA_WME: Station is a QoS-STA. |
32 | * @WLAN_STA_WDS: Station is one of our WDS peers. | 32 | * @WLAN_STA_WDS: Station is one of our WDS peers. |
33 | * @WLAN_STA_PSPOLL: Station has just PS-polled us. | ||
34 | * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the | 33 | * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the |
35 | * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next | 34 | * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next |
36 | * frame to this station is transmitted. | 35 | * frame to this station is transmitted. |
@@ -47,7 +46,6 @@ enum ieee80211_sta_info_flags { | |||
47 | WLAN_STA_ASSOC_AP = 1<<5, | 46 | WLAN_STA_ASSOC_AP = 1<<5, |
48 | WLAN_STA_WME = 1<<6, | 47 | WLAN_STA_WME = 1<<6, |
49 | WLAN_STA_WDS = 1<<7, | 48 | WLAN_STA_WDS = 1<<7, |
50 | WLAN_STA_PSPOLL = 1<<8, | ||
51 | WLAN_STA_CLEAR_PS_FILT = 1<<9, | 49 | WLAN_STA_CLEAR_PS_FILT = 1<<9, |
52 | WLAN_STA_MFP = 1<<10, | 50 | WLAN_STA_MFP = 1<<10, |
53 | WLAN_STA_SUSPEND = 1<<11 | 51 | WLAN_STA_SUSPEND = 1<<11 |
@@ -359,17 +357,6 @@ static inline void clear_sta_flags(struct sta_info *sta, const u32 flags) | |||
359 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | 357 | spin_unlock_irqrestore(&sta->flaglock, irqfl); |
360 | } | 358 | } |
361 | 359 | ||
362 | static inline void set_and_clear_sta_flags(struct sta_info *sta, | ||
363 | const u32 set, const u32 clear) | ||
364 | { | ||
365 | unsigned long irqfl; | ||
366 | |||
367 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
368 | sta->flags |= set; | ||
369 | sta->flags &= ~clear; | ||
370 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
371 | } | ||
372 | |||
373 | static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags) | 360 | static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags) |
374 | { | 361 | { |
375 | u32 ret; | 362 | u32 ret; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 2572509d5568..4e1b2ba122cd 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -192,7 +192,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
192 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) | 192 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) |
193 | return TX_CONTINUE; | 193 | return TX_CONTINUE; |
194 | 194 | ||
195 | if (unlikely(tx->local->sw_scanning) && | 195 | if (unlikely(test_bit(SCAN_OFF_CHANNEL, &tx->local->scanning)) && |
196 | !ieee80211_is_probe_req(hdr->frame_control) && | 196 | !ieee80211_is_probe_req(hdr->frame_control) && |
197 | !ieee80211_is_nullfunc(hdr->frame_control)) | 197 | !ieee80211_is_nullfunc(hdr->frame_control)) |
198 | /* | 198 | /* |
@@ -373,7 +373,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
373 | staflags = get_sta_flags(sta); | 373 | staflags = get_sta_flags(sta); |
374 | 374 | ||
375 | if (unlikely((staflags & WLAN_STA_PS) && | 375 | if (unlikely((staflags & WLAN_STA_PS) && |
376 | !(staflags & WLAN_STA_PSPOLL))) { | 376 | !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) { |
377 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 377 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
378 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries " | 378 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries " |
379 | "before %d)\n", | 379 | "before %d)\n", |
@@ -400,6 +400,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
400 | sta_info_set_tim_bit(sta); | 400 | sta_info_set_tim_bit(sta); |
401 | 401 | ||
402 | info->control.jiffies = jiffies; | 402 | info->control.jiffies = jiffies; |
403 | info->control.vif = &tx->sdata->vif; | ||
403 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 404 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
404 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); | 405 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); |
405 | return TX_QUEUED; | 406 | return TX_QUEUED; |
@@ -411,24 +412,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
411 | sta->sta.addr); | 412 | sta->sta.addr); |
412 | } | 413 | } |
413 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 414 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
414 | if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) { | ||
415 | /* | ||
416 | * The sleeping station with pending data is now snoozing. | ||
417 | * It queried us for its buffered frames and will go back | ||
418 | * to deep sleep once it got everything. | ||
419 | * | ||
420 | * inform the driver, in case the hardware does powersave | ||
421 | * frame filtering and keeps a station blacklist on its own | ||
422 | * (e.g: p54), so that frames can be delivered unimpeded. | ||
423 | * | ||
424 | * Note: It should be safe to disable the filter now. | ||
425 | * As, it is really unlikely that we still have any pending | ||
426 | * frame for this station in the hw's buffers/fifos left, | ||
427 | * that is not rejected with a unsuccessful tx_status yet. | ||
428 | */ | ||
429 | 415 | ||
430 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | ||
431 | } | ||
432 | return TX_CONTINUE; | 416 | return TX_CONTINUE; |
433 | } | 417 | } |
434 | 418 | ||
@@ -551,7 +535,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
551 | * Lets not bother rate control if we're associated and cannot | 535 | * Lets not bother rate control if we're associated and cannot |
552 | * talk to the sta. This should not happen. | 536 | * talk to the sta. This should not happen. |
553 | */ | 537 | */ |
554 | if (WARN((tx->local->sw_scanning) && | 538 | if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) && |
555 | (sta_flags & WLAN_STA_ASSOC) && | 539 | (sta_flags & WLAN_STA_ASSOC) && |
556 | !rate_usable_index_exists(sband, &tx->sta->sta), | 540 | !rate_usable_index_exists(sband, &tx->sta->sta), |
557 | "%s: Dropped data frame as no usable bitrate found while " | 541 | "%s: Dropped data frame as no usable bitrate found while " |
@@ -696,7 +680,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | |||
696 | * number, if we have no matching interface then we | 680 | * number, if we have no matching interface then we |
697 | * neither assign one ourselves nor ask the driver to. | 681 | * neither assign one ourselves nor ask the driver to. |
698 | */ | 682 | */ |
699 | if (unlikely(!info->control.vif)) | 683 | if (unlikely(info->control.vif->type == NL80211_IFTYPE_MONITOR)) |
700 | return TX_CONTINUE; | 684 | return TX_CONTINUE; |
701 | 685 | ||
702 | if (unlikely(ieee80211_is_ctl(hdr->frame_control))) | 686 | if (unlikely(ieee80211_is_ctl(hdr->frame_control))) |
@@ -1092,6 +1076,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1092 | } else if (*state != HT_AGG_STATE_IDLE) { | 1076 | } else if (*state != HT_AGG_STATE_IDLE) { |
1093 | /* in progress */ | 1077 | /* in progress */ |
1094 | queued = true; | 1078 | queued = true; |
1079 | info->control.vif = &sdata->vif; | ||
1095 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1080 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1096 | __skb_queue_tail(&tid_tx->pending, skb); | 1081 | __skb_queue_tail(&tid_tx->pending, skb); |
1097 | } | 1082 | } |
@@ -1143,6 +1128,7 @@ static int __ieee80211_tx(struct ieee80211_local *local, | |||
1143 | { | 1128 | { |
1144 | struct sk_buff *skb = *skbp, *next; | 1129 | struct sk_buff *skb = *skbp, *next; |
1145 | struct ieee80211_tx_info *info; | 1130 | struct ieee80211_tx_info *info; |
1131 | struct ieee80211_sub_if_data *sdata; | ||
1146 | unsigned long flags; | 1132 | unsigned long flags; |
1147 | int ret, len; | 1133 | int ret, len; |
1148 | bool fragm = false; | 1134 | bool fragm = false; |
@@ -1167,13 +1153,32 @@ static int __ieee80211_tx(struct ieee80211_local *local, | |||
1167 | 1153 | ||
1168 | next = skb->next; | 1154 | next = skb->next; |
1169 | len = skb->len; | 1155 | len = skb->len; |
1156 | |||
1157 | sdata = vif_to_sdata(info->control.vif); | ||
1158 | |||
1159 | switch (sdata->vif.type) { | ||
1160 | case NL80211_IFTYPE_MONITOR: | ||
1161 | info->control.vif = NULL; | ||
1162 | break; | ||
1163 | case NL80211_IFTYPE_AP_VLAN: | ||
1164 | info->control.vif = &container_of(sdata->bss, | ||
1165 | struct ieee80211_sub_if_data, u.ap)->vif; | ||
1166 | break; | ||
1167 | default: | ||
1168 | /* keep */ | ||
1169 | break; | ||
1170 | } | ||
1171 | |||
1170 | ret = drv_tx(local, skb); | 1172 | ret = drv_tx(local, skb); |
1171 | if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { | 1173 | if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { |
1172 | dev_kfree_skb(skb); | 1174 | dev_kfree_skb(skb); |
1173 | ret = NETDEV_TX_OK; | 1175 | ret = NETDEV_TX_OK; |
1174 | } | 1176 | } |
1175 | if (ret != NETDEV_TX_OK) | 1177 | if (ret != NETDEV_TX_OK) { |
1178 | info->control.vif = &sdata->vif; | ||
1176 | return IEEE80211_TX_AGAIN; | 1179 | return IEEE80211_TX_AGAIN; |
1180 | } | ||
1181 | |||
1177 | *skbp = skb = next; | 1182 | *skbp = skb = next; |
1178 | ieee80211_led_tx(local, 1); | 1183 | ieee80211_led_tx(local, 1); |
1179 | fragm = true; | 1184 | fragm = true; |
@@ -1386,17 +1391,12 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1386 | struct ieee80211_sub_if_data *tmp_sdata; | 1391 | struct ieee80211_sub_if_data *tmp_sdata; |
1387 | int headroom; | 1392 | int headroom; |
1388 | bool may_encrypt; | 1393 | bool may_encrypt; |
1389 | enum { | ||
1390 | NOT_MONITOR, | ||
1391 | FOUND_SDATA, | ||
1392 | UNKNOWN_ADDRESS, | ||
1393 | } monitor_iface = NOT_MONITOR; | ||
1394 | 1394 | ||
1395 | dev_hold(sdata->dev); | 1395 | dev_hold(sdata->dev); |
1396 | 1396 | ||
1397 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && | 1397 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && |
1398 | local->hw.conf.dynamic_ps_timeout > 0 && | 1398 | local->hw.conf.dynamic_ps_timeout > 0 && |
1399 | !local->sw_scanning && !local->hw_scanning && local->ps_sdata) { | 1399 | !(local->scanning) && local->ps_sdata) { |
1400 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 1400 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
1401 | ieee80211_stop_queues_by_reason(&local->hw, | 1401 | ieee80211_stop_queues_by_reason(&local->hw, |
1402 | IEEE80211_QUEUE_STOP_REASON_PS); | 1402 | IEEE80211_QUEUE_STOP_REASON_PS); |
@@ -1424,7 +1424,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1424 | u16 len_rthdr; | 1424 | u16 len_rthdr; |
1425 | 1425 | ||
1426 | info->flags |= IEEE80211_TX_CTL_INJECTED; | 1426 | info->flags |= IEEE80211_TX_CTL_INJECTED; |
1427 | monitor_iface = UNKNOWN_ADDRESS; | ||
1428 | 1427 | ||
1429 | len_rthdr = ieee80211_get_radiotap_len(skb->data); | 1428 | len_rthdr = ieee80211_get_radiotap_len(skb->data); |
1430 | hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); | 1429 | hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); |
@@ -1454,7 +1453,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1454 | dev_hold(tmp_sdata->dev); | 1453 | dev_hold(tmp_sdata->dev); |
1455 | dev_put(sdata->dev); | 1454 | dev_put(sdata->dev); |
1456 | sdata = tmp_sdata; | 1455 | sdata = tmp_sdata; |
1457 | monitor_iface = FOUND_SDATA; | ||
1458 | break; | 1456 | break; |
1459 | } | 1457 | } |
1460 | } | 1458 | } |
@@ -1476,13 +1474,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1476 | return; | 1474 | return; |
1477 | } | 1475 | } |
1478 | 1476 | ||
1479 | tmp_sdata = sdata; | 1477 | info->control.vif = &sdata->vif; |
1480 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
1481 | tmp_sdata = container_of(sdata->bss, | ||
1482 | struct ieee80211_sub_if_data, | ||
1483 | u.ap); | ||
1484 | if (likely(monitor_iface != UNKNOWN_ADDRESS)) | ||
1485 | info->control.vif = &tmp_sdata->vif; | ||
1486 | 1478 | ||
1487 | ieee80211_select_queue(local, skb); | 1479 | ieee80211_select_queue(local, skb); |
1488 | ieee80211_tx(sdata, skb, false); | 1480 | ieee80211_tx(sdata, skb, false); |
@@ -1534,9 +1526,6 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1534 | if (unlikely(skb->len < len_rthdr)) | 1526 | if (unlikely(skb->len < len_rthdr)) |
1535 | goto fail; /* skb too short for claimed rt header extent */ | 1527 | goto fail; /* skb too short for claimed rt header extent */ |
1536 | 1528 | ||
1537 | /* needed because we set skb device to master */ | ||
1538 | skb->iif = dev->ifindex; | ||
1539 | |||
1540 | /* | 1529 | /* |
1541 | * fix up the pointers accounting for the radiotap | 1530 | * fix up the pointers accounting for the radiotap |
1542 | * header still being in there. We are being given | 1531 | * header still being in there. We are being given |
@@ -1810,8 +1799,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1810 | nh_pos += hdrlen; | 1799 | nh_pos += hdrlen; |
1811 | h_pos += hdrlen; | 1800 | h_pos += hdrlen; |
1812 | 1801 | ||
1813 | skb->iif = dev->ifindex; | ||
1814 | |||
1815 | dev->stats.tx_packets++; | 1802 | dev->stats.tx_packets++; |
1816 | dev->stats.tx_bytes += skb->len; | 1803 | dev->stats.tx_bytes += skb->len; |
1817 | 1804 | ||
@@ -1856,32 +1843,13 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, | |||
1856 | struct ieee80211_sub_if_data *sdata; | 1843 | struct ieee80211_sub_if_data *sdata; |
1857 | struct sta_info *sta; | 1844 | struct sta_info *sta; |
1858 | struct ieee80211_hdr *hdr; | 1845 | struct ieee80211_hdr *hdr; |
1859 | struct net_device *dev; | ||
1860 | int ret; | 1846 | int ret; |
1861 | bool result = true; | 1847 | bool result = true; |
1862 | 1848 | ||
1863 | /* does interface still exist? */ | 1849 | sdata = vif_to_sdata(info->control.vif); |
1864 | dev = dev_get_by_index(&init_net, skb->iif); | ||
1865 | if (!dev) { | ||
1866 | dev_kfree_skb(skb); | ||
1867 | return true; | ||
1868 | } | ||
1869 | |||
1870 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1871 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
1872 | sdata = container_of(sdata->bss, | ||
1873 | struct ieee80211_sub_if_data, | ||
1874 | u.ap); | ||
1875 | |||
1876 | if (unlikely(info->control.vif && info->control.vif != &sdata->vif)) { | ||
1877 | dev_kfree_skb(skb); | ||
1878 | result = true; | ||
1879 | goto out; | ||
1880 | } | ||
1881 | 1850 | ||
1882 | if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) { | 1851 | if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) { |
1883 | /* do not use sdata, it may have been changed above */ | 1852 | ieee80211_tx(sdata, skb, true); |
1884 | ieee80211_tx(IEEE80211_DEV_TO_SUB_IF(dev), skb, true); | ||
1885 | } else { | 1853 | } else { |
1886 | hdr = (struct ieee80211_hdr *)skb->data; | 1854 | hdr = (struct ieee80211_hdr *)skb->data; |
1887 | sta = sta_info_get(local, hdr->addr1); | 1855 | sta = sta_info_get(local, hdr->addr1); |
@@ -1891,9 +1859,6 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, | |||
1891 | result = false; | 1859 | result = false; |
1892 | } | 1860 | } |
1893 | 1861 | ||
1894 | out: | ||
1895 | dev_put(dev); | ||
1896 | |||
1897 | return result; | 1862 | return result; |
1898 | } | 1863 | } |
1899 | 1864 | ||
@@ -1921,10 +1886,21 @@ void ieee80211_tx_pending(unsigned long data) | |||
1921 | 1886 | ||
1922 | while (!skb_queue_empty(&local->pending[i])) { | 1887 | while (!skb_queue_empty(&local->pending[i])) { |
1923 | struct sk_buff *skb = __skb_dequeue(&local->pending[i]); | 1888 | struct sk_buff *skb = __skb_dequeue(&local->pending[i]); |
1889 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1890 | struct ieee80211_sub_if_data *sdata; | ||
1891 | |||
1892 | if (WARN_ON(!info->control.vif)) { | ||
1893 | kfree_skb(skb); | ||
1894 | continue; | ||
1895 | } | ||
1896 | |||
1897 | sdata = vif_to_sdata(info->control.vif); | ||
1898 | dev_hold(sdata->dev); | ||
1924 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, | 1899 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, |
1925 | flags); | 1900 | flags); |
1926 | 1901 | ||
1927 | txok = ieee80211_tx_pending_skb(local, skb); | 1902 | txok = ieee80211_tx_pending_skb(local, skb); |
1903 | dev_put(sdata->dev); | ||
1928 | if (!txok) | 1904 | if (!txok) |
1929 | __skb_queue_head(&local->pending[i], skb); | 1905 | __skb_queue_head(&local->pending[i], skb); |
1930 | spin_lock_irqsave(&local->queue_stop_reason_lock, | 1906 | spin_lock_irqsave(&local->queue_stop_reason_lock, |
@@ -2234,7 +2210,6 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | |||
2234 | skb_set_network_header(skb, 0); | 2210 | skb_set_network_header(skb, 0); |
2235 | skb_set_transport_header(skb, 0); | 2211 | skb_set_transport_header(skb, 0); |
2236 | 2212 | ||
2237 | skb->iif = sdata->dev->ifindex; | ||
2238 | if (!encrypt) | 2213 | if (!encrypt) |
2239 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 2214 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
2240 | 2215 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 7fc55846d601..8502936e5314 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -336,6 +336,12 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, | |||
336 | struct ieee80211_hw *hw = &local->hw; | 336 | struct ieee80211_hw *hw = &local->hw; |
337 | unsigned long flags; | 337 | unsigned long flags; |
338 | 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 | } | ||
339 | 345 | ||
340 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | 346 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); |
341 | __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | 347 | __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); |
@@ -358,6 +364,13 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local, | |||
358 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | 364 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); |
359 | 365 | ||
360 | 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 | |||
361 | ret++; | 374 | ret++; |
362 | queue = skb_get_queue_mapping(skb); | 375 | queue = skb_get_queue_mapping(skb); |
363 | __skb_queue_tail(&local->pending[queue], skb); | 376 | __skb_queue_tail(&local->pending[queue], skb); |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c deleted file mode 100644 index 5acb8140ee58..000000000000 --- a/net/mac80211/wext.c +++ /dev/null | |||
@@ -1,235 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2002-2005, Instant802 Networks, Inc. | ||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/netdevice.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/skbuff.h> | ||
16 | #include <linux/etherdevice.h> | ||
17 | #include <linux/if_arp.h> | ||
18 | #include <linux/wireless.h> | ||
19 | #include <net/iw_handler.h> | ||
20 | #include <asm/uaccess.h> | ||
21 | |||
22 | #include <net/mac80211.h> | ||
23 | #include "ieee80211_i.h" | ||
24 | #include "led.h" | ||
25 | #include "rate.h" | ||
26 | #include "wpa.h" | ||
27 | #include "aes_ccm.h" | ||
28 | |||
29 | |||
30 | static int ieee80211_ioctl_siwfreq(struct net_device *dev, | ||
31 | struct iw_request_info *info, | ||
32 | struct iw_freq *freq, char *extra) | ||
33 | { | ||
34 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
35 | struct ieee80211_local *local = sdata->local; | ||
36 | struct ieee80211_channel *chan; | ||
37 | |||
38 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
39 | return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); | ||
40 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
41 | return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra); | ||
42 | |||
43 | /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ | ||
44 | if (freq->e == 0) { | ||
45 | if (freq->m < 0) | ||
46 | return -EINVAL; | ||
47 | else | ||
48 | chan = ieee80211_get_channel(local->hw.wiphy, | ||
49 | ieee80211_channel_to_frequency(freq->m)); | ||
50 | } else { | ||
51 | int i, div = 1000000; | ||
52 | for (i = 0; i < freq->e; i++) | ||
53 | div /= 10; | ||
54 | if (div <= 0) | ||
55 | return -EINVAL; | ||
56 | chan = ieee80211_get_channel(local->hw.wiphy, freq->m / div); | ||
57 | } | ||
58 | |||
59 | if (!chan) | ||
60 | return -EINVAL; | ||
61 | |||
62 | if (chan->flags & IEEE80211_CHAN_DISABLED) | ||
63 | return -EINVAL; | ||
64 | |||
65 | /* | ||
66 | * no change except maybe auto -> fixed, ignore the HT | ||
67 | * setting so you can fix a channel you're on already | ||
68 | */ | ||
69 | if (local->oper_channel == chan) | ||
70 | return 0; | ||
71 | |||
72 | local->oper_channel = chan; | ||
73 | local->oper_channel_type = NL80211_CHAN_NO_HT; | ||
74 | ieee80211_hw_config(local, 0); | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | |||
80 | static int ieee80211_ioctl_giwfreq(struct net_device *dev, | ||
81 | struct iw_request_info *info, | ||
82 | struct iw_freq *freq, char *extra) | ||
83 | { | ||
84 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
85 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
86 | |||
87 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
88 | return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); | ||
89 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
90 | return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra); | ||
91 | |||
92 | freq->m = local->oper_channel->center_freq; | ||
93 | freq->e = 6; | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | |||
99 | static int ieee80211_ioctl_siwessid(struct net_device *dev, | ||
100 | struct iw_request_info *info, | ||
101 | struct iw_point *data, char *ssid) | ||
102 | { | ||
103 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
104 | |||
105 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
106 | return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); | ||
107 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
108 | return cfg80211_mgd_wext_siwessid(dev, info, data, ssid); | ||
109 | |||
110 | return -EOPNOTSUPP; | ||
111 | } | ||
112 | |||
113 | |||
114 | static int ieee80211_ioctl_giwessid(struct net_device *dev, | ||
115 | struct iw_request_info *info, | ||
116 | struct iw_point *data, char *ssid) | ||
117 | { | ||
118 | struct ieee80211_sub_if_data *sdata; | ||
119 | |||
120 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
121 | |||
122 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
123 | return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); | ||
124 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
125 | return cfg80211_mgd_wext_giwessid(dev, info, data, ssid); | ||
126 | |||
127 | return -EOPNOTSUPP; | ||
128 | } | ||
129 | |||
130 | |||
131 | static int ieee80211_ioctl_siwap(struct net_device *dev, | ||
132 | struct iw_request_info *info, | ||
133 | struct sockaddr *ap_addr, char *extra) | ||
134 | { | ||
135 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
136 | |||
137 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
138 | return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); | ||
139 | |||
140 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
141 | return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra); | ||
142 | |||
143 | if (sdata->vif.type == NL80211_IFTYPE_WDS) | ||
144 | return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra); | ||
145 | return -EOPNOTSUPP; | ||
146 | } | ||
147 | |||
148 | |||
149 | static int ieee80211_ioctl_giwap(struct net_device *dev, | ||
150 | struct iw_request_info *info, | ||
151 | struct sockaddr *ap_addr, char *extra) | ||
152 | { | ||
153 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
154 | |||
155 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
156 | return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra); | ||
157 | |||
158 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
159 | return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra); | ||
160 | |||
161 | if (sdata->vif.type == NL80211_IFTYPE_WDS) | ||
162 | return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra); | ||
163 | |||
164 | return -EOPNOTSUPP; | ||
165 | } | ||
166 | |||
167 | |||
168 | /* Structures to export the Wireless Handlers */ | ||
169 | |||
170 | static const iw_handler ieee80211_handler[] = | ||
171 | { | ||
172 | (iw_handler) NULL, /* SIOCSIWCOMMIT */ | ||
173 | (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */ | ||
174 | (iw_handler) NULL, /* SIOCSIWNWID */ | ||
175 | (iw_handler) NULL, /* SIOCGIWNWID */ | ||
176 | (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */ | ||
177 | (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */ | ||
178 | (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */ | ||
179 | (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */ | ||
180 | (iw_handler) NULL, /* SIOCSIWSENS */ | ||
181 | (iw_handler) NULL, /* SIOCGIWSENS */ | ||
182 | (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */ | ||
183 | (iw_handler) cfg80211_wext_giwrange, /* SIOCGIWRANGE */ | ||
184 | (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */ | ||
185 | (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */ | ||
186 | (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */ | ||
187 | (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */ | ||
188 | (iw_handler) NULL, /* SIOCSIWSPY */ | ||
189 | (iw_handler) NULL, /* SIOCGIWSPY */ | ||
190 | (iw_handler) NULL, /* SIOCSIWTHRSPY */ | ||
191 | (iw_handler) NULL, /* SIOCGIWTHRSPY */ | ||
192 | (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */ | ||
193 | (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */ | ||
194 | (iw_handler) cfg80211_wext_siwmlme, /* SIOCSIWMLME */ | ||
195 | (iw_handler) NULL, /* SIOCGIWAPLIST */ | ||
196 | (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */ | ||
197 | (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */ | ||
198 | (iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */ | ||
199 | (iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */ | ||
200 | (iw_handler) NULL, /* SIOCSIWNICKN */ | ||
201 | (iw_handler) NULL, /* SIOCGIWNICKN */ | ||
202 | (iw_handler) NULL, /* -- hole -- */ | ||
203 | (iw_handler) NULL, /* -- hole -- */ | ||
204 | (iw_handler) cfg80211_wext_siwrate, /* SIOCSIWRATE */ | ||
205 | (iw_handler) cfg80211_wext_giwrate, /* SIOCGIWRATE */ | ||
206 | (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */ | ||
207 | (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */ | ||
208 | (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */ | ||
209 | (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */ | ||
210 | (iw_handler) cfg80211_wext_siwtxpower, /* SIOCSIWTXPOW */ | ||
211 | (iw_handler) cfg80211_wext_giwtxpower, /* SIOCGIWTXPOW */ | ||
212 | (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */ | ||
213 | (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */ | ||
214 | (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */ | ||
215 | (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */ | ||
216 | (iw_handler) cfg80211_wext_siwpower, /* SIOCSIWPOWER */ | ||
217 | (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */ | ||
218 | (iw_handler) NULL, /* -- hole -- */ | ||
219 | (iw_handler) NULL, /* -- hole -- */ | ||
220 | (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */ | ||
221 | (iw_handler) NULL, /* SIOCGIWGENIE */ | ||
222 | (iw_handler) cfg80211_wext_siwauth, /* SIOCSIWAUTH */ | ||
223 | (iw_handler) cfg80211_wext_giwauth, /* SIOCGIWAUTH */ | ||
224 | (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */ | ||
225 | (iw_handler) NULL, /* SIOCGIWENCODEEXT */ | ||
226 | (iw_handler) NULL, /* SIOCSIWPMKSA */ | ||
227 | (iw_handler) NULL, /* -- hole -- */ | ||
228 | }; | ||
229 | |||
230 | const struct iw_handler_def ieee80211_iw_handler_def = | ||
231 | { | ||
232 | .num_standard = ARRAY_SIZE(ieee80211_handler), | ||
233 | .standard = (iw_handler *) ieee80211_handler, | ||
234 | .get_wireless_stats = cfg80211_wireless_stats, | ||
235 | }; | ||