]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.fixes/mac80211-add-direct-probe.patch
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / mac80211-add-direct-probe.patch
CommitLineData
00e5a55c
BS
1From: Ron Rindjunsky <ron.rindjunsky@intel.com>
2Date: Sat, 9 Aug 2008 03:02:19 +0300
3Subject: [PATCH] mac80211: add direct probe before association
4Patch-mainline: 2.6.28-rc1
5References: bnc#461889
6
7This patch adds a direct probe request as first step in the association
8flow if data we have is not up to date. Motivation of this step is to make
9sure that the bss information we have is correct, since last scan could
10have been done a while ago, and beacons do not fully answer this need as
11there are potential differences between them and probe responses (e.g.
12WMM parameter element)
13
14Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com>
15Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
16Signed-off-by: John W. Linville <linville@tuxdriver.com>
17
18Modified not to break kABI: auth_tries is overriden to also mean
19direct_probe_tries, last_probe_resp is moved to the end of the
20ieee80211_sta_bss structure.
21
22Signed-off-by: Jiri Benc <jbenc@suse.cz>
23
24---
25 net/mac80211/ieee80211_i.h | 10 +++++
26 net/mac80211/mlme.c | 79 ++++++++++++++++++++++++++++++++++++++-------
27 2 files changed, 77 insertions(+), 12 deletions(-)
28
29--- linux-2.6.27.orig/net/mac80211/ieee80211_i.h
30+++ linux-2.6.27/net/mac80211/ieee80211_i.h
31@@ -117,6 +117,10 @@ struct ieee80211_sta_bss {
32 * otherwise, you probably don't want to use them. */
33 int has_erp_value;
34 u8 erp_value;
35+
36+#ifndef __GENKSYMS__
37+ unsigned long last_probe_resp;
38+#endif
39 };
40
41 static inline u8 *bss_mesh_cfg(struct ieee80211_sta_bss *bss)
42@@ -310,6 +314,9 @@ struct ieee80211_if_sta {
43 IEEE80211_ASSOCIATE, IEEE80211_ASSOCIATED,
44 IEEE80211_IBSS_SEARCH, IEEE80211_IBSS_JOINED,
45 IEEE80211_MESH_UP
46+#ifndef __GENKSYMS__
47+ , IEEE80211_DIRECT_PROBE
48+#endif
49 } state;
50 size_t ssid_len;
51 u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
52@@ -363,6 +370,7 @@ struct ieee80211_if_sta {
53 #define IEEE80211_STA_REQ_SCAN 0
54 #define IEEE80211_STA_REQ_AUTH 1
55 #define IEEE80211_STA_REQ_RUN 2
56+#define IEEE80211_STA_REQ_DIRECT_PROBE 3
57
58 #define IEEE80211_AUTH_ALG_OPEN BIT(0)
59 #define IEEE80211_AUTH_ALG_SHARED_KEY BIT(1)
60--- linux-2.6.27.orig/net/mac80211/mlme.c
61+++ linux-2.6.27/net/mac80211/mlme.c
62@@ -658,6 +658,36 @@ static void ieee80211_send_auth(struct n
63 ieee80211_sta_tx(dev, skb, encrypt);
64 }
65
66+static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
67+ struct ieee80211_if_sta *ifsta)
68+{
69+ DECLARE_MAC_BUF(mac);
70+
71+ ifsta->auth_tries++; /* used as direct_probe_tries */
72+ if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
73+ printk(KERN_DEBUG "%s: direct probe to AP %s timed out\n",
74+ sdata->dev->name, print_mac(mac, ifsta->bssid));
75+ ifsta->state = IEEE80211_DISABLED;
76+ return;
77+ }
78+
79+ printk(KERN_DEBUG "%s: direct probe to AP %s try %d\n",
80+ sdata->dev->name, print_mac(mac, ifsta->bssid),
81+ ifsta->auth_tries);
82+
83+ ifsta->state = IEEE80211_DIRECT_PROBE;
84+
85+ set_bit(IEEE80211_STA_REQ_DIRECT_PROBE, &ifsta->request);
86+
87+ /* Direct probe is sent to broadcast address as some APs
88+ * will not answer to direct packet in unassociated state.
89+ */
90+ ieee80211_send_probe_req(sdata->dev, NULL,
91+ ifsta->ssid, ifsta->ssid_len);
92+
93+ mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
94+}
95+
96
97 static void ieee80211_authenticate(struct net_device *dev,
98 struct ieee80211_if_sta *ifsta)
99@@ -1958,7 +1988,7 @@ static void ieee80211_rx_mgmt_deauth(str
100 if (ifsta->state == IEEE80211_AUTHENTICATE ||
101 ifsta->state == IEEE80211_ASSOCIATE ||
102 ifsta->state == IEEE80211_ASSOCIATED) {
103- ifsta->state = IEEE80211_AUTHENTICATE;
104+ ifsta->state = IEEE80211_DIRECT_PROBE;
105 mod_timer(&ifsta->timer, jiffies +
106 IEEE80211_RETRY_AUTH_INTERVAL);
107 }
108@@ -2559,8 +2589,7 @@ static void ieee80211_rx_bss_info(struct
109 struct ieee80211_mgmt *mgmt,
110 size_t len,
111 struct ieee80211_rx_status *rx_status,
112- struct ieee802_11_elems *elems,
113- int beacon)
114+ struct ieee802_11_elems *elems)
115 {
116 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
117 int freq, clen;
118@@ -2569,6 +2598,7 @@ static void ieee80211_rx_bss_info(struct
119 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
120 u64 beacon_timestamp, rx_timestamp;
121 struct ieee80211_channel *channel;
122+ bool beacon = ieee80211_is_beacon(mgmt->frame_control);
123 DECLARE_MAC_BUF(mac);
124 DECLARE_MAC_BUF(mac2);
125
126@@ -2728,15 +2758,14 @@ static void ieee80211_rx_bss_info(struct
127 bss->signal = rx_status->signal;
128 bss->noise = rx_status->noise;
129 bss->qual = rx_status->qual;
130- if (!beacon && !bss->probe_resp)
131- bss->probe_resp = true;
132-
133+ if (!beacon)
134+ bss->last_probe_resp = jiffies;
135 /*
136 * In STA mode, the remaining parameters should not be overridden
137 * by beacons because they're not necessarily accurate there.
138 */
139 if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
140- bss->probe_resp && beacon) {
141+ bss->last_probe_resp && beacon) {
142 ieee80211_rx_bss_put(local, bss);
143 return;
144 }
145@@ -2891,6 +2920,8 @@ static void ieee80211_rx_mgmt_probe_resp
146 {
147 size_t baselen;
148 struct ieee802_11_elems elems;
149+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
150+ struct ieee80211_if_sta *ifsta = &sdata->u.sta;
151
152 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
153 if (baselen > len)
154@@ -2899,7 +2930,17 @@ static void ieee80211_rx_mgmt_probe_resp
155 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
156 &elems);
157
158- ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 0);
159+ ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems);
160+
161+ /* direct probe may be part of the association flow */
162+ if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE,
163+ &ifsta->request)) {
164+ printk(KERN_DEBUG "%s direct probe responded\n",
165+ sdata->dev->name);
166+ ifsta->auth_tries = 0; /* direct_probe_tries -> auth_tries */
167+ ieee80211_authenticate(dev, ifsta);
168+ }
169+
170 }
171
172
173@@ -2923,7 +2964,7 @@ static void ieee80211_rx_mgmt_beacon(str
174
175 ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
176
177- ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 1);
178+ ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems);
179
180 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
181 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
182@@ -3361,7 +3402,8 @@ void ieee80211_sta_work(struct work_stru
183 mesh_path_start_discovery(dev);
184 #endif
185
186- if (ifsta->state != IEEE80211_AUTHENTICATE &&
187+ if (ifsta->state != IEEE80211_DIRECT_PROBE &&
188+ ifsta->state != IEEE80211_AUTHENTICATE &&
189 ifsta->state != IEEE80211_ASSOCIATE &&
190 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
191 if (ifsta->scan_ssid_len)
192@@ -3381,6 +3423,10 @@ void ieee80211_sta_work(struct work_stru
193 switch (ifsta->state) {
194 case IEEE80211_DISABLED:
195 break;
196+ case IEEE80211_DIRECT_PROBE:
197+ ieee80211_direct_probe(sdata, ifsta);
198+ break;
199+
200 case IEEE80211_AUTHENTICATE:
201 ieee80211_authenticate(dev, ifsta);
202 break;
203@@ -3541,8 +3587,18 @@ static int ieee80211_sta_config_auth(str
204 selected->ssid_len);
205 ieee80211_sta_set_bssid(dev, selected->bssid);
206 ieee80211_sta_def_wmm_params(dev, selected, 0);
207+
208+ /* Send out direct probe if no probe resp was received or
209+ * the one we have is outdated
210+ */
211+ if (!selected->last_probe_resp ||
212+ time_after(jiffies, selected->last_probe_resp
213+ + IEEE80211_SCAN_RESULT_EXPIRE))
214+ ifsta->state = IEEE80211_DIRECT_PROBE;
215+ else
216+ ifsta->state = IEEE80211_AUTHENTICATE;
217+
218 ieee80211_rx_bss_put(local, selected);
219- ifsta->state = IEEE80211_AUTHENTICATE;
220 ieee80211_sta_reset_auth(dev, ifsta);
221 return 0;
222 } else {
223@@ -3553,6 +3609,7 @@ static int ieee80211_sta_config_auth(str
224 ieee80211_sta_start_scan(dev, ifsta->ssid,
225 ifsta->ssid_len);
226 ifsta->state = IEEE80211_AUTHENTICATE;
227+ ifsta->auth_tries = 0; /* direct_probe_tries -> auth_tries */
228 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
229 } else
230 ifsta->state = IEEE80211_DISABLED;