aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/scan.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-09-08 11:44:26 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-11 15:53:37 -0400
commit98c8fccfaea838e62ffde2f2e44568844e0e5472 (patch)
treec69552d4be03dd8321b6f90b3fbb17c607fa9940 /net/mac80211/scan.c
parent0a51b27e956bd9580296c48191b78175ed8b5971 (diff)
mac80211: refactor and move scan RX code
This patch refactors some code and moves the scan RX function to scan.c. More importantly, however, it changes it so that the MLME's beacon/probe_resp functions aren't invoked when scanning so that we can remove a "if (scanning)" conditions from two places. There's a very slight behavioural change in this patch: now, when scanning, IBSS and mesh aren't updated even on the same channel. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r--net/mac80211/scan.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 68fa782acd75..2848ba3a08e3 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -23,6 +23,74 @@
23#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5) 23#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5)
24 24
25 25
26ieee80211_rx_result
27ieee80211_sta_rx_scan(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
28 struct ieee80211_rx_status *rx_status)
29{
30 struct ieee80211_mgmt *mgmt;
31 struct ieee80211_sta_bss *bss;
32 u8 *elements;
33 struct ieee80211_channel *channel;
34 size_t baselen;
35 int freq;
36 __le16 fc;
37 bool presp, beacon = false;
38 struct ieee802_11_elems elems;
39
40 if (skb->len < 2)
41 return RX_DROP_UNUSABLE;
42
43 mgmt = (struct ieee80211_mgmt *) skb->data;
44 fc = mgmt->frame_control;
45
46 if (ieee80211_is_ctl(fc))
47 return RX_CONTINUE;
48
49 if (skb->len < 24)
50 return RX_DROP_MONITOR;
51
52 presp = ieee80211_is_probe_resp(fc);
53 if (presp) {
54 /* ignore ProbeResp to foreign address */
55 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
56 return RX_DROP_MONITOR;
57
58 presp = true;
59 elements = mgmt->u.probe_resp.variable;
60 baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
61 } else {
62 beacon = ieee80211_is_beacon(fc);
63 baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
64 elements = mgmt->u.beacon.variable;
65 }
66
67 if (!presp && !beacon)
68 return RX_CONTINUE;
69
70 if (baselen > skb->len)
71 return RX_DROP_MONITOR;
72
73 ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
74
75 if (elems.ds_params && elems.ds_params_len == 1)
76 freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
77 else
78 freq = rx_status->freq;
79
80 channel = ieee80211_get_channel(sdata->local->hw.wiphy, freq);
81
82 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
83 return RX_DROP_MONITOR;
84
85 bss = ieee80211_bss_info_update(sdata->local, rx_status,
86 mgmt, skb->len, &elems,
87 freq, beacon);
88 ieee80211_rx_bss_put(sdata->local, bss);
89
90 dev_kfree_skb(skb);
91 return RX_QUEUED;
92}
93
26static void ieee80211_send_nullfunc(struct ieee80211_local *local, 94static void ieee80211_send_nullfunc(struct ieee80211_local *local,
27 struct ieee80211_sub_if_data *sdata, 95 struct ieee80211_sub_if_data *sdata,
28 int powersave) 96 int powersave)