diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 13:43:21 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 13:43:21 -0700 |
commit | 06f4e926d256d902dd9a53dcb400fd74974ce087 (patch) | |
tree | 0b438b67f5f0eff6fd617bc497a9dace6164a488 /net/mac80211/scan.c | |
parent | 8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff) | |
parent | d93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits)
macvlan: fix panic if lowerdev in a bond
tg3: Add braces around 5906 workaround.
tg3: Fix NETIF_F_LOOPBACK error
macvlan: remove one synchronize_rcu() call
networking: NET_CLS_ROUTE4 depends on INET
irda: Fix error propagation in ircomm_lmp_connect_response()
irda: Kill set but unused variable 'bytes' in irlan_check_command_param()
irda: Kill set but unused variable 'clen' in ircomm_connect_indication()
rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport()
be2net: Kill set but unused variable 'req' in lancer_fw_download()
irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication()
atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined.
rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer().
rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler()
rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection()
rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window()
pkt_sched: Kill set but unused variable 'protocol' in tc_classify()
isdn: capi: Use pr_debug() instead of ifdefs.
tg3: Update version to 3.119
tg3: Apply rx_discards fix to 5719/5720
...
Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c
as per Davem.
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r-- | net/mac80211/scan.c | 122 |
1 files changed, 121 insertions, 1 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 489b6ad200d..d20046b5d8f 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -15,6 +15,7 @@ #include <linux/if_arp.h> #include <linux/rtnetlink.h> #include <linux/pm_qos_params.h> +#include <linux/slab.h> #include <net/sch_generic.h> #include <linux/slab.h> #include <net/mac80211.h> @@ -170,7 +171,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) return RX_CONTINUE; if (skb->len < 24) - return RX_DROP_MONITOR; + return RX_CONTINUE; presp = ieee80211_is_probe_resp(fc); if (presp) { @@ -850,3 +851,122 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) } mutex_unlock(&local->mtx); } + +int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, + struct cfg80211_sched_scan_request *req) +{ + struct ieee80211_local *local = sdata->local; + int ret, i; + + mutex_lock(&sdata->local->mtx); + + if (local->sched_scanning) { + ret = -EBUSY; + goto out; + } + + if (!local->ops->sched_scan_start) { + ret = -ENOTSUPP; + goto out; + } + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) { + local->sched_scan_ies.ie[i] = kzalloc(2 + + IEEE80211_MAX_SSID_LEN + + local->scan_ies_len, + GFP_KERNEL); + if (!local->sched_scan_ies.ie[i]) { + ret = -ENOMEM; + goto out_free; + } + + local->sched_scan_ies.len[i] = + ieee80211_build_preq_ies(local, + local->sched_scan_ies.ie[i], + req->ie, req->ie_len, i, + (u32) -1, 0); + } + + ret = drv_sched_scan_start(local, sdata, req, + &local->sched_scan_ies); + if (ret == 0) { + local->sched_scanning = true; + goto out; + } + +out_free: + while (i > 0) + kfree(local->sched_scan_ies.ie[--i]); +out: + mutex_unlock(&sdata->local->mtx); + return ret; +} + +int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_local *local = sdata->local; + int ret = 0, i; + + mutex_lock(&sdata->local->mtx); + + if (!local->ops->sched_scan_stop) { + ret = -ENOTSUPP; + goto out; + } + + if (local->sched_scanning) { + for (i = 0; i < IEEE80211_NUM_BANDS; i++) + kfree(local->sched_scan_ies.ie[i]); + + drv_sched_scan_stop(local, sdata); + local->sched_scanning = false; + } +out: + mutex_unlock(&sdata->local->mtx); + + return ret; +} + +void ieee80211_sched_scan_results(struct ieee80211_hw *hw) +{ + struct ieee80211_local *local = hw_to_local(hw); + + trace_api_sched_scan_results(local); + + cfg80211_sched_scan_results(hw->wiphy); +} +EXPORT_SYMBOL(ieee80211_sched_scan_results); + +void ieee80211_sched_scan_stopped_work(struct work_struct *work) +{ + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, + sched_scan_stopped_work); + int i; + + mutex_lock(&local->mtx); + + if (!local->sched_scanning) { + mutex_unlock(&local->mtx); + return; + } + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) + kfree(local->sched_scan_ies.ie[i]); + + local->sched_scanning = false; + + mutex_unlock(&local->mtx); + + cfg80211_sched_scan_stopped(local->hw.wiphy); +} + +void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw) +{ + struct ieee80211_local *local = hw_to_local(hw); + + trace_api_sched_scan_stopped(local); + + ieee80211_queue_work(&local->hw, &local->sched_scan_stopped_work); +} +EXPORT_SYMBOL(ieee80211_sched_scan_stopped); |