aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-07-30 22:26:55 -0400
committerDavid S. Miller <davem@davemloft.net>2009-07-30 22:26:55 -0400
commit2f6d7c1b34403b97fa57473edcb6749d1db5ace3 (patch)
tree97da33c077b08b72a361ff5a4542b86d190b0164 /net
parentdf597efb5737063497f1a4f7c996cc9aec294230 (diff)
parent1e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c1
-rw-r--r--net/mac80211/Kconfig1
-rw-r--r--net/mac80211/Makefile1
-rw-r--r--net/mac80211/cfg.c14
-rw-r--r--net/mac80211/ibss.c2
-rw-r--r--net/mac80211/ieee80211_i.h45
-rw-r--r--net/mac80211/iface.c22
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mesh.c2
-rw-r--r--net/mac80211/mlme.c35
-rw-r--r--net/mac80211/rx.c21
-rw-r--r--net/mac80211/scan.c304
-rw-r--r--net/mac80211/sta_info.h13
-rw-r--r--net/mac80211/tx.c109
-rw-r--r--net/mac80211/util.c13
-rw-r--r--net/mac80211/wext.c235
-rw-r--r--net/wireless/core.c78
-rw-r--r--net/wireless/core.h8
-rw-r--r--net/wireless/ibss.c13
-rw-r--r--net/wireless/mlme.c8
-rw-r--r--net/wireless/nl80211.c206
-rw-r--r--net/wireless/scan.c25
-rw-r--r--net/wireless/sme.c5
-rw-r--r--net/wireless/wext-compat.c180
-rw-r--r--net/wireless/wext-compat.h50
-rw-r--r--net/wireless/wext-sme.c13
26 files changed, 846 insertions, 561 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index d6c657ee413d..71347668c506 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5344,6 +5344,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
5344out: 5344out:
5345 return err; 5345 return err;
5346} 5346}
5347EXPORT_SYMBOL_GPL(dev_change_net_namespace);
5347 5348
5348static int dev_cpu_callback(struct notifier_block *nfb, 5349static int dev_cpu_callback(struct notifier_block *nfb,
5349 unsigned long action, 5350 unsigned long action,
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
4mac80211-y := \ 4mac80211-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
60static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) 60static 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 */
582enum {
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 */
601enum 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
573struct ieee80211_local { 609struct 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,
914void ieee80211_configure_filter(struct ieee80211_local *local); 950void ieee80211_configure_filter(struct ieee80211_local *local);
915u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); 951u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
916 952
917/* wireless extensions */
918extern const struct iw_handler_def ieee80211_iw_handler_def;
919
920/* STA code */ 953/* STA code */
921void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); 954void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
922int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, 955int 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
472static 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
522static 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
550static 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
582static 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
635static 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
477void ieee80211_scan_work(struct work_struct *work) 656void 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
362static 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
373static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags) 360static 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
30static 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
80static 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
99static 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
114static 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
131static 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
149static 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
170static 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
230const 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};
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 6891cd0e38d5..f9fee65dc06a 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -19,6 +19,7 @@
19#include "core.h" 19#include "core.h"
20#include "sysfs.h" 20#include "sysfs.h"
21#include "debugfs.h" 21#include "debugfs.h"
22#include "wext-compat.h"
22 23
23/* name for sysfs, %d is appended */ 24/* name for sysfs, %d is appended */
24#define PHY_NAME "phy" 25#define PHY_NAME "phy"
@@ -106,7 +107,7 @@ __cfg80211_rdev_from_info(struct genl_info *info)
106 107
107 if (info->attrs[NL80211_ATTR_IFINDEX]) { 108 if (info->attrs[NL80211_ATTR_IFINDEX]) {
108 ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); 109 ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
109 dev = dev_get_by_index(&init_net, ifindex); 110 dev = dev_get_by_index(genl_info_net(info), ifindex);
110 if (dev) { 111 if (dev) {
111 if (dev->ieee80211_ptr) 112 if (dev->ieee80211_ptr)
112 byifidx = 113 byifidx =
@@ -151,13 +152,13 @@ cfg80211_get_dev_from_info(struct genl_info *info)
151} 152}
152 153
153struct cfg80211_registered_device * 154struct cfg80211_registered_device *
154cfg80211_get_dev_from_ifindex(int ifindex) 155cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
155{ 156{
156 struct cfg80211_registered_device *rdev = ERR_PTR(-ENODEV); 157 struct cfg80211_registered_device *rdev = ERR_PTR(-ENODEV);
157 struct net_device *dev; 158 struct net_device *dev;
158 159
159 mutex_lock(&cfg80211_mutex); 160 mutex_lock(&cfg80211_mutex);
160 dev = dev_get_by_index(&init_net, ifindex); 161 dev = dev_get_by_index(net, ifindex);
161 if (!dev) 162 if (!dev)
162 goto out; 163 goto out;
163 if (dev->ieee80211_ptr) { 164 if (dev->ieee80211_ptr) {
@@ -222,6 +223,42 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
222 return 0; 223 return 0;
223} 224}
224 225
226int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
227 struct net *net)
228{
229 struct wireless_dev *wdev;
230 int err = 0;
231
232 if (!rdev->wiphy.netnsok)
233 return -EOPNOTSUPP;
234
235 list_for_each_entry(wdev, &rdev->netdev_list, list) {
236 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
237 err = dev_change_net_namespace(wdev->netdev, net, "wlan%d");
238 if (err)
239 break;
240 wdev->netdev->features |= NETIF_F_NETNS_LOCAL;
241 }
242
243 if (err) {
244 /* failed -- clean up to old netns */
245 net = wiphy_net(&rdev->wiphy);
246
247 list_for_each_entry_continue_reverse(wdev, &rdev->netdev_list,
248 list) {
249 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
250 err = dev_change_net_namespace(wdev->netdev, net,
251 "wlan%d");
252 WARN_ON(err);
253 wdev->netdev->features |= NETIF_F_NETNS_LOCAL;
254 }
255 }
256
257 wiphy_net_set(&rdev->wiphy, net);
258
259 return err;
260}
261
225static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) 262static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
226{ 263{
227 struct cfg80211_registered_device *rdev = data; 264 struct cfg80211_registered_device *rdev = data;
@@ -375,6 +412,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
375 rdev->wiphy.dev.class = &ieee80211_class; 412 rdev->wiphy.dev.class = &ieee80211_class;
376 rdev->wiphy.dev.platform_data = rdev; 413 rdev->wiphy.dev.platform_data = rdev;
377 414
415 wiphy_net_set(&rdev->wiphy, &init_net);
416
378 rdev->rfkill_ops.set_block = cfg80211_rfkill_set_block; 417 rdev->rfkill_ops.set_block = cfg80211_rfkill_set_block;
379 rdev->rfkill = rfkill_alloc(dev_name(&rdev->wiphy.dev), 418 rdev->rfkill = rfkill_alloc(dev_name(&rdev->wiphy.dev),
380 &rdev->wiphy.dev, RFKILL_TYPE_WLAN, 419 &rdev->wiphy.dev, RFKILL_TYPE_WLAN,
@@ -615,6 +654,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
615 spin_lock_init(&wdev->event_lock); 654 spin_lock_init(&wdev->event_lock);
616 mutex_lock(&rdev->devlist_mtx); 655 mutex_lock(&rdev->devlist_mtx);
617 list_add(&wdev->list, &rdev->netdev_list); 656 list_add(&wdev->list, &rdev->netdev_list);
657 /* can only change netns with wiphy */
658 dev->features |= NETIF_F_NETNS_LOCAL;
659
618 if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj, 660 if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj,
619 "phy80211")) { 661 "phy80211")) {
620 printk(KERN_ERR "wireless: failed to add phy80211 " 662 printk(KERN_ERR "wireless: failed to add phy80211 "
@@ -624,6 +666,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
624 wdev->sme_state = CFG80211_SME_IDLE; 666 wdev->sme_state = CFG80211_SME_IDLE;
625 mutex_unlock(&rdev->devlist_mtx); 667 mutex_unlock(&rdev->devlist_mtx);
626#ifdef CONFIG_WIRELESS_EXT 668#ifdef CONFIG_WIRELESS_EXT
669 if (!dev->wireless_handlers)
670 dev->wireless_handlers = &cfg80211_wext_handler;
627 wdev->wext.default_key = -1; 671 wdev->wext.default_key = -1;
628 wdev->wext.default_mgmt_key = -1; 672 wdev->wext.default_mgmt_key = -1;
629 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; 673 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
@@ -705,10 +749,32 @@ static struct notifier_block cfg80211_netdev_notifier = {
705 .notifier_call = cfg80211_netdev_notifier_call, 749 .notifier_call = cfg80211_netdev_notifier_call,
706}; 750};
707 751
708static int cfg80211_init(void) 752static void __net_exit cfg80211_pernet_exit(struct net *net)
753{
754 struct cfg80211_registered_device *rdev;
755
756 rtnl_lock();
757 mutex_lock(&cfg80211_mutex);
758 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
759 if (net_eq(wiphy_net(&rdev->wiphy), net))
760 WARN_ON(cfg80211_switch_netns(rdev, &init_net));
761 }
762 mutex_unlock(&cfg80211_mutex);
763 rtnl_unlock();
764}
765
766static struct pernet_operations cfg80211_pernet_ops = {
767 .exit = cfg80211_pernet_exit,
768};
769
770static int __init cfg80211_init(void)
709{ 771{
710 int err; 772 int err;
711 773
774 err = register_pernet_device(&cfg80211_pernet_ops);
775 if (err)
776 goto out_fail_pernet;
777
712 err = wiphy_sysfs_init(); 778 err = wiphy_sysfs_init();
713 if (err) 779 if (err)
714 goto out_fail_sysfs; 780 goto out_fail_sysfs;
@@ -736,9 +802,10 @@ out_fail_nl80211:
736out_fail_notifier: 802out_fail_notifier:
737 wiphy_sysfs_exit(); 803 wiphy_sysfs_exit();
738out_fail_sysfs: 804out_fail_sysfs:
805 unregister_pernet_device(&cfg80211_pernet_ops);
806out_fail_pernet:
739 return err; 807 return err;
740} 808}
741
742subsys_initcall(cfg80211_init); 809subsys_initcall(cfg80211_init);
743 810
744static void cfg80211_exit(void) 811static void cfg80211_exit(void)
@@ -748,5 +815,6 @@ static void cfg80211_exit(void)
748 unregister_netdevice_notifier(&cfg80211_netdev_notifier); 815 unregister_netdevice_notifier(&cfg80211_netdev_notifier);
749 wiphy_sysfs_exit(); 816 wiphy_sysfs_exit();
750 regulatory_exit(); 817 regulatory_exit();
818 unregister_pernet_device(&cfg80211_pernet_ops);
751} 819}
752module_exit(cfg80211_exit); 820module_exit(cfg80211_exit);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 2ec8ddbe57de..6d903c1d721d 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -66,6 +66,9 @@ struct cfg80211_registered_device {
66 struct work_struct conn_work; 66 struct work_struct conn_work;
67 struct work_struct event_work; 67 struct work_struct event_work;
68 68
69 /* current channel */
70 struct ieee80211_channel *channel;
71
69#ifdef CONFIG_CFG80211_DEBUGFS 72#ifdef CONFIG_CFG80211_DEBUGFS
70 /* Debugfs entries */ 73 /* Debugfs entries */
71 struct wiphy_debugfsdentries { 74 struct wiphy_debugfsdentries {
@@ -170,7 +173,10 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
170 173
171/* identical to cfg80211_get_dev_from_info but only operate on ifindex */ 174/* identical to cfg80211_get_dev_from_info but only operate on ifindex */
172extern struct cfg80211_registered_device * 175extern struct cfg80211_registered_device *
173cfg80211_get_dev_from_ifindex(int ifindex); 176cfg80211_get_dev_from_ifindex(struct net *net, int ifindex);
177
178int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
179 struct net *net);
174 180
175static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev) 181static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev)
176{ 182{
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 8b65e212ae49..4d7a084b35e2 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -7,6 +7,7 @@
7#include <linux/etherdevice.h> 7#include <linux/etherdevice.h>
8#include <linux/if_arp.h> 8#include <linux/if_arp.h>
9#include <net/cfg80211.h> 9#include <net/cfg80211.h>
10#include "wext-compat.h"
10#include "nl80211.h" 11#include "nl80211.h"
11 12
12 13
@@ -312,8 +313,6 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
312 313
313 return err; 314 return err;
314} 315}
315/* temporary symbol - mark GPL - in the future the handler won't be */
316EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq);
317 316
318int cfg80211_ibss_wext_giwfreq(struct net_device *dev, 317int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
319 struct iw_request_info *info, 318 struct iw_request_info *info,
@@ -342,8 +341,6 @@ int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
342 /* no channel if not joining */ 341 /* no channel if not joining */
343 return -EINVAL; 342 return -EINVAL;
344} 343}
345/* temporary symbol - mark GPL - in the future the handler won't be */
346EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq);
347 344
348int cfg80211_ibss_wext_siwessid(struct net_device *dev, 345int cfg80211_ibss_wext_siwessid(struct net_device *dev,
349 struct iw_request_info *info, 346 struct iw_request_info *info,
@@ -384,8 +381,6 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev,
384 381
385 return err; 382 return err;
386} 383}
387/* temporary symbol - mark GPL - in the future the handler won't be */
388EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid);
389 384
390int cfg80211_ibss_wext_giwessid(struct net_device *dev, 385int cfg80211_ibss_wext_giwessid(struct net_device *dev,
391 struct iw_request_info *info, 386 struct iw_request_info *info,
@@ -413,8 +408,6 @@ int cfg80211_ibss_wext_giwessid(struct net_device *dev,
413 408
414 return 0; 409 return 0;
415} 410}
416/* temporary symbol - mark GPL - in the future the handler won't be */
417EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid);
418 411
419int cfg80211_ibss_wext_siwap(struct net_device *dev, 412int cfg80211_ibss_wext_siwap(struct net_device *dev,
420 struct iw_request_info *info, 413 struct iw_request_info *info,
@@ -469,8 +462,6 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
469 462
470 return err; 463 return err;
471} 464}
472/* temporary symbol - mark GPL - in the future the handler won't be */
473EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);
474 465
475int cfg80211_ibss_wext_giwap(struct net_device *dev, 466int cfg80211_ibss_wext_giwap(struct net_device *dev,
476 struct iw_request_info *info, 467 struct iw_request_info *info,
@@ -496,6 +487,4 @@ int cfg80211_ibss_wext_giwap(struct net_device *dev,
496 487
497 return 0; 488 return 0;
498} 489}
499/* temporary symbol - mark GPL - in the future the handler won't be */
500EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwap);
501#endif 490#endif
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 5b9b22120824..097a87d7bae1 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -8,7 +8,9 @@
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/netdevice.h> 9#include <linux/netdevice.h>
10#include <linux/nl80211.h> 10#include <linux/nl80211.h>
11#include <linux/wireless.h>
11#include <net/cfg80211.h> 12#include <net/cfg80211.h>
13#include <net/iw_handler.h>
12#include "core.h" 14#include "core.h"
13#include "nl80211.h" 15#include "nl80211.h"
14 16
@@ -545,6 +547,12 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
545 547
546 ASSERT_WDEV_LOCK(wdev); 548 ASSERT_WDEV_LOCK(wdev);
547 549
550 if (wdev->sme_state != CFG80211_SME_CONNECTED)
551 return -ENOTCONN;
552
553 if (WARN_ON(!wdev->current_bss))
554 return -ENOTCONN;
555
548 memset(&req, 0, sizeof(req)); 556 memset(&req, 0, sizeof(req));
549 req.reason_code = reason; 557 req.reason_code = reason;
550 req.ie = ie; 558 req.ie = ie;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index da450ef1fc7e..0cd548267d4a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -14,8 +14,10 @@
14#include <linux/rtnetlink.h> 14#include <linux/rtnetlink.h>
15#include <linux/netlink.h> 15#include <linux/netlink.h>
16#include <linux/etherdevice.h> 16#include <linux/etherdevice.h>
17#include <net/net_namespace.h>
17#include <net/genetlink.h> 18#include <net/genetlink.h>
18#include <net/cfg80211.h> 19#include <net/cfg80211.h>
20#include <net/sock.h>
19#include "core.h" 21#include "core.h"
20#include "nl80211.h" 22#include "nl80211.h"
21#include "reg.h" 23#include "reg.h"
@@ -27,24 +29,26 @@ static struct genl_family nl80211_fam = {
27 .hdrsize = 0, /* no private header */ 29 .hdrsize = 0, /* no private header */
28 .version = 1, /* no particular meaning now */ 30 .version = 1, /* no particular meaning now */
29 .maxattr = NL80211_ATTR_MAX, 31 .maxattr = NL80211_ATTR_MAX,
32 .netnsok = true,
30}; 33};
31 34
32/* internal helper: get rdev and dev */ 35/* internal helper: get rdev and dev */
33static int get_rdev_dev_by_info_ifindex(struct nlattr **attrs, 36static int get_rdev_dev_by_info_ifindex(struct genl_info *info,
34 struct cfg80211_registered_device **rdev, 37 struct cfg80211_registered_device **rdev,
35 struct net_device **dev) 38 struct net_device **dev)
36{ 39{
40 struct nlattr **attrs = info->attrs;
37 int ifindex; 41 int ifindex;
38 42
39 if (!attrs[NL80211_ATTR_IFINDEX]) 43 if (!attrs[NL80211_ATTR_IFINDEX])
40 return -EINVAL; 44 return -EINVAL;
41 45
42 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); 46 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
43 *dev = dev_get_by_index(&init_net, ifindex); 47 *dev = dev_get_by_index(genl_info_net(info), ifindex);
44 if (!*dev) 48 if (!*dev)
45 return -ENODEV; 49 return -ENODEV;
46 50
47 *rdev = cfg80211_get_dev_from_ifindex(ifindex); 51 *rdev = cfg80211_get_dev_from_ifindex(genl_info_net(info), ifindex);
48 if (IS_ERR(*rdev)) { 52 if (IS_ERR(*rdev)) {
49 dev_put(*dev); 53 dev_put(*dev);
50 return PTR_ERR(*rdev); 54 return PTR_ERR(*rdev);
@@ -133,6 +137,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
133 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG }, 137 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
134 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, 138 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
135 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, 139 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
140 [NL80211_ATTR_PID] = { .type = NLA_U32 },
136}; 141};
137 142
138/* policy for the attributes */ 143/* policy for the attributes */
@@ -532,6 +537,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
532 CMD(deauth, DEAUTHENTICATE); 537 CMD(deauth, DEAUTHENTICATE);
533 CMD(disassoc, DISASSOCIATE); 538 CMD(disassoc, DISASSOCIATE);
534 CMD(join_ibss, JOIN_IBSS); 539 CMD(join_ibss, JOIN_IBSS);
540 if (dev->wiphy.netnsok) {
541 i++;
542 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
543 }
535 544
536#undef CMD 545#undef CMD
537 546
@@ -562,6 +571,8 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
562 571
563 mutex_lock(&cfg80211_mutex); 572 mutex_lock(&cfg80211_mutex);
564 list_for_each_entry(dev, &cfg80211_rdev_list, list) { 573 list_for_each_entry(dev, &cfg80211_rdev_list, list) {
574 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
575 continue;
565 if (++idx <= start) 576 if (++idx <= start)
566 continue; 577 continue;
567 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid, 578 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
@@ -746,6 +757,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
746 channel_type); 757 channel_type);
747 if (result) 758 if (result)
748 goto bad_res; 759 goto bad_res;
760
761 rdev->channel = chan;
749 } 762 }
750 763
751 changed = 0; 764 changed = 0;
@@ -867,6 +880,8 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
867 880
868 mutex_lock(&cfg80211_mutex); 881 mutex_lock(&cfg80211_mutex);
869 list_for_each_entry(dev, &cfg80211_rdev_list, list) { 882 list_for_each_entry(dev, &cfg80211_rdev_list, list) {
883 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
884 continue;
870 if (wp_idx < wp_start) { 885 if (wp_idx < wp_start) {
871 wp_idx++; 886 wp_idx++;
872 continue; 887 continue;
@@ -907,7 +922,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
907 struct net_device *netdev; 922 struct net_device *netdev;
908 int err; 923 int err;
909 924
910 err = get_rdev_dev_by_info_ifindex(info->attrs, &dev, &netdev); 925 err = get_rdev_dev_by_info_ifindex(info, &dev, &netdev);
911 if (err) 926 if (err)
912 return err; 927 return err;
913 928
@@ -975,7 +990,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
975 990
976 rtnl_lock(); 991 rtnl_lock();
977 992
978 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 993 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
979 if (err) 994 if (err)
980 goto unlock_rtnl; 995 goto unlock_rtnl;
981 996
@@ -1098,26 +1113,25 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1098static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) 1113static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
1099{ 1114{
1100 struct cfg80211_registered_device *rdev; 1115 struct cfg80211_registered_device *rdev;
1101 int ifindex, err; 1116 int err;
1102 struct net_device *dev; 1117 struct net_device *dev;
1103 1118
1104 rtnl_lock(); 1119 rtnl_lock();
1105 1120
1106 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1121 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1107 if (err) 1122 if (err)
1108 goto unlock_rtnl; 1123 goto unlock_rtnl;
1109 ifindex = dev->ifindex;
1110 dev_put(dev);
1111 1124
1112 if (!rdev->ops->del_virtual_intf) { 1125 if (!rdev->ops->del_virtual_intf) {
1113 err = -EOPNOTSUPP; 1126 err = -EOPNOTSUPP;
1114 goto out; 1127 goto out;
1115 } 1128 }
1116 1129
1117 err = rdev->ops->del_virtual_intf(&rdev->wiphy, ifindex); 1130 err = rdev->ops->del_virtual_intf(&rdev->wiphy, dev);
1118 1131
1119 out: 1132 out:
1120 cfg80211_unlock_rdev(rdev); 1133 cfg80211_unlock_rdev(rdev);
1134 dev_put(dev);
1121 unlock_rtnl: 1135 unlock_rtnl:
1122 rtnl_unlock(); 1136 rtnl_unlock();
1123 return err; 1137 return err;
@@ -1195,7 +1209,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1195 1209
1196 rtnl_lock(); 1210 rtnl_lock();
1197 1211
1198 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1212 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1199 if (err) 1213 if (err)
1200 goto unlock_rtnl; 1214 goto unlock_rtnl;
1201 1215
@@ -1274,7 +1288,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1274 1288
1275 rtnl_lock(); 1289 rtnl_lock();
1276 1290
1277 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1291 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1278 if (err) 1292 if (err)
1279 goto unlock_rtnl; 1293 goto unlock_rtnl;
1280 1294
@@ -1333,7 +1347,7 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1333 1347
1334 rtnl_lock(); 1348 rtnl_lock();
1335 1349
1336 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1350 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1337 if (err) 1351 if (err)
1338 goto unlock_rtnl; 1352 goto unlock_rtnl;
1339 1353
@@ -1380,7 +1394,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1380 1394
1381 rtnl_lock(); 1395 rtnl_lock();
1382 1396
1383 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1397 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1384 if (err) 1398 if (err)
1385 goto unlock_rtnl; 1399 goto unlock_rtnl;
1386 1400
@@ -1429,7 +1443,7 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1429 1443
1430 rtnl_lock(); 1444 rtnl_lock();
1431 1445
1432 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1446 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1433 if (err) 1447 if (err)
1434 goto unlock_rtnl; 1448 goto unlock_rtnl;
1435 1449
@@ -1516,7 +1530,7 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1516 1530
1517 rtnl_lock(); 1531 rtnl_lock();
1518 1532
1519 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1533 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1520 if (err) 1534 if (err)
1521 goto unlock_rtnl; 1535 goto unlock_rtnl;
1522 1536
@@ -1726,13 +1740,13 @@ static int nl80211_dump_station(struct sk_buff *skb,
1726 1740
1727 rtnl_lock(); 1741 rtnl_lock();
1728 1742
1729 netdev = __dev_get_by_index(&init_net, ifidx); 1743 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
1730 if (!netdev) { 1744 if (!netdev) {
1731 err = -ENODEV; 1745 err = -ENODEV;
1732 goto out_rtnl; 1746 goto out_rtnl;
1733 } 1747 }
1734 1748
1735 dev = cfg80211_get_dev_from_ifindex(ifidx); 1749 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
1736 if (IS_ERR(dev)) { 1750 if (IS_ERR(dev)) {
1737 err = PTR_ERR(dev); 1751 err = PTR_ERR(dev);
1738 goto out_rtnl; 1752 goto out_rtnl;
@@ -1791,7 +1805,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1791 1805
1792 rtnl_lock(); 1806 rtnl_lock();
1793 1807
1794 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1808 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1795 if (err) 1809 if (err)
1796 goto out_rtnl; 1810 goto out_rtnl;
1797 1811
@@ -1829,14 +1843,16 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1829/* 1843/*
1830 * Get vlan interface making sure it is on the right wiphy. 1844 * Get vlan interface making sure it is on the right wiphy.
1831 */ 1845 */
1832static int get_vlan(struct nlattr *vlanattr, 1846static int get_vlan(struct genl_info *info,
1833 struct cfg80211_registered_device *rdev, 1847 struct cfg80211_registered_device *rdev,
1834 struct net_device **vlan) 1848 struct net_device **vlan)
1835{ 1849{
1850 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
1836 *vlan = NULL; 1851 *vlan = NULL;
1837 1852
1838 if (vlanattr) { 1853 if (vlanattr) {
1839 *vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr)); 1854 *vlan = dev_get_by_index(genl_info_net(info),
1855 nla_get_u32(vlanattr));
1840 if (!*vlan) 1856 if (!*vlan)
1841 return -ENODEV; 1857 return -ENODEV;
1842 if (!(*vlan)->ieee80211_ptr) 1858 if (!(*vlan)->ieee80211_ptr)
@@ -1891,11 +1907,11 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1891 1907
1892 rtnl_lock(); 1908 rtnl_lock();
1893 1909
1894 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1910 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1895 if (err) 1911 if (err)
1896 goto out_rtnl; 1912 goto out_rtnl;
1897 1913
1898 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], rdev, &params.vlan); 1914 err = get_vlan(info, rdev, &params.vlan);
1899 if (err) 1915 if (err)
1900 goto out; 1916 goto out;
1901 1917
@@ -2004,11 +2020,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2004 2020
2005 rtnl_lock(); 2021 rtnl_lock();
2006 2022
2007 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2023 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2008 if (err) 2024 if (err)
2009 goto out_rtnl; 2025 goto out_rtnl;
2010 2026
2011 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], rdev, &params.vlan); 2027 err = get_vlan(info, rdev, &params.vlan);
2012 if (err) 2028 if (err)
2013 goto out; 2029 goto out;
2014 2030
@@ -2079,7 +2095,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
2079 2095
2080 rtnl_lock(); 2096 rtnl_lock();
2081 2097
2082 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2098 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2083 if (err) 2099 if (err)
2084 goto out_rtnl; 2100 goto out_rtnl;
2085 2101
@@ -2185,13 +2201,13 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
2185 2201
2186 rtnl_lock(); 2202 rtnl_lock();
2187 2203
2188 netdev = __dev_get_by_index(&init_net, ifidx); 2204 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
2189 if (!netdev) { 2205 if (!netdev) {
2190 err = -ENODEV; 2206 err = -ENODEV;
2191 goto out_rtnl; 2207 goto out_rtnl;
2192 } 2208 }
2193 2209
2194 dev = cfg80211_get_dev_from_ifindex(ifidx); 2210 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
2195 if (IS_ERR(dev)) { 2211 if (IS_ERR(dev)) {
2196 err = PTR_ERR(dev); 2212 err = PTR_ERR(dev);
2197 goto out_rtnl; 2213 goto out_rtnl;
@@ -2255,7 +2271,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
2255 2271
2256 rtnl_lock(); 2272 rtnl_lock();
2257 2273
2258 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2274 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2259 if (err) 2275 if (err)
2260 goto out_rtnl; 2276 goto out_rtnl;
2261 2277
@@ -2314,7 +2330,7 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
2314 2330
2315 rtnl_lock(); 2331 rtnl_lock();
2316 2332
2317 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2333 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2318 if (err) 2334 if (err)
2319 goto out_rtnl; 2335 goto out_rtnl;
2320 2336
@@ -2362,7 +2378,7 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
2362 2378
2363 rtnl_lock(); 2379 rtnl_lock();
2364 2380
2365 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2381 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2366 if (err) 2382 if (err)
2367 goto out_rtnl; 2383 goto out_rtnl;
2368 2384
@@ -2404,7 +2420,7 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
2404 2420
2405 rtnl_lock(); 2421 rtnl_lock();
2406 2422
2407 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2423 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2408 if (err) 2424 if (err)
2409 goto out_rtnl; 2425 goto out_rtnl;
2410 2426
@@ -2455,7 +2471,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
2455 2471
2456 rtnl_lock(); 2472 rtnl_lock();
2457 2473
2458 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2474 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2459 if (err) 2475 if (err)
2460 goto out_rtnl; 2476 goto out_rtnl;
2461 2477
@@ -2574,7 +2590,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2574 rtnl_lock(); 2590 rtnl_lock();
2575 2591
2576 /* Look up our device */ 2592 /* Look up our device */
2577 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2593 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2578 if (err) 2594 if (err)
2579 goto out_rtnl; 2595 goto out_rtnl;
2580 2596
@@ -2691,7 +2707,7 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2691 2707
2692 rtnl_lock(); 2708 rtnl_lock();
2693 2709
2694 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2710 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2695 if (err) 2711 if (err)
2696 goto out_rtnl; 2712 goto out_rtnl;
2697 2713
@@ -2947,7 +2963,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2947 2963
2948 rtnl_lock(); 2964 rtnl_lock();
2949 2965
2950 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2966 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2951 if (err) 2967 if (err)
2952 goto out_rtnl; 2968 goto out_rtnl;
2953 2969
@@ -3069,14 +3085,16 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3069 request->ie_len); 3085 request->ie_len);
3070 } 3086 }
3071 3087
3072 request->ifidx = dev->ifindex; 3088 request->dev = dev;
3073 request->wiphy = &rdev->wiphy; 3089 request->wiphy = &rdev->wiphy;
3074 3090
3075 rdev->scan_req = request; 3091 rdev->scan_req = request;
3076 err = rdev->ops->scan(&rdev->wiphy, dev, request); 3092 err = rdev->ops->scan(&rdev->wiphy, dev, request);
3077 3093
3078 if (!err) 3094 if (!err) {
3079 nl80211_send_scan_start(rdev, dev); 3095 nl80211_send_scan_start(rdev, dev);
3096 dev_hold(dev);
3097 }
3080 3098
3081 out_free: 3099 out_free:
3082 if (err) { 3100 if (err) {
@@ -3198,11 +3216,11 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3198 cb->args[0] = ifidx; 3216 cb->args[0] = ifidx;
3199 } 3217 }
3200 3218
3201 dev = dev_get_by_index(&init_net, ifidx); 3219 dev = dev_get_by_index(sock_net(skb->sk), ifidx);
3202 if (!dev) 3220 if (!dev)
3203 return -ENODEV; 3221 return -ENODEV;
3204 3222
3205 rdev = cfg80211_get_dev_from_ifindex(ifidx); 3223 rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
3206 if (IS_ERR(rdev)) { 3224 if (IS_ERR(rdev)) {
3207 err = PTR_ERR(rdev); 3225 err = PTR_ERR(rdev);
3208 goto out_put_netdev; 3226 goto out_put_netdev;
@@ -3312,7 +3330,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3312 3330
3313 rtnl_lock(); 3331 rtnl_lock();
3314 3332
3315 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3333 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3316 if (err) 3334 if (err)
3317 goto unlock_rtnl; 3335 goto unlock_rtnl;
3318 3336
@@ -3369,6 +3387,8 @@ static int nl80211_crypto_settings(struct genl_info *info,
3369 struct cfg80211_crypto_settings *settings, 3387 struct cfg80211_crypto_settings *settings,
3370 int cipher_limit) 3388 int cipher_limit)
3371{ 3389{
3390 memset(settings, 0, sizeof(*settings));
3391
3372 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT]; 3392 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
3373 3393
3374 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) { 3394 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
@@ -3448,7 +3468,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3448 3468
3449 rtnl_lock(); 3469 rtnl_lock();
3450 3470
3451 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3471 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3452 if (err) 3472 if (err)
3453 goto unlock_rtnl; 3473 goto unlock_rtnl;
3454 3474
@@ -3531,7 +3551,7 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
3531 3551
3532 rtnl_lock(); 3552 rtnl_lock();
3533 3553
3534 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3554 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3535 if (err) 3555 if (err)
3536 goto unlock_rtnl; 3556 goto unlock_rtnl;
3537 3557
@@ -3593,7 +3613,7 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
3593 3613
3594 rtnl_lock(); 3614 rtnl_lock();
3595 3615
3596 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3616 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3597 if (err) 3617 if (err)
3598 goto unlock_rtnl; 3618 goto unlock_rtnl;
3599 3619
@@ -3666,7 +3686,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
3666 3686
3667 rtnl_lock(); 3687 rtnl_lock();
3668 3688
3669 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3689 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3670 if (err) 3690 if (err)
3671 goto unlock_rtnl; 3691 goto unlock_rtnl;
3672 3692
@@ -3739,7 +3759,7 @@ static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
3739 3759
3740 rtnl_lock(); 3760 rtnl_lock();
3741 3761
3742 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3762 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3743 if (err) 3763 if (err)
3744 goto unlock_rtnl; 3764 goto unlock_rtnl;
3745 3765
@@ -3924,7 +3944,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
3924 return err; 3944 return err;
3925 rtnl_lock(); 3945 rtnl_lock();
3926 3946
3927 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3947 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3928 if (err) 3948 if (err)
3929 goto unlock_rtnl; 3949 goto unlock_rtnl;
3930 3950
@@ -4000,7 +4020,7 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
4000 4020
4001 rtnl_lock(); 4021 rtnl_lock();
4002 4022
4003 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 4023 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4004 if (err) 4024 if (err)
4005 goto unlock_rtnl; 4025 goto unlock_rtnl;
4006 4026
@@ -4024,6 +4044,47 @@ unlock_rtnl:
4024 return err; 4044 return err;
4025} 4045}
4026 4046
4047static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
4048{
4049 struct cfg80211_registered_device *rdev;
4050 struct net *net;
4051 int err;
4052 u32 pid;
4053
4054 if (!info->attrs[NL80211_ATTR_PID])
4055 return -EINVAL;
4056
4057 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
4058
4059 rtnl_lock();
4060
4061 rdev = cfg80211_get_dev_from_info(info);
4062 if (IS_ERR(rdev)) {
4063 err = PTR_ERR(rdev);
4064 goto out;
4065 }
4066
4067 net = get_net_ns_by_pid(pid);
4068 if (IS_ERR(net)) {
4069 err = PTR_ERR(net);
4070 goto out;
4071 }
4072
4073 err = 0;
4074
4075 /* check if anything to do */
4076 if (net_eq(wiphy_net(&rdev->wiphy), net))
4077 goto out_put_net;
4078
4079 err = cfg80211_switch_netns(rdev, net);
4080 out_put_net:
4081 put_net(net);
4082 out:
4083 cfg80211_unlock_rdev(rdev);
4084 rtnl_unlock();
4085 return err;
4086}
4087
4027static struct genl_ops nl80211_ops[] = { 4088static struct genl_ops nl80211_ops[] = {
4028 { 4089 {
4029 .cmd = NL80211_CMD_GET_WIPHY, 4090 .cmd = NL80211_CMD_GET_WIPHY,
@@ -4257,6 +4318,12 @@ static struct genl_ops nl80211_ops[] = {
4257 .policy = nl80211_policy, 4318 .policy = nl80211_policy,
4258 .flags = GENL_ADMIN_PERM, 4319 .flags = GENL_ADMIN_PERM,
4259 }, 4320 },
4321 {
4322 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
4323 .doit = nl80211_wiphy_netns,
4324 .policy = nl80211_policy,
4325 .flags = GENL_ADMIN_PERM,
4326 },
4260}; 4327};
4261static struct genl_multicast_group nl80211_mlme_mcgrp = { 4328static struct genl_multicast_group nl80211_mlme_mcgrp = {
4262 .name = "mlme", 4329 .name = "mlme",
@@ -4288,7 +4355,8 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
4288 return; 4355 return;
4289 } 4356 }
4290 4357
4291 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); 4358 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4359 nl80211_config_mcgrp.id, GFP_KERNEL);
4292} 4360}
4293 4361
4294static int nl80211_add_scan_req(struct sk_buff *msg, 4362static int nl80211_add_scan_req(struct sk_buff *msg,
@@ -4365,7 +4433,8 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
4365 return; 4433 return;
4366 } 4434 }
4367 4435
4368 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL); 4436 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4437 nl80211_scan_mcgrp.id, GFP_KERNEL);
4369} 4438}
4370 4439
4371void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, 4440void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
@@ -4383,7 +4452,8 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
4383 return; 4452 return;
4384 } 4453 }
4385 4454
4386 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL); 4455 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4456 nl80211_scan_mcgrp.id, GFP_KERNEL);
4387} 4457}
4388 4458
4389void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, 4459void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
@@ -4401,7 +4471,8 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
4401 return; 4471 return;
4402 } 4472 }
4403 4473
4404 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL); 4474 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4475 nl80211_scan_mcgrp.id, GFP_KERNEL);
4405} 4476}
4406 4477
4407/* 4478/*
@@ -4450,7 +4521,10 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
4450 return; 4521 return;
4451 } 4522 }
4452 4523
4453 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_KERNEL); 4524 rcu_read_lock();
4525 genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
4526 GFP_ATOMIC);
4527 rcu_read_unlock();
4454 4528
4455 return; 4529 return;
4456 4530
@@ -4486,7 +4560,8 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
4486 return; 4560 return;
4487 } 4561 }
4488 4562
4489 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4563 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4564 nl80211_mlme_mcgrp.id, gfp);
4490 return; 4565 return;
4491 4566
4492 nla_put_failure: 4567 nla_put_failure:
@@ -4553,7 +4628,8 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
4553 return; 4628 return;
4554 } 4629 }
4555 4630
4556 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4631 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4632 nl80211_mlme_mcgrp.id, gfp);
4557 return; 4633 return;
4558 4634
4559 nla_put_failure: 4635 nla_put_failure:
@@ -4611,7 +4687,8 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
4611 return; 4687 return;
4612 } 4688 }
4613 4689
4614 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4690 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4691 nl80211_mlme_mcgrp.id, gfp);
4615 return; 4692 return;
4616 4693
4617 nla_put_failure: 4694 nla_put_failure:
@@ -4651,7 +4728,8 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
4651 return; 4728 return;
4652 } 4729 }
4653 4730
4654 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4731 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4732 nl80211_mlme_mcgrp.id, gfp);
4655 return; 4733 return;
4656 4734
4657 nla_put_failure: 4735 nla_put_failure:
@@ -4691,7 +4769,8 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
4691 return; 4769 return;
4692 } 4770 }
4693 4771
4694 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL); 4772 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4773 nl80211_mlme_mcgrp.id, GFP_KERNEL);
4695 return; 4774 return;
4696 4775
4697 nla_put_failure: 4776 nla_put_failure:
@@ -4726,7 +4805,8 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
4726 return; 4805 return;
4727 } 4806 }
4728 4807
4729 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4808 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4809 nl80211_mlme_mcgrp.id, gfp);
4730 return; 4810 return;
4731 4811
4732 nla_put_failure: 4812 nla_put_failure:
@@ -4766,7 +4846,8 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
4766 return; 4846 return;
4767 } 4847 }
4768 4848
4769 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4849 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4850 nl80211_mlme_mcgrp.id, gfp);
4770 return; 4851 return;
4771 4852
4772 nla_put_failure: 4853 nla_put_failure:
@@ -4819,7 +4900,10 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
4819 return; 4900 return;
4820 } 4901 }
4821 4902
4822 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC); 4903 rcu_read_lock();
4904 genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
4905 GFP_ATOMIC);
4906 rcu_read_unlock();
4823 4907
4824 return; 4908 return;
4825 4909
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index decc59fe0ee8..67714d7ed5b4 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -14,8 +14,9 @@
14#include <net/iw_handler.h> 14#include <net/iw_handler.h>
15#include "core.h" 15#include "core.h"
16#include "nl80211.h" 16#include "nl80211.h"
17#include "wext-compat.h"
17 18
18#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ) 19#define IEEE80211_SCAN_RESULT_EXPIRE (15 * HZ)
19 20
20void __cfg80211_scan_done(struct work_struct *wk) 21void __cfg80211_scan_done(struct work_struct *wk)
21{ 22{
@@ -32,9 +33,7 @@ void __cfg80211_scan_done(struct work_struct *wk)
32 mutex_lock(&rdev->mtx); 33 mutex_lock(&rdev->mtx);
33 request = rdev->scan_req; 34 request = rdev->scan_req;
34 35
35 dev = dev_get_by_index(&init_net, request->ifidx); 36 dev = request->dev;
36 if (!dev)
37 goto out;
38 37
39 /* 38 /*
40 * This must be before sending the other events! 39 * This must be before sending the other events!
@@ -58,7 +57,6 @@ void __cfg80211_scan_done(struct work_struct *wk)
58 57
59 dev_put(dev); 58 dev_put(dev);
60 59
61 out:
62 cfg80211_unlock_rdev(rdev); 60 cfg80211_unlock_rdev(rdev);
63 wiphy_to_dev(request->wiphy)->scan_req = NULL; 61 wiphy_to_dev(request->wiphy)->scan_req = NULL;
64 kfree(request); 62 kfree(request);
@@ -66,17 +64,10 @@ void __cfg80211_scan_done(struct work_struct *wk)
66 64
67void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) 65void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
68{ 66{
69 struct net_device *dev = dev_get_by_index(&init_net, request->ifidx);
70 if (WARN_ON(!dev)) {
71 kfree(request);
72 return;
73 }
74
75 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); 67 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
76 68
77 request->aborted = aborted; 69 request->aborted = aborted;
78 schedule_work(&wiphy_to_dev(request->wiphy)->scan_done_wk); 70 schedule_work(&wiphy_to_dev(request->wiphy)->scan_done_wk);
79 dev_put(dev);
80} 71}
81EXPORT_SYMBOL(cfg80211_scan_done); 72EXPORT_SYMBOL(cfg80211_scan_done);
82 73
@@ -592,7 +583,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
592 if (!netif_running(dev)) 583 if (!netif_running(dev))
593 return -ENETDOWN; 584 return -ENETDOWN;
594 585
595 rdev = cfg80211_get_dev_from_ifindex(dev->ifindex); 586 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
596 587
597 if (IS_ERR(rdev)) 588 if (IS_ERR(rdev))
598 return PTR_ERR(rdev); 589 return PTR_ERR(rdev);
@@ -617,7 +608,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
617 } 608 }
618 609
619 creq->wiphy = wiphy; 610 creq->wiphy = wiphy;
620 creq->ifidx = dev->ifindex; 611 creq->dev = dev;
621 creq->ssids = (void *)(creq + 1); 612 creq->ssids = (void *)(creq + 1);
622 creq->channels = (void *)(creq->ssids + 1); 613 creq->channels = (void *)(creq->ssids + 1);
623 creq->n_channels = n_channels; 614 creq->n_channels = n_channels;
@@ -654,8 +645,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
654 if (err) { 645 if (err) {
655 rdev->scan_req = NULL; 646 rdev->scan_req = NULL;
656 kfree(creq); 647 kfree(creq);
657 } else 648 } else {
658 nl80211_send_scan_start(rdev, dev); 649 nl80211_send_scan_start(rdev, dev);
650 dev_hold(dev);
651 }
659 out: 652 out:
660 cfg80211_unlock_rdev(rdev); 653 cfg80211_unlock_rdev(rdev);
661 return err; 654 return err;
@@ -948,7 +941,7 @@ int cfg80211_wext_giwscan(struct net_device *dev,
948 if (!netif_running(dev)) 941 if (!netif_running(dev))
949 return -ENETDOWN; 942 return -ENETDOWN;
950 943
951 rdev = cfg80211_get_dev_from_ifindex(dev->ifindex); 944 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
952 945
953 if (IS_ERR(rdev)) 946 if (IS_ERR(rdev))
954 return PTR_ERR(rdev); 947 return PTR_ERR(rdev);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 82de2d9795f4..d2b5d4ce0a00 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -8,6 +8,8 @@
8#include <linux/etherdevice.h> 8#include <linux/etherdevice.h>
9#include <linux/if_arp.h> 9#include <linux/if_arp.h>
10#include <linux/workqueue.h> 10#include <linux/workqueue.h>
11#include <linux/wireless.h>
12#include <net/iw_handler.h>
11#include <net/cfg80211.h> 13#include <net/cfg80211.h>
12#include <net/rtnetlink.h> 14#include <net/rtnetlink.h>
13#include "nl80211.h" 15#include "nl80211.h"
@@ -86,7 +88,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
86 wdev->conn->params.ssid_len); 88 wdev->conn->params.ssid_len);
87 request->ssids[0].ssid_len = wdev->conn->params.ssid_len; 89 request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
88 90
89 request->ifidx = wdev->netdev->ifindex; 91 request->dev = wdev->netdev;
90 request->wiphy = &rdev->wiphy; 92 request->wiphy = &rdev->wiphy;
91 93
92 rdev->scan_req = request; 94 rdev->scan_req = request;
@@ -95,6 +97,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
95 if (!err) { 97 if (!err) {
96 wdev->conn->state = CFG80211_CONN_SCANNING; 98 wdev->conn->state = CFG80211_CONN_SCANNING;
97 nl80211_send_scan_start(rdev, wdev->netdev); 99 nl80211_send_scan_start(rdev, wdev->netdev);
100 dev_hold(wdev->netdev);
98 } else { 101 } else {
99 rdev->scan_req = NULL; 102 rdev->scan_req = NULL;
100 kfree(request); 103 kfree(request);
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index c7351a98e660..e4e90e249bab 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -14,6 +14,7 @@
14#include <linux/etherdevice.h> 14#include <linux/etherdevice.h>
15#include <net/iw_handler.h> 15#include <net/iw_handler.h>
16#include <net/cfg80211.h> 16#include <net/cfg80211.h>
17#include "wext-compat.h"
17#include "core.h" 18#include "core.h"
18 19
19int cfg80211_wext_giwname(struct net_device *dev, 20int cfg80211_wext_giwname(struct net_device *dev,
@@ -300,7 +301,6 @@ struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
300 return ERR_PTR(-EINVAL); 301 return ERR_PTR(-EINVAL);
301 return chan; 302 return chan;
302} 303}
303EXPORT_SYMBOL_GPL(cfg80211_wext_freq);
304 304
305int cfg80211_wext_siwrts(struct net_device *dev, 305int cfg80211_wext_siwrts(struct net_device *dev,
306 struct iw_request_info *info, 306 struct iw_request_info *info,
@@ -759,6 +759,58 @@ int cfg80211_wext_giwencode(struct net_device *dev,
759} 759}
760EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode); 760EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
761 761
762int cfg80211_wext_siwfreq(struct net_device *dev,
763 struct iw_request_info *info,
764 struct iw_freq *freq, char *extra)
765{
766 struct wireless_dev *wdev = dev->ieee80211_ptr;
767 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
768 struct ieee80211_channel *chan;
769 int err;
770
771 switch (wdev->iftype) {
772 case NL80211_IFTYPE_STATION:
773 return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra);
774 case NL80211_IFTYPE_ADHOC:
775 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
776 default:
777 chan = cfg80211_wext_freq(wdev->wiphy, freq);
778 if (!chan)
779 return -EINVAL;
780 if (IS_ERR(chan))
781 return PTR_ERR(chan);
782 err = rdev->ops->set_channel(wdev->wiphy, chan,
783 NL80211_CHAN_NO_HT);
784 if (err)
785 return err;
786 rdev->channel = chan;
787 return 0;
788 }
789}
790EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq);
791
792int cfg80211_wext_giwfreq(struct net_device *dev,
793 struct iw_request_info *info,
794 struct iw_freq *freq, char *extra)
795{
796 struct wireless_dev *wdev = dev->ieee80211_ptr;
797 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
798
799 switch (wdev->iftype) {
800 case NL80211_IFTYPE_STATION:
801 return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
802 case NL80211_IFTYPE_ADHOC:
803 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
804 default:
805 if (!rdev->channel)
806 return -EINVAL;
807 freq->m = rdev->channel->center_freq;
808 freq->e = 6;
809 return 0;
810 }
811}
812EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq);
813
762int cfg80211_wext_siwtxpower(struct net_device *dev, 814int cfg80211_wext_siwtxpower(struct net_device *dev,
763 struct iw_request_info *info, 815 struct iw_request_info *info,
764 union iwreq_data *data, char *extra) 816 union iwreq_data *data, char *extra)
@@ -1097,9 +1149,9 @@ int cfg80211_wext_giwpower(struct net_device *dev,
1097} 1149}
1098EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower); 1150EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
1099 1151
1100int cfg80211_wds_wext_siwap(struct net_device *dev, 1152static int cfg80211_wds_wext_siwap(struct net_device *dev,
1101 struct iw_request_info *info, 1153 struct iw_request_info *info,
1102 struct sockaddr *addr, char *extra) 1154 struct sockaddr *addr, char *extra)
1103{ 1155{
1104 struct wireless_dev *wdev = dev->ieee80211_ptr; 1156 struct wireless_dev *wdev = dev->ieee80211_ptr;
1105 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1157 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1125,11 +1177,10 @@ int cfg80211_wds_wext_siwap(struct net_device *dev,
1125 1177
1126 return 0; 1178 return 0;
1127} 1179}
1128EXPORT_SYMBOL_GPL(cfg80211_wds_wext_siwap);
1129 1180
1130int cfg80211_wds_wext_giwap(struct net_device *dev, 1181static int cfg80211_wds_wext_giwap(struct net_device *dev,
1131 struct iw_request_info *info, 1182 struct iw_request_info *info,
1132 struct sockaddr *addr, char *extra) 1183 struct sockaddr *addr, char *extra)
1133{ 1184{
1134 struct wireless_dev *wdev = dev->ieee80211_ptr; 1185 struct wireless_dev *wdev = dev->ieee80211_ptr;
1135 1186
@@ -1141,7 +1192,6 @@ int cfg80211_wds_wext_giwap(struct net_device *dev,
1141 1192
1142 return 0; 1193 return 0;
1143} 1194}
1144EXPORT_SYMBOL_GPL(cfg80211_wds_wext_giwap);
1145 1195
1146int cfg80211_wext_siwrate(struct net_device *dev, 1196int cfg80211_wext_siwrate(struct net_device *dev,
1147 struct iw_request_info *info, 1197 struct iw_request_info *info,
@@ -1275,3 +1325,115 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1275 return &wstats; 1325 return &wstats;
1276} 1326}
1277EXPORT_SYMBOL_GPL(cfg80211_wireless_stats); 1327EXPORT_SYMBOL_GPL(cfg80211_wireless_stats);
1328
1329int cfg80211_wext_siwap(struct net_device *dev,
1330 struct iw_request_info *info,
1331 struct sockaddr *ap_addr, char *extra)
1332{
1333 struct wireless_dev *wdev = dev->ieee80211_ptr;
1334
1335 switch (wdev->iftype) {
1336 case NL80211_IFTYPE_ADHOC:
1337 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
1338 case NL80211_IFTYPE_STATION:
1339 return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
1340 case NL80211_IFTYPE_WDS:
1341 return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra);
1342 default:
1343 return -EOPNOTSUPP;
1344 }
1345}
1346EXPORT_SYMBOL_GPL(cfg80211_wext_siwap);
1347
1348int cfg80211_wext_giwap(struct net_device *dev,
1349 struct iw_request_info *info,
1350 struct sockaddr *ap_addr, char *extra)
1351{
1352 struct wireless_dev *wdev = dev->ieee80211_ptr;
1353
1354 switch (wdev->iftype) {
1355 case NL80211_IFTYPE_ADHOC:
1356 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
1357 case NL80211_IFTYPE_STATION:
1358 return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
1359 case NL80211_IFTYPE_WDS:
1360 return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra);
1361 default:
1362 return -EOPNOTSUPP;
1363 }
1364}
1365EXPORT_SYMBOL_GPL(cfg80211_wext_giwap);
1366
1367int cfg80211_wext_siwessid(struct net_device *dev,
1368 struct iw_request_info *info,
1369 struct iw_point *data, char *ssid)
1370{
1371 struct wireless_dev *wdev = dev->ieee80211_ptr;
1372
1373 switch (wdev->iftype) {
1374 case NL80211_IFTYPE_ADHOC:
1375 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
1376 case NL80211_IFTYPE_STATION:
1377 return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
1378 default:
1379 return -EOPNOTSUPP;
1380 }
1381}
1382EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid);
1383
1384int cfg80211_wext_giwessid(struct net_device *dev,
1385 struct iw_request_info *info,
1386 struct iw_point *data, char *ssid)
1387{
1388 struct wireless_dev *wdev = dev->ieee80211_ptr;
1389
1390 switch (wdev->iftype) {
1391 case NL80211_IFTYPE_ADHOC:
1392 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
1393 case NL80211_IFTYPE_STATION:
1394 return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
1395 default:
1396 return -EOPNOTSUPP;
1397 }
1398}
1399EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid);
1400
1401static const iw_handler cfg80211_handlers[] = {
1402 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname,
1403 [IW_IOCTL_IDX(SIOCSIWFREQ)] = (iw_handler) cfg80211_wext_siwfreq,
1404 [IW_IOCTL_IDX(SIOCGIWFREQ)] = (iw_handler) cfg80211_wext_giwfreq,
1405 [IW_IOCTL_IDX(SIOCSIWMODE)] = (iw_handler) cfg80211_wext_siwmode,
1406 [IW_IOCTL_IDX(SIOCGIWMODE)] = (iw_handler) cfg80211_wext_giwmode,
1407 [IW_IOCTL_IDX(SIOCGIWRANGE)] = (iw_handler) cfg80211_wext_giwrange,
1408 [IW_IOCTL_IDX(SIOCSIWAP)] = (iw_handler) cfg80211_wext_siwap,
1409 [IW_IOCTL_IDX(SIOCGIWAP)] = (iw_handler) cfg80211_wext_giwap,
1410 [IW_IOCTL_IDX(SIOCSIWMLME)] = (iw_handler) cfg80211_wext_siwmlme,
1411 [IW_IOCTL_IDX(SIOCSIWSCAN)] = (iw_handler) cfg80211_wext_siwscan,
1412 [IW_IOCTL_IDX(SIOCGIWSCAN)] = (iw_handler) cfg80211_wext_giwscan,
1413 [IW_IOCTL_IDX(SIOCSIWESSID)] = (iw_handler) cfg80211_wext_siwessid,
1414 [IW_IOCTL_IDX(SIOCGIWESSID)] = (iw_handler) cfg80211_wext_giwessid,
1415 [IW_IOCTL_IDX(SIOCSIWRATE)] = (iw_handler) cfg80211_wext_siwrate,
1416 [IW_IOCTL_IDX(SIOCGIWRATE)] = (iw_handler) cfg80211_wext_giwrate,
1417 [IW_IOCTL_IDX(SIOCSIWRTS)] = (iw_handler) cfg80211_wext_siwrts,
1418 [IW_IOCTL_IDX(SIOCGIWRTS)] = (iw_handler) cfg80211_wext_giwrts,
1419 [IW_IOCTL_IDX(SIOCSIWFRAG)] = (iw_handler) cfg80211_wext_siwfrag,
1420 [IW_IOCTL_IDX(SIOCGIWFRAG)] = (iw_handler) cfg80211_wext_giwfrag,
1421 [IW_IOCTL_IDX(SIOCSIWTXPOW)] = (iw_handler) cfg80211_wext_siwtxpower,
1422 [IW_IOCTL_IDX(SIOCGIWTXPOW)] = (iw_handler) cfg80211_wext_giwtxpower,
1423 [IW_IOCTL_IDX(SIOCSIWRETRY)] = (iw_handler) cfg80211_wext_siwretry,
1424 [IW_IOCTL_IDX(SIOCGIWRETRY)] = (iw_handler) cfg80211_wext_giwretry,
1425 [IW_IOCTL_IDX(SIOCSIWENCODE)] = (iw_handler) cfg80211_wext_siwencode,
1426 [IW_IOCTL_IDX(SIOCGIWENCODE)] = (iw_handler) cfg80211_wext_giwencode,
1427 [IW_IOCTL_IDX(SIOCSIWPOWER)] = (iw_handler) cfg80211_wext_siwpower,
1428 [IW_IOCTL_IDX(SIOCGIWPOWER)] = (iw_handler) cfg80211_wext_giwpower,
1429 [IW_IOCTL_IDX(SIOCSIWGENIE)] = (iw_handler) cfg80211_wext_siwgenie,
1430 [IW_IOCTL_IDX(SIOCSIWAUTH)] = (iw_handler) cfg80211_wext_siwauth,
1431 [IW_IOCTL_IDX(SIOCGIWAUTH)] = (iw_handler) cfg80211_wext_giwauth,
1432 [IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= (iw_handler) cfg80211_wext_siwencodeext,
1433};
1434
1435const struct iw_handler_def cfg80211_wext_handler = {
1436 .num_standard = ARRAY_SIZE(cfg80211_handlers),
1437 .standard = cfg80211_handlers,
1438 .get_wireless_stats = cfg80211_wireless_stats,
1439};
diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h
new file mode 100644
index 000000000000..9a3774749589
--- /dev/null
+++ b/net/wireless/wext-compat.h
@@ -0,0 +1,50 @@
1#ifndef __WEXT_COMPAT
2#define __WEXT_COMPAT
3
4#include <net/iw_handler.h>
5#include <linux/wireless.h>
6
7int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
8 struct iw_request_info *info,
9 struct iw_freq *freq, char *extra);
10int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
11 struct iw_request_info *info,
12 struct iw_freq *freq, char *extra);
13int cfg80211_ibss_wext_siwap(struct net_device *dev,
14 struct iw_request_info *info,
15 struct sockaddr *ap_addr, char *extra);
16int cfg80211_ibss_wext_giwap(struct net_device *dev,
17 struct iw_request_info *info,
18 struct sockaddr *ap_addr, char *extra);
19int cfg80211_ibss_wext_siwessid(struct net_device *dev,
20 struct iw_request_info *info,
21 struct iw_point *data, char *ssid);
22int cfg80211_ibss_wext_giwessid(struct net_device *dev,
23 struct iw_request_info *info,
24 struct iw_point *data, char *ssid);
25
26int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
27 struct iw_request_info *info,
28 struct iw_freq *freq, char *extra);
29int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
30 struct iw_request_info *info,
31 struct iw_freq *freq, char *extra);
32int cfg80211_mgd_wext_siwap(struct net_device *dev,
33 struct iw_request_info *info,
34 struct sockaddr *ap_addr, char *extra);
35int cfg80211_mgd_wext_giwap(struct net_device *dev,
36 struct iw_request_info *info,
37 struct sockaddr *ap_addr, char *extra);
38int cfg80211_mgd_wext_siwessid(struct net_device *dev,
39 struct iw_request_info *info,
40 struct iw_point *data, char *ssid);
41int cfg80211_mgd_wext_giwessid(struct net_device *dev,
42 struct iw_request_info *info,
43 struct iw_point *data, char *ssid);
44
45struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
46 struct iw_freq *freq);
47
48
49extern const struct iw_handler_def cfg80211_wext_handler;
50#endif /* __WEXT_COMPAT */
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 4c689fd865b0..7bacbd1c2af6 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -8,6 +8,7 @@
8#include <linux/etherdevice.h> 8#include <linux/etherdevice.h>
9#include <linux/if_arp.h> 9#include <linux/if_arp.h>
10#include <net/cfg80211.h> 10#include <net/cfg80211.h>
11#include "wext-compat.h"
11#include "nl80211.h" 12#include "nl80211.h"
12 13
13int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, 14int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
@@ -108,8 +109,6 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
108 cfg80211_unlock_rdev(rdev); 109 cfg80211_unlock_rdev(rdev);
109 return err; 110 return err;
110} 111}
111/* temporary symbol - mark GPL - in the future the handler won't be */
112EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwfreq);
113 112
114int cfg80211_mgd_wext_giwfreq(struct net_device *dev, 113int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
115 struct iw_request_info *info, 114 struct iw_request_info *info,
@@ -138,8 +137,6 @@ int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
138 /* no channel if not joining */ 137 /* no channel if not joining */
139 return -EINVAL; 138 return -EINVAL;
140} 139}
141/* temporary symbol - mark GPL - in the future the handler won't be */
142EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwfreq);
143 140
144int cfg80211_mgd_wext_siwessid(struct net_device *dev, 141int cfg80211_mgd_wext_siwessid(struct net_device *dev,
145 struct iw_request_info *info, 142 struct iw_request_info *info,
@@ -195,8 +192,6 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
195 cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy)); 192 cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy));
196 return err; 193 return err;
197} 194}
198/* temporary symbol - mark GPL - in the future the handler won't be */
199EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwessid);
200 195
201int cfg80211_mgd_wext_giwessid(struct net_device *dev, 196int cfg80211_mgd_wext_giwessid(struct net_device *dev,
202 struct iw_request_info *info, 197 struct iw_request_info *info,
@@ -221,8 +216,6 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev,
221 216
222 return 0; 217 return 0;
223} 218}
224/* temporary symbol - mark GPL - in the future the handler won't be */
225EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwessid);
226 219
227int cfg80211_mgd_wext_siwap(struct net_device *dev, 220int cfg80211_mgd_wext_siwap(struct net_device *dev,
228 struct iw_request_info *info, 221 struct iw_request_info *info,
@@ -276,8 +269,6 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
276 cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy)); 269 cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy));
277 return err; 270 return err;
278} 271}
279/* temporary symbol - mark GPL - in the future the handler won't be */
280EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwap);
281 272
282int cfg80211_mgd_wext_giwap(struct net_device *dev, 273int cfg80211_mgd_wext_giwap(struct net_device *dev,
283 struct iw_request_info *info, 274 struct iw_request_info *info,
@@ -302,8 +293,6 @@ int cfg80211_mgd_wext_giwap(struct net_device *dev,
302 293
303 return 0; 294 return 0;
304} 295}
305/* temporary symbol - mark GPL - in the future the handler won't be */
306EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwap);
307 296
308int cfg80211_wext_siwgenie(struct net_device *dev, 297int cfg80211_wext_siwgenie(struct net_device *dev,
309 struct iw_request_info *info, 298 struct iw_request_info *info,