aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-02-15 02:06:44 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-15 02:06:44 -0500
commitac178ef0ae9eb44fd527d87aa9b6394e05f56e1f (patch)
tree5d6bd46ecf9ce989134d3c460e1ecf5dd1fceadc /net
parentf3a7c66b5ce0b75a9774a50b5dcce93e5ba28370 (diff)
parent6d08b9b9c6eb2414c4a037407dd121298a74fb36 (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/mac80211/Makefile2
-rw-r--r--net/mac80211/agg-rx.c302
-rw-r--r--net/mac80211/agg-tx.c636
-rw-r--r--net/mac80211/cfg.c31
-rw-r--r--net/mac80211/ht.c869
-rw-r--r--net/mac80211/ieee80211_i.h81
-rw-r--r--net/mac80211/iface.c5
-rw-r--r--net/mac80211/main.c48
-rw-r--r--net/mac80211/mesh.c10
-rw-r--r--net/mac80211/mesh.h1
-rw-r--r--net/mac80211/mesh_hwmp.c1
-rw-r--r--net/mac80211/mlme.c703
-rw-r--r--net/mac80211/rx.c68
-rw-r--r--net/mac80211/scan.c620
-rw-r--r--net/mac80211/spectmgmt.c7
-rw-r--r--net/mac80211/sta_info.c37
-rw-r--r--net/mac80211/sta_info.h4
-rw-r--r--net/mac80211/tx.c8
-rw-r--r--net/mac80211/wext.c98
-rw-r--r--net/wireless/Makefile2
-rw-r--r--net/wireless/core.c8
-rw-r--r--net/wireless/core.h20
-rw-r--r--net/wireless/nl80211.c323
-rw-r--r--net/wireless/nl80211.h8
-rw-r--r--net/wireless/scan.c836
25 files changed, 2855 insertions, 1873 deletions
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 58c94bb38e87..3503a3d21318 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -8,7 +8,7 @@ mac80211-y := \
8 wep.o \ 8 wep.o \
9 wpa.o \ 9 wpa.o \
10 scan.o \ 10 scan.o \
11 ht.o \ 11 ht.o agg-tx.o agg-rx.o \
12 mlme.o \ 12 mlme.o \
13 iface.o \ 13 iface.o \
14 rate.o \ 14 rate.o \
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
new file mode 100644
index 000000000000..3112bfd441b6
--- /dev/null
+++ b/net/mac80211/agg-rx.c
@@ -0,0 +1,302 @@
1/*
2 * HT handling
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2002-2005, Instant802 Networks, Inc.
6 * Copyright 2005-2006, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 * Copyright 2007-2008, Intel Corporation
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/ieee80211.h>
17#include <net/mac80211.h>
18#include "ieee80211_i.h"
19
20void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
21 u16 initiator, u16 reason)
22{
23 struct ieee80211_local *local = sta->local;
24 struct ieee80211_hw *hw = &local->hw;
25 int i;
26
27 /* check if TID is in operational state */
28 spin_lock_bh(&sta->lock);
29 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) {
30 spin_unlock_bh(&sta->lock);
31 return;
32 }
33
34 sta->ampdu_mlme.tid_state_rx[tid] =
35 HT_AGG_STATE_REQ_STOP_BA_MSK |
36 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
37 spin_unlock_bh(&sta->lock);
38
39#ifdef CONFIG_MAC80211_HT_DEBUG
40 printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n",
41 sta->sta.addr, tid);
42#endif /* CONFIG_MAC80211_HT_DEBUG */
43
44 if (local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
45 &sta->sta, tid, NULL))
46 printk(KERN_DEBUG "HW problem - can not stop rx "
47 "aggregation for tid %d\n", tid);
48
49 /* shutdown timer has not expired */
50 if (initiator != WLAN_BACK_TIMER)
51 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
52
53 /* check if this is a self generated aggregation halt */
54 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
55 ieee80211_send_delba(sta->sdata, sta->sta.addr,
56 tid, 0, reason);
57
58 /* free the reordering buffer */
59 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
60 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
61 /* release the reordered frames */
62 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
63 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
64 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
65 }
66 }
67
68 spin_lock_bh(&sta->lock);
69 /* free resources */
70 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
71
72 if (!sta->ampdu_mlme.tid_rx[tid]->shutdown) {
73 kfree(sta->ampdu_mlme.tid_rx[tid]);
74 sta->ampdu_mlme.tid_rx[tid] = NULL;
75 }
76
77 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
78 spin_unlock_bh(&sta->lock);
79}
80
81void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
82 u16 initiator, u16 reason)
83{
84 struct ieee80211_local *local = sdata->local;
85 struct sta_info *sta;
86
87 /* stop HW Rx aggregation. ampdu_action existence
88 * already verified in session init so we add the BUG_ON */
89 BUG_ON(!local->ops->ampdu_action);
90
91 rcu_read_lock();
92
93 sta = sta_info_get(local, ra);
94 if (!sta) {
95 rcu_read_unlock();
96 return;
97 }
98
99 __ieee80211_stop_rx_ba_session(sta, tid, initiator, reason);
100
101 rcu_read_unlock();
102}
103
104/*
105 * After accepting the AddBA Request we activated a timer,
106 * resetting it after each frame that arrives from the originator.
107 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
108 */
109static void sta_rx_agg_session_timer_expired(unsigned long data)
110{
111 /* not an elegant detour, but there is no choice as the timer passes
112 * only one argument, and various sta_info are needed here, so init
113 * flow in sta_info_create gives the TID as data, while the timer_to_id
114 * array gives the sta through container_of */
115 u8 *ptid = (u8 *)data;
116 u8 *timer_to_id = ptid - *ptid;
117 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
118 timer_to_tid[0]);
119
120#ifdef CONFIG_MAC80211_HT_DEBUG
121 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
122#endif
123 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr,
124 (u16)*ptid, WLAN_BACK_TIMER,
125 WLAN_REASON_QSTA_TIMEOUT);
126}
127
128static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
129 u8 dialog_token, u16 status, u16 policy,
130 u16 buf_size, u16 timeout)
131{
132 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
133 struct ieee80211_local *local = sdata->local;
134 struct sk_buff *skb;
135 struct ieee80211_mgmt *mgmt;
136 u16 capab;
137
138 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
139
140 if (!skb) {
141 printk(KERN_DEBUG "%s: failed to allocate buffer "
142 "for addba resp frame\n", sdata->dev->name);
143 return;
144 }
145
146 skb_reserve(skb, local->hw.extra_tx_headroom);
147 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
148 memset(mgmt, 0, 24);
149 memcpy(mgmt->da, da, ETH_ALEN);
150 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
151 if (sdata->vif.type == NL80211_IFTYPE_AP ||
152 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
153 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
154 else
155 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
156 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
157 IEEE80211_STYPE_ACTION);
158
159 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp));
160 mgmt->u.action.category = WLAN_CATEGORY_BACK;
161 mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
162 mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
163
164 capab = (u16)(policy << 1); /* bit 1 aggregation policy */
165 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
166 capab |= (u16)(buf_size << 6); /* bit 15:6 max size of aggregation */
167
168 mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab);
169 mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
170 mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
171
172 ieee80211_tx_skb(sdata, skb, 1);
173}
174
175void ieee80211_process_addba_request(struct ieee80211_local *local,
176 struct sta_info *sta,
177 struct ieee80211_mgmt *mgmt,
178 size_t len)
179{
180 struct ieee80211_hw *hw = &local->hw;
181 struct ieee80211_conf *conf = &hw->conf;
182 struct tid_ampdu_rx *tid_agg_rx;
183 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
184 u8 dialog_token;
185 int ret = -EOPNOTSUPP;
186
187 /* extract session parameters from addba request frame */
188 dialog_token = mgmt->u.action.u.addba_req.dialog_token;
189 timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout);
190 start_seq_num =
191 le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
192
193 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
194 ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
195 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
196 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
197
198 status = WLAN_STATUS_REQUEST_DECLINED;
199
200 /* sanity check for incoming parameters:
201 * check if configuration can support the BA policy
202 * and if buffer size does not exceeds max value */
203 /* XXX: check own ht delayed BA capability?? */
204 if (((ba_policy != 1)
205 && (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA)))
206 || (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
207 status = WLAN_STATUS_INVALID_QOS_PARAM;
208#ifdef CONFIG_MAC80211_HT_DEBUG
209 if (net_ratelimit())
210 printk(KERN_DEBUG "AddBA Req with bad params from "
211 "%pM on tid %u. policy %d, buffer size %d\n",
212 mgmt->sa, tid, ba_policy,
213 buf_size);
214#endif /* CONFIG_MAC80211_HT_DEBUG */
215 goto end_no_lock;
216 }
217 /* determine default buffer size */
218 if (buf_size == 0) {
219 struct ieee80211_supported_band *sband;
220
221 sband = local->hw.wiphy->bands[conf->channel->band];
222 buf_size = IEEE80211_MIN_AMPDU_BUF;
223 buf_size = buf_size << sband->ht_cap.ampdu_factor;
224 }
225
226
227 /* examine state machine */
228 spin_lock_bh(&sta->lock);
229
230 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
231#ifdef CONFIG_MAC80211_HT_DEBUG
232 if (net_ratelimit())
233 printk(KERN_DEBUG "unexpected AddBA Req from "
234 "%pM on tid %u\n",
235 mgmt->sa, tid);
236#endif /* CONFIG_MAC80211_HT_DEBUG */
237 goto end;
238 }
239
240 /* prepare A-MPDU MLME for Rx aggregation */
241 sta->ampdu_mlme.tid_rx[tid] =
242 kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
243 if (!sta->ampdu_mlme.tid_rx[tid]) {
244#ifdef CONFIG_MAC80211_HT_DEBUG
245 if (net_ratelimit())
246 printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
247 tid);
248#endif
249 goto end;
250 }
251 /* rx timer */
252 sta->ampdu_mlme.tid_rx[tid]->session_timer.function =
253 sta_rx_agg_session_timer_expired;
254 sta->ampdu_mlme.tid_rx[tid]->session_timer.data =
255 (unsigned long)&sta->timer_to_tid[tid];
256 init_timer(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
257
258 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
259
260 /* prepare reordering buffer */
261 tid_agg_rx->reorder_buf =
262 kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC);
263 if (!tid_agg_rx->reorder_buf) {
264#ifdef CONFIG_MAC80211_HT_DEBUG
265 if (net_ratelimit())
266 printk(KERN_ERR "can not allocate reordering buffer "
267 "to tid %d\n", tid);
268#endif
269 kfree(sta->ampdu_mlme.tid_rx[tid]);
270 goto end;
271 }
272
273 if (local->ops->ampdu_action)
274 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
275 &sta->sta, tid, &start_seq_num);
276#ifdef CONFIG_MAC80211_HT_DEBUG
277 printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
278#endif /* CONFIG_MAC80211_HT_DEBUG */
279
280 if (ret) {
281 kfree(tid_agg_rx->reorder_buf);
282 kfree(tid_agg_rx);
283 sta->ampdu_mlme.tid_rx[tid] = NULL;
284 goto end;
285 }
286
287 /* change state and send addba resp */
288 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
289 tid_agg_rx->dialog_token = dialog_token;
290 tid_agg_rx->ssn = start_seq_num;
291 tid_agg_rx->head_seq_num = start_seq_num;
292 tid_agg_rx->buf_size = buf_size;
293 tid_agg_rx->timeout = timeout;
294 tid_agg_rx->stored_mpdu_num = 0;
295 status = WLAN_STATUS_SUCCESS;
296end:
297 spin_unlock_bh(&sta->lock);
298
299end_no_lock:
300 ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid,
301 dialog_token, status, 1, buf_size, timeout);
302}
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
new file mode 100644
index 000000000000..1232d9f01ca9
--- /dev/null
+++ b/net/mac80211/agg-tx.c
@@ -0,0 +1,636 @@
1/*
2 * HT handling
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2002-2005, Instant802 Networks, Inc.
6 * Copyright 2005-2006, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 * Copyright 2007-2009, Intel Corporation
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/ieee80211.h>
17#include <net/mac80211.h>
18#include "ieee80211_i.h"
19#include "wme.h"
20
21/**
22 * DOC: TX aggregation
23 *
24 * Aggregation on the TX side requires setting the hardware flag
25 * %IEEE80211_HW_AMPDU_AGGREGATION as well as, if present, the @ampdu_queues
26 * hardware parameter to the number of hardware AMPDU queues. If there are no
27 * hardware queues then the driver will (currently) have to do all frame
28 * buffering.
29 *
30 * When TX aggregation is started by some subsystem (usually the rate control
31 * algorithm would be appropriate) by calling the
32 * ieee80211_start_tx_ba_session() function, the driver will be notified via
33 * its @ampdu_action function, with the %IEEE80211_AMPDU_TX_START action.
34 *
35 * In response to that, the driver is later required to call the
36 * ieee80211_start_tx_ba_cb() (or ieee80211_start_tx_ba_cb_irqsafe())
37 * function, which will start the aggregation session.
38 *
39 * Similarly, when the aggregation session is stopped by
40 * ieee80211_stop_tx_ba_session(), the driver's @ampdu_action function will
41 * be called with the action %IEEE80211_AMPDU_TX_STOP. In this case, the
42 * call must not fail, and the driver must later call ieee80211_stop_tx_ba_cb()
43 * (or ieee80211_stop_tx_ba_cb_irqsafe()).
44 */
45
46static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
47 const u8 *da, u16 tid,
48 u8 dialog_token, u16 start_seq_num,
49 u16 agg_size, u16 timeout)
50{
51 struct ieee80211_local *local = sdata->local;
52 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
53 struct sk_buff *skb;
54 struct ieee80211_mgmt *mgmt;
55 u16 capab;
56
57 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
58
59 if (!skb) {
60 printk(KERN_ERR "%s: failed to allocate buffer "
61 "for addba request frame\n", sdata->dev->name);
62 return;
63 }
64 skb_reserve(skb, local->hw.extra_tx_headroom);
65 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
66 memset(mgmt, 0, 24);
67 memcpy(mgmt->da, da, ETH_ALEN);
68 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
69 if (sdata->vif.type == NL80211_IFTYPE_AP ||
70 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
71 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
72 else
73 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
74
75 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
76 IEEE80211_STYPE_ACTION);
77
78 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
79
80 mgmt->u.action.category = WLAN_CATEGORY_BACK;
81 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
82
83 mgmt->u.action.u.addba_req.dialog_token = dialog_token;
84 capab = (u16)(1 << 1); /* bit 1 aggregation policy */
85 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
86 capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */
87
88 mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
89
90 mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
91 mgmt->u.action.u.addba_req.start_seq_num =
92 cpu_to_le16(start_seq_num << 4);
93
94 ieee80211_tx_skb(sdata, skb, 1);
95}
96
97void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
98{
99 struct ieee80211_local *local = sdata->local;
100 struct sk_buff *skb;
101 struct ieee80211_bar *bar;
102 u16 bar_control = 0;
103
104 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
105 if (!skb) {
106 printk(KERN_ERR "%s: failed to allocate buffer for "
107 "bar frame\n", sdata->dev->name);
108 return;
109 }
110 skb_reserve(skb, local->hw.extra_tx_headroom);
111 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
112 memset(bar, 0, sizeof(*bar));
113 bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
114 IEEE80211_STYPE_BACK_REQ);
115 memcpy(bar->ra, ra, ETH_ALEN);
116 memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
117 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
118 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
119 bar_control |= (u16)(tid << 12);
120 bar->control = cpu_to_le16(bar_control);
121 bar->start_seq_num = cpu_to_le16(ssn);
122
123 ieee80211_tx_skb(sdata, skb, 0);
124}
125
126static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
127 enum ieee80211_back_parties initiator)
128{
129 struct ieee80211_local *local = sta->local;
130 int ret;
131 u8 *state;
132
133 state = &sta->ampdu_mlme.tid_state_tx[tid];
134
135 if (local->hw.ampdu_queues)
136 ieee80211_stop_queue(&local->hw, sta->tid_to_tx_q[tid]);
137
138 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
139 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
140
141 ret = local->ops->ampdu_action(&local->hw, IEEE80211_AMPDU_TX_STOP,
142 &sta->sta, tid, NULL);
143
144 /* HW shall not deny going back to legacy */
145 if (WARN_ON(ret)) {
146 *state = HT_AGG_STATE_OPERATIONAL;
147 if (local->hw.ampdu_queues)
148 ieee80211_wake_queue(&local->hw, sta->tid_to_tx_q[tid]);
149 }
150
151 return ret;
152}
153
154/*
155 * After sending add Block Ack request we activated a timer until
156 * add Block Ack response will arrive from the recipient.
157 * If this timer expires sta_addba_resp_timer_expired will be executed.
158 */
159static void sta_addba_resp_timer_expired(unsigned long data)
160{
161 /* not an elegant detour, but there is no choice as the timer passes
162 * only one argument, and both sta_info and TID are needed, so init
163 * flow in sta_info_create gives the TID as data, while the timer_to_id
164 * array gives the sta through container_of */
165 u16 tid = *(u8 *)data;
166 struct sta_info *sta = container_of((void *)data,
167 struct sta_info, timer_to_tid[tid]);
168 u8 *state;
169
170 state = &sta->ampdu_mlme.tid_state_tx[tid];
171
172 /* check if the TID waits for addBA response */
173 spin_lock_bh(&sta->lock);
174 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
175 spin_unlock_bh(&sta->lock);
176 *state = HT_AGG_STATE_IDLE;
177#ifdef CONFIG_MAC80211_HT_DEBUG
178 printk(KERN_DEBUG "timer expired on tid %d but we are not "
179 "expecting addBA response there", tid);
180#endif
181 return;
182 }
183
184#ifdef CONFIG_MAC80211_HT_DEBUG
185 printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
186#endif
187
188 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
189 spin_unlock_bh(&sta->lock);
190}
191
192int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
193{
194 struct ieee80211_local *local = hw_to_local(hw);
195 struct sta_info *sta;
196 struct ieee80211_sub_if_data *sdata;
197 u16 start_seq_num;
198 u8 *state;
199 int ret = 0;
200
201 if (WARN_ON(!local->ops->ampdu_action))
202 return -EINVAL;
203
204 if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
205 return -EINVAL;
206
207#ifdef CONFIG_MAC80211_HT_DEBUG
208 printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n",
209 ra, tid);
210#endif /* CONFIG_MAC80211_HT_DEBUG */
211
212 rcu_read_lock();
213
214 sta = sta_info_get(local, ra);
215 if (!sta) {
216#ifdef CONFIG_MAC80211_HT_DEBUG
217 printk(KERN_DEBUG "Could not find the station\n");
218#endif
219 ret = -ENOENT;
220 goto exit;
221 }
222
223 /*
224 * The aggregation code is not prepared to handle
225 * anything but STA/AP due to the BSSID handling.
226 * IBSS could work in the code but isn't supported
227 * by drivers or the standard.
228 */
229 if (sta->sdata->vif.type != NL80211_IFTYPE_STATION &&
230 sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
231 sta->sdata->vif.type != NL80211_IFTYPE_AP) {
232 ret = -EINVAL;
233 goto exit;
234 }
235
236 spin_lock_bh(&sta->lock);
237
238 /* we have tried too many times, receiver does not want A-MPDU */
239 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
240 ret = -EBUSY;
241 goto err_unlock_sta;
242 }
243
244 state = &sta->ampdu_mlme.tid_state_tx[tid];
245 /* check if the TID is not in aggregation flow already */
246 if (*state != HT_AGG_STATE_IDLE) {
247#ifdef CONFIG_MAC80211_HT_DEBUG
248 printk(KERN_DEBUG "BA request denied - session is not "
249 "idle on tid %u\n", tid);
250#endif /* CONFIG_MAC80211_HT_DEBUG */
251 ret = -EAGAIN;
252 goto err_unlock_sta;
253 }
254
255 /* prepare A-MPDU MLME for Tx aggregation */
256 sta->ampdu_mlme.tid_tx[tid] =
257 kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
258 if (!sta->ampdu_mlme.tid_tx[tid]) {
259#ifdef CONFIG_MAC80211_HT_DEBUG
260 if (net_ratelimit())
261 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
262 tid);
263#endif
264 ret = -ENOMEM;
265 goto err_unlock_sta;
266 }
267 /* Tx timer */
268 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
269 sta_addba_resp_timer_expired;
270 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
271 (unsigned long)&sta->timer_to_tid[tid];
272 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
273
274 if (hw->ampdu_queues) {
275 /* create a new queue for this aggregation */
276 ret = ieee80211_ht_agg_queue_add(local, sta, tid);
277
278 /* case no queue is available to aggregation
279 * don't switch to aggregation */
280 if (ret) {
281#ifdef CONFIG_MAC80211_HT_DEBUG
282 printk(KERN_DEBUG "BA request denied - "
283 "queue unavailable for tid %d\n", tid);
284#endif /* CONFIG_MAC80211_HT_DEBUG */
285 goto err_unlock_queue;
286 }
287 }
288 sdata = sta->sdata;
289
290 /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
291 * call back right away, it must see that the flow has begun */
292 *state |= HT_ADDBA_REQUESTED_MSK;
293
294 /* This is slightly racy because the queue isn't stopped */
295 start_seq_num = sta->tid_seq[tid];
296
297 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
298 &sta->sta, tid, &start_seq_num);
299
300 if (ret) {
301 /* No need to requeue the packets in the agg queue, since we
302 * held the tx lock: no packet could be enqueued to the newly
303 * allocated queue */
304 if (hw->ampdu_queues)
305 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
306#ifdef CONFIG_MAC80211_HT_DEBUG
307 printk(KERN_DEBUG "BA request denied - HW unavailable for"
308 " tid %d\n", tid);
309#endif /* CONFIG_MAC80211_HT_DEBUG */
310 *state = HT_AGG_STATE_IDLE;
311 goto err_unlock_queue;
312 }
313
314 /* Will put all the packets in the new SW queue */
315 if (hw->ampdu_queues)
316 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
317 spin_unlock_bh(&sta->lock);
318
319 /* send an addBA request */
320 sta->ampdu_mlme.dialog_token_allocator++;
321 sta->ampdu_mlme.tid_tx[tid]->dialog_token =
322 sta->ampdu_mlme.dialog_token_allocator;
323 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
324
325
326 ieee80211_send_addba_request(sta->sdata, ra, tid,
327 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
328 sta->ampdu_mlme.tid_tx[tid]->ssn,
329 0x40, 5000);
330 /* activate the timer for the recipient's addBA response */
331 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
332 jiffies + ADDBA_RESP_INTERVAL;
333 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
334#ifdef CONFIG_MAC80211_HT_DEBUG
335 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
336#endif
337 goto exit;
338
339err_unlock_queue:
340 kfree(sta->ampdu_mlme.tid_tx[tid]);
341 sta->ampdu_mlme.tid_tx[tid] = NULL;
342 ret = -EBUSY;
343err_unlock_sta:
344 spin_unlock_bh(&sta->lock);
345exit:
346 rcu_read_unlock();
347 return ret;
348}
349EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
350
351void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
352{
353 struct ieee80211_local *local = hw_to_local(hw);
354 struct sta_info *sta;
355 u8 *state;
356
357 if (tid >= STA_TID_NUM) {
358#ifdef CONFIG_MAC80211_HT_DEBUG
359 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
360 tid, STA_TID_NUM);
361#endif
362 return;
363 }
364
365 rcu_read_lock();
366 sta = sta_info_get(local, ra);
367 if (!sta) {
368 rcu_read_unlock();
369#ifdef CONFIG_MAC80211_HT_DEBUG
370 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
371#endif
372 return;
373 }
374
375 state = &sta->ampdu_mlme.tid_state_tx[tid];
376 spin_lock_bh(&sta->lock);
377
378 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
379#ifdef CONFIG_MAC80211_HT_DEBUG
380 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
381 *state);
382#endif
383 spin_unlock_bh(&sta->lock);
384 rcu_read_unlock();
385 return;
386 }
387
388 WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK);
389
390 *state |= HT_ADDBA_DRV_READY_MSK;
391
392 if (*state == HT_AGG_STATE_OPERATIONAL) {
393#ifdef CONFIG_MAC80211_HT_DEBUG
394 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
395#endif
396 if (hw->ampdu_queues)
397 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
398 }
399 spin_unlock_bh(&sta->lock);
400 rcu_read_unlock();
401}
402EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
403
404void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
405 const u8 *ra, u16 tid)
406{
407 struct ieee80211_local *local = hw_to_local(hw);
408 struct ieee80211_ra_tid *ra_tid;
409 struct sk_buff *skb = dev_alloc_skb(0);
410
411 if (unlikely(!skb)) {
412#ifdef CONFIG_MAC80211_HT_DEBUG
413 if (net_ratelimit())
414 printk(KERN_WARNING "%s: Not enough memory, "
415 "dropping start BA session", skb->dev->name);
416#endif
417 return;
418 }
419 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
420 memcpy(&ra_tid->ra, ra, ETH_ALEN);
421 ra_tid->tid = tid;
422
423 skb->pkt_type = IEEE80211_ADDBA_MSG;
424 skb_queue_tail(&local->skb_queue, skb);
425 tasklet_schedule(&local->tasklet);
426}
427EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
428
429int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
430 enum ieee80211_back_parties initiator)
431{
432 u8 *state;
433 int ret;
434
435 /* check if the TID is in aggregation */
436 state = &sta->ampdu_mlme.tid_state_tx[tid];
437 spin_lock_bh(&sta->lock);
438
439 if (*state != HT_AGG_STATE_OPERATIONAL) {
440 ret = -ENOENT;
441 goto unlock;
442 }
443
444#ifdef CONFIG_MAC80211_HT_DEBUG
445 printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
446 sta->sta.addr, tid);
447#endif /* CONFIG_MAC80211_HT_DEBUG */
448
449 ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator);
450
451 unlock:
452 spin_unlock_bh(&sta->lock);
453 return ret;
454}
455
456int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
457 u8 *ra, u16 tid,
458 enum ieee80211_back_parties initiator)
459{
460 struct ieee80211_local *local = hw_to_local(hw);
461 struct sta_info *sta;
462 int ret = 0;
463
464 if (WARN_ON(!local->ops->ampdu_action))
465 return -EINVAL;
466
467 if (tid >= STA_TID_NUM)
468 return -EINVAL;
469
470 rcu_read_lock();
471 sta = sta_info_get(local, ra);
472 if (!sta) {
473 rcu_read_unlock();
474 return -ENOENT;
475 }
476
477 ret = __ieee80211_stop_tx_ba_session(sta, tid, initiator);
478 rcu_read_unlock();
479 return ret;
480}
481EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
482
483void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
484{
485 struct ieee80211_local *local = hw_to_local(hw);
486 struct sta_info *sta;
487 u8 *state;
488 int agg_queue;
489
490 if (tid >= STA_TID_NUM) {
491#ifdef CONFIG_MAC80211_HT_DEBUG
492 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
493 tid, STA_TID_NUM);
494#endif
495 return;
496 }
497
498#ifdef CONFIG_MAC80211_HT_DEBUG
499 printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n",
500 ra, tid);
501#endif /* CONFIG_MAC80211_HT_DEBUG */
502
503 rcu_read_lock();
504 sta = sta_info_get(local, ra);
505 if (!sta) {
506#ifdef CONFIG_MAC80211_HT_DEBUG
507 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
508#endif
509 rcu_read_unlock();
510 return;
511 }
512 state = &sta->ampdu_mlme.tid_state_tx[tid];
513
514 /* NOTE: no need to use sta->lock in this state check, as
515 * ieee80211_stop_tx_ba_session will let only one stop call to
516 * pass through per sta/tid
517 */
518 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
519#ifdef CONFIG_MAC80211_HT_DEBUG
520 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
521#endif
522 rcu_read_unlock();
523 return;
524 }
525
526 if (*state & HT_AGG_STATE_INITIATOR_MSK)
527 ieee80211_send_delba(sta->sdata, ra, tid,
528 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
529
530 if (hw->ampdu_queues) {
531 agg_queue = sta->tid_to_tx_q[tid];
532 ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
533
534 /* We just requeued the all the frames that were in the
535 * removed queue, and since we might miss a softirq we do
536 * netif_schedule_queue. ieee80211_wake_queue is not used
537 * here as this queue is not necessarily stopped
538 */
539 netif_schedule_queue(netdev_get_tx_queue(local->mdev,
540 agg_queue));
541 }
542 spin_lock_bh(&sta->lock);
543 *state = HT_AGG_STATE_IDLE;
544 sta->ampdu_mlme.addba_req_num[tid] = 0;
545 kfree(sta->ampdu_mlme.tid_tx[tid]);
546 sta->ampdu_mlme.tid_tx[tid] = NULL;
547 spin_unlock_bh(&sta->lock);
548
549 rcu_read_unlock();
550}
551EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
552
553void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
554 const u8 *ra, u16 tid)
555{
556 struct ieee80211_local *local = hw_to_local(hw);
557 struct ieee80211_ra_tid *ra_tid;
558 struct sk_buff *skb = dev_alloc_skb(0);
559
560 if (unlikely(!skb)) {
561#ifdef CONFIG_MAC80211_HT_DEBUG
562 if (net_ratelimit())
563 printk(KERN_WARNING "%s: Not enough memory, "
564 "dropping stop BA session", skb->dev->name);
565#endif
566 return;
567 }
568 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
569 memcpy(&ra_tid->ra, ra, ETH_ALEN);
570 ra_tid->tid = tid;
571
572 skb->pkt_type = IEEE80211_DELBA_MSG;
573 skb_queue_tail(&local->skb_queue, skb);
574 tasklet_schedule(&local->tasklet);
575}
576EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
577
578
579void ieee80211_process_addba_resp(struct ieee80211_local *local,
580 struct sta_info *sta,
581 struct ieee80211_mgmt *mgmt,
582 size_t len)
583{
584 struct ieee80211_hw *hw = &local->hw;
585 u16 capab;
586 u16 tid, start_seq_num;
587 u8 *state;
588
589 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
590 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
591
592 state = &sta->ampdu_mlme.tid_state_tx[tid];
593
594 spin_lock_bh(&sta->lock);
595
596 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
597 spin_unlock_bh(&sta->lock);
598 return;
599 }
600
601 if (mgmt->u.action.u.addba_resp.dialog_token !=
602 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
603 spin_unlock_bh(&sta->lock);
604#ifdef CONFIG_MAC80211_HT_DEBUG
605 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
606#endif /* CONFIG_MAC80211_HT_DEBUG */
607 return;
608 }
609
610 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
611#ifdef CONFIG_MAC80211_HT_DEBUG
612 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
613#endif /* CONFIG_MAC80211_HT_DEBUG */
614 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
615 == WLAN_STATUS_SUCCESS) {
616 *state |= HT_ADDBA_RECEIVED_MSK;
617 sta->ampdu_mlme.addba_req_num[tid] = 0;
618
619 if (*state == HT_AGG_STATE_OPERATIONAL &&
620 local->hw.ampdu_queues)
621 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
622
623 if (local->ops->ampdu_action) {
624 (void)local->ops->ampdu_action(hw,
625 IEEE80211_AMPDU_TX_RESUME,
626 &sta->sta, tid, &start_seq_num);
627 }
628#ifdef CONFIG_MAC80211_HT_DEBUG
629 printk(KERN_DEBUG "Resuming TX aggregation for tid %d\n", tid);
630#endif /* CONFIG_MAC80211_HT_DEBUG */
631 } else {
632 sta->ampdu_mlme.addba_req_num[tid]++;
633 ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
634 }
635 spin_unlock_bh(&sta->lock);
636}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a1a1344c5c4b..c8d969be440b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1176,11 +1176,16 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
1176 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 1176 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
1177} 1177}
1178 1178
1179static int set_mgmt_extra_ie_sta(struct ieee80211_if_sta *ifsta, u8 subtype, 1179static int set_mgmt_extra_ie_sta(struct ieee80211_sub_if_data *sdata,
1180 u8 *ies, size_t ies_len) 1180 u8 subtype, u8 *ies, size_t ies_len)
1181{ 1181{
1182 struct ieee80211_local *local = sdata->local;
1183 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1184
1182 switch (subtype) { 1185 switch (subtype) {
1183 case IEEE80211_STYPE_PROBE_REQ >> 4: 1186 case IEEE80211_STYPE_PROBE_REQ >> 4:
1187 if (local->ops->hw_scan)
1188 break;
1184 kfree(ifsta->ie_probereq); 1189 kfree(ifsta->ie_probereq);
1185 ifsta->ie_probereq = ies; 1190 ifsta->ie_probereq = ies;
1186 ifsta->ie_probereq_len = ies_len; 1191 ifsta->ie_probereq_len = ies_len;
@@ -1244,7 +1249,7 @@ static int ieee80211_set_mgmt_extra_ie(struct wiphy *wiphy,
1244 switch (sdata->vif.type) { 1249 switch (sdata->vif.type) {
1245 case NL80211_IFTYPE_STATION: 1250 case NL80211_IFTYPE_STATION:
1246 case NL80211_IFTYPE_ADHOC: 1251 case NL80211_IFTYPE_ADHOC:
1247 ret = set_mgmt_extra_ie_sta(&sdata->u.sta, params->subtype, 1252 ret = set_mgmt_extra_ie_sta(sdata, params->subtype,
1248 ies, ies_len); 1253 ies, ies_len);
1249 break; 1254 break;
1250 default: 1255 default:
@@ -1272,6 +1277,25 @@ static int ieee80211_resume(struct wiphy *wiphy)
1272#define ieee80211_resume NULL 1277#define ieee80211_resume NULL
1273#endif 1278#endif
1274 1279
1280static int ieee80211_scan(struct wiphy *wiphy,
1281 struct net_device *dev,
1282 struct cfg80211_scan_request *req)
1283{
1284 struct ieee80211_sub_if_data *sdata;
1285
1286 if (!netif_running(dev))
1287 return -ENETDOWN;
1288
1289 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1290
1291 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
1292 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1293 sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
1294 return -EOPNOTSUPP;
1295
1296 return ieee80211_request_scan(sdata, req);
1297}
1298
1275struct cfg80211_ops mac80211_config_ops = { 1299struct cfg80211_ops mac80211_config_ops = {
1276 .add_virtual_intf = ieee80211_add_iface, 1300 .add_virtual_intf = ieee80211_add_iface,
1277 .del_virtual_intf = ieee80211_del_iface, 1301 .del_virtual_intf = ieee80211_del_iface,
@@ -1304,4 +1328,5 @@ struct cfg80211_ops mac80211_config_ops = {
1304 .set_mgmt_extra_ie = ieee80211_set_mgmt_extra_ie, 1328 .set_mgmt_extra_ie = ieee80211_set_mgmt_extra_ie,
1305 .suspend = ieee80211_suspend, 1329 .suspend = ieee80211_suspend,
1306 .resume = ieee80211_resume, 1330 .resume = ieee80211_resume,
1331 .scan = ieee80211_scan,
1307}; 1332};
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 7a38d2e76ca9..82ea0b63a386 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -17,8 +17,6 @@
17#include <net/wireless.h> 17#include <net/wireless.h>
18#include <net/mac80211.h> 18#include <net/mac80211.h>
19#include "ieee80211_i.h" 19#include "ieee80211_i.h"
20#include "sta_info.h"
21#include "wme.h"
22 20
23void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, 21void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
24 struct ieee80211_ht_cap *ht_cap_ie, 22 struct ieee80211_ht_cap *ht_cap_ie,
@@ -155,105 +153,20 @@ u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
155 return changed; 153 return changed;
156} 154}
157 155
158static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, 156void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta)
159 const u8 *da, u16 tid,
160 u8 dialog_token, u16 start_seq_num,
161 u16 agg_size, u16 timeout)
162{ 157{
163 struct ieee80211_local *local = sdata->local; 158 int i;
164 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
165 struct sk_buff *skb;
166 struct ieee80211_mgmt *mgmt;
167 u16 capab;
168
169 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
170
171 if (!skb) {
172 printk(KERN_ERR "%s: failed to allocate buffer "
173 "for addba request frame\n", sdata->dev->name);
174 return;
175 }
176 skb_reserve(skb, local->hw.extra_tx_headroom);
177 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
178 memset(mgmt, 0, 24);
179 memcpy(mgmt->da, da, ETH_ALEN);
180 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
181 if (sdata->vif.type == NL80211_IFTYPE_AP)
182 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
183 else
184 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
185
186 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
187 IEEE80211_STYPE_ACTION);
188
189 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
190
191 mgmt->u.action.category = WLAN_CATEGORY_BACK;
192 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
193
194 mgmt->u.action.u.addba_req.dialog_token = dialog_token;
195 capab = (u16)(1 << 1); /* bit 1 aggregation policy */
196 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
197 capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */
198
199 mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
200
201 mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
202 mgmt->u.action.u.addba_req.start_seq_num =
203 cpu_to_le16(start_seq_num << 4);
204
205 ieee80211_tx_skb(sdata, skb, 1);
206}
207
208static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
209 u8 dialog_token, u16 status, u16 policy,
210 u16 buf_size, u16 timeout)
211{
212 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
213 struct ieee80211_local *local = sdata->local;
214 struct sk_buff *skb;
215 struct ieee80211_mgmt *mgmt;
216 u16 capab;
217
218 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
219 159
220 if (!skb) { 160 for (i = 0; i < STA_TID_NUM; i++) {
221 printk(KERN_DEBUG "%s: failed to allocate buffer " 161 __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR);
222 "for addba resp frame\n", sdata->dev->name); 162 __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
223 return; 163 WLAN_REASON_QSTA_LEAVE_QBSS);
224 } 164 }
225
226 skb_reserve(skb, local->hw.extra_tx_headroom);
227 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
228 memset(mgmt, 0, 24);
229 memcpy(mgmt->da, da, ETH_ALEN);
230 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
231 if (sdata->vif.type == NL80211_IFTYPE_AP)
232 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
233 else
234 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
235 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
236 IEEE80211_STYPE_ACTION);
237
238 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp));
239 mgmt->u.action.category = WLAN_CATEGORY_BACK;
240 mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
241 mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
242
243 capab = (u16)(policy << 1); /* bit 1 aggregation policy */
244 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
245 capab |= (u16)(buf_size << 6); /* bit 15:6 max size of aggregation */
246
247 mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab);
248 mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
249 mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
250
251 ieee80211_tx_skb(sdata, skb, 1);
252} 165}
253 166
254static void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, 167void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
255 const u8 *da, u16 tid, 168 const u8 *da, u16 tid,
256 u16 initiator, u16 reason_code) 169 u16 initiator, u16 reason_code)
257{ 170{
258 struct ieee80211_local *local = sdata->local; 171 struct ieee80211_local *local = sdata->local;
259 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 172 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
@@ -274,7 +187,8 @@ static void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
274 memset(mgmt, 0, 24); 187 memset(mgmt, 0, 24);
275 memcpy(mgmt->da, da, ETH_ALEN); 188 memcpy(mgmt->da, da, ETH_ALEN);
276 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 189 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
277 if (sdata->vif.type == NL80211_IFTYPE_AP) 190 if (sdata->vif.type == NL80211_IFTYPE_AP ||
191 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
278 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN); 192 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
279 else 193 else
280 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 194 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
@@ -294,767 +208,6 @@ static void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
294 ieee80211_tx_skb(sdata, skb, 1); 208 ieee80211_tx_skb(sdata, skb, 1);
295} 209}
296 210
297void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
298{
299 struct ieee80211_local *local = sdata->local;
300 struct sk_buff *skb;
301 struct ieee80211_bar *bar;
302 u16 bar_control = 0;
303
304 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
305 if (!skb) {
306 printk(KERN_ERR "%s: failed to allocate buffer for "
307 "bar frame\n", sdata->dev->name);
308 return;
309 }
310 skb_reserve(skb, local->hw.extra_tx_headroom);
311 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
312 memset(bar, 0, sizeof(*bar));
313 bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
314 IEEE80211_STYPE_BACK_REQ);
315 memcpy(bar->ra, ra, ETH_ALEN);
316 memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
317 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
318 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
319 bar_control |= (u16)(tid << 12);
320 bar->control = cpu_to_le16(bar_control);
321 bar->start_seq_num = cpu_to_le16(ssn);
322
323 ieee80211_tx_skb(sdata, skb, 0);
324}
325
326void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
327 u16 initiator, u16 reason)
328{
329 struct ieee80211_local *local = sdata->local;
330 struct ieee80211_hw *hw = &local->hw;
331 struct sta_info *sta;
332 int ret, i;
333
334 rcu_read_lock();
335
336 sta = sta_info_get(local, ra);
337 if (!sta) {
338 rcu_read_unlock();
339 return;
340 }
341
342 /* check if TID is in operational state */
343 spin_lock_bh(&sta->lock);
344 if (sta->ampdu_mlme.tid_state_rx[tid]
345 != HT_AGG_STATE_OPERATIONAL) {
346 spin_unlock_bh(&sta->lock);
347 rcu_read_unlock();
348 return;
349 }
350 sta->ampdu_mlme.tid_state_rx[tid] =
351 HT_AGG_STATE_REQ_STOP_BA_MSK |
352 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
353 spin_unlock_bh(&sta->lock);
354
355 /* stop HW Rx aggregation. ampdu_action existence
356 * already verified in session init so we add the BUG_ON */
357 BUG_ON(!local->ops->ampdu_action);
358
359#ifdef CONFIG_MAC80211_HT_DEBUG
360 printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n",
361 ra, tid);
362#endif /* CONFIG_MAC80211_HT_DEBUG */
363
364 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
365 &sta->sta, tid, NULL);
366 if (ret)
367 printk(KERN_DEBUG "HW problem - can not stop rx "
368 "aggregation for tid %d\n", tid);
369
370 /* shutdown timer has not expired */
371 if (initiator != WLAN_BACK_TIMER)
372 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
373
374 /* check if this is a self generated aggregation halt */
375 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
376 ieee80211_send_delba(sdata, ra, tid, 0, reason);
377
378 /* free the reordering buffer */
379 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
380 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
381 /* release the reordered frames */
382 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
383 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
384 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
385 }
386 }
387 /* free resources */
388 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
389 kfree(sta->ampdu_mlme.tid_rx[tid]);
390 sta->ampdu_mlme.tid_rx[tid] = NULL;
391 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
392
393 rcu_read_unlock();
394}
395
396
397/*
398 * After sending add Block Ack request we activated a timer until
399 * add Block Ack response will arrive from the recipient.
400 * If this timer expires sta_addba_resp_timer_expired will be executed.
401 */
402static void sta_addba_resp_timer_expired(unsigned long data)
403{
404 /* not an elegant detour, but there is no choice as the timer passes
405 * only one argument, and both sta_info and TID are needed, so init
406 * flow in sta_info_create gives the TID as data, while the timer_to_id
407 * array gives the sta through container_of */
408 u16 tid = *(u8 *)data;
409 struct sta_info *temp_sta = container_of((void *)data,
410 struct sta_info, timer_to_tid[tid]);
411
412 struct ieee80211_local *local = temp_sta->local;
413 struct ieee80211_hw *hw = &local->hw;
414 struct sta_info *sta;
415 u8 *state;
416
417 rcu_read_lock();
418
419 sta = sta_info_get(local, temp_sta->sta.addr);
420 if (!sta) {
421 rcu_read_unlock();
422 return;
423 }
424
425 state = &sta->ampdu_mlme.tid_state_tx[tid];
426 /* check if the TID waits for addBA response */
427 spin_lock_bh(&sta->lock);
428 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
429 spin_unlock_bh(&sta->lock);
430 *state = HT_AGG_STATE_IDLE;
431#ifdef CONFIG_MAC80211_HT_DEBUG
432 printk(KERN_DEBUG "timer expired on tid %d but we are not "
433 "expecting addBA response there", tid);
434#endif
435 goto timer_expired_exit;
436 }
437
438#ifdef CONFIG_MAC80211_HT_DEBUG
439 printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
440#endif
441
442 /* go through the state check in stop_BA_session */
443 *state = HT_AGG_STATE_OPERATIONAL;
444 spin_unlock_bh(&sta->lock);
445 ieee80211_stop_tx_ba_session(hw, temp_sta->sta.addr, tid,
446 WLAN_BACK_INITIATOR);
447
448timer_expired_exit:
449 rcu_read_unlock();
450}
451
452void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr)
453{
454 struct ieee80211_local *local = sdata->local;
455 int i;
456
457 for (i = 0; i < STA_TID_NUM; i++) {
458 ieee80211_stop_tx_ba_session(&local->hw, addr, i,
459 WLAN_BACK_INITIATOR);
460 ieee80211_sta_stop_rx_ba_session(sdata, addr, i,
461 WLAN_BACK_RECIPIENT,
462 WLAN_REASON_QSTA_LEAVE_QBSS);
463 }
464}
465
466int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
467{
468 struct ieee80211_local *local = hw_to_local(hw);
469 struct sta_info *sta;
470 struct ieee80211_sub_if_data *sdata;
471 u16 start_seq_num;
472 u8 *state;
473 int ret = 0;
474
475 if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
476 return -EINVAL;
477
478#ifdef CONFIG_MAC80211_HT_DEBUG
479 printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n",
480 ra, tid);
481#endif /* CONFIG_MAC80211_HT_DEBUG */
482
483 rcu_read_lock();
484
485 sta = sta_info_get(local, ra);
486 if (!sta) {
487#ifdef CONFIG_MAC80211_HT_DEBUG
488 printk(KERN_DEBUG "Could not find the station\n");
489#endif
490 ret = -ENOENT;
491 goto exit;
492 }
493
494 spin_lock_bh(&sta->lock);
495
496 /* we have tried too many times, receiver does not want A-MPDU */
497 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
498 ret = -EBUSY;
499 goto err_unlock_sta;
500 }
501
502 state = &sta->ampdu_mlme.tid_state_tx[tid];
503 /* check if the TID is not in aggregation flow already */
504 if (*state != HT_AGG_STATE_IDLE) {
505#ifdef CONFIG_MAC80211_HT_DEBUG
506 printk(KERN_DEBUG "BA request denied - session is not "
507 "idle on tid %u\n", tid);
508#endif /* CONFIG_MAC80211_HT_DEBUG */
509 ret = -EAGAIN;
510 goto err_unlock_sta;
511 }
512
513 /* prepare A-MPDU MLME for Tx aggregation */
514 sta->ampdu_mlme.tid_tx[tid] =
515 kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
516 if (!sta->ampdu_mlme.tid_tx[tid]) {
517#ifdef CONFIG_MAC80211_HT_DEBUG
518 if (net_ratelimit())
519 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
520 tid);
521#endif
522 ret = -ENOMEM;
523 goto err_unlock_sta;
524 }
525 /* Tx timer */
526 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
527 sta_addba_resp_timer_expired;
528 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
529 (unsigned long)&sta->timer_to_tid[tid];
530 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
531
532 if (hw->ampdu_queues) {
533 /* create a new queue for this aggregation */
534 ret = ieee80211_ht_agg_queue_add(local, sta, tid);
535
536 /* case no queue is available to aggregation
537 * don't switch to aggregation */
538 if (ret) {
539#ifdef CONFIG_MAC80211_HT_DEBUG
540 printk(KERN_DEBUG "BA request denied - "
541 "queue unavailable for tid %d\n", tid);
542#endif /* CONFIG_MAC80211_HT_DEBUG */
543 goto err_unlock_queue;
544 }
545 }
546 sdata = sta->sdata;
547
548 /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
549 * call back right away, it must see that the flow has begun */
550 *state |= HT_ADDBA_REQUESTED_MSK;
551
552 /* This is slightly racy because the queue isn't stopped */
553 start_seq_num = sta->tid_seq[tid];
554
555 if (local->ops->ampdu_action)
556 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
557 &sta->sta, tid, &start_seq_num);
558
559 if (ret) {
560 /* No need to requeue the packets in the agg queue, since we
561 * held the tx lock: no packet could be enqueued to the newly
562 * allocated queue */
563 if (hw->ampdu_queues)
564 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
565#ifdef CONFIG_MAC80211_HT_DEBUG
566 printk(KERN_DEBUG "BA request denied - HW unavailable for"
567 " tid %d\n", tid);
568#endif /* CONFIG_MAC80211_HT_DEBUG */
569 *state = HT_AGG_STATE_IDLE;
570 goto err_unlock_queue;
571 }
572
573 /* Will put all the packets in the new SW queue */
574 if (hw->ampdu_queues)
575 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
576 spin_unlock_bh(&sta->lock);
577
578 /* send an addBA request */
579 sta->ampdu_mlme.dialog_token_allocator++;
580 sta->ampdu_mlme.tid_tx[tid]->dialog_token =
581 sta->ampdu_mlme.dialog_token_allocator;
582 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
583
584
585 ieee80211_send_addba_request(sta->sdata, ra, tid,
586 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
587 sta->ampdu_mlme.tid_tx[tid]->ssn,
588 0x40, 5000);
589 /* activate the timer for the recipient's addBA response */
590 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
591 jiffies + ADDBA_RESP_INTERVAL;
592 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
593#ifdef CONFIG_MAC80211_HT_DEBUG
594 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
595#endif
596 goto exit;
597
598err_unlock_queue:
599 kfree(sta->ampdu_mlme.tid_tx[tid]);
600 sta->ampdu_mlme.tid_tx[tid] = NULL;
601 ret = -EBUSY;
602err_unlock_sta:
603 spin_unlock_bh(&sta->lock);
604exit:
605 rcu_read_unlock();
606 return ret;
607}
608EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
609
610int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
611 u8 *ra, u16 tid,
612 enum ieee80211_back_parties initiator)
613{
614 struct ieee80211_local *local = hw_to_local(hw);
615 struct sta_info *sta;
616 u8 *state;
617 int ret = 0;
618
619 if (tid >= STA_TID_NUM)
620 return -EINVAL;
621
622 rcu_read_lock();
623 sta = sta_info_get(local, ra);
624 if (!sta) {
625 rcu_read_unlock();
626 return -ENOENT;
627 }
628
629 /* check if the TID is in aggregation */
630 state = &sta->ampdu_mlme.tid_state_tx[tid];
631 spin_lock_bh(&sta->lock);
632
633 if (*state != HT_AGG_STATE_OPERATIONAL) {
634 ret = -ENOENT;
635 goto stop_BA_exit;
636 }
637
638#ifdef CONFIG_MAC80211_HT_DEBUG
639 printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
640 ra, tid);
641#endif /* CONFIG_MAC80211_HT_DEBUG */
642
643 if (hw->ampdu_queues)
644 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
645
646 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
647 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
648
649 if (local->ops->ampdu_action)
650 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP,
651 &sta->sta, tid, NULL);
652
653 /* case HW denied going back to legacy */
654 if (ret) {
655 WARN_ON(ret != -EBUSY);
656 *state = HT_AGG_STATE_OPERATIONAL;
657 if (hw->ampdu_queues)
658 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
659 goto stop_BA_exit;
660 }
661
662stop_BA_exit:
663 spin_unlock_bh(&sta->lock);
664 rcu_read_unlock();
665 return ret;
666}
667EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
668
669void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
670{
671 struct ieee80211_local *local = hw_to_local(hw);
672 struct sta_info *sta;
673 u8 *state;
674
675 if (tid >= STA_TID_NUM) {
676#ifdef CONFIG_MAC80211_HT_DEBUG
677 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
678 tid, STA_TID_NUM);
679#endif
680 return;
681 }
682
683 rcu_read_lock();
684 sta = sta_info_get(local, ra);
685 if (!sta) {
686 rcu_read_unlock();
687#ifdef CONFIG_MAC80211_HT_DEBUG
688 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
689#endif
690 return;
691 }
692
693 state = &sta->ampdu_mlme.tid_state_tx[tid];
694 spin_lock_bh(&sta->lock);
695
696 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
697#ifdef CONFIG_MAC80211_HT_DEBUG
698 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
699 *state);
700#endif
701 spin_unlock_bh(&sta->lock);
702 rcu_read_unlock();
703 return;
704 }
705
706 WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK);
707
708 *state |= HT_ADDBA_DRV_READY_MSK;
709
710 if (*state == HT_AGG_STATE_OPERATIONAL) {
711#ifdef CONFIG_MAC80211_HT_DEBUG
712 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
713#endif
714 if (hw->ampdu_queues)
715 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
716 }
717 spin_unlock_bh(&sta->lock);
718 rcu_read_unlock();
719}
720EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
721
722void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
723{
724 struct ieee80211_local *local = hw_to_local(hw);
725 struct sta_info *sta;
726 u8 *state;
727 int agg_queue;
728
729 if (tid >= STA_TID_NUM) {
730#ifdef CONFIG_MAC80211_HT_DEBUG
731 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
732 tid, STA_TID_NUM);
733#endif
734 return;
735 }
736
737#ifdef CONFIG_MAC80211_HT_DEBUG
738 printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n",
739 ra, tid);
740#endif /* CONFIG_MAC80211_HT_DEBUG */
741
742 rcu_read_lock();
743 sta = sta_info_get(local, ra);
744 if (!sta) {
745#ifdef CONFIG_MAC80211_HT_DEBUG
746 printk(KERN_DEBUG "Could not find station: %pM\n", ra);
747#endif
748 rcu_read_unlock();
749 return;
750 }
751 state = &sta->ampdu_mlme.tid_state_tx[tid];
752
753 /* NOTE: no need to use sta->lock in this state check, as
754 * ieee80211_stop_tx_ba_session will let only one stop call to
755 * pass through per sta/tid
756 */
757 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
758#ifdef CONFIG_MAC80211_HT_DEBUG
759 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
760#endif
761 rcu_read_unlock();
762 return;
763 }
764
765 if (*state & HT_AGG_STATE_INITIATOR_MSK)
766 ieee80211_send_delba(sta->sdata, ra, tid,
767 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
768
769 if (hw->ampdu_queues) {
770 agg_queue = sta->tid_to_tx_q[tid];
771 ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
772
773 /* We just requeued the all the frames that were in the
774 * removed queue, and since we might miss a softirq we do
775 * netif_schedule_queue. ieee80211_wake_queue is not used
776 * here as this queue is not necessarily stopped
777 */
778 netif_schedule_queue(netdev_get_tx_queue(local->mdev,
779 agg_queue));
780 }
781 spin_lock_bh(&sta->lock);
782 *state = HT_AGG_STATE_IDLE;
783 sta->ampdu_mlme.addba_req_num[tid] = 0;
784 kfree(sta->ampdu_mlme.tid_tx[tid]);
785 sta->ampdu_mlme.tid_tx[tid] = NULL;
786 spin_unlock_bh(&sta->lock);
787
788 rcu_read_unlock();
789}
790EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
791
792void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
793 const u8 *ra, u16 tid)
794{
795 struct ieee80211_local *local = hw_to_local(hw);
796 struct ieee80211_ra_tid *ra_tid;
797 struct sk_buff *skb = dev_alloc_skb(0);
798
799 if (unlikely(!skb)) {
800#ifdef CONFIG_MAC80211_HT_DEBUG
801 if (net_ratelimit())
802 printk(KERN_WARNING "%s: Not enough memory, "
803 "dropping start BA session", skb->dev->name);
804#endif
805 return;
806 }
807 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
808 memcpy(&ra_tid->ra, ra, ETH_ALEN);
809 ra_tid->tid = tid;
810
811 skb->pkt_type = IEEE80211_ADDBA_MSG;
812 skb_queue_tail(&local->skb_queue, skb);
813 tasklet_schedule(&local->tasklet);
814}
815EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
816
817void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
818 const u8 *ra, u16 tid)
819{
820 struct ieee80211_local *local = hw_to_local(hw);
821 struct ieee80211_ra_tid *ra_tid;
822 struct sk_buff *skb = dev_alloc_skb(0);
823
824 if (unlikely(!skb)) {
825#ifdef CONFIG_MAC80211_HT_DEBUG
826 if (net_ratelimit())
827 printk(KERN_WARNING "%s: Not enough memory, "
828 "dropping stop BA session", skb->dev->name);
829#endif
830 return;
831 }
832 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
833 memcpy(&ra_tid->ra, ra, ETH_ALEN);
834 ra_tid->tid = tid;
835
836 skb->pkt_type = IEEE80211_DELBA_MSG;
837 skb_queue_tail(&local->skb_queue, skb);
838 tasklet_schedule(&local->tasklet);
839}
840EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
841
842/*
843 * After accepting the AddBA Request we activated a timer,
844 * resetting it after each frame that arrives from the originator.
845 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
846 */
847static void sta_rx_agg_session_timer_expired(unsigned long data)
848{
849 /* not an elegant detour, but there is no choice as the timer passes
850 * only one argument, and various sta_info are needed here, so init
851 * flow in sta_info_create gives the TID as data, while the timer_to_id
852 * array gives the sta through container_of */
853 u8 *ptid = (u8 *)data;
854 u8 *timer_to_id = ptid - *ptid;
855 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
856 timer_to_tid[0]);
857
858#ifdef CONFIG_MAC80211_HT_DEBUG
859 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
860#endif
861 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr,
862 (u16)*ptid, WLAN_BACK_TIMER,
863 WLAN_REASON_QSTA_TIMEOUT);
864}
865
866void ieee80211_process_addba_request(struct ieee80211_local *local,
867 struct sta_info *sta,
868 struct ieee80211_mgmt *mgmt,
869 size_t len)
870{
871 struct ieee80211_hw *hw = &local->hw;
872 struct ieee80211_conf *conf = &hw->conf;
873 struct tid_ampdu_rx *tid_agg_rx;
874 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
875 u8 dialog_token;
876 int ret = -EOPNOTSUPP;
877
878 /* extract session parameters from addba request frame */
879 dialog_token = mgmt->u.action.u.addba_req.dialog_token;
880 timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout);
881 start_seq_num =
882 le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
883
884 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
885 ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
886 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
887 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
888
889 status = WLAN_STATUS_REQUEST_DECLINED;
890
891 /* sanity check for incoming parameters:
892 * check if configuration can support the BA policy
893 * and if buffer size does not exceeds max value */
894 /* XXX: check own ht delayed BA capability?? */
895 if (((ba_policy != 1)
896 && (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA)))
897 || (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
898 status = WLAN_STATUS_INVALID_QOS_PARAM;
899#ifdef CONFIG_MAC80211_HT_DEBUG
900 if (net_ratelimit())
901 printk(KERN_DEBUG "AddBA Req with bad params from "
902 "%pM on tid %u. policy %d, buffer size %d\n",
903 mgmt->sa, tid, ba_policy,
904 buf_size);
905#endif /* CONFIG_MAC80211_HT_DEBUG */
906 goto end_no_lock;
907 }
908 /* determine default buffer size */
909 if (buf_size == 0) {
910 struct ieee80211_supported_band *sband;
911
912 sband = local->hw.wiphy->bands[conf->channel->band];
913 buf_size = IEEE80211_MIN_AMPDU_BUF;
914 buf_size = buf_size << sband->ht_cap.ampdu_factor;
915 }
916
917
918 /* examine state machine */
919 spin_lock_bh(&sta->lock);
920
921 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
922#ifdef CONFIG_MAC80211_HT_DEBUG
923 if (net_ratelimit())
924 printk(KERN_DEBUG "unexpected AddBA Req from "
925 "%pM on tid %u\n",
926 mgmt->sa, tid);
927#endif /* CONFIG_MAC80211_HT_DEBUG */
928 goto end;
929 }
930
931 /* prepare A-MPDU MLME for Rx aggregation */
932 sta->ampdu_mlme.tid_rx[tid] =
933 kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
934 if (!sta->ampdu_mlme.tid_rx[tid]) {
935#ifdef CONFIG_MAC80211_HT_DEBUG
936 if (net_ratelimit())
937 printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
938 tid);
939#endif
940 goto end;
941 }
942 /* rx timer */
943 sta->ampdu_mlme.tid_rx[tid]->session_timer.function =
944 sta_rx_agg_session_timer_expired;
945 sta->ampdu_mlme.tid_rx[tid]->session_timer.data =
946 (unsigned long)&sta->timer_to_tid[tid];
947 init_timer(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
948
949 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
950
951 /* prepare reordering buffer */
952 tid_agg_rx->reorder_buf =
953 kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC);
954 if (!tid_agg_rx->reorder_buf) {
955#ifdef CONFIG_MAC80211_HT_DEBUG
956 if (net_ratelimit())
957 printk(KERN_ERR "can not allocate reordering buffer "
958 "to tid %d\n", tid);
959#endif
960 kfree(sta->ampdu_mlme.tid_rx[tid]);
961 goto end;
962 }
963
964 if (local->ops->ampdu_action)
965 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
966 &sta->sta, tid, &start_seq_num);
967#ifdef CONFIG_MAC80211_HT_DEBUG
968 printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
969#endif /* CONFIG_MAC80211_HT_DEBUG */
970
971 if (ret) {
972 kfree(tid_agg_rx->reorder_buf);
973 kfree(tid_agg_rx);
974 sta->ampdu_mlme.tid_rx[tid] = NULL;
975 goto end;
976 }
977
978 /* change state and send addba resp */
979 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
980 tid_agg_rx->dialog_token = dialog_token;
981 tid_agg_rx->ssn = start_seq_num;
982 tid_agg_rx->head_seq_num = start_seq_num;
983 tid_agg_rx->buf_size = buf_size;
984 tid_agg_rx->timeout = timeout;
985 tid_agg_rx->stored_mpdu_num = 0;
986 status = WLAN_STATUS_SUCCESS;
987end:
988 spin_unlock_bh(&sta->lock);
989
990end_no_lock:
991 ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid,
992 dialog_token, status, 1, buf_size, timeout);
993}
994
995void ieee80211_process_addba_resp(struct ieee80211_local *local,
996 struct sta_info *sta,
997 struct ieee80211_mgmt *mgmt,
998 size_t len)
999{
1000 struct ieee80211_hw *hw = &local->hw;
1001 u16 capab;
1002 u16 tid, start_seq_num;
1003 u8 *state;
1004
1005 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
1006 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
1007
1008 state = &sta->ampdu_mlme.tid_state_tx[tid];
1009
1010 spin_lock_bh(&sta->lock);
1011
1012 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1013 spin_unlock_bh(&sta->lock);
1014 return;
1015 }
1016
1017 if (mgmt->u.action.u.addba_resp.dialog_token !=
1018 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
1019 spin_unlock_bh(&sta->lock);
1020#ifdef CONFIG_MAC80211_HT_DEBUG
1021 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
1022#endif /* CONFIG_MAC80211_HT_DEBUG */
1023 return;
1024 }
1025
1026 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
1027#ifdef CONFIG_MAC80211_HT_DEBUG
1028 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
1029#endif /* CONFIG_MAC80211_HT_DEBUG */
1030 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
1031 == WLAN_STATUS_SUCCESS) {
1032 *state |= HT_ADDBA_RECEIVED_MSK;
1033 sta->ampdu_mlme.addba_req_num[tid] = 0;
1034
1035 if (*state == HT_AGG_STATE_OPERATIONAL &&
1036 local->hw.ampdu_queues)
1037 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
1038
1039 if (local->ops->ampdu_action) {
1040 (void)local->ops->ampdu_action(hw,
1041 IEEE80211_AMPDU_TX_RESUME,
1042 &sta->sta, tid, &start_seq_num);
1043 }
1044#ifdef CONFIG_MAC80211_HT_DEBUG
1045 printk(KERN_DEBUG "Resuming TX aggregation for tid %d\n", tid);
1046#endif /* CONFIG_MAC80211_HT_DEBUG */
1047 spin_unlock_bh(&sta->lock);
1048 } else {
1049 sta->ampdu_mlme.addba_req_num[tid]++;
1050 /* this will allow the state check in stop_BA_session */
1051 *state = HT_AGG_STATE_OPERATIONAL;
1052 spin_unlock_bh(&sta->lock);
1053 ieee80211_stop_tx_ba_session(hw, sta->sta.addr, tid,
1054 WLAN_BACK_INITIATOR);
1055 }
1056}
1057
1058void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, 211void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
1059 struct sta_info *sta, 212 struct sta_info *sta,
1060 struct ieee80211_mgmt *mgmt, size_t len) 213 struct ieee80211_mgmt *mgmt, size_t len)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index eaf3603862b7..2cb743ed9f9c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -57,6 +57,8 @@ struct ieee80211_local;
57 */ 57 */
58#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ) 58#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ)
59 59
60#define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024))
61
60struct ieee80211_fragment_entry { 62struct ieee80211_fragment_entry {
61 unsigned long first_frag_time; 63 unsigned long first_frag_time;
62 unsigned int seq; 64 unsigned int seq;
@@ -70,43 +72,36 @@ struct ieee80211_fragment_entry {
70 72
71 73
72struct ieee80211_bss { 74struct ieee80211_bss {
73 struct list_head list; 75 /* Yes, this is a hack */
74 struct ieee80211_bss *hnext; 76 struct cfg80211_bss cbss;
75 size_t ssid_len;
76 77
77 atomic_t users; 78 /* don't want to look up all the time */
78 79 size_t ssid_len;
79 u8 bssid[ETH_ALEN];
80 u8 ssid[IEEE80211_MAX_SSID_LEN]; 80 u8 ssid[IEEE80211_MAX_SSID_LEN];
81
81 u8 dtim_period; 82 u8 dtim_period;
82 u16 capability; /* host byte order */ 83
83 enum ieee80211_band band;
84 int freq;
85 int signal, noise, qual;
86 u8 *ies; /* all information elements from the last Beacon or Probe
87 * Response frames; note Beacon frame is not allowed to
88 * override values from Probe Response */
89 size_t ies_len;
90 bool wmm_used; 84 bool wmm_used;
85
86 unsigned long last_probe_resp;
87
91#ifdef CONFIG_MAC80211_MESH 88#ifdef CONFIG_MAC80211_MESH
92 u8 *mesh_id; 89 u8 *mesh_id;
93 size_t mesh_id_len; 90 size_t mesh_id_len;
94 u8 *mesh_cfg; 91 u8 *mesh_cfg;
95#endif 92#endif
93
96#define IEEE80211_MAX_SUPP_RATES 32 94#define IEEE80211_MAX_SUPP_RATES 32
97 u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; 95 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
98 size_t supp_rates_len; 96 size_t supp_rates_len;
99 u64 timestamp;
100 int beacon_int;
101 97
102 unsigned long last_probe_resp; 98 /*
103 unsigned long last_update; 99 * During assocation, we save an ERP value from a probe response so
104
105 /* during assocation, we save an ERP value from a probe response so
106 * that we can feed ERP info to the driver when handling the 100 * that we can feed ERP info to the driver when handling the
107 * association completes. these fields probably won't be up-to-date 101 * association completes. these fields probably won't be up-to-date
108 * otherwise, you probably don't want to use them. */ 102 * otherwise, you probably don't want to use them.
109 int has_erp_value; 103 */
104 bool has_erp_value;
110 u8 erp_value; 105 u8 erp_value;
111}; 106};
112 107
@@ -292,8 +287,6 @@ struct ieee80211_if_sta {
292 u8 ssid[IEEE80211_MAX_SSID_LEN]; 287 u8 ssid[IEEE80211_MAX_SSID_LEN];
293 enum ieee80211_sta_mlme_state state; 288 enum ieee80211_sta_mlme_state state;
294 size_t ssid_len; 289 size_t ssid_len;
295 u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
296 size_t scan_ssid_len;
297 u16 aid; 290 u16 aid;
298 u16 ap_capab, capab; 291 u16 ap_capab, capab;
299 u8 *extra_ie; /* to be added to the end of AssocReq */ 292 u8 *extra_ie; /* to be added to the end of AssocReq */
@@ -599,7 +592,6 @@ struct ieee80211_local {
599 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss; 592 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss;
600 unsigned int filter_flags; /* FIF_* */ 593 unsigned int filter_flags; /* FIF_* */
601 struct iw_statistics wstats; 594 struct iw_statistics wstats;
602 u8 wstats_flags;
603 bool tim_in_locked_section; /* see ieee80211_beacon_get() */ 595 bool tim_in_locked_section; /* see ieee80211_beacon_get() */
604 int tx_headroom; /* required headroom for hardware/radiotap */ 596 int tx_headroom; /* required headroom for hardware/radiotap */
605 597
@@ -656,20 +648,18 @@ struct ieee80211_local {
656 648
657 /* Scanning and BSS list */ 649 /* Scanning and BSS list */
658 bool sw_scanning, hw_scanning; 650 bool sw_scanning, hw_scanning;
651 struct cfg80211_ssid scan_ssid;
652 struct cfg80211_scan_request int_scan_req;
653 struct cfg80211_scan_request *scan_req;
654 struct ieee80211_channel *scan_channel;
659 int scan_channel_idx; 655 int scan_channel_idx;
660 enum ieee80211_band scan_band;
661 656
662 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; 657 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
663 unsigned long last_scan_completed; 658 unsigned long last_scan_completed;
664 struct delayed_work scan_work; 659 struct delayed_work scan_work;
665 struct ieee80211_sub_if_data *scan_sdata; 660 struct ieee80211_sub_if_data *scan_sdata;
666 struct ieee80211_channel *oper_channel, *scan_channel, *csa_channel;
667 enum nl80211_channel_type oper_channel_type; 661 enum nl80211_channel_type oper_channel_type;
668 u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; 662 struct ieee80211_channel *oper_channel, *csa_channel;
669 size_t scan_ssid_len;
670 struct list_head bss_list;
671 struct ieee80211_bss *bss_hash[STA_HASH_SIZE];
672 spinlock_t bss_lock;
673 663
674 /* SNMP counters */ 664 /* SNMP counters */
675 /* dot11CountersTable */ 665 /* dot11CountersTable */
@@ -728,6 +718,7 @@ struct ieee80211_local {
728 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ 718 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
729 719
730 bool powersave; 720 bool powersave;
721 bool pspolling;
731 struct work_struct dynamic_ps_enable_work; 722 struct work_struct dynamic_ps_enable_work;
732 struct work_struct dynamic_ps_disable_work; 723 struct work_struct dynamic_ps_disable_work;
733 struct timer_list dynamic_ps_timer; 724 struct timer_list dynamic_ps_timer;
@@ -921,10 +912,12 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
921 enum ieee80211_band band); 912 enum ieee80211_band band);
922void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 913void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
923 u8 *ssid, size_t ssid_len); 914 u8 *ssid, size_t ssid_len);
915void ieee80211_send_pspoll(struct ieee80211_local *local,
916 struct ieee80211_sub_if_data *sdata);
924 917
925/* scan/BSS handling */ 918/* scan/BSS handling */
926int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, 919int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
927 u8 *ssid, size_t ssid_len); 920 struct cfg80211_scan_request *req);
928int ieee80211_scan_results(struct ieee80211_local *local, 921int ieee80211_scan_results(struct ieee80211_local *local,
929 struct iw_request_info *info, 922 struct iw_request_info *info,
930 char *buf, size_t len); 923 char *buf, size_t len);
@@ -932,29 +925,27 @@ ieee80211_rx_result
932ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, 925ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata,
933 struct sk_buff *skb, 926 struct sk_buff *skb,
934 struct ieee80211_rx_status *rx_status); 927 struct ieee80211_rx_status *rx_status);
935void ieee80211_rx_bss_list_init(struct ieee80211_local *local);
936void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local);
937int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, 928int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
938 char *ie, size_t len); 929 char *ie, size_t len);
939 930
940void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); 931void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
941int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata, 932int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
942 u8 *ssid, size_t ssid_len); 933 struct cfg80211_scan_request *req);
943struct ieee80211_bss * 934struct ieee80211_bss *
944ieee80211_bss_info_update(struct ieee80211_local *local, 935ieee80211_bss_info_update(struct ieee80211_local *local,
945 struct ieee80211_rx_status *rx_status, 936 struct ieee80211_rx_status *rx_status,
946 struct ieee80211_mgmt *mgmt, 937 struct ieee80211_mgmt *mgmt,
947 size_t len, 938 size_t len,
948 struct ieee802_11_elems *elems, 939 struct ieee802_11_elems *elems,
949 int freq, bool beacon); 940 struct ieee80211_channel *channel,
950struct ieee80211_bss * 941 bool beacon);
951ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
952 u8 *ssid, u8 ssid_len);
953struct ieee80211_bss * 942struct ieee80211_bss *
954ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, 943ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
955 u8 *ssid, u8 ssid_len); 944 u8 *ssid, u8 ssid_len);
956void ieee80211_rx_bss_put(struct ieee80211_local *local, 945void ieee80211_rx_bss_put(struct ieee80211_local *local,
957 struct ieee80211_bss *bss); 946 struct ieee80211_bss *bss);
947void ieee80211_rx_bss_remove(struct ieee80211_sub_if_data *sdata, u8 *bssid,
948 int freq, u8 *ssid, u8 ssid_len);
958 949
959/* interface handling */ 950/* interface handling */
960int ieee80211_if_add(struct ieee80211_local *local, const char *name, 951int ieee80211_if_add(struct ieee80211_local *local, const char *name,
@@ -980,10 +971,15 @@ u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
980 struct ieee80211_ht_info *hti, 971 struct ieee80211_ht_info *hti,
981 u16 ap_ht_cap_flags); 972 u16 ap_ht_cap_flags);
982void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); 973void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
974void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
975 const u8 *da, u16 tid,
976 u16 initiator, u16 reason_code);
983 977
984void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, 978void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da,
985 u16 tid, u16 initiator, u16 reason); 979 u16 tid, u16 initiator, u16 reason);
986void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr); 980void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
981 u16 initiator, u16 reason);
982void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta);
987void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, 983void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
988 struct sta_info *sta, 984 struct sta_info *sta,
989 struct ieee80211_mgmt *mgmt, size_t len); 985 struct ieee80211_mgmt *mgmt, size_t len);
@@ -996,6 +992,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
996 struct ieee80211_mgmt *mgmt, 992 struct ieee80211_mgmt *mgmt,
997 size_t len); 993 size_t len);
998 994
995int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
996 enum ieee80211_back_parties initiator);
997
999/* Spectrum management */ 998/* Spectrum management */
1000void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, 999void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
1001 struct ieee80211_mgmt *mgmt, 1000 struct ieee80211_mgmt *mgmt,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 915d04323a32..df94b9365264 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -362,8 +362,7 @@ static int ieee80211_stop(struct net_device *dev)
362 362
363 list_for_each_entry_rcu(sta, &local->sta_list, list) { 363 list_for_each_entry_rcu(sta, &local->sta_list, list) {
364 if (sta->sdata == sdata) 364 if (sta->sdata == sdata)
365 ieee80211_sta_tear_down_BA_sessions(sdata, 365 ieee80211_sta_tear_down_BA_sessions(sta);
366 sta->sta.addr);
367 } 366 }
368 367
369 rcu_read_unlock(); 368 rcu_read_unlock();
@@ -523,7 +522,7 @@ static int ieee80211_stop(struct net_device *dev)
523 * scan event to userspace -- the scan is incomplete. 522 * scan event to userspace -- the scan is incomplete.
524 */ 523 */
525 if (local->sw_scanning) 524 if (local->sw_scanning)
526 ieee80211_scan_completed(&local->hw); 525 ieee80211_scan_completed(&local->hw, true);
527 } 526 }
528 527
529 conf.vif = &sdata->vif; 528 conf.vif = &sdata->vif;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index caf92424c76d..5667f4e8067f 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -210,6 +210,8 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
210 !!rcu_dereference(sdata->u.ap.beacon); 210 !!rcu_dereference(sdata->u.ap.beacon);
211 break; 211 break;
212 case NL80211_IFTYPE_ADHOC: 212 case NL80211_IFTYPE_ADHOC:
213 conf.enable_beacon = !!sdata->u.sta.probe_resp;
214 break;
213 case NL80211_IFTYPE_MESH_POINT: 215 case NL80211_IFTYPE_MESH_POINT:
214 conf.enable_beacon = true; 216 conf.enable_beacon = true;
215 break; 217 break;
@@ -731,6 +733,10 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
731 return NULL; 733 return NULL;
732 734
733 wiphy->privid = mac80211_wiphy_privid; 735 wiphy->privid = mac80211_wiphy_privid;
736 wiphy->max_scan_ssids = 4;
737 /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */
738 wiphy->bss_priv_size = sizeof(struct ieee80211_bss) -
739 sizeof(struct cfg80211_bss);
734 740
735 local = wiphy_priv(wiphy); 741 local = wiphy_priv(wiphy);
736 local->hw.wiphy = wiphy; 742 local->hw.wiphy = wiphy;
@@ -815,25 +821,33 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
815 enum ieee80211_band band; 821 enum ieee80211_band band;
816 struct net_device *mdev; 822 struct net_device *mdev;
817 struct ieee80211_master_priv *mpriv; 823 struct ieee80211_master_priv *mpriv;
824 int channels, i, j;
818 825
819 /* 826 /*
820 * generic code guarantees at least one band, 827 * generic code guarantees at least one band,
821 * set this very early because much code assumes 828 * set this very early because much code assumes
822 * that hw.conf.channel is assigned 829 * that hw.conf.channel is assigned
823 */ 830 */
831 channels = 0;
824 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 832 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
825 struct ieee80211_supported_band *sband; 833 struct ieee80211_supported_band *sband;
826 834
827 sband = local->hw.wiphy->bands[band]; 835 sband = local->hw.wiphy->bands[band];
828 if (sband) { 836 if (sband && !local->oper_channel) {
829 /* init channel we're on */ 837 /* init channel we're on */
830 local->hw.conf.channel = 838 local->hw.conf.channel =
831 local->oper_channel = 839 local->oper_channel =
832 local->scan_channel = &sband->channels[0]; 840 local->scan_channel = &sband->channels[0];
833 break;
834 } 841 }
842 if (sband)
843 channels += sband->n_channels;
835 } 844 }
836 845
846 local->int_scan_req.n_channels = channels;
847 local->int_scan_req.channels = kzalloc(sizeof(void *) * channels, GFP_KERNEL);
848 if (!local->int_scan_req.channels)
849 return -ENOMEM;
850
837 /* if low-level driver supports AP, we also support VLAN */ 851 /* if low-level driver supports AP, we also support VLAN */
838 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) 852 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP))
839 local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); 853 local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
@@ -843,7 +857,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
843 857
844 result = wiphy_register(local->hw.wiphy); 858 result = wiphy_register(local->hw.wiphy);
845 if (result < 0) 859 if (result < 0)
846 return result; 860 goto fail_wiphy_register;
847 861
848 /* 862 /*
849 * We use the number of queues for feature tests (QoS, HT) internally 863 * We use the number of queues for feature tests (QoS, HT) internally
@@ -866,8 +880,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
866 mpriv->local = local; 880 mpriv->local = local;
867 local->mdev = mdev; 881 local->mdev = mdev;
868 882
869 ieee80211_rx_bss_list_init(local);
870
871 local->hw.workqueue = 883 local->hw.workqueue =
872 create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); 884 create_singlethread_workqueue(wiphy_name(local->hw.wiphy));
873 if (!local->hw.workqueue) { 885 if (!local->hw.workqueue) {
@@ -893,14 +905,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
893 905
894 local->hw.conf.listen_interval = local->hw.max_listen_interval; 906 local->hw.conf.listen_interval = local->hw.max_listen_interval;
895 907
896 local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
897 IEEE80211_HW_SIGNAL_DBM) ?
898 IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID;
899 local->wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ?
900 IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID;
901 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
902 local->wstats_flags |= IW_QUAL_DBM;
903
904 result = sta_info_start(local); 908 result = sta_info_start(local);
905 if (result < 0) 909 if (result < 0)
906 goto fail_sta_info; 910 goto fail_sta_info;
@@ -946,6 +950,20 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
946 950
947 ieee80211_led_init(local); 951 ieee80211_led_init(local);
948 952
953 /* alloc internal scan request */
954 i = 0;
955 local->int_scan_req.ssids = &local->scan_ssid;
956 local->int_scan_req.n_ssids = 1;
957 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
958 if (!hw->wiphy->bands[band])
959 continue;
960 for (j = 0; j < hw->wiphy->bands[band]->n_channels; j++) {
961 local->int_scan_req.channels[i] =
962 &hw->wiphy->bands[band]->channels[j];
963 i++;
964 }
965 }
966
949 return 0; 967 return 0;
950 968
951fail_wep: 969fail_wep:
@@ -964,6 +982,8 @@ fail_workqueue:
964 free_netdev(local->mdev); 982 free_netdev(local->mdev);
965fail_mdev_alloc: 983fail_mdev_alloc:
966 wiphy_unregister(local->hw.wiphy); 984 wiphy_unregister(local->hw.wiphy);
985fail_wiphy_register:
986 kfree(local->int_scan_req.channels);
967 return result; 987 return result;
968} 988}
969EXPORT_SYMBOL(ieee80211_register_hw); 989EXPORT_SYMBOL(ieee80211_register_hw);
@@ -991,7 +1011,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
991 1011
992 rtnl_unlock(); 1012 rtnl_unlock();
993 1013
994 ieee80211_rx_bss_list_deinit(local);
995 ieee80211_clear_tx_pending(local); 1014 ieee80211_clear_tx_pending(local);
996 sta_info_stop(local); 1015 sta_info_stop(local);
997 rate_control_deinitialize(local); 1016 rate_control_deinitialize(local);
@@ -1009,6 +1028,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1009 ieee80211_wep_free(local); 1028 ieee80211_wep_free(local);
1010 ieee80211_led_exit(local); 1029 ieee80211_led_exit(local);
1011 free_netdev(local->mdev); 1030 free_netdev(local->mdev);
1031 kfree(local->int_scan_req.channels);
1012} 1032}
1013EXPORT_SYMBOL(ieee80211_unregister_hw); 1033EXPORT_SYMBOL(ieee80211_unregister_hw);
1014 1034
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 8a1fcaeee4f2..9a3e5de0410a 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -275,16 +275,6 @@ u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_t
275 & tbl->hash_mask; 275 & tbl->hash_mask;
276} 276}
277 277
278u8 mesh_id_hash(u8 *mesh_id, int mesh_id_len)
279{
280 if (!mesh_id_len)
281 return 1;
282 else if (mesh_id_len == 1)
283 return (u8) mesh_id[0];
284 else
285 return (u8) (mesh_id[0] + 2 * mesh_id[1]);
286}
287
288struct mesh_table *mesh_table_alloc(int size_order) 278struct mesh_table *mesh_table_alloc(int size_order)
289{ 279{
290 int i; 280 int i;
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 9e064ee98ee0..d891d7ddccd7 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -196,7 +196,6 @@ struct mesh_rmc {
196 196
197/* Public interfaces */ 197/* Public interfaces */
198/* Various */ 198/* Various */
199u8 mesh_id_hash(u8 *mesh_id, int mesh_id_len);
200int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); 199int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
201int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 200int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
202 struct ieee80211_sub_if_data *sdata); 201 struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 4f862b2a0041..60b35accda91 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -58,7 +58,6 @@ static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae)
58#define PERR_IE_DST_ADDR(x) (x + 2) 58#define PERR_IE_DST_ADDR(x) (x + 2)
59#define PERR_IE_DST_DSN(x) u32_field_get(x, 8, 0); 59#define PERR_IE_DST_DSN(x) u32_field_get(x, 8, 0);
60 60
61#define TU_TO_EXP_TIME(x) (jiffies + msecs_to_jiffies(x * 1024 / 1000))
62#define MSEC_TO_TU(x) (x*1000/1024) 61#define MSEC_TO_TU(x) (x*1000/1024)
63#define DSN_GT(x, y) ((long) (y) - (long) (x) < 0) 62#define DSN_GT(x, y) ((long) (y) - (long) (x) < 0)
64#define DSN_LT(x, y) ((long) (x) - (long) (y) < 0) 63#define DSN_LT(x, y) ((long) (x) - (long) (y) < 0)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 57967d32e5fd..fbb766afe599 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -55,10 +55,10 @@ static u8 *ieee80211_bss_get_ie(struct ieee80211_bss *bss, u8 ie)
55{ 55{
56 u8 *end, *pos; 56 u8 *end, *pos;
57 57
58 pos = bss->ies; 58 pos = bss->cbss.information_elements;
59 if (pos == NULL) 59 if (pos == NULL)
60 return NULL; 60 return NULL;
61 end = pos + bss->ies_len; 61 end = pos + bss->cbss.len_information_elements;
62 62
63 while (pos + 1 < end) { 63 while (pos + 1 < end) {
64 if (pos + 2 + pos[1] > end) 64 if (pos + 2 + pos[1] > end)
@@ -289,7 +289,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
289 local->hw.conf.channel->center_freq, 289 local->hw.conf.channel->center_freq,
290 ifsta->ssid, ifsta->ssid_len); 290 ifsta->ssid, ifsta->ssid_len);
291 if (bss) { 291 if (bss) {
292 if (bss->capability & WLAN_CAPABILITY_PRIVACY) 292 if (bss->cbss.capability & WLAN_CAPABILITY_PRIVACY)
293 capab |= WLAN_CAPABILITY_PRIVACY; 293 capab |= WLAN_CAPABILITY_PRIVACY;
294 if (bss->wmm_used) 294 if (bss->wmm_used)
295 wmm = 1; 295 wmm = 1;
@@ -300,7 +300,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
300 * b-only mode) */ 300 * b-only mode) */
301 rates_len = ieee80211_compatible_rates(bss, sband, &rates); 301 rates_len = ieee80211_compatible_rates(bss, sband, &rates);
302 302
303 if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) && 303 if ((bss->cbss.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
304 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) 304 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
305 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; 305 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
306 306
@@ -511,16 +511,50 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
511 ieee80211_tx_skb(sdata, skb, ifsta->flags & IEEE80211_STA_MFP_ENABLED); 511 ieee80211_tx_skb(sdata, skb, ifsta->flags & IEEE80211_STA_MFP_ENABLED);
512} 512}
513 513
514void ieee80211_send_pspoll(struct ieee80211_local *local,
515 struct ieee80211_sub_if_data *sdata)
516{
517 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
518 struct ieee80211_pspoll *pspoll;
519 struct sk_buff *skb;
520 u16 fc;
521
522 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*pspoll));
523 if (!skb) {
524 printk(KERN_DEBUG "%s: failed to allocate buffer for "
525 "pspoll frame\n", sdata->dev->name);
526 return;
527 }
528 skb_reserve(skb, local->hw.extra_tx_headroom);
529
530 pspoll = (struct ieee80211_pspoll *) skb_put(skb, sizeof(*pspoll));
531 memset(pspoll, 0, sizeof(*pspoll));
532 fc = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL | IEEE80211_FCTL_PM;
533 pspoll->frame_control = cpu_to_le16(fc);
534 pspoll->aid = cpu_to_le16(ifsta->aid);
535
536 /* aid in PS-Poll has its two MSBs each set to 1 */
537 pspoll->aid |= cpu_to_le16(1 << 15 | 1 << 14);
538
539 memcpy(pspoll->bssid, ifsta->bssid, ETH_ALEN);
540 memcpy(pspoll->ta, sdata->dev->dev_addr, ETH_ALEN);
541
542 ieee80211_tx_skb(sdata, skb, 0);
543
544 return;
545}
546
514/* MLME */ 547/* MLME */
515static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 548static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
516 struct ieee80211_bss *bss) 549 const size_t supp_rates_len,
550 const u8 *supp_rates)
517{ 551{
518 struct ieee80211_local *local = sdata->local; 552 struct ieee80211_local *local = sdata->local;
519 int i, have_higher_than_11mbit = 0; 553 int i, have_higher_than_11mbit = 0;
520 554
521 /* cf. IEEE 802.11 9.2.12 */ 555 /* cf. IEEE 802.11 9.2.12 */
522 for (i = 0; i < bss->supp_rates_len; i++) 556 for (i = 0; i < supp_rates_len; i++)
523 if ((bss->supp_rates[i] & 0x7f) * 5 > 110) 557 if ((supp_rates[i] & 0x7f) * 5 > 110)
524 have_higher_than_11mbit = 1; 558 have_higher_than_11mbit = 1;
525 559
526 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && 560 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
@@ -611,7 +645,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
611 } 645 }
612} 646}
613 647
614static bool check_tim(struct ieee802_11_elems *elems, u16 aid, bool *is_mc) 648static bool ieee80211_check_tim(struct ieee802_11_elems *elems, u16 aid)
615{ 649{
616 u8 mask; 650 u8 mask;
617 u8 index, indexn1, indexn2; 651 u8 index, indexn1, indexn2;
@@ -621,9 +655,6 @@ static bool check_tim(struct ieee802_11_elems *elems, u16 aid, bool *is_mc)
621 index = aid / 8; 655 index = aid / 8;
622 mask = 1 << (aid & 7); 656 mask = 1 << (aid & 7);
623 657
624 if (tim->bitmap_ctrl & 0x01)
625 *is_mc = true;
626
627 indexn1 = tim->bitmap_ctrl & 0xfe; 658 indexn1 = tim->bitmap_ctrl & 0xfe;
628 indexn2 = elems->tim_len + indexn1 - 4; 659 indexn2 = elems->tim_len + indexn1 - 4;
629 660
@@ -777,20 +808,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
777 bss_info_changed |= BSS_CHANGED_ASSOC; 808 bss_info_changed |= BSS_CHANGED_ASSOC;
778 ifsta->flags |= IEEE80211_STA_ASSOCIATED; 809 ifsta->flags |= IEEE80211_STA_ASSOCIATED;
779 810
780 if (sdata->vif.type != NL80211_IFTYPE_STATION)
781 return;
782
783 bss = ieee80211_rx_bss_get(local, ifsta->bssid, 811 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
784 conf->channel->center_freq, 812 conf->channel->center_freq,
785 ifsta->ssid, ifsta->ssid_len); 813 ifsta->ssid, ifsta->ssid_len);
786 if (bss) { 814 if (bss) {
787 /* set timing information */ 815 /* set timing information */
788 sdata->vif.bss_conf.beacon_int = bss->beacon_int; 816 sdata->vif.bss_conf.beacon_int = bss->cbss.beacon_interval;
789 sdata->vif.bss_conf.timestamp = bss->timestamp; 817 sdata->vif.bss_conf.timestamp = bss->cbss.tsf;
790 sdata->vif.bss_conf.dtim_period = bss->dtim_period; 818 sdata->vif.bss_conf.dtim_period = bss->dtim_period;
791 819
792 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 820 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
793 bss->capability, bss->has_erp_value, bss->erp_value); 821 bss->cbss.capability, bss->has_erp_value, bss->erp_value);
794 822
795 ieee80211_rx_bss_put(local, bss); 823 ieee80211_rx_bss_put(local, bss);
796 } 824 }
@@ -840,6 +868,14 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
840 sdata->dev->name, ifsta->bssid); 868 sdata->dev->name, ifsta->bssid);
841 ifsta->state = IEEE80211_STA_MLME_DISABLED; 869 ifsta->state = IEEE80211_STA_MLME_DISABLED;
842 ieee80211_sta_send_apinfo(sdata, ifsta); 870 ieee80211_sta_send_apinfo(sdata, ifsta);
871
872 /*
873 * Most likely AP is not in the range so remove the
874 * bss information associated to the AP
875 */
876 ieee80211_rx_bss_remove(sdata, ifsta->bssid,
877 sdata->local->hw.conf.channel->center_freq,
878 ifsta->ssid, ifsta->ssid_len);
843 return; 879 return;
844 } 880 }
845 881
@@ -871,6 +907,9 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
871 sdata->dev->name, ifsta->bssid); 907 sdata->dev->name, ifsta->bssid);
872 ifsta->state = IEEE80211_STA_MLME_DISABLED; 908 ifsta->state = IEEE80211_STA_MLME_DISABLED;
873 ieee80211_sta_send_apinfo(sdata, ifsta); 909 ieee80211_sta_send_apinfo(sdata, ifsta);
910 ieee80211_rx_bss_remove(sdata, ifsta->bssid,
911 sdata->local->hw.conf.channel->center_freq,
912 ifsta->ssid, ifsta->ssid_len);
874 return; 913 return;
875 } 914 }
876 915
@@ -913,7 +952,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
913 netif_tx_stop_all_queues(sdata->dev); 952 netif_tx_stop_all_queues(sdata->dev);
914 netif_carrier_off(sdata->dev); 953 netif_carrier_off(sdata->dev);
915 954
916 ieee80211_sta_tear_down_BA_sessions(sdata, sta->sta.addr); 955 ieee80211_sta_tear_down_BA_sessions(sta);
917 956
918 if (self_disconnected) { 957 if (self_disconnected) {
919 if (deauth) 958 if (deauth)
@@ -933,8 +972,12 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
933 972
934 ieee80211_sta_send_apinfo(sdata, ifsta); 973 ieee80211_sta_send_apinfo(sdata, ifsta);
935 974
936 if (self_disconnected || reason == WLAN_REASON_DISASSOC_STA_HAS_LEFT) 975 if (self_disconnected || reason == WLAN_REASON_DISASSOC_STA_HAS_LEFT) {
937 ifsta->state = IEEE80211_STA_MLME_DISABLED; 976 ifsta->state = IEEE80211_STA_MLME_DISABLED;
977 ieee80211_rx_bss_remove(sdata, ifsta->bssid,
978 sdata->local->hw.conf.channel->center_freq,
979 ifsta->ssid, ifsta->ssid_len);
980 }
938 981
939 rcu_read_unlock(); 982 rcu_read_unlock();
940 983
@@ -995,7 +1038,7 @@ static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
995 if (!bss) 1038 if (!bss)
996 return 0; 1039 return 0;
997 1040
998 bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY); 1041 bss_privacy = !!(bss->cbss.capability & WLAN_CAPABILITY_PRIVACY);
999 wep_privacy = !!ieee80211_sta_wep_configured(sdata); 1042 wep_privacy = !!ieee80211_sta_wep_configured(sdata);
1000 privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); 1043 privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED);
1001 1044
@@ -1017,6 +1060,9 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata,
1017 sdata->dev->name, ifsta->bssid); 1060 sdata->dev->name, ifsta->bssid);
1018 ifsta->state = IEEE80211_STA_MLME_DISABLED; 1061 ifsta->state = IEEE80211_STA_MLME_DISABLED;
1019 ieee80211_sta_send_apinfo(sdata, ifsta); 1062 ieee80211_sta_send_apinfo(sdata, ifsta);
1063 ieee80211_rx_bss_remove(sdata, ifsta->bssid,
1064 sdata->local->hw.conf.channel->center_freq,
1065 ifsta->ssid, ifsta->ssid_len);
1020 return; 1066 return;
1021 } 1067 }
1022 1068
@@ -1042,7 +1088,6 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
1042 struct ieee80211_local *local = sdata->local; 1088 struct ieee80211_local *local = sdata->local;
1043 struct sta_info *sta; 1089 struct sta_info *sta;
1044 int disassoc; 1090 int disassoc;
1045 bool remove_bss = false;
1046 1091
1047 /* TODO: start monitoring current AP signal quality and number of 1092 /* TODO: start monitoring current AP signal quality and number of
1048 * missed beacons. Scan other channels every now and then and search 1093 * missed beacons. Scan other channels every now and then and search
@@ -1068,7 +1113,6 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
1068 "range\n", 1113 "range\n",
1069 sdata->dev->name, ifsta->bssid); 1114 sdata->dev->name, ifsta->bssid);
1070 disassoc = 1; 1115 disassoc = 1;
1071 remove_bss = true;
1072 } else 1116 } else
1073 ieee80211_send_probe_req(sdata, ifsta->bssid, 1117 ieee80211_send_probe_req(sdata, ifsta->bssid,
1074 ifsta->ssid, 1118 ifsta->ssid,
@@ -1088,24 +1132,12 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
1088 1132
1089 rcu_read_unlock(); 1133 rcu_read_unlock();
1090 1134
1091 if (disassoc) { 1135 if (disassoc)
1092 ieee80211_set_disassoc(sdata, ifsta, true, true, 1136 ieee80211_set_disassoc(sdata, ifsta, true, true,
1093 WLAN_REASON_PREV_AUTH_NOT_VALID); 1137 WLAN_REASON_PREV_AUTH_NOT_VALID);
1094 if (remove_bss) { 1138 else
1095 struct ieee80211_bss *bss;
1096
1097 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
1098 local->hw.conf.channel->center_freq,
1099 ifsta->ssid, ifsta->ssid_len);
1100 if (bss) {
1101 atomic_dec(&bss->users);
1102 ieee80211_rx_bss_put(local, bss);
1103 }
1104 }
1105 } else {
1106 mod_timer(&ifsta->timer, jiffies + 1139 mod_timer(&ifsta->timer, jiffies +
1107 IEEE80211_MONITORING_INTERVAL); 1140 IEEE80211_MONITORING_INTERVAL);
1108 }
1109} 1141}
1110 1142
1111 1143
@@ -1134,6 +1166,30 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1134 elems.challenge_len + 2, 1); 1166 elems.challenge_len + 2, 1);
1135} 1167}
1136 1168
1169static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
1170 struct ieee80211_if_sta *ifsta,
1171 struct ieee80211_mgmt *mgmt,
1172 size_t len)
1173{
1174 u16 auth_alg, auth_transaction, status_code;
1175
1176 if (len < 24 + 6)
1177 return;
1178
1179 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
1180 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
1181 status_code = le16_to_cpu(mgmt->u.auth.status_code);
1182
1183 /*
1184 * IEEE 802.11 standard does not require authentication in IBSS
1185 * networks and most implementations do not seem to use it.
1186 * However, try to reply to authentication attempts if someone
1187 * has actually implemented this.
1188 */
1189 if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1)
1190 ieee80211_send_auth(sdata, ifsta, 2, NULL, 0, 0);
1191}
1192
1137static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, 1193static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1138 struct ieee80211_if_sta *ifsta, 1194 struct ieee80211_if_sta *ifsta,
1139 struct ieee80211_mgmt *mgmt, 1195 struct ieee80211_mgmt *mgmt,
@@ -1141,37 +1197,22 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1141{ 1197{
1142 u16 auth_alg, auth_transaction, status_code; 1198 u16 auth_alg, auth_transaction, status_code;
1143 1199
1144 if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE && 1200 if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE)
1145 sdata->vif.type != NL80211_IFTYPE_ADHOC)
1146 return; 1201 return;
1147 1202
1148 if (len < 24 + 6) 1203 if (len < 24 + 6)
1149 return; 1204 return;
1150 1205
1151 if (sdata->vif.type != NL80211_IFTYPE_ADHOC && 1206 if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0)
1152 memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0)
1153 return; 1207 return;
1154 1208
1155 if (sdata->vif.type != NL80211_IFTYPE_ADHOC && 1209 if (memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
1156 memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
1157 return; 1210 return;
1158 1211
1159 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); 1212 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
1160 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); 1213 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
1161 status_code = le16_to_cpu(mgmt->u.auth.status_code); 1214 status_code = le16_to_cpu(mgmt->u.auth.status_code);
1162 1215
1163 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
1164 /*
1165 * IEEE 802.11 standard does not require authentication in IBSS
1166 * networks and most implementations do not seem to use it.
1167 * However, try to reply to authentication attempts if someone
1168 * has actually implemented this.
1169 */
1170 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
1171 return;
1172 ieee80211_send_auth(sdata, ifsta, 2, NULL, 0, 0);
1173 }
1174
1175 if (auth_alg != ifsta->auth_alg || 1216 if (auth_alg != ifsta->auth_alg ||
1176 auth_transaction != ifsta->auth_transaction) 1217 auth_transaction != ifsta->auth_transaction)
1177 return; 1218 return;
@@ -1381,8 +1422,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1381 /* Add STA entry for the AP */ 1422 /* Add STA entry for the AP */
1382 sta = sta_info_get(local, ifsta->bssid); 1423 sta = sta_info_get(local, ifsta->bssid);
1383 if (!sta) { 1424 if (!sta) {
1384 struct ieee80211_bss *bss;
1385
1386 newsta = true; 1425 newsta = true;
1387 1426
1388 sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); 1427 sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC);
@@ -1392,15 +1431,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1392 rcu_read_unlock(); 1431 rcu_read_unlock();
1393 return; 1432 return;
1394 } 1433 }
1395 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
1396 local->hw.conf.channel->center_freq,
1397 ifsta->ssid, ifsta->ssid_len);
1398 if (bss) {
1399 sta->last_signal = bss->signal;
1400 sta->last_qual = bss->qual;
1401 sta->last_noise = bss->noise;
1402 ieee80211_rx_bss_put(local, bss);
1403 }
1404 1434
1405 /* update new sta with its last rx activity */ 1435 /* update new sta with its last rx activity */
1406 sta->last_rx = jiffies; 1436 sta->last_rx = jiffies;
@@ -1512,9 +1542,13 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1512} 1542}
1513 1543
1514 1544
1515static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 1545static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1516 struct ieee80211_if_sta *ifsta, 1546 struct ieee80211_if_sta *ifsta,
1517 struct ieee80211_bss *bss) 1547 const u8 *bssid, const int beacon_int,
1548 const int freq,
1549 const size_t supp_rates_len,
1550 const u8 *supp_rates,
1551 const u16 capability)
1518{ 1552{
1519 struct ieee80211_local *local = sdata->local; 1553 struct ieee80211_local *local = sdata->local;
1520 int res = 0, rates, i, j; 1554 int res = 0, rates, i, j;
@@ -1530,7 +1564,7 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1530 } 1564 }
1531 1565
1532 if ((ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) && 1566 if ((ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) &&
1533 memcmp(ifsta->bssid, bss->bssid, ETH_ALEN) == 0) 1567 memcmp(ifsta->bssid, bssid, ETH_ALEN) == 0)
1534 return res; 1568 return res;
1535 1569
1536 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + 1570 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
@@ -1541,28 +1575,28 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1541 return -ENOMEM; 1575 return -ENOMEM;
1542 } 1576 }
1543 1577
1544 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1545
1546 if (!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET)) { 1578 if (!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET)) {
1547 /* Remove possible STA entries from other IBSS networks. */ 1579 /* Remove possible STA entries from other IBSS networks. */
1548 sta_info_flush_delayed(sdata); 1580 sta_info_flush_delayed(sdata);
1549 } 1581 }
1550 1582
1551 memcpy(ifsta->bssid, bss->bssid, ETH_ALEN); 1583 memcpy(ifsta->bssid, bssid, ETH_ALEN);
1552 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID); 1584 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
1553 if (res) 1585 if (res)
1554 return res; 1586 return res;
1555 1587
1556 local->hw.conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10; 1588 local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10;
1557 1589
1558 sdata->drop_unencrypted = bss->capability & 1590 sdata->drop_unencrypted = capability &
1559 WLAN_CAPABILITY_PRIVACY ? 1 : 0; 1591 WLAN_CAPABILITY_PRIVACY ? 1 : 0;
1560 1592
1561 res = ieee80211_set_freq(sdata, bss->freq); 1593 res = ieee80211_set_freq(sdata, freq);
1562 1594
1563 if (res) 1595 if (res)
1564 return res; 1596 return res;
1565 1597
1598 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1599
1566 /* Build IBSS probe response */ 1600 /* Build IBSS probe response */
1567 1601
1568 skb_reserve(skb, local->hw.extra_tx_headroom); 1602 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -1571,33 +1605,32 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1571 skb_put(skb, 24 + sizeof(mgmt->u.beacon)); 1605 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
1572 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 1606 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
1573 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 1607 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1574 IEEE80211_STYPE_PROBE_RESP); 1608 IEEE80211_STYPE_PROBE_RESP);
1575 memset(mgmt->da, 0xff, ETH_ALEN); 1609 memset(mgmt->da, 0xff, ETH_ALEN);
1576 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 1610 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1577 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 1611 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1578 mgmt->u.beacon.beacon_int = 1612 mgmt->u.beacon.beacon_int =
1579 cpu_to_le16(local->hw.conf.beacon_int); 1613 cpu_to_le16(local->hw.conf.beacon_int);
1580 mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp); 1614 mgmt->u.beacon.capab_info = cpu_to_le16(capability);
1581 mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability);
1582 1615
1583 pos = skb_put(skb, 2 + ifsta->ssid_len); 1616 pos = skb_put(skb, 2 + ifsta->ssid_len);
1584 *pos++ = WLAN_EID_SSID; 1617 *pos++ = WLAN_EID_SSID;
1585 *pos++ = ifsta->ssid_len; 1618 *pos++ = ifsta->ssid_len;
1586 memcpy(pos, ifsta->ssid, ifsta->ssid_len); 1619 memcpy(pos, ifsta->ssid, ifsta->ssid_len);
1587 1620
1588 rates = bss->supp_rates_len; 1621 rates = supp_rates_len;
1589 if (rates > 8) 1622 if (rates > 8)
1590 rates = 8; 1623 rates = 8;
1591 pos = skb_put(skb, 2 + rates); 1624 pos = skb_put(skb, 2 + rates);
1592 *pos++ = WLAN_EID_SUPP_RATES; 1625 *pos++ = WLAN_EID_SUPP_RATES;
1593 *pos++ = rates; 1626 *pos++ = rates;
1594 memcpy(pos, bss->supp_rates, rates); 1627 memcpy(pos, supp_rates, rates);
1595 1628
1596 if (bss->band == IEEE80211_BAND_2GHZ) { 1629 if (sband->band == IEEE80211_BAND_2GHZ) {
1597 pos = skb_put(skb, 2 + 1); 1630 pos = skb_put(skb, 2 + 1);
1598 *pos++ = WLAN_EID_DS_PARAMS; 1631 *pos++ = WLAN_EID_DS_PARAMS;
1599 *pos++ = 1; 1632 *pos++ = 1;
1600 *pos++ = ieee80211_frequency_to_channel(bss->freq); 1633 *pos++ = ieee80211_frequency_to_channel(freq);
1601 } 1634 }
1602 1635
1603 pos = skb_put(skb, 2 + 2); 1636 pos = skb_put(skb, 2 + 2);
@@ -1607,12 +1640,12 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1607 *pos++ = 0; 1640 *pos++ = 0;
1608 *pos++ = 0; 1641 *pos++ = 0;
1609 1642
1610 if (bss->supp_rates_len > 8) { 1643 if (supp_rates_len > 8) {
1611 rates = bss->supp_rates_len - 8; 1644 rates = supp_rates_len - 8;
1612 pos = skb_put(skb, 2 + rates); 1645 pos = skb_put(skb, 2 + rates);
1613 *pos++ = WLAN_EID_EXT_SUPP_RATES; 1646 *pos++ = WLAN_EID_EXT_SUPP_RATES;
1614 *pos++ = rates; 1647 *pos++ = rates;
1615 memcpy(pos, &bss->supp_rates[8], rates); 1648 memcpy(pos, &supp_rates[8], rates);
1616 } 1649 }
1617 1650
1618 add_extra_ies(skb, sdata->u.sta.ie_proberesp, 1651 add_extra_ies(skb, sdata->u.sta.ie_proberesp,
@@ -1625,16 +1658,15 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1625 1658
1626 1659
1627 rates = 0; 1660 rates = 0;
1628 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1661 for (i = 0; i < supp_rates_len; i++) {
1629 for (i = 0; i < bss->supp_rates_len; i++) { 1662 int bitrate = (supp_rates[i] & 0x7f) * 5;
1630 int bitrate = (bss->supp_rates[i] & 0x7f) * 5;
1631 for (j = 0; j < sband->n_bitrates; j++) 1663 for (j = 0; j < sband->n_bitrates; j++)
1632 if (sband->bitrates[j].bitrate == bitrate) 1664 if (sband->bitrates[j].bitrate == bitrate)
1633 rates |= BIT(j); 1665 rates |= BIT(j);
1634 } 1666 }
1635 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; 1667 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
1636 1668
1637 ieee80211_sta_def_wmm_params(sdata, bss); 1669 ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
1638 1670
1639 ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; 1671 ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
1640 ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED; 1672 ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
@@ -1643,12 +1675,24 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1643 ieee80211_led_assoc(local, true); 1675 ieee80211_led_assoc(local, true);
1644 1676
1645 memset(&wrqu, 0, sizeof(wrqu)); 1677 memset(&wrqu, 0, sizeof(wrqu));
1646 memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN); 1678 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
1647 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL); 1679 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
1648 1680
1649 return res; 1681 return res;
1650} 1682}
1651 1683
1684static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1685 struct ieee80211_if_sta *ifsta,
1686 struct ieee80211_bss *bss)
1687{
1688 return __ieee80211_sta_join_ibss(sdata, ifsta,
1689 bss->cbss.bssid,
1690 bss->cbss.beacon_interval,
1691 bss->cbss.channel->center_freq,
1692 bss->supp_rates_len, bss->supp_rates,
1693 bss->cbss.capability);
1694}
1695
1652static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 1696static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1653 struct ieee80211_mgmt *mgmt, 1697 struct ieee80211_mgmt *mgmt,
1654 size_t len, 1698 size_t len,
@@ -1709,7 +1753,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1709 } 1753 }
1710 1754
1711 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, 1755 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
1712 freq, beacon); 1756 channel, beacon);
1713 if (!bss) 1757 if (!bss)
1714 return; 1758 return;
1715 1759
@@ -1721,76 +1765,87 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1721 } 1765 }
1722 1766
1723 /* was just updated in ieee80211_bss_info_update */ 1767 /* was just updated in ieee80211_bss_info_update */
1724 beacon_timestamp = bss->timestamp; 1768 beacon_timestamp = bss->cbss.tsf;
1725 1769
1726 /* 1770 if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
1727 * In STA mode, the remaining parameters should not be overridden 1771 goto put_bss;
1728 * by beacons because they're not necessarily accurate there.
1729 */
1730 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1731 bss->last_probe_resp && beacon) {
1732 ieee80211_rx_bss_put(local, bss);
1733 return;
1734 }
1735 1772
1736 /* check if we need to merge IBSS */ 1773 /* check if we need to merge IBSS */
1737 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && beacon && 1774
1738 (!(sdata->u.sta.flags & IEEE80211_STA_BSSID_SET)) && 1775 /* merge only on beacons (???) */
1739 bss->capability & WLAN_CAPABILITY_IBSS && 1776 if (!beacon)
1740 bss->freq == local->oper_channel->center_freq && 1777 goto put_bss;
1741 elems->ssid_len == sdata->u.sta.ssid_len && 1778
1779 /* we use a fixed BSSID */
1780 if (sdata->u.sta.flags & IEEE80211_STA_BSSID_SET)
1781 goto put_bss;
1782
1783 /* not an IBSS */
1784 if (!(bss->cbss.capability & WLAN_CAPABILITY_IBSS))
1785 goto put_bss;
1786
1787 /* different channel */
1788 if (bss->cbss.channel != local->oper_channel)
1789 goto put_bss;
1790
1791 /* different SSID */
1792 if (elems->ssid_len != sdata->u.sta.ssid_len ||
1742 memcmp(elems->ssid, sdata->u.sta.ssid, 1793 memcmp(elems->ssid, sdata->u.sta.ssid,
1743 sdata->u.sta.ssid_len) == 0) { 1794 sdata->u.sta.ssid_len))
1744 if (rx_status->flag & RX_FLAG_TSFT) { 1795 goto put_bss;
1745 /* in order for correct IBSS merging we need mactime 1796
1746 * 1797 if (rx_status->flag & RX_FLAG_TSFT) {
1747 * since mactime is defined as the time the first data 1798 /*
1748 * symbol of the frame hits the PHY, and the timestamp 1799 * For correct IBSS merging we need mactime; since mactime is
1749 * of the beacon is defined as "the time that the data 1800 * defined as the time the first data symbol of the frame hits
1750 * symbol containing the first bit of the timestamp is 1801 * the PHY, and the timestamp of the beacon is defined as "the
1751 * transmitted to the PHY plus the transmitting STA’s 1802 * time that the data symbol containing the first bit of the
1752 * delays through its local PHY from the MAC-PHY 1803 * timestamp is transmitted to the PHY plus the transmitting
1753 * interface to its interface with the WM" 1804 * STA's delays through its local PHY from the MAC-PHY
1754 * (802.11 11.1.2) - equals the time this bit arrives at 1805 * interface to its interface with the WM" (802.11 11.1.2)
1755 * the receiver - we have to take into account the 1806 * - equals the time this bit arrives at the receiver - we have
1756 * offset between the two. 1807 * to take into account the offset between the two.
1757 * e.g: at 1 MBit that means mactime is 192 usec earlier 1808 *
1758 * (=24 bytes * 8 usecs/byte) than the beacon timestamp. 1809 * E.g. at 1 MBit that means mactime is 192 usec earlier
1759 */ 1810 * (=24 bytes * 8 usecs/byte) than the beacon timestamp.
1760 int rate; 1811 */
1761 if (rx_status->flag & RX_FLAG_HT) { 1812 int rate;
1762 rate = 65; /* TODO: HT rates */ 1813
1763 } else { 1814 if (rx_status->flag & RX_FLAG_HT)
1764 rate = local->hw.wiphy->bands[band]-> 1815 rate = 65; /* TODO: HT rates */
1765 bitrates[rx_status->rate_idx].bitrate;
1766 }
1767 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
1768 } else if (local && local->ops && local->ops->get_tsf)
1769 /* second best option: get current TSF */
1770 rx_timestamp = local->ops->get_tsf(local_to_hw(local));
1771 else 1816 else
1772 /* can't merge without knowing the TSF */ 1817 rate = local->hw.wiphy->bands[band]->
1773 rx_timestamp = -1LLU; 1818 bitrates[rx_status->rate_idx].bitrate;
1819
1820 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
1821 } else if (local && local->ops && local->ops->get_tsf)
1822 /* second best option: get current TSF */
1823 rx_timestamp = local->ops->get_tsf(local_to_hw(local));
1824 else
1825 /* can't merge without knowing the TSF */
1826 rx_timestamp = -1LLU;
1827
1774#ifdef CONFIG_MAC80211_IBSS_DEBUG 1828#ifdef CONFIG_MAC80211_IBSS_DEBUG
1775 printk(KERN_DEBUG "RX beacon SA=%pM BSSID=" 1829 printk(KERN_DEBUG "RX beacon SA=%pM BSSID="
1776 "%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", 1830 "%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n",
1777 mgmt->sa, mgmt->bssid, 1831 mgmt->sa, mgmt->bssid,
1778 (unsigned long long)rx_timestamp, 1832 (unsigned long long)rx_timestamp,
1779 (unsigned long long)beacon_timestamp, 1833 (unsigned long long)beacon_timestamp,
1780 (unsigned long long)(rx_timestamp - beacon_timestamp), 1834 (unsigned long long)(rx_timestamp - beacon_timestamp),
1781 jiffies); 1835 jiffies);
1782#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 1836#endif
1783 if (beacon_timestamp > rx_timestamp) { 1837
1838 if (beacon_timestamp > rx_timestamp) {
1784#ifdef CONFIG_MAC80211_IBSS_DEBUG 1839#ifdef CONFIG_MAC80211_IBSS_DEBUG
1785 printk(KERN_DEBUG "%s: beacon TSF higher than " 1840 printk(KERN_DEBUG "%s: beacon TSF higher than "
1786 "local TSF - IBSS merge with BSSID %pM\n", 1841 "local TSF - IBSS merge with BSSID %pM\n",
1787 sdata->dev->name, mgmt->bssid); 1842 sdata->dev->name, mgmt->bssid);
1788#endif 1843#endif
1789 ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss); 1844 ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
1790 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates); 1845 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates);
1791 }
1792 } 1846 }
1793 1847
1848 put_bss:
1794 ieee80211_rx_bss_put(local, bss); 1849 ieee80211_rx_bss_put(local, bss);
1795} 1850}
1796 1851
@@ -1836,7 +1891,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1836 struct ieee802_11_elems elems; 1891 struct ieee802_11_elems elems;
1837 struct ieee80211_local *local = sdata->local; 1892 struct ieee80211_local *local = sdata->local;
1838 u32 changed = 0; 1893 u32 changed = 0;
1839 bool erp_valid, directed_tim, is_mc = false; 1894 bool erp_valid, directed_tim;
1840 u8 erp_value = 0; 1895 u8 erp_value = 0;
1841 1896
1842 /* Process beacon from the current BSS */ 1897 /* Process beacon from the current BSS */
@@ -1864,12 +1919,27 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1864 1919
1865 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK && 1920 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK &&
1866 local->hw.conf.flags & IEEE80211_CONF_PS) { 1921 local->hw.conf.flags & IEEE80211_CONF_PS) {
1867 directed_tim = check_tim(&elems, ifsta->aid, &is_mc); 1922 directed_tim = ieee80211_check_tim(&elems, ifsta->aid);
1868 1923
1869 if (directed_tim || is_mc) { 1924 if (directed_tim) {
1870 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 1925 if (local->hw.conf.dynamic_ps_timeout > 0) {
1871 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 1926 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
1872 ieee80211_send_nullfunc(local, sdata, 0); 1927 ieee80211_hw_config(local,
1928 IEEE80211_CONF_CHANGE_PS);
1929 ieee80211_send_nullfunc(local, sdata, 0);
1930 } else {
1931 local->pspolling = true;
1932
1933 /*
1934 * Here is assumed that the driver will be
1935 * able to send ps-poll frame and receive a
1936 * response even though power save mode is
1937 * enabled, but some drivers might require
1938 * to disable power save here. This needs
1939 * to be investigated.
1940 */
1941 ieee80211_send_pspoll(local, sdata);
1942 }
1873 } 1943 }
1874 } 1944 }
1875 1945
@@ -1939,8 +2009,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
1939 struct ieee80211_mgmt *resp; 2009 struct ieee80211_mgmt *resp;
1940 u8 *pos, *end; 2010 u8 *pos, *end;
1941 2011
1942 if (sdata->vif.type != NL80211_IFTYPE_ADHOC || 2012 if (ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED ||
1943 ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED ||
1944 len < 24 + 2 || !ifsta->probe_resp) 2013 len < 24 + 2 || !ifsta->probe_resp)
1945 return; 2014 return;
1946 2015
@@ -2044,31 +2113,54 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
2044 mgmt = (struct ieee80211_mgmt *) skb->data; 2113 mgmt = (struct ieee80211_mgmt *) skb->data;
2045 fc = le16_to_cpu(mgmt->frame_control); 2114 fc = le16_to_cpu(mgmt->frame_control);
2046 2115
2047 switch (fc & IEEE80211_FCTL_STYPE) { 2116 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
2048 case IEEE80211_STYPE_PROBE_REQ: 2117 switch (fc & IEEE80211_FCTL_STYPE) {
2049 ieee80211_rx_mgmt_probe_req(sdata, ifsta, mgmt, skb->len); 2118 case IEEE80211_STYPE_PROBE_REQ:
2050 break; 2119 ieee80211_rx_mgmt_probe_req(sdata, ifsta, mgmt,
2051 case IEEE80211_STYPE_PROBE_RESP: 2120 skb->len);
2052 ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, rx_status); 2121 break;
2053 break; 2122 case IEEE80211_STYPE_PROBE_RESP:
2054 case IEEE80211_STYPE_BEACON: 2123 ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len,
2055 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status); 2124 rx_status);
2056 break; 2125 break;
2057 case IEEE80211_STYPE_AUTH: 2126 case IEEE80211_STYPE_BEACON:
2058 ieee80211_rx_mgmt_auth(sdata, ifsta, mgmt, skb->len); 2127 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
2059 break; 2128 rx_status);
2060 case IEEE80211_STYPE_ASSOC_RESP: 2129 break;
2061 ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 0); 2130 case IEEE80211_STYPE_AUTH:
2062 break; 2131 ieee80211_rx_mgmt_auth_ibss(sdata, ifsta, mgmt,
2063 case IEEE80211_STYPE_REASSOC_RESP: 2132 skb->len);
2064 ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 1); 2133 break;
2065 break; 2134 }
2066 case IEEE80211_STYPE_DEAUTH: 2135 } else { /* NL80211_IFTYPE_STATION */
2067 ieee80211_rx_mgmt_deauth(sdata, ifsta, mgmt, skb->len); 2136 switch (fc & IEEE80211_FCTL_STYPE) {
2068 break; 2137 case IEEE80211_STYPE_PROBE_RESP:
2069 case IEEE80211_STYPE_DISASSOC: 2138 ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len,
2070 ieee80211_rx_mgmt_disassoc(sdata, ifsta, mgmt, skb->len); 2139 rx_status);
2071 break; 2140 break;
2141 case IEEE80211_STYPE_BEACON:
2142 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
2143 rx_status);
2144 break;
2145 case IEEE80211_STYPE_AUTH:
2146 ieee80211_rx_mgmt_auth(sdata, ifsta, mgmt, skb->len);
2147 break;
2148 case IEEE80211_STYPE_ASSOC_RESP:
2149 ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt,
2150 skb->len, 0);
2151 break;
2152 case IEEE80211_STYPE_REASSOC_RESP:
2153 ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt,
2154 skb->len, 1);
2155 break;
2156 case IEEE80211_STYPE_DEAUTH:
2157 ieee80211_rx_mgmt_deauth(sdata, ifsta, mgmt, skb->len);
2158 break;
2159 case IEEE80211_STYPE_DISASSOC:
2160 ieee80211_rx_mgmt_disassoc(sdata, ifsta, mgmt,
2161 skb->len);
2162 break;
2163 }
2072 } 2164 }
2073 2165
2074 kfree_skb(skb); 2166 kfree_skb(skb);
@@ -2113,7 +2205,15 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata,
2113 2205
2114 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " 2206 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
2115 "IBSS networks with same SSID (merge)\n", sdata->dev->name); 2207 "IBSS networks with same SSID (merge)\n", sdata->dev->name);
2116 ieee80211_request_scan(sdata, ifsta->ssid, ifsta->ssid_len); 2208
2209 /* XXX maybe racy? */
2210 if (sdata->local->scan_req)
2211 return;
2212
2213 memcpy(sdata->local->int_scan_req.ssids[0].ssid,
2214 ifsta->ssid, IEEE80211_MAX_SSID_LEN);
2215 sdata->local->int_scan_req.ssids[0].ssid_len = ifsta->ssid_len;
2216 ieee80211_request_scan(sdata, &sdata->local->int_scan_req);
2117} 2217}
2118 2218
2119 2219
@@ -2159,46 +2259,16 @@ static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata,
2159 netif_carrier_off(sdata->dev); 2259 netif_carrier_off(sdata->dev);
2160} 2260}
2161 2261
2162
2163static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta,
2164 const char *ssid, int ssid_len)
2165{
2166 int tmp, hidden_ssid;
2167
2168 if (ssid_len == ifsta->ssid_len &&
2169 !memcmp(ifsta->ssid, ssid, ssid_len))
2170 return 1;
2171
2172 if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
2173 return 0;
2174
2175 hidden_ssid = 1;
2176 tmp = ssid_len;
2177 while (tmp--) {
2178 if (ssid[tmp] != '\0') {
2179 hidden_ssid = 0;
2180 break;
2181 }
2182 }
2183
2184 if (hidden_ssid && (ifsta->ssid_len == ssid_len || ssid_len == 0))
2185 return 1;
2186
2187 if (ssid_len == 1 && ssid[0] == ' ')
2188 return 1;
2189
2190 return 0;
2191}
2192
2193static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata, 2262static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
2194 struct ieee80211_if_sta *ifsta) 2263 struct ieee80211_if_sta *ifsta)
2195{ 2264{
2196 struct ieee80211_local *local = sdata->local; 2265 struct ieee80211_local *local = sdata->local;
2197 struct ieee80211_bss *bss;
2198 struct ieee80211_supported_band *sband; 2266 struct ieee80211_supported_band *sband;
2199 u8 bssid[ETH_ALEN], *pos; 2267 u8 *pos;
2268 u8 bssid[ETH_ALEN];
2269 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
2270 u16 capability;
2200 int i; 2271 int i;
2201 int ret;
2202 2272
2203 if (sdata->u.sta.flags & IEEE80211_STA_BSSID_SET) { 2273 if (sdata->u.sta.flags & IEEE80211_STA_BSSID_SET) {
2204 memcpy(bssid, ifsta->bssid, ETH_ALEN); 2274 memcpy(bssid, ifsta->bssid, ETH_ALEN);
@@ -2216,36 +2286,29 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
2216 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", 2286 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
2217 sdata->dev->name, bssid); 2287 sdata->dev->name, bssid);
2218 2288
2219 bss = ieee80211_rx_bss_add(local, bssid, 2289 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2220 local->hw.conf.channel->center_freq,
2221 sdata->u.sta.ssid, sdata->u.sta.ssid_len);
2222 if (!bss)
2223 return -ENOMEM;
2224
2225 bss->band = local->hw.conf.channel->band;
2226 sband = local->hw.wiphy->bands[bss->band];
2227 2290
2228 if (local->hw.conf.beacon_int == 0) 2291 if (local->hw.conf.beacon_int == 0)
2229 local->hw.conf.beacon_int = 100; 2292 local->hw.conf.beacon_int = 100;
2230 bss->beacon_int = local->hw.conf.beacon_int; 2293
2231 bss->last_update = jiffies; 2294 capability = WLAN_CAPABILITY_IBSS;
2232 bss->capability = WLAN_CAPABILITY_IBSS;
2233 2295
2234 if (sdata->default_key) 2296 if (sdata->default_key)
2235 bss->capability |= WLAN_CAPABILITY_PRIVACY; 2297 capability |= WLAN_CAPABILITY_PRIVACY;
2236 else 2298 else
2237 sdata->drop_unencrypted = 0; 2299 sdata->drop_unencrypted = 0;
2238 2300
2239 bss->supp_rates_len = sband->n_bitrates; 2301 pos = supp_rates;
2240 pos = bss->supp_rates;
2241 for (i = 0; i < sband->n_bitrates; i++) { 2302 for (i = 0; i < sband->n_bitrates; i++) {
2242 int rate = sband->bitrates[i].bitrate; 2303 int rate = sband->bitrates[i].bitrate;
2243 *pos++ = (u8) (rate / 5); 2304 *pos++ = (u8) (rate / 5);
2244 } 2305 }
2245 2306
2246 ret = ieee80211_sta_join_ibss(sdata, ifsta, bss); 2307 return __ieee80211_sta_join_ibss(sdata, ifsta,
2247 ieee80211_rx_bss_put(local, bss); 2308 bssid, local->hw.conf.beacon_int,
2248 return ret; 2309 local->hw.conf.channel->center_freq,
2310 sband->n_bitrates, supp_rates,
2311 capability);
2249} 2312}
2250 2313
2251 2314
@@ -2254,8 +2317,6 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
2254{ 2317{
2255 struct ieee80211_local *local = sdata->local; 2318 struct ieee80211_local *local = sdata->local;
2256 struct ieee80211_bss *bss; 2319 struct ieee80211_bss *bss;
2257 int found = 0;
2258 u8 bssid[ETH_ALEN];
2259 int active_ibss; 2320 int active_ibss;
2260 2321
2261 if (ifsta->ssid_len == 0) 2322 if (ifsta->ssid_len == 0)
@@ -2266,56 +2327,39 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
2266 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", 2327 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
2267 sdata->dev->name, active_ibss); 2328 sdata->dev->name, active_ibss);
2268#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2329#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2269 spin_lock_bh(&local->bss_lock); 2330
2270 list_for_each_entry(bss, &local->bss_list, list) { 2331 if (active_ibss)
2271 if (ifsta->ssid_len != bss->ssid_len || 2332 return 0;
2272 memcmp(ifsta->ssid, bss->ssid, bss->ssid_len) != 0 2333
2273 || !(bss->capability & WLAN_CAPABILITY_IBSS)) 2334 if (ifsta->flags & IEEE80211_STA_BSSID_SET)
2274 continue; 2335 bss = ieee80211_rx_bss_get(local, ifsta->bssid, 0,
2275 if ((ifsta->flags & IEEE80211_STA_BSSID_SET) && 2336 ifsta->ssid, ifsta->ssid_len);
2276 memcmp(ifsta->bssid, bss->bssid, ETH_ALEN) != 0) 2337 else
2277 continue; 2338 bss = (void *)cfg80211_get_ibss(local->hw.wiphy,
2278#ifdef CONFIG_MAC80211_IBSS_DEBUG 2339 NULL,
2279 printk(KERN_DEBUG " bssid=%pM found\n", bss->bssid); 2340 ifsta->ssid, ifsta->ssid_len);
2280#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2281 memcpy(bssid, bss->bssid, ETH_ALEN);
2282 found = 1;
2283 if (active_ibss || memcmp(bssid, ifsta->bssid, ETH_ALEN) != 0)
2284 break;
2285 }
2286 spin_unlock_bh(&local->bss_lock);
2287 2341
2288#ifdef CONFIG_MAC80211_IBSS_DEBUG 2342#ifdef CONFIG_MAC80211_IBSS_DEBUG
2289 if (found) 2343 if (bss)
2290 printk(KERN_DEBUG " sta_find_ibss: selected %pM current " 2344 printk(KERN_DEBUG " sta_find_ibss: selected %pM current "
2291 "%pM\n", bssid, ifsta->bssid); 2345 "%pM\n", bss->cbss.bssid, ifsta->bssid);
2292#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2346#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2293 2347
2294 if (found && 2348 if (bss &&
2295 ((!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET)) || 2349 (!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) ||
2296 memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0)) { 2350 memcmp(ifsta->bssid, bss->cbss.bssid, ETH_ALEN))) {
2297 int ret; 2351 int ret;
2298 int search_freq;
2299
2300 if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL)
2301 search_freq = bss->freq;
2302 else
2303 search_freq = local->hw.conf.channel->center_freq;
2304
2305 bss = ieee80211_rx_bss_get(local, bssid, search_freq,
2306 ifsta->ssid, ifsta->ssid_len);
2307 if (!bss)
2308 goto dont_join;
2309 2352
2310 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" 2353 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
2311 " based on configured SSID\n", 2354 " based on configured SSID\n",
2312 sdata->dev->name, bssid); 2355 sdata->dev->name, bss->cbss.bssid);
2356
2313 ret = ieee80211_sta_join_ibss(sdata, ifsta, bss); 2357 ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
2314 ieee80211_rx_bss_put(local, bss); 2358 ieee80211_rx_bss_put(local, bss);
2315 return ret; 2359 return ret;
2316 } 2360 } else if (bss)
2361 ieee80211_rx_bss_put(local, bss);
2317 2362
2318dont_join:
2319#ifdef CONFIG_MAC80211_IBSS_DEBUG 2363#ifdef CONFIG_MAC80211_IBSS_DEBUG
2320 printk(KERN_DEBUG " did not try to join ibss\n"); 2364 printk(KERN_DEBUG " did not try to join ibss\n");
2321#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2365#endif /* CONFIG_MAC80211_IBSS_DEBUG */
@@ -2329,8 +2373,15 @@ dont_join:
2329 IEEE80211_SCAN_INTERVAL)) { 2373 IEEE80211_SCAN_INTERVAL)) {
2330 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " 2374 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
2331 "join\n", sdata->dev->name); 2375 "join\n", sdata->dev->name);
2332 return ieee80211_request_scan(sdata, ifsta->ssid, 2376
2333 ifsta->ssid_len); 2377 /* XXX maybe racy? */
2378 if (local->scan_req)
2379 return -EBUSY;
2380
2381 memcpy(local->int_scan_req.ssids[0].ssid,
2382 ifsta->ssid, IEEE80211_MAX_SSID_LEN);
2383 local->int_scan_req.ssids[0].ssid_len = ifsta->ssid_len;
2384 return ieee80211_request_scan(sdata, &local->int_scan_req);
2334 } else if (ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED) { 2385 } else if (ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED) {
2335 int interval = IEEE80211_SCAN_INTERVAL; 2386 int interval = IEEE80211_SCAN_INTERVAL;
2336 2387
@@ -2364,50 +2415,44 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
2364 struct ieee80211_if_sta *ifsta) 2415 struct ieee80211_if_sta *ifsta)
2365{ 2416{
2366 struct ieee80211_local *local = sdata->local; 2417 struct ieee80211_local *local = sdata->local;
2367 struct ieee80211_bss *bss, *selected = NULL; 2418 struct ieee80211_bss *bss;
2368 int top_rssi = 0, freq; 2419 u8 *bssid = ifsta->bssid, *ssid = ifsta->ssid;
2369 2420 u8 ssid_len = ifsta->ssid_len;
2370 spin_lock_bh(&local->bss_lock); 2421 u16 capa_mask = WLAN_CAPABILITY_ESS;
2371 freq = local->oper_channel->center_freq; 2422 u16 capa_val = WLAN_CAPABILITY_ESS;
2372 list_for_each_entry(bss, &local->bss_list, list) { 2423 struct ieee80211_channel *chan = local->oper_channel;
2373 if (!(bss->capability & WLAN_CAPABILITY_ESS)) 2424
2374 continue; 2425 if (ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL |
2375 2426 IEEE80211_STA_AUTO_BSSID_SEL |
2376 if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL | 2427 IEEE80211_STA_AUTO_CHANNEL_SEL)) {
2377 IEEE80211_STA_AUTO_BSSID_SEL | 2428 capa_mask |= WLAN_CAPABILITY_PRIVACY;
2378 IEEE80211_STA_AUTO_CHANNEL_SEL)) && 2429 if (sdata->default_key)
2379 (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^ 2430 capa_val |= WLAN_CAPABILITY_PRIVACY;
2380 !!sdata->default_key)) 2431 }
2381 continue; 2432
2382 2433 if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL)
2383 if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) && 2434 chan = NULL;
2384 bss->freq != freq) 2435
2385 continue; 2436 if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
2386 2437 bssid = NULL;
2387 if (!(ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) && 2438
2388 memcmp(bss->bssid, ifsta->bssid, ETH_ALEN)) 2439 if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) {
2389 continue; 2440 ssid = NULL;
2390 2441 ssid_len = 0;
2391 if (!(ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) &&
2392 !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
2393 continue;
2394
2395 if (!selected || top_rssi < bss->signal) {
2396 selected = bss;
2397 top_rssi = bss->signal;
2398 }
2399 } 2442 }
2400 if (selected)
2401 atomic_inc(&selected->users);
2402 spin_unlock_bh(&local->bss_lock);
2403 2443
2404 if (selected) { 2444 bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan,
2405 ieee80211_set_freq(sdata, selected->freq); 2445 bssid, ssid, ssid_len,
2446 capa_mask, capa_val);
2447
2448 if (bss) {
2449 ieee80211_set_freq(sdata, bss->cbss.channel->center_freq);
2406 if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) 2450 if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
2407 ieee80211_sta_set_ssid(sdata, selected->ssid, 2451 ieee80211_sta_set_ssid(sdata, bss->ssid,
2408 selected->ssid_len); 2452 bss->ssid_len);
2409 ieee80211_sta_set_bssid(sdata, selected->bssid); 2453 ieee80211_sta_set_bssid(sdata, bss->cbss.bssid);
2410 ieee80211_sta_def_wmm_params(sdata, selected); 2454 ieee80211_sta_def_wmm_params(sdata, bss->supp_rates_len,
2455 bss->supp_rates);
2411 if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED) 2456 if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED)
2412 sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED; 2457 sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED;
2413 else 2458 else
@@ -2416,24 +2461,29 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
2416 /* Send out direct probe if no probe resp was received or 2461 /* Send out direct probe if no probe resp was received or
2417 * the one we have is outdated 2462 * the one we have is outdated
2418 */ 2463 */
2419 if (!selected->last_probe_resp || 2464 if (!bss->last_probe_resp ||
2420 time_after(jiffies, selected->last_probe_resp 2465 time_after(jiffies, bss->last_probe_resp
2421 + IEEE80211_SCAN_RESULT_EXPIRE)) 2466 + IEEE80211_SCAN_RESULT_EXPIRE))
2422 ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE; 2467 ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
2423 else 2468 else
2424 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE; 2469 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
2425 2470
2426 ieee80211_rx_bss_put(local, selected); 2471 ieee80211_rx_bss_put(local, bss);
2427 ieee80211_sta_reset_auth(sdata, ifsta); 2472 ieee80211_sta_reset_auth(sdata, ifsta);
2428 return 0; 2473 return 0;
2429 } else { 2474 } else {
2430 if (ifsta->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) { 2475 if (ifsta->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
2431 ifsta->assoc_scan_tries++; 2476 ifsta->assoc_scan_tries++;
2477 /* XXX maybe racy? */
2478 if (local->scan_req)
2479 return -1;
2480 memcpy(local->int_scan_req.ssids[0].ssid,
2481 ifsta->ssid, IEEE80211_MAX_SSID_LEN);
2432 if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) 2482 if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL)
2433 ieee80211_start_scan(sdata, NULL, 0); 2483 local->int_scan_req.ssids[0].ssid_len = 0;
2434 else 2484 else
2435 ieee80211_start_scan(sdata, ifsta->ssid, 2485 local->int_scan_req.ssids[0].ssid_len = ifsta->ssid_len;
2436 ifsta->ssid_len); 2486 ieee80211_start_scan(sdata, &local->int_scan_req);
2437 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE; 2487 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
2438 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request); 2488 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
2439 } else { 2489 } else {
@@ -2471,8 +2521,7 @@ static void ieee80211_sta_work(struct work_struct *work)
2471 ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE && 2521 ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
2472 ifsta->state != IEEE80211_STA_MLME_ASSOCIATE && 2522 ifsta->state != IEEE80211_STA_MLME_ASSOCIATE &&
2473 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) { 2523 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
2474 ieee80211_start_scan(sdata, ifsta->scan_ssid, 2524 ieee80211_start_scan(sdata, local->scan_req);
2475 ifsta->scan_ssid_len);
2476 return; 2525 return;
2477 } 2526 }
2478 2527
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 8e8ddbfcd236..1327d424bf31 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -731,6 +731,39 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
731 return result; 731 return result;
732} 732}
733 733
734static ieee80211_rx_result debug_noinline
735ieee80211_rx_h_check_more_data(struct ieee80211_rx_data *rx)
736{
737 struct ieee80211_local *local;
738 struct ieee80211_hdr *hdr;
739 struct sk_buff *skb;
740
741 local = rx->local;
742 skb = rx->skb;
743 hdr = (struct ieee80211_hdr *) skb->data;
744
745 if (!local->pspolling)
746 return RX_CONTINUE;
747
748 if (!ieee80211_has_fromds(hdr->frame_control))
749 /* this is not from AP */
750 return RX_CONTINUE;
751
752 if (!ieee80211_is_data(hdr->frame_control))
753 return RX_CONTINUE;
754
755 if (!ieee80211_has_moredata(hdr->frame_control)) {
756 /* AP has no more frames buffered for us */
757 local->pspolling = false;
758 return RX_CONTINUE;
759 }
760
761 /* more data bit is set, let's request a new frame from the AP */
762 ieee80211_send_pspoll(local, rx->sdata);
763
764 return RX_CONTINUE;
765}
766
734static void ap_sta_ps_start(struct sta_info *sta) 767static void ap_sta_ps_start(struct sta_info *sta)
735{ 768{
736 struct ieee80211_sub_if_data *sdata = sta->sdata; 769 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -1640,11 +1673,9 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
1640 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; 1673 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4;
1641 1674
1642 /* reset session timer */ 1675 /* reset session timer */
1643 if (tid_agg_rx->timeout) { 1676 if (tid_agg_rx->timeout)
1644 unsigned long expires = 1677 mod_timer(&tid_agg_rx->session_timer,
1645 jiffies + (tid_agg_rx->timeout / 1000) * HZ; 1678 TU_TO_EXP_TIME(tid_agg_rx->timeout));
1646 mod_timer(&tid_agg_rx->session_timer, expires);
1647 }
1648 1679
1649 /* manage reordering buffer according to requested */ 1680 /* manage reordering buffer according to requested */
1650 /* sequence number */ 1681 /* sequence number */
@@ -1737,6 +1768,17 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
1737 1768
1738 switch (mgmt->u.action.category) { 1769 switch (mgmt->u.action.category) {
1739 case WLAN_CATEGORY_BACK: 1770 case WLAN_CATEGORY_BACK:
1771 /*
1772 * The aggregation code is not prepared to handle
1773 * anything but STA/AP due to the BSSID handling;
1774 * IBSS could work in the code but isn't supported
1775 * by drivers or the standard.
1776 */
1777 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
1778 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
1779 sdata->vif.type != NL80211_IFTYPE_AP)
1780 return RX_DROP_MONITOR;
1781
1740 switch (mgmt->u.action.u.addba_req.action_code) { 1782 switch (mgmt->u.action.u.addba_req.action_code) {
1741 case WLAN_ACTION_ADDBA_REQ: 1783 case WLAN_ACTION_ADDBA_REQ:
1742 if (len < (IEEE80211_MIN_ACTION_SIZE + 1784 if (len < (IEEE80211_MIN_ACTION_SIZE +
@@ -1987,6 +2029,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
1987 CALL_RXH(ieee80211_rx_h_passive_scan) 2029 CALL_RXH(ieee80211_rx_h_passive_scan)
1988 CALL_RXH(ieee80211_rx_h_check) 2030 CALL_RXH(ieee80211_rx_h_check)
1989 CALL_RXH(ieee80211_rx_h_decrypt) 2031 CALL_RXH(ieee80211_rx_h_decrypt)
2032 CALL_RXH(ieee80211_rx_h_check_more_data)
1990 CALL_RXH(ieee80211_rx_h_sta_process) 2033 CALL_RXH(ieee80211_rx_h_sta_process)
1991 CALL_RXH(ieee80211_rx_h_defragment) 2034 CALL_RXH(ieee80211_rx_h_defragment)
1992 CALL_RXH(ieee80211_rx_h_ps_poll) 2035 CALL_RXH(ieee80211_rx_h_ps_poll)
@@ -2030,9 +2073,10 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
2030/* main receive path */ 2073/* main receive path */
2031 2074
2032static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, 2075static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
2033 u8 *bssid, struct ieee80211_rx_data *rx, 2076 struct ieee80211_rx_data *rx,
2034 struct ieee80211_hdr *hdr) 2077 struct ieee80211_hdr *hdr)
2035{ 2078{
2079 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, sdata->vif.type);
2036 int multicast = is_multicast_ether_addr(hdr->addr1); 2080 int multicast = is_multicast_ether_addr(hdr->addr1);
2037 2081
2038 switch (sdata->vif.type) { 2082 switch (sdata->vif.type) {
@@ -2135,7 +2179,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2135 int prepares; 2179 int prepares;
2136 struct ieee80211_sub_if_data *prev = NULL; 2180 struct ieee80211_sub_if_data *prev = NULL;
2137 struct sk_buff *skb_new; 2181 struct sk_buff *skb_new;
2138 u8 *bssid;
2139 2182
2140 hdr = (struct ieee80211_hdr *)skb->data; 2183 hdr = (struct ieee80211_hdr *)skb->data;
2141 memset(&rx, 0, sizeof(rx)); 2184 memset(&rx, 0, sizeof(rx));
@@ -2174,9 +2217,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2174 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) 2217 if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
2175 continue; 2218 continue;
2176 2219
2177 bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
2178 rx.flags |= IEEE80211_RX_RA_MATCH; 2220 rx.flags |= IEEE80211_RX_RA_MATCH;
2179 prepares = prepare_for_handlers(sdata, bssid, &rx, hdr); 2221 prepares = prepare_for_handlers(sdata, &rx, hdr);
2180 2222
2181 if (!prepares) 2223 if (!prepares)
2182 continue; 2224 continue;
@@ -2381,11 +2423,9 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2381 /* new un-ordered ampdu frame - process it */ 2423 /* new un-ordered ampdu frame - process it */
2382 2424
2383 /* reset session timer */ 2425 /* reset session timer */
2384 if (tid_agg_rx->timeout) { 2426 if (tid_agg_rx->timeout)
2385 unsigned long expires = 2427 mod_timer(&tid_agg_rx->session_timer,
2386 jiffies + (tid_agg_rx->timeout / 1000) * HZ; 2428 TU_TO_EXP_TIME(tid_agg_rx->timeout));
2387 mod_timer(&tid_agg_rx->session_timer, expires);
2388 }
2389 2429
2390 /* if this mpdu is fragmented - terminate rx aggregation session */ 2430 /* if this mpdu is fragmented - terminate rx aggregation session */
2391 sc = le16_to_cpu(hdr->seq_ctrl); 2431 sc = le16_to_cpu(hdr->seq_ctrl);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 282e6a0dec01..f883ab9f1e6e 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -12,11 +12,7 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15/* TODO: 15/* TODO: figure out how to avoid that the "current BSS" expires */
16 * order BSS list by RSSI(?) ("quality of AP")
17 * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
18 * SSID)
19 */
20 16
21#include <linux/wireless.h> 17#include <linux/wireless.h>
22#include <linux/if_arp.h> 18#include <linux/if_arp.h>
@@ -31,192 +27,29 @@
31#define IEEE80211_CHANNEL_TIME (HZ / 33) 27#define IEEE80211_CHANNEL_TIME (HZ / 33)
32#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5) 28#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5)
33 29
34void ieee80211_rx_bss_list_init(struct ieee80211_local *local)
35{
36 spin_lock_init(&local->bss_lock);
37 INIT_LIST_HEAD(&local->bss_list);
38}
39
40void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local)
41{
42 struct ieee80211_bss *bss, *tmp;
43
44 list_for_each_entry_safe(bss, tmp, &local->bss_list, list)
45 ieee80211_rx_bss_put(local, bss);
46}
47
48struct ieee80211_bss * 30struct ieee80211_bss *
49ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, 31ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
50 u8 *ssid, u8 ssid_len) 32 u8 *ssid, u8 ssid_len)
51{ 33{
52 struct ieee80211_bss *bss; 34 return (void *)cfg80211_get_bss(local->hw.wiphy,
53 35 ieee80211_get_channel(local->hw.wiphy,
54 spin_lock_bh(&local->bss_lock); 36 freq),
55 bss = local->bss_hash[STA_HASH(bssid)]; 37 bssid, ssid, ssid_len,
56 while (bss) { 38 0, 0);
57 if (!bss_mesh_cfg(bss) &&
58 !memcmp(bss->bssid, bssid, ETH_ALEN) &&
59 bss->freq == freq &&
60 bss->ssid_len == ssid_len &&
61 (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
62 atomic_inc(&bss->users);
63 break;
64 }
65 bss = bss->hnext;
66 }
67 spin_unlock_bh(&local->bss_lock);
68 return bss;
69}
70
71/* Caller must hold local->bss_lock */
72static void __ieee80211_rx_bss_hash_add(struct ieee80211_local *local,
73 struct ieee80211_bss *bss)
74{
75 u8 hash_idx;
76
77 if (bss_mesh_cfg(bss))
78 hash_idx = mesh_id_hash(bss_mesh_id(bss),
79 bss_mesh_id_len(bss));
80 else
81 hash_idx = STA_HASH(bss->bssid);
82
83 bss->hnext = local->bss_hash[hash_idx];
84 local->bss_hash[hash_idx] = bss;
85}
86
87/* Caller must hold local->bss_lock */
88static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local,
89 struct ieee80211_bss *bss)
90{
91 struct ieee80211_bss *b, *prev = NULL;
92 b = local->bss_hash[STA_HASH(bss->bssid)];
93 while (b) {
94 if (b == bss) {
95 if (!prev)
96 local->bss_hash[STA_HASH(bss->bssid)] =
97 bss->hnext;
98 else
99 prev->hnext = bss->hnext;
100 break;
101 }
102 prev = b;
103 b = b->hnext;
104 }
105}
106
107struct ieee80211_bss *
108ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
109 u8 *ssid, u8 ssid_len)
110{
111 struct ieee80211_bss *bss;
112
113 bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
114 if (!bss)
115 return NULL;
116 atomic_set(&bss->users, 2);
117 memcpy(bss->bssid, bssid, ETH_ALEN);
118 bss->freq = freq;
119 if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
120 memcpy(bss->ssid, ssid, ssid_len);
121 bss->ssid_len = ssid_len;
122 }
123
124 spin_lock_bh(&local->bss_lock);
125 /* TODO: order by RSSI? */
126 list_add_tail(&bss->list, &local->bss_list);
127 __ieee80211_rx_bss_hash_add(local, bss);
128 spin_unlock_bh(&local->bss_lock);
129 return bss;
130}
131
132#ifdef CONFIG_MAC80211_MESH
133static struct ieee80211_bss *
134ieee80211_rx_mesh_bss_get(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
135 u8 *mesh_cfg, int freq)
136{
137 struct ieee80211_bss *bss;
138
139 spin_lock_bh(&local->bss_lock);
140 bss = local->bss_hash[mesh_id_hash(mesh_id, mesh_id_len)];
141 while (bss) {
142 if (bss_mesh_cfg(bss) &&
143 !memcmp(bss_mesh_cfg(bss), mesh_cfg, MESH_CFG_CMP_LEN) &&
144 bss->freq == freq &&
145 mesh_id_len == bss->mesh_id_len &&
146 (mesh_id_len == 0 || !memcmp(bss->mesh_id, mesh_id,
147 mesh_id_len))) {
148 atomic_inc(&bss->users);
149 break;
150 }
151 bss = bss->hnext;
152 }
153 spin_unlock_bh(&local->bss_lock);
154 return bss;
155} 39}
156 40
157static struct ieee80211_bss * 41static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss)
158ieee80211_rx_mesh_bss_add(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
159 u8 *mesh_cfg, int mesh_config_len, int freq)
160{ 42{
161 struct ieee80211_bss *bss; 43 struct ieee80211_bss *bss = (void *)cbss;
162 44
163 if (mesh_config_len != IEEE80211_MESH_CONFIG_LEN)
164 return NULL;
165
166 bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
167 if (!bss)
168 return NULL;
169
170 bss->mesh_cfg = kmalloc(MESH_CFG_CMP_LEN, GFP_ATOMIC);
171 if (!bss->mesh_cfg) {
172 kfree(bss);
173 return NULL;
174 }
175
176 if (mesh_id_len && mesh_id_len <= IEEE80211_MAX_MESH_ID_LEN) {
177 bss->mesh_id = kmalloc(mesh_id_len, GFP_ATOMIC);
178 if (!bss->mesh_id) {
179 kfree(bss->mesh_cfg);
180 kfree(bss);
181 return NULL;
182 }
183 memcpy(bss->mesh_id, mesh_id, mesh_id_len);
184 }
185
186 atomic_set(&bss->users, 2);
187 memcpy(bss->mesh_cfg, mesh_cfg, MESH_CFG_CMP_LEN);
188 bss->mesh_id_len = mesh_id_len;
189 bss->freq = freq;
190 spin_lock_bh(&local->bss_lock);
191 /* TODO: order by RSSI? */
192 list_add_tail(&bss->list, &local->bss_list);
193 __ieee80211_rx_bss_hash_add(local, bss);
194 spin_unlock_bh(&local->bss_lock);
195 return bss;
196}
197#endif
198
199static void ieee80211_rx_bss_free(struct ieee80211_bss *bss)
200{
201 kfree(bss->ies);
202 kfree(bss_mesh_id(bss)); 45 kfree(bss_mesh_id(bss));
203 kfree(bss_mesh_cfg(bss)); 46 kfree(bss_mesh_cfg(bss));
204 kfree(bss);
205} 47}
206 48
207void ieee80211_rx_bss_put(struct ieee80211_local *local, 49void ieee80211_rx_bss_put(struct ieee80211_local *local,
208 struct ieee80211_bss *bss) 50 struct ieee80211_bss *bss)
209{ 51{
210 local_bh_disable(); 52 cfg80211_put_bss((struct cfg80211_bss *)bss);
211 if (!atomic_dec_and_lock(&bss->users, &local->bss_lock)) {
212 local_bh_enable();
213 return;
214 }
215
216 __ieee80211_rx_bss_hash_del(local, bss);
217 list_del(&bss->list);
218 spin_unlock_bh(&local->bss_lock);
219 ieee80211_rx_bss_free(bss);
220} 53}
221 54
222struct ieee80211_bss * 55struct ieee80211_bss *
@@ -225,49 +58,37 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
225 struct ieee80211_mgmt *mgmt, 58 struct ieee80211_mgmt *mgmt,
226 size_t len, 59 size_t len,
227 struct ieee802_11_elems *elems, 60 struct ieee802_11_elems *elems,
228 int freq, bool beacon) 61 struct ieee80211_channel *channel,
62 bool beacon)
229{ 63{
230 struct ieee80211_bss *bss; 64 struct ieee80211_bss *bss;
231 int clen; 65 int clen;
232 66 enum cfg80211_signal_type sigtype = CFG80211_SIGNAL_TYPE_NONE;
233#ifdef CONFIG_MAC80211_MESH 67 s32 signal = 0;
234 if (elems->mesh_config) 68
235 bss = ieee80211_rx_mesh_bss_get(local, elems->mesh_id, 69 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
236 elems->mesh_id_len, elems->mesh_config, freq); 70 sigtype = CFG80211_SIGNAL_TYPE_MBM;
237 else 71 signal = rx_status->signal * 100;
238#endif 72 } else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) {
239 bss = ieee80211_rx_bss_get(local, mgmt->bssid, freq, 73 sigtype = CFG80211_SIGNAL_TYPE_UNSPEC;
240 elems->ssid, elems->ssid_len); 74 signal = (rx_status->signal * 100) / local->hw.max_signal;
241 if (!bss) {
242#ifdef CONFIG_MAC80211_MESH
243 if (elems->mesh_config)
244 bss = ieee80211_rx_mesh_bss_add(local, elems->mesh_id,
245 elems->mesh_id_len, elems->mesh_config,
246 elems->mesh_config_len, freq);
247 else
248#endif
249 bss = ieee80211_rx_bss_add(local, mgmt->bssid, freq,
250 elems->ssid, elems->ssid_len);
251 if (!bss)
252 return NULL;
253 } else {
254#if 0
255 /* TODO: order by RSSI? */
256 spin_lock_bh(&local->bss_lock);
257 list_move_tail(&bss->list, &local->bss_list);
258 spin_unlock_bh(&local->bss_lock);
259#endif
260 } 75 }
261 76
77 bss = (void *)cfg80211_inform_bss_frame(local->hw.wiphy, channel,
78 mgmt, len, signal, sigtype,
79 GFP_ATOMIC);
80
81 if (!bss)
82 return NULL;
83
84 bss->cbss.free_priv = ieee80211_rx_bss_free;
85
262 /* save the ERP value so that it is available at association time */ 86 /* save the ERP value so that it is available at association time */
263 if (elems->erp_info && elems->erp_info_len >= 1) { 87 if (elems->erp_info && elems->erp_info_len >= 1) {
264 bss->erp_value = elems->erp_info[0]; 88 bss->erp_value = elems->erp_info[0];
265 bss->has_erp_value = 1; 89 bss->has_erp_value = 1;
266 } 90 }
267 91
268 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
269 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
270
271 if (elems->tim) { 92 if (elems->tim) {
272 struct ieee80211_tim_ie *tim_ie = 93 struct ieee80211_tim_ie *tim_ie =
273 (struct ieee80211_tim_ie *)elems->tim; 94 (struct ieee80211_tim_ie *)elems->tim;
@@ -296,37 +117,27 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
296 bss->supp_rates_len += clen; 117 bss->supp_rates_len += clen;
297 } 118 }
298 119
299 bss->band = rx_status->band;
300
301 bss->timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
302 bss->last_update = jiffies;
303 bss->signal = rx_status->signal;
304 bss->noise = rx_status->noise;
305 bss->qual = rx_status->qual;
306 bss->wmm_used = elems->wmm_param || elems->wmm_info; 120 bss->wmm_used = elems->wmm_param || elems->wmm_info;
307 121
308 if (!beacon) 122 if (!beacon)
309 bss->last_probe_resp = jiffies; 123 bss->last_probe_resp = jiffies;
310 124
311 /*
312 * For probe responses, or if we don't have any information yet,
313 * use the IEs from the beacon.
314 */
315 if (!bss->ies || !beacon) {
316 if (bss->ies == NULL || bss->ies_len < elems->total_len) {
317 kfree(bss->ies);
318 bss->ies = kmalloc(elems->total_len, GFP_ATOMIC);
319 }
320 if (bss->ies) {
321 memcpy(bss->ies, elems->ie_start, elems->total_len);
322 bss->ies_len = elems->total_len;
323 } else
324 bss->ies_len = 0;
325 }
326
327 return bss; 125 return bss;
328} 126}
329 127
128void ieee80211_rx_bss_remove(struct ieee80211_sub_if_data *sdata, u8 *bssid,
129 int freq, u8 *ssid, u8 ssid_len)
130{
131 struct ieee80211_bss *bss;
132 struct ieee80211_local *local = sdata->local;
133
134 bss = ieee80211_rx_bss_get(local, bssid, freq, ssid, ssid_len);
135 if (bss) {
136 cfg80211_unlink_bss(local->hw.wiphy, (void *)bss);
137 ieee80211_rx_bss_put(local, bss);
138 }
139}
140
330ieee80211_rx_result 141ieee80211_rx_result
331ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, 142ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
332 struct ieee80211_rx_status *rx_status) 143 struct ieee80211_rx_status *rx_status)
@@ -388,7 +199,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
388 199
389 bss = ieee80211_bss_info_update(sdata->local, rx_status, 200 bss = ieee80211_bss_info_update(sdata->local, rx_status,
390 mgmt, skb->len, &elems, 201 mgmt, skb->len, &elems,
391 freq, beacon); 202 channel, beacon);
392 if (bss) 203 if (bss)
393 ieee80211_rx_bss_put(sdata->local, bss); 204 ieee80211_rx_bss_put(sdata->local, bss);
394 205
@@ -426,26 +237,22 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
426 ieee80211_tx_skb(sdata, skb, 0); 237 ieee80211_tx_skb(sdata, skb, 0);
427} 238}
428 239
429void ieee80211_scan_completed(struct ieee80211_hw *hw) 240void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
430{ 241{
431 struct ieee80211_local *local = hw_to_local(hw); 242 struct ieee80211_local *local = hw_to_local(hw);
432 struct ieee80211_sub_if_data *sdata; 243 struct ieee80211_sub_if_data *sdata;
433 union iwreq_data wrqu;
434 244
435 if (WARN_ON(!local->hw_scanning && !local->sw_scanning)) 245 if (WARN_ON(!local->hw_scanning && !local->sw_scanning))
436 return; 246 return;
437 247
438 local->last_scan_completed = jiffies; 248 if (WARN_ON(!local->scan_req))
439 memset(&wrqu, 0, sizeof(wrqu)); 249 return;
440 250
441 /* 251 if (local->scan_req != &local->int_scan_req)
442 * local->scan_sdata could have been NULLed by the interface 252 cfg80211_scan_done(local->scan_req, aborted);
443 * down code in case we were scanning on an interface that is 253 local->scan_req = NULL;
444 * being taken down. 254
445 */ 255 local->last_scan_completed = jiffies;
446 sdata = local->scan_sdata;
447 if (sdata)
448 wireless_send_event(sdata->dev, SIOCGIWSCAN, &wrqu, NULL);
449 256
450 if (local->hw_scanning) { 257 if (local->hw_scanning) {
451 local->hw_scanning = false; 258 local->hw_scanning = false;
@@ -487,7 +294,12 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
487 } else 294 } else
488 netif_tx_wake_all_queues(sdata->dev); 295 netif_tx_wake_all_queues(sdata->dev);
489 296
490 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED); 297 /* re-enable beaconing */
298 if (sdata->vif.type == NL80211_IFTYPE_AP ||
299 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
300 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
301 ieee80211_if_config(sdata,
302 IEEE80211_IFCC_BEACON_ENABLED);
491 } 303 }
492 mutex_unlock(&local->iflist_mtx); 304 mutex_unlock(&local->iflist_mtx);
493 305
@@ -502,9 +314,8 @@ void ieee80211_scan_work(struct work_struct *work)
502 struct ieee80211_local *local = 314 struct ieee80211_local *local =
503 container_of(work, struct ieee80211_local, scan_work.work); 315 container_of(work, struct ieee80211_local, scan_work.work);
504 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 316 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
505 struct ieee80211_supported_band *sband;
506 struct ieee80211_channel *chan; 317 struct ieee80211_channel *chan;
507 int skip; 318 int skip, i;
508 unsigned long next_delay = 0; 319 unsigned long next_delay = 0;
509 320
510 /* 321 /*
@@ -515,33 +326,13 @@ void ieee80211_scan_work(struct work_struct *work)
515 326
516 switch (local->scan_state) { 327 switch (local->scan_state) {
517 case SCAN_SET_CHANNEL: 328 case SCAN_SET_CHANNEL:
518 /*
519 * Get current scan band. scan_band may be IEEE80211_NUM_BANDS
520 * after we successfully scanned the last channel of the last
521 * band (and the last band is supported by the hw)
522 */
523 if (local->scan_band < IEEE80211_NUM_BANDS)
524 sband = local->hw.wiphy->bands[local->scan_band];
525 else
526 sband = NULL;
527
528 /*
529 * If we are at an unsupported band and have more bands
530 * left to scan, advance to the next supported one.
531 */
532 while (!sband && local->scan_band < IEEE80211_NUM_BANDS - 1) {
533 local->scan_band++;
534 sband = local->hw.wiphy->bands[local->scan_band];
535 local->scan_channel_idx = 0;
536 }
537
538 /* if no more bands/channels left, complete scan */ 329 /* if no more bands/channels left, complete scan */
539 if (!sband || local->scan_channel_idx >= sband->n_channels) { 330 if (local->scan_channel_idx >= local->scan_req->n_channels) {
540 ieee80211_scan_completed(local_to_hw(local)); 331 ieee80211_scan_completed(local_to_hw(local), false);
541 return; 332 return;
542 } 333 }
543 skip = 0; 334 skip = 0;
544 chan = &sband->channels[local->scan_channel_idx]; 335 chan = local->scan_req->channels[local->scan_channel_idx];
545 336
546 if (chan->flags & IEEE80211_CHAN_DISABLED || 337 if (chan->flags & IEEE80211_CHAN_DISABLED ||
547 (sdata->vif.type == NL80211_IFTYPE_ADHOC && 338 (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
@@ -557,15 +348,6 @@ void ieee80211_scan_work(struct work_struct *work)
557 348
558 /* advance state machine to next channel/band */ 349 /* advance state machine to next channel/band */
559 local->scan_channel_idx++; 350 local->scan_channel_idx++;
560 if (local->scan_channel_idx >= sband->n_channels) {
561 /*
562 * scan_band may end up == IEEE80211_NUM_BANDS, but
563 * we'll catch that case above and complete the scan
564 * if that is the case.
565 */
566 local->scan_band++;
567 local->scan_channel_idx = 0;
568 }
569 351
570 if (skip) 352 if (skip)
571 break; 353 break;
@@ -578,10 +360,14 @@ void ieee80211_scan_work(struct work_struct *work)
578 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; 360 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
579 local->scan_state = SCAN_SET_CHANNEL; 361 local->scan_state = SCAN_SET_CHANNEL;
580 362
581 if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN) 363 if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
364 !local->scan_req->n_ssids)
582 break; 365 break;
583 ieee80211_send_probe_req(sdata, NULL, local->scan_ssid, 366 for (i = 0; i < local->scan_req->n_ssids; i++)
584 local->scan_ssid_len); 367 ieee80211_send_probe_req(
368 sdata, NULL,
369 local->scan_req->ssids[i].ssid,
370 local->scan_req->ssids[i].ssid_len);
585 next_delay = IEEE80211_CHANNEL_TIME; 371 next_delay = IEEE80211_CHANNEL_TIME;
586 break; 372 break;
587 } 373 }
@@ -592,14 +378,19 @@ void ieee80211_scan_work(struct work_struct *work)
592 378
593 379
594int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata, 380int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
595 u8 *ssid, size_t ssid_len) 381 struct cfg80211_scan_request *req)
596{ 382{
597 struct ieee80211_local *local = scan_sdata->local; 383 struct ieee80211_local *local = scan_sdata->local;
598 struct ieee80211_sub_if_data *sdata; 384 struct ieee80211_sub_if_data *sdata;
599 385
600 if (ssid_len > IEEE80211_MAX_SSID_LEN) 386 if (!req)
601 return -EINVAL; 387 return -EINVAL;
602 388
389 if (local->scan_req && local->scan_req != req)
390 return -EBUSY;
391
392 local->scan_req = req;
393
603 /* MLME-SCAN.request (page 118) page 144 (11.1.3.1) 394 /* MLME-SCAN.request (page 118) page 144 (11.1.3.1)
604 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS 395 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
605 * BSSID: MACAddress 396 * BSSID: MACAddress
@@ -627,7 +418,7 @@ int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
627 int rc; 418 int rc;
628 419
629 local->hw_scanning = true; 420 local->hw_scanning = true;
630 rc = local->ops->hw_scan(local_to_hw(local), ssid, ssid_len); 421 rc = local->ops->hw_scan(local_to_hw(local), req);
631 if (rc) { 422 if (rc) {
632 local->hw_scanning = false; 423 local->hw_scanning = false;
633 return rc; 424 return rc;
@@ -643,7 +434,12 @@ int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
643 if (!netif_running(sdata->dev)) 434 if (!netif_running(sdata->dev))
644 continue; 435 continue;
645 436
646 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED); 437 /* disable beaconing */
438 if (sdata->vif.type == NL80211_IFTYPE_AP ||
439 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
440 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
441 ieee80211_if_config(sdata,
442 IEEE80211_IFCC_BEACON_ENABLED);
647 443
648 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 444 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
649 if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) { 445 if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
@@ -655,15 +451,10 @@ int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
655 } 451 }
656 mutex_unlock(&local->iflist_mtx); 452 mutex_unlock(&local->iflist_mtx);
657 453
658 if (ssid) {
659 local->scan_ssid_len = ssid_len;
660 memcpy(local->scan_ssid, ssid, ssid_len);
661 } else
662 local->scan_ssid_len = 0;
663 local->scan_state = SCAN_SET_CHANNEL; 454 local->scan_state = SCAN_SET_CHANNEL;
664 local->scan_channel_idx = 0; 455 local->scan_channel_idx = 0;
665 local->scan_band = IEEE80211_BAND_2GHZ;
666 local->scan_sdata = scan_sdata; 456 local->scan_sdata = scan_sdata;
457 local->scan_req = req;
667 458
668 netif_addr_lock_bh(local->mdev); 459 netif_addr_lock_bh(local->mdev);
669 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC; 460 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
@@ -683,13 +474,21 @@ int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
683 474
684 475
685int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, 476int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
686 u8 *ssid, size_t ssid_len) 477 struct cfg80211_scan_request *req)
687{ 478{
688 struct ieee80211_local *local = sdata->local; 479 struct ieee80211_local *local = sdata->local;
689 struct ieee80211_if_sta *ifsta; 480 struct ieee80211_if_sta *ifsta;
690 481
482 if (!req)
483 return -EINVAL;
484
485 if (local->scan_req && local->scan_req != req)
486 return -EBUSY;
487
488 local->scan_req = req;
489
691 if (sdata->vif.type != NL80211_IFTYPE_STATION) 490 if (sdata->vif.type != NL80211_IFTYPE_STATION)
692 return ieee80211_start_scan(sdata, ssid, ssid_len); 491 return ieee80211_start_scan(sdata, req);
693 492
694 /* 493 /*
695 * STA has a state machine that might need to defer scanning 494 * STA has a state machine that might need to defer scanning
@@ -704,241 +503,8 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
704 } 503 }
705 504
706 ifsta = &sdata->u.sta; 505 ifsta = &sdata->u.sta;
707
708 ifsta->scan_ssid_len = ssid_len;
709 if (ssid_len)
710 memcpy(ifsta->scan_ssid, ssid, ssid_len);
711 set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request); 506 set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
712 queue_work(local->hw.workqueue, &ifsta->work); 507 queue_work(local->hw.workqueue, &ifsta->work);
713 508
714 return 0; 509 return 0;
715} 510}
716
717
718static void ieee80211_scan_add_ies(struct iw_request_info *info,
719 struct ieee80211_bss *bss,
720 char **current_ev, char *end_buf)
721{
722 u8 *pos, *end, *next;
723 struct iw_event iwe;
724
725 if (bss == NULL || bss->ies == NULL)
726 return;
727
728 /*
729 * If needed, fragment the IEs buffer (at IE boundaries) into short
730 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
731 */
732 pos = bss->ies;
733 end = pos + bss->ies_len;
734
735 while (end - pos > IW_GENERIC_IE_MAX) {
736 next = pos + 2 + pos[1];
737 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
738 next = next + 2 + next[1];
739
740 memset(&iwe, 0, sizeof(iwe));
741 iwe.cmd = IWEVGENIE;
742 iwe.u.data.length = next - pos;
743 *current_ev = iwe_stream_add_point(info, *current_ev,
744 end_buf, &iwe, pos);
745
746 pos = next;
747 }
748
749 if (end > pos) {
750 memset(&iwe, 0, sizeof(iwe));
751 iwe.cmd = IWEVGENIE;
752 iwe.u.data.length = end - pos;
753 *current_ev = iwe_stream_add_point(info, *current_ev,
754 end_buf, &iwe, pos);
755 }
756}
757
758
759static char *
760ieee80211_scan_result(struct ieee80211_local *local,
761 struct iw_request_info *info,
762 struct ieee80211_bss *bss,
763 char *current_ev, char *end_buf)
764{
765 struct iw_event iwe;
766 char *buf;
767
768 if (time_after(jiffies,
769 bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE))
770 return current_ev;
771
772 memset(&iwe, 0, sizeof(iwe));
773 iwe.cmd = SIOCGIWAP;
774 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
775 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
776 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
777 IW_EV_ADDR_LEN);
778
779 memset(&iwe, 0, sizeof(iwe));
780 iwe.cmd = SIOCGIWESSID;
781 if (bss_mesh_cfg(bss)) {
782 iwe.u.data.length = bss_mesh_id_len(bss);
783 iwe.u.data.flags = 1;
784 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
785 &iwe, bss_mesh_id(bss));
786 } else {
787 iwe.u.data.length = bss->ssid_len;
788 iwe.u.data.flags = 1;
789 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
790 &iwe, bss->ssid);
791 }
792
793 if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
794 || bss_mesh_cfg(bss)) {
795 memset(&iwe, 0, sizeof(iwe));
796 iwe.cmd = SIOCGIWMODE;
797 if (bss_mesh_cfg(bss))
798 iwe.u.mode = IW_MODE_MESH;
799 else if (bss->capability & WLAN_CAPABILITY_ESS)
800 iwe.u.mode = IW_MODE_MASTER;
801 else
802 iwe.u.mode = IW_MODE_ADHOC;
803 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
804 &iwe, IW_EV_UINT_LEN);
805 }
806
807 memset(&iwe, 0, sizeof(iwe));
808 iwe.cmd = SIOCGIWFREQ;
809 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
810 iwe.u.freq.e = 0;
811 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
812 IW_EV_FREQ_LEN);
813
814 memset(&iwe, 0, sizeof(iwe));
815 iwe.cmd = SIOCGIWFREQ;
816 iwe.u.freq.m = bss->freq;
817 iwe.u.freq.e = 6;
818 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
819 IW_EV_FREQ_LEN);
820 memset(&iwe, 0, sizeof(iwe));
821 iwe.cmd = IWEVQUAL;
822 iwe.u.qual.qual = bss->qual;
823 iwe.u.qual.level = bss->signal;
824 iwe.u.qual.noise = bss->noise;
825 iwe.u.qual.updated = local->wstats_flags;
826 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
827 IW_EV_QUAL_LEN);
828
829 memset(&iwe, 0, sizeof(iwe));
830 iwe.cmd = SIOCGIWENCODE;
831 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
832 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
833 else
834 iwe.u.data.flags = IW_ENCODE_DISABLED;
835 iwe.u.data.length = 0;
836 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
837 &iwe, "");
838
839 ieee80211_scan_add_ies(info, bss, &current_ev, end_buf);
840
841 if (bss->supp_rates_len > 0) {
842 /* display all supported rates in readable format */
843 char *p = current_ev + iwe_stream_lcp_len(info);
844 int i;
845
846 memset(&iwe, 0, sizeof(iwe));
847 iwe.cmd = SIOCGIWRATE;
848 /* Those two flags are ignored... */
849 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
850
851 for (i = 0; i < bss->supp_rates_len; i++) {
852 iwe.u.bitrate.value = ((bss->supp_rates[i] &
853 0x7f) * 500000);
854 p = iwe_stream_add_value(info, current_ev, p,
855 end_buf, &iwe, IW_EV_PARAM_LEN);
856 }
857 current_ev = p;
858 }
859
860 buf = kmalloc(30, GFP_ATOMIC);
861 if (buf) {
862 memset(&iwe, 0, sizeof(iwe));
863 iwe.cmd = IWEVCUSTOM;
864 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
865 iwe.u.data.length = strlen(buf);
866 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
867 &iwe, buf);
868 memset(&iwe, 0, sizeof(iwe));
869 iwe.cmd = IWEVCUSTOM;
870 sprintf(buf, " Last beacon: %dms ago",
871 jiffies_to_msecs(jiffies - bss->last_update));
872 iwe.u.data.length = strlen(buf);
873 current_ev = iwe_stream_add_point(info, current_ev,
874 end_buf, &iwe, buf);
875 kfree(buf);
876 }
877
878 if (bss_mesh_cfg(bss)) {
879 u8 *cfg = bss_mesh_cfg(bss);
880 buf = kmalloc(50, GFP_ATOMIC);
881 if (buf) {
882 memset(&iwe, 0, sizeof(iwe));
883 iwe.cmd = IWEVCUSTOM;
884 sprintf(buf, "Mesh network (version %d)", cfg[0]);
885 iwe.u.data.length = strlen(buf);
886 current_ev = iwe_stream_add_point(info, current_ev,
887 end_buf,
888 &iwe, buf);
889 sprintf(buf, "Path Selection Protocol ID: "
890 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
891 cfg[4]);
892 iwe.u.data.length = strlen(buf);
893 current_ev = iwe_stream_add_point(info, current_ev,
894 end_buf,
895 &iwe, buf);
896 sprintf(buf, "Path Selection Metric ID: "
897 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
898 cfg[8]);
899 iwe.u.data.length = strlen(buf);
900 current_ev = iwe_stream_add_point(info, current_ev,
901 end_buf,
902 &iwe, buf);
903 sprintf(buf, "Congestion Control Mode ID: "
904 "0x%02X%02X%02X%02X", cfg[9], cfg[10],
905 cfg[11], cfg[12]);
906 iwe.u.data.length = strlen(buf);
907 current_ev = iwe_stream_add_point(info, current_ev,
908 end_buf,
909 &iwe, buf);
910 sprintf(buf, "Channel Precedence: "
911 "0x%02X%02X%02X%02X", cfg[13], cfg[14],
912 cfg[15], cfg[16]);
913 iwe.u.data.length = strlen(buf);
914 current_ev = iwe_stream_add_point(info, current_ev,
915 end_buf,
916 &iwe, buf);
917 kfree(buf);
918 }
919 }
920
921 return current_ev;
922}
923
924
925int ieee80211_scan_results(struct ieee80211_local *local,
926 struct iw_request_info *info,
927 char *buf, size_t len)
928{
929 char *current_ev = buf;
930 char *end_buf = buf + len;
931 struct ieee80211_bss *bss;
932
933 spin_lock_bh(&local->bss_lock);
934 list_for_each_entry(bss, &local->bss_list, list) {
935 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
936 spin_unlock_bh(&local->bss_lock);
937 return -E2BIG;
938 }
939 current_ev = ieee80211_scan_result(local, info, bss,
940 current_ev, end_buf);
941 }
942 spin_unlock_bh(&local->bss_lock);
943 return current_ev - buf;
944}
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 8d4ec2968f8f..47bb2aed2813 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -102,8 +102,9 @@ void ieee80211_chswitch_work(struct work_struct *work)
102 goto exit; 102 goto exit;
103 103
104 sdata->local->oper_channel = sdata->local->csa_channel; 104 sdata->local->oper_channel = sdata->local->csa_channel;
105 /* XXX: shouldn't really modify cfg80211-owned data! */
105 if (!ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL)) 106 if (!ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL))
106 bss->freq = sdata->local->oper_channel->center_freq; 107 bss->cbss.channel = sdata->local->oper_channel;
107 108
108 ieee80211_rx_bss_put(sdata->local, bss); 109 ieee80211_rx_bss_put(sdata->local, bss);
109exit: 110exit:
@@ -158,7 +159,9 @@ void ieee80211_process_chanswitch(struct ieee80211_sub_if_data *sdata,
158 IEEE80211_QUEUE_STOP_REASON_CSA); 159 IEEE80211_QUEUE_STOP_REASON_CSA);
159 ifsta->flags |= IEEE80211_STA_CSA_RECEIVED; 160 ifsta->flags |= IEEE80211_STA_CSA_RECEIVED;
160 mod_timer(&ifsta->chswitch_timer, 161 mod_timer(&ifsta->chswitch_timer,
161 jiffies + msecs_to_jiffies(sw_elem->count * bss->beacon_int)); 162 jiffies +
163 msecs_to_jiffies(sw_elem->count *
164 bss->cbss.beacon_interval));
162 } 165 }
163} 166}
164 167
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 10c5539c20ab..634f65c0130e 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -194,12 +194,41 @@ void sta_info_destroy(struct sta_info *sta)
194 dev_kfree_skb_any(skb); 194 dev_kfree_skb_any(skb);
195 195
196 for (i = 0; i < STA_TID_NUM; i++) { 196 for (i = 0; i < STA_TID_NUM; i++) {
197 struct tid_ampdu_rx *tid_rx;
198 struct tid_ampdu_tx *tid_tx;
199
197 spin_lock_bh(&sta->lock); 200 spin_lock_bh(&sta->lock);
198 if (sta->ampdu_mlme.tid_rx[i]) 201 tid_rx = sta->ampdu_mlme.tid_rx[i];
199 del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); 202 /* Make sure timer won't free the tid_rx struct, see below */
200 if (sta->ampdu_mlme.tid_tx[i]) 203 if (tid_rx)
201 del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); 204 tid_rx->shutdown = true;
202 spin_unlock_bh(&sta->lock); 205 spin_unlock_bh(&sta->lock);
206
207 /*
208 * Outside spinlock - shutdown is true now so that the timer
209 * won't free tid_rx, we have to do that now. Can't let the
210 * timer do it because we have to sync the timer outside the
211 * lock that it takes itself.
212 */
213 if (tid_rx) {
214 del_timer_sync(&tid_rx->session_timer);
215 kfree(tid_rx);
216 }
217
218 /*
219 * No need to do such complications for TX agg sessions, the
220 * path leading to freeing the tid_tx struct goes via a call
221 * from the driver, and thus needs to look up the sta struct
222 * again, which cannot be found when we get here. Hence, we
223 * just need to delete the timer and free the aggregation
224 * info; we won't be telling the peer about it then but that
225 * doesn't matter if we're not talking to it again anyway.
226 */
227 tid_tx = sta->ampdu_mlme.tid_tx[i];
228 if (tid_tx) {
229 del_timer_sync(&tid_tx->addba_resp_timer);
230 kfree(tid_tx);
231 }
203 } 232 }
204 233
205 __sta_info_free(local, sta); 234 __sta_info_free(local, sta);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index d13a44b935e2..d9653231992f 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -65,7 +65,6 @@ enum ieee80211_sta_info_flags {
65#define HT_AGG_STATE_OPERATIONAL (HT_ADDBA_REQUESTED_MSK | \ 65#define HT_AGG_STATE_OPERATIONAL (HT_ADDBA_REQUESTED_MSK | \
66 HT_ADDBA_DRV_READY_MSK | \ 66 HT_ADDBA_DRV_READY_MSK | \
67 HT_ADDBA_RECEIVED_MSK) 67 HT_ADDBA_RECEIVED_MSK)
68#define HT_AGG_STATE_DEBUGFS_CTL BIT(7)
69 68
70/** 69/**
71 * struct tid_ampdu_tx - TID aggregation information (Tx). 70 * struct tid_ampdu_tx - TID aggregation information (Tx).
@@ -89,7 +88,7 @@ struct tid_ampdu_tx {
89 * @stored_mpdu_num: number of MPDUs in reordering buffer 88 * @stored_mpdu_num: number of MPDUs in reordering buffer
90 * @ssn: Starting Sequence Number expected to be aggregated. 89 * @ssn: Starting Sequence Number expected to be aggregated.
91 * @buf_size: buffer size for incoming A-MPDUs 90 * @buf_size: buffer size for incoming A-MPDUs
92 * @timeout: reset timer value. 91 * @timeout: reset timer value (in TUs).
93 * @dialog_token: dialog token for aggregation session 92 * @dialog_token: dialog token for aggregation session
94 */ 93 */
95struct tid_ampdu_rx { 94struct tid_ampdu_rx {
@@ -101,6 +100,7 @@ struct tid_ampdu_rx {
101 u16 buf_size; 100 u16 buf_size;
102 u16 timeout; 101 u16 timeout;
103 u8 dialog_token; 102 u8 dialog_token;
103 bool shutdown;
104}; 104};
105 105
106/** 106/**
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index f1c726d94f47..bf73f6d561b7 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -35,6 +35,7 @@
35#define IEEE80211_TX_OK 0 35#define IEEE80211_TX_OK 0
36#define IEEE80211_TX_AGAIN 1 36#define IEEE80211_TX_AGAIN 1
37#define IEEE80211_TX_FRAG_AGAIN 2 37#define IEEE80211_TX_FRAG_AGAIN 2
38#define IEEE80211_TX_PENDING 3
38 39
39/* misc utils */ 40/* misc utils */
40 41
@@ -1085,7 +1086,7 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
1085 1086
1086 if (skb) { 1087 if (skb) {
1087 if (netif_subqueue_stopped(local->mdev, skb)) 1088 if (netif_subqueue_stopped(local->mdev, skb))
1088 return IEEE80211_TX_AGAIN; 1089 return IEEE80211_TX_PENDING;
1089 1090
1090 ret = local->ops->tx(local_to_hw(local), skb); 1091 ret = local->ops->tx(local_to_hw(local), skb);
1091 if (ret) 1092 if (ret)
@@ -1211,8 +1212,9 @@ retry:
1211 * queues, there's no reason for a driver to reject 1212 * queues, there's no reason for a driver to reject
1212 * a frame there, warn and drop it. 1213 * a frame there, warn and drop it.
1213 */ 1214 */
1214 if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) 1215 if (ret != IEEE80211_TX_PENDING)
1215 goto drop; 1216 if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
1217 goto drop;
1216 1218
1217 store = &local->pending_packet[queue]; 1219 store = &local->pending_packet[queue];
1218 1220
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index bad1cfbfdf18..2b023dce8b24 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -145,6 +145,21 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev,
145 return -EOPNOTSUPP; 145 return -EOPNOTSUPP;
146} 146}
147 147
148static u8 ieee80211_get_wstats_flags(struct ieee80211_local *local)
149{
150 u8 wstats_flags = 0;
151
152 wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
153 IEEE80211_HW_SIGNAL_DBM) ?
154 IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID;
155 wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ?
156 IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID;
157 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
158 wstats_flags |= IW_QUAL_DBM;
159
160 return wstats_flags;
161}
162
148static int ieee80211_ioctl_giwrange(struct net_device *dev, 163static int ieee80211_ioctl_giwrange(struct net_device *dev,
149 struct iw_request_info *info, 164 struct iw_request_info *info,
150 struct iw_point *data, char *extra) 165 struct iw_point *data, char *extra)
@@ -173,8 +188,9 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
173 range->num_encoding_sizes = 2; 188 range->num_encoding_sizes = 2;
174 range->max_encoding_tokens = NUM_DEFAULT_KEYS; 189 range->max_encoding_tokens = NUM_DEFAULT_KEYS;
175 190
191 /* cfg80211 requires this, and enforces 0..100 */
176 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 192 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
177 range->max_qual.level = local->hw.max_signal; 193 range->max_qual.level = 100;
178 else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) 194 else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
179 range->max_qual.level = -110; 195 range->max_qual.level = -110;
180 else 196 else
@@ -186,13 +202,13 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
186 range->max_qual.noise = 0; 202 range->max_qual.noise = 0;
187 203
188 range->max_qual.qual = 100; 204 range->max_qual.qual = 100;
189 range->max_qual.updated = local->wstats_flags; 205 range->max_qual.updated = ieee80211_get_wstats_flags(local);
190 206
191 range->avg_qual.qual = 50; 207 range->avg_qual.qual = 50;
192 /* not always true but better than nothing */ 208 /* not always true but better than nothing */
193 range->avg_qual.level = range->max_qual.level / 2; 209 range->avg_qual.level = range->max_qual.level / 2;
194 range->avg_qual.noise = range->max_qual.noise / 2; 210 range->avg_qual.noise = range->max_qual.noise / 2;
195 range->avg_qual.updated = local->wstats_flags; 211 range->avg_qual.updated = ieee80211_get_wstats_flags(local);
196 212
197 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 213 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
198 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; 214 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
@@ -415,58 +431,6 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
415} 431}
416 432
417 433
418static int ieee80211_ioctl_siwscan(struct net_device *dev,
419 struct iw_request_info *info,
420 union iwreq_data *wrqu, char *extra)
421{
422 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
423 struct iw_scan_req *req = NULL;
424 u8 *ssid = NULL;
425 size_t ssid_len = 0;
426
427 if (!netif_running(dev))
428 return -ENETDOWN;
429
430 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
431 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
432 sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
433 return -EOPNOTSUPP;
434
435 /* if SSID was specified explicitly then use that */
436 if (wrqu->data.length == sizeof(struct iw_scan_req) &&
437 wrqu->data.flags & IW_SCAN_THIS_ESSID) {
438 req = (struct iw_scan_req *)extra;
439 ssid = req->essid;
440 ssid_len = req->essid_len;
441 }
442
443 return ieee80211_request_scan(sdata, ssid, ssid_len);
444}
445
446
447static int ieee80211_ioctl_giwscan(struct net_device *dev,
448 struct iw_request_info *info,
449 struct iw_point *data, char *extra)
450{
451 int res;
452 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
453 struct ieee80211_sub_if_data *sdata;
454
455 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
456
457 if (local->sw_scanning || local->hw_scanning)
458 return -EAGAIN;
459
460 res = ieee80211_scan_results(local, info, extra, data->length);
461 if (res >= 0) {
462 data->length = res;
463 return 0;
464 }
465 data->length = 0;
466 return res;
467}
468
469
470static int ieee80211_ioctl_siwrate(struct net_device *dev, 434static int ieee80211_ioctl_siwrate(struct net_device *dev,
471 struct iw_request_info *info, 435 struct iw_request_info *info,
472 struct iw_param *rate, char *extra) 436 struct iw_param *rate, char *extra)
@@ -982,9 +946,21 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
982 break; 946 break;
983 } 947 }
984 if (sdata->vif.type == NL80211_IFTYPE_STATION || 948 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
985 sdata->vif.type == NL80211_IFTYPE_ADHOC) 949 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
986 sdata->u.sta.mfp = data->value; 950 switch (data->value) {
987 else 951 case IW_AUTH_MFP_DISABLED:
952 sdata->u.sta.mfp = IEEE80211_MFP_DISABLED;
953 break;
954 case IW_AUTH_MFP_OPTIONAL:
955 sdata->u.sta.mfp = IEEE80211_MFP_OPTIONAL;
956 break;
957 case IW_AUTH_MFP_REQUIRED:
958 sdata->u.sta.mfp = IEEE80211_MFP_REQUIRED;
959 break;
960 default:
961 ret = -EINVAL;
962 }
963 } else
988 ret = -EOPNOTSUPP; 964 ret = -EOPNOTSUPP;
989 break; 965 break;
990 default: 966 default:
@@ -1018,7 +994,7 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
1018 wstats->qual.level = sta->last_signal; 994 wstats->qual.level = sta->last_signal;
1019 wstats->qual.qual = sta->last_qual; 995 wstats->qual.qual = sta->last_qual;
1020 wstats->qual.noise = sta->last_noise; 996 wstats->qual.noise = sta->last_noise;
1021 wstats->qual.updated = local->wstats_flags; 997 wstats->qual.updated = ieee80211_get_wstats_flags(local);
1022 } 998 }
1023 999
1024 rcu_read_unlock(); 1000 rcu_read_unlock();
@@ -1153,8 +1129,8 @@ static const iw_handler ieee80211_handler[] =
1153 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */ 1129 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */
1154 (iw_handler) ieee80211_ioctl_siwmlme, /* SIOCSIWMLME */ 1130 (iw_handler) ieee80211_ioctl_siwmlme, /* SIOCSIWMLME */
1155 (iw_handler) NULL, /* SIOCGIWAPLIST */ 1131 (iw_handler) NULL, /* SIOCGIWAPLIST */
1156 (iw_handler) ieee80211_ioctl_siwscan, /* SIOCSIWSCAN */ 1132 (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */
1157 (iw_handler) ieee80211_ioctl_giwscan, /* SIOCGIWSCAN */ 1133 (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */
1158 (iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */ 1134 (iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */
1159 (iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */ 1135 (iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */
1160 (iw_handler) NULL, /* SIOCSIWNICKN */ 1136 (iw_handler) NULL, /* SIOCSIWNICKN */
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index 938a334c8dbc..dad43c24f695 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o 5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o 6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
7 7
8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o 8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o
9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o 9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
10cfg80211-$(CONFIG_NL80211) += nl80211.o 10cfg80211-$(CONFIG_NL80211) += nl80211.o
11 11
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 125226476089..0668b2bfc1da 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -240,6 +240,8 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
240 mutex_init(&drv->mtx); 240 mutex_init(&drv->mtx);
241 mutex_init(&drv->devlist_mtx); 241 mutex_init(&drv->devlist_mtx);
242 INIT_LIST_HEAD(&drv->netdev_list); 242 INIT_LIST_HEAD(&drv->netdev_list);
243 spin_lock_init(&drv->bss_lock);
244 INIT_LIST_HEAD(&drv->bss_list);
243 245
244 device_initialize(&drv->wiphy.dev); 246 device_initialize(&drv->wiphy.dev);
245 drv->wiphy.dev.class = &ieee80211_class; 247 drv->wiphy.dev.class = &ieee80211_class;
@@ -259,6 +261,9 @@ int wiphy_register(struct wiphy *wiphy)
259 int i; 261 int i;
260 u16 ifmodes = wiphy->interface_modes; 262 u16 ifmodes = wiphy->interface_modes;
261 263
264 if (WARN_ON(wiphy->max_scan_ssids < 1))
265 return -EINVAL;
266
262 /* sanity check ifmodes */ 267 /* sanity check ifmodes */
263 WARN_ON(!ifmodes); 268 WARN_ON(!ifmodes);
264 ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1; 269 ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1;
@@ -367,8 +372,11 @@ EXPORT_SYMBOL(wiphy_unregister);
367 372
368void cfg80211_dev_free(struct cfg80211_registered_device *drv) 373void cfg80211_dev_free(struct cfg80211_registered_device *drv)
369{ 374{
375 struct cfg80211_internal_bss *scan, *tmp;
370 mutex_destroy(&drv->mtx); 376 mutex_destroy(&drv->mtx);
371 mutex_destroy(&drv->devlist_mtx); 377 mutex_destroy(&drv->devlist_mtx);
378 list_for_each_entry_safe(scan, tmp, &drv->bss_list, list)
379 cfg80211_put_bss(&scan->pub);
372 kfree(drv); 380 kfree(drv);
373} 381}
374 382
diff --git a/net/wireless/core.h b/net/wireless/core.h
index f7fb9f413028..e29ad4cd464f 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -8,6 +8,8 @@
8#include <linux/mutex.h> 8#include <linux/mutex.h>
9#include <linux/list.h> 9#include <linux/list.h>
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <linux/kref.h>
12#include <linux/rbtree.h>
11#include <net/genetlink.h> 13#include <net/genetlink.h>
12#include <net/wireless.h> 14#include <net/wireless.h>
13#include <net/cfg80211.h> 15#include <net/cfg80211.h>
@@ -41,6 +43,13 @@ struct cfg80211_registered_device {
41 struct mutex devlist_mtx; 43 struct mutex devlist_mtx;
42 struct list_head netdev_list; 44 struct list_head netdev_list;
43 45
46 /* BSSes/scanning */
47 spinlock_t bss_lock;
48 struct list_head bss_list;
49 struct rb_root bss_tree;
50 u32 bss_generation;
51 struct cfg80211_scan_request *scan_req; /* protected by RTNL */
52
44 /* must be last because of the way we do wiphy_priv(), 53 /* must be last because of the way we do wiphy_priv(),
45 * and it should at least be aligned to NETDEV_ALIGN */ 54 * and it should at least be aligned to NETDEV_ALIGN */
46 struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN))); 55 struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
@@ -56,6 +65,15 @@ struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy)
56extern struct mutex cfg80211_drv_mutex; 65extern struct mutex cfg80211_drv_mutex;
57extern struct list_head cfg80211_drv_list; 66extern struct list_head cfg80211_drv_list;
58 67
68struct cfg80211_internal_bss {
69 struct list_head list;
70 struct rb_node rbn;
71 unsigned long ts;
72 struct kref ref;
73 /* must be last because of priv member */
74 struct cfg80211_bss pub;
75};
76
59/* 77/*
60 * This function returns a pointer to the driver 78 * This function returns a pointer to the driver
61 * that the genl_info item that is passed refers to. 79 * that the genl_info item that is passed refers to.
@@ -94,4 +112,6 @@ extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv,
94void ieee80211_set_bitrate_flags(struct wiphy *wiphy); 112void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
95void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby); 113void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby);
96 114
115void cfg80211_bss_expire(struct cfg80211_registered_device *dev);
116
97#endif /* __NET_WIRELESS_CORE_H */ 117#endif /* __NET_WIRELESS_CORE_H */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d452396006ee..298a4de59948 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -14,6 +14,7 @@
14#include <linux/nl80211.h> 14#include <linux/nl80211.h>
15#include <linux/rtnetlink.h> 15#include <linux/rtnetlink.h>
16#include <linux/netlink.h> 16#include <linux/netlink.h>
17#include <linux/etherdevice.h>
17#include <net/genetlink.h> 18#include <net/genetlink.h>
18#include <net/cfg80211.h> 19#include <net/cfg80211.h>
19#include "core.h" 20#include "core.h"
@@ -109,6 +110,8 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
109 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 }, 110 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
110 [NL80211_ATTR_IE] = { .type = NLA_BINARY, 111 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
111 .len = IEEE80211_MAX_DATA_LEN }, 112 .len = IEEE80211_MAX_DATA_LEN },
113 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
114 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
112}; 115};
113 116
114/* message building helper */ 117/* message building helper */
@@ -141,6 +144,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
141 144
142 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx); 145 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx);
143 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); 146 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
147 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
148 dev->wiphy.max_scan_ssids);
144 149
145 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); 150 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
146 if (!nl_modes) 151 if (!nl_modes)
@@ -2270,6 +2275,246 @@ static int nl80211_set_mgmt_extra_ie(struct sk_buff *skb,
2270 return err; 2275 return err;
2271} 2276}
2272 2277
2278static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2279{
2280 struct cfg80211_registered_device *drv;
2281 struct net_device *dev;
2282 struct cfg80211_scan_request *request;
2283 struct cfg80211_ssid *ssid;
2284 struct ieee80211_channel *channel;
2285 struct nlattr *attr;
2286 struct wiphy *wiphy;
2287 int err, tmp, n_ssids = 0, n_channels = 0, i;
2288 enum ieee80211_band band;
2289
2290 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2291 if (err)
2292 return err;
2293
2294 wiphy = &drv->wiphy;
2295
2296 if (!drv->ops->scan) {
2297 err = -EOPNOTSUPP;
2298 goto out;
2299 }
2300
2301 rtnl_lock();
2302
2303 if (drv->scan_req) {
2304 err = -EBUSY;
2305 goto out_unlock;
2306 }
2307
2308 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
2309 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp)
2310 n_channels++;
2311 if (!n_channels) {
2312 err = -EINVAL;
2313 goto out_unlock;
2314 }
2315 } else {
2316 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
2317 if (wiphy->bands[band])
2318 n_channels += wiphy->bands[band]->n_channels;
2319 }
2320
2321 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
2322 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
2323 n_ssids++;
2324
2325 if (n_ssids > wiphy->max_scan_ssids) {
2326 err = -EINVAL;
2327 goto out_unlock;
2328 }
2329
2330 request = kzalloc(sizeof(*request)
2331 + sizeof(*ssid) * n_ssids
2332 + sizeof(channel) * n_channels, GFP_KERNEL);
2333 if (!request) {
2334 err = -ENOMEM;
2335 goto out_unlock;
2336 }
2337
2338 request->channels = (void *)((char *)request + sizeof(*request));
2339 request->n_channels = n_channels;
2340 if (n_ssids)
2341 request->ssids = (void *)(request->channels + n_channels);
2342 request->n_ssids = n_ssids;
2343
2344 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
2345 /* user specified, bail out if channel not found */
2346 request->n_channels = n_channels;
2347 i = 0;
2348 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
2349 request->channels[i] = ieee80211_get_channel(wiphy, nla_get_u32(attr));
2350 if (!request->channels[i]) {
2351 err = -EINVAL;
2352 goto out_free;
2353 }
2354 i++;
2355 }
2356 } else {
2357 /* all channels */
2358 i = 0;
2359 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2360 int j;
2361 if (!wiphy->bands[band])
2362 continue;
2363 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
2364 request->channels[i] = &wiphy->bands[band]->channels[j];
2365 i++;
2366 }
2367 }
2368 }
2369
2370 i = 0;
2371 if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
2372 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
2373 if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) {
2374 err = -EINVAL;
2375 goto out_free;
2376 }
2377 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2378 request->ssids[i].ssid_len = nla_len(attr);
2379 i++;
2380 }
2381 }
2382
2383 request->ifidx = dev->ifindex;
2384 request->wiphy = &drv->wiphy;
2385
2386 drv->scan_req = request;
2387 err = drv->ops->scan(&drv->wiphy, dev, request);
2388
2389 out_free:
2390 if (err) {
2391 drv->scan_req = NULL;
2392 kfree(request);
2393 }
2394 out_unlock:
2395 rtnl_unlock();
2396 out:
2397 cfg80211_put_dev(drv);
2398 dev_put(dev);
2399 return err;
2400}
2401
2402static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
2403 struct cfg80211_registered_device *rdev,
2404 struct net_device *dev,
2405 struct cfg80211_bss *res)
2406{
2407 void *hdr;
2408 struct nlattr *bss;
2409
2410 hdr = nl80211hdr_put(msg, pid, seq, flags,
2411 NL80211_CMD_NEW_SCAN_RESULTS);
2412 if (!hdr)
2413 return -1;
2414
2415 NLA_PUT_U32(msg, NL80211_ATTR_SCAN_GENERATION,
2416 rdev->bss_generation);
2417 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
2418
2419 bss = nla_nest_start(msg, NL80211_ATTR_BSS);
2420 if (!bss)
2421 goto nla_put_failure;
2422 if (!is_zero_ether_addr(res->bssid))
2423 NLA_PUT(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid);
2424 if (res->information_elements && res->len_information_elements)
2425 NLA_PUT(msg, NL80211_BSS_INFORMATION_ELEMENTS,
2426 res->len_information_elements,
2427 res->information_elements);
2428 if (res->tsf)
2429 NLA_PUT_U64(msg, NL80211_BSS_TSF, res->tsf);
2430 if (res->beacon_interval)
2431 NLA_PUT_U16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval);
2432 NLA_PUT_U16(msg, NL80211_BSS_CAPABILITY, res->capability);
2433 NLA_PUT_U32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq);
2434
2435 switch (res->signal_type) {
2436 case CFG80211_SIGNAL_TYPE_MBM:
2437 NLA_PUT_U32(msg, NL80211_BSS_SIGNAL_MBM, res->signal);
2438 break;
2439 case CFG80211_SIGNAL_TYPE_UNSPEC:
2440 NLA_PUT_U8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal);
2441 break;
2442 default:
2443 break;
2444 }
2445
2446 nla_nest_end(msg, bss);
2447
2448 return genlmsg_end(msg, hdr);
2449
2450 nla_put_failure:
2451 genlmsg_cancel(msg, hdr);
2452 return -EMSGSIZE;
2453}
2454
2455static int nl80211_dump_scan(struct sk_buff *skb,
2456 struct netlink_callback *cb)
2457{
2458 struct cfg80211_registered_device *dev;
2459 struct net_device *netdev;
2460 struct cfg80211_internal_bss *scan;
2461 int ifidx = cb->args[0];
2462 int start = cb->args[1], idx = 0;
2463 int err;
2464
2465 if (!ifidx) {
2466 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
2467 nl80211_fam.attrbuf, nl80211_fam.maxattr,
2468 nl80211_policy);
2469 if (err)
2470 return err;
2471
2472 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
2473 return -EINVAL;
2474
2475 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
2476 if (!ifidx)
2477 return -EINVAL;
2478 cb->args[0] = ifidx;
2479 }
2480
2481 netdev = dev_get_by_index(&init_net, ifidx);
2482 if (!netdev)
2483 return -ENODEV;
2484
2485 dev = cfg80211_get_dev_from_ifindex(ifidx);
2486 if (IS_ERR(dev)) {
2487 err = PTR_ERR(dev);
2488 goto out_put_netdev;
2489 }
2490
2491 spin_lock_bh(&dev->bss_lock);
2492 cfg80211_bss_expire(dev);
2493
2494 list_for_each_entry(scan, &dev->bss_list, list) {
2495 if (++idx <= start)
2496 continue;
2497 if (nl80211_send_bss(skb,
2498 NETLINK_CB(cb->skb).pid,
2499 cb->nlh->nlmsg_seq, NLM_F_MULTI,
2500 dev, netdev, &scan->pub) < 0) {
2501 idx--;
2502 goto out;
2503 }
2504 }
2505
2506 out:
2507 spin_unlock_bh(&dev->bss_lock);
2508
2509 cb->args[1] = idx;
2510 err = skb->len;
2511 cfg80211_put_dev(dev);
2512 out_put_netdev:
2513 dev_put(netdev);
2514
2515 return err;
2516}
2517
2273static struct genl_ops nl80211_ops[] = { 2518static struct genl_ops nl80211_ops[] = {
2274 { 2519 {
2275 .cmd = NL80211_CMD_GET_WIPHY, 2520 .cmd = NL80211_CMD_GET_WIPHY,
@@ -2443,12 +2688,26 @@ static struct genl_ops nl80211_ops[] = {
2443 .policy = nl80211_policy, 2688 .policy = nl80211_policy,
2444 .flags = GENL_ADMIN_PERM, 2689 .flags = GENL_ADMIN_PERM,
2445 }, 2690 },
2691 {
2692 .cmd = NL80211_CMD_TRIGGER_SCAN,
2693 .doit = nl80211_trigger_scan,
2694 .policy = nl80211_policy,
2695 .flags = GENL_ADMIN_PERM,
2696 },
2697 {
2698 .cmd = NL80211_CMD_GET_SCAN,
2699 .policy = nl80211_policy,
2700 .dumpit = nl80211_dump_scan,
2701 },
2446}; 2702};
2447 2703
2448/* multicast groups */ 2704/* multicast groups */
2449static struct genl_multicast_group nl80211_config_mcgrp = { 2705static struct genl_multicast_group nl80211_config_mcgrp = {
2450 .name = "config", 2706 .name = "config",
2451}; 2707};
2708static struct genl_multicast_group nl80211_scan_mcgrp = {
2709 .name = "scan",
2710};
2452 2711
2453/* notification functions */ 2712/* notification functions */
2454 2713
@@ -2468,6 +2727,66 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
2468 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); 2727 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
2469} 2728}
2470 2729
2730static int nl80211_send_scan_donemsg(struct sk_buff *msg,
2731 struct cfg80211_registered_device *rdev,
2732 struct net_device *netdev,
2733 u32 pid, u32 seq, int flags,
2734 u32 cmd)
2735{
2736 void *hdr;
2737
2738 hdr = nl80211hdr_put(msg, pid, seq, flags, cmd);
2739 if (!hdr)
2740 return -1;
2741
2742 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->idx);
2743 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
2744
2745 /* XXX: we should probably bounce back the request? */
2746
2747 return genlmsg_end(msg, hdr);
2748
2749 nla_put_failure:
2750 genlmsg_cancel(msg, hdr);
2751 return -EMSGSIZE;
2752}
2753
2754void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
2755 struct net_device *netdev)
2756{
2757 struct sk_buff *msg;
2758
2759 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2760 if (!msg)
2761 return;
2762
2763 if (nl80211_send_scan_donemsg(msg, rdev, netdev, 0, 0, 0,
2764 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2765 nlmsg_free(msg);
2766 return;
2767 }
2768
2769 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL);
2770}
2771
2772void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
2773 struct net_device *netdev)
2774{
2775 struct sk_buff *msg;
2776
2777 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2778 if (!msg)
2779 return;
2780
2781 if (nl80211_send_scan_donemsg(msg, rdev, netdev, 0, 0, 0,
2782 NL80211_CMD_SCAN_ABORTED) < 0) {
2783 nlmsg_free(msg);
2784 return;
2785 }
2786
2787 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL);
2788}
2789
2471/* initialisation/exit functions */ 2790/* initialisation/exit functions */
2472 2791
2473int nl80211_init(void) 2792int nl80211_init(void)
@@ -2488,6 +2807,10 @@ int nl80211_init(void)
2488 if (err) 2807 if (err)
2489 goto err_out; 2808 goto err_out;
2490 2809
2810 err = genl_register_mc_group(&nl80211_fam, &nl80211_scan_mcgrp);
2811 if (err)
2812 goto err_out;
2813
2491 return 0; 2814 return 0;
2492 err_out: 2815 err_out:
2493 genl_unregister_family(&nl80211_fam); 2816 genl_unregister_family(&nl80211_fam);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index f3ea5c029aee..b565a5f84e97 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -7,6 +7,10 @@
7extern int nl80211_init(void); 7extern int nl80211_init(void);
8extern void nl80211_exit(void); 8extern void nl80211_exit(void);
9extern void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); 9extern void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
10extern void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
11 struct net_device *netdev);
12extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
13 struct net_device *netdev);
10#else 14#else
11static inline int nl80211_init(void) 15static inline int nl80211_init(void)
12{ 16{
@@ -19,6 +23,10 @@ static inline void nl80211_notify_dev_rename(
19 struct cfg80211_registered_device *rdev) 23 struct cfg80211_registered_device *rdev)
20{ 24{
21} 25}
26static inline void
27nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
28 struct net_device *netdev)
29{}
22#endif /* CONFIG_NL80211 */ 30#endif /* CONFIG_NL80211 */
23 31
24#endif /* __NET_WIRELESS_NL80211_H */ 32#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
new file mode 100644
index 000000000000..b1893c863b97
--- /dev/null
+++ b/net/wireless/scan.c
@@ -0,0 +1,836 @@
1/*
2 * cfg80211 scan result handling
3 *
4 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
5 */
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/netdevice.h>
9#include <linux/wireless.h>
10#include <linux/nl80211.h>
11#include <linux/etherdevice.h>
12#include <net/arp.h>
13#include <net/cfg80211.h>
14#include <net/iw_handler.h>
15#include "core.h"
16#include "nl80211.h"
17
18#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ)
19
20void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
21{
22 struct net_device *dev;
23#ifdef CONFIG_WIRELESS_EXT
24 union iwreq_data wrqu;
25#endif
26
27 dev = dev_get_by_index(&init_net, request->ifidx);
28 if (!dev)
29 goto out;
30
31 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
32 wiphy_to_dev(request->wiphy)->scan_req = NULL;
33
34 if (aborted)
35 nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev);
36 else
37 nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev);
38
39#ifdef CONFIG_WIRELESS_EXT
40 if (!aborted) {
41 memset(&wrqu, 0, sizeof(wrqu));
42
43 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
44 }
45#endif
46
47 dev_put(dev);
48
49 out:
50 kfree(request);
51}
52EXPORT_SYMBOL(cfg80211_scan_done);
53
54static void bss_release(struct kref *ref)
55{
56 struct cfg80211_internal_bss *bss;
57
58 bss = container_of(ref, struct cfg80211_internal_bss, ref);
59 if (bss->pub.free_priv)
60 bss->pub.free_priv(&bss->pub);
61 kfree(bss);
62}
63
64/* must hold dev->bss_lock! */
65void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
66{
67 struct cfg80211_internal_bss *bss, *tmp;
68 bool expired = false;
69
70 list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) {
71 if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
72 continue;
73 list_del(&bss->list);
74 rb_erase(&bss->rbn, &dev->bss_tree);
75 kref_put(&bss->ref, bss_release);
76 expired = true;
77 }
78
79 if (expired)
80 dev->bss_generation++;
81}
82
83static u8 *find_ie(u8 num, u8 *ies, size_t len)
84{
85 while (len > 2 && ies[0] != num) {
86 len -= ies[1] + 2;
87 ies += ies[1] + 2;
88 }
89 if (len < 2)
90 return NULL;
91 if (len < 2 + ies[1])
92 return NULL;
93 return ies;
94}
95
96static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
97{
98 const u8 *ie1 = find_ie(num, ies1, len1);
99 const u8 *ie2 = find_ie(num, ies2, len2);
100 int r;
101
102 if (!ie1 && !ie2)
103 return 0;
104 if (!ie1)
105 return -1;
106
107 r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1]));
108 if (r == 0 && ie1[1] != ie2[1])
109 return ie2[1] - ie1[1];
110 return r;
111}
112
113static bool is_bss(struct cfg80211_bss *a,
114 const u8 *bssid,
115 const u8 *ssid, size_t ssid_len)
116{
117 const u8 *ssidie;
118
119 if (bssid && compare_ether_addr(a->bssid, bssid))
120 return false;
121
122 if (!ssid)
123 return true;
124
125 ssidie = find_ie(WLAN_EID_SSID,
126 a->information_elements,
127 a->len_information_elements);
128 if (!ssidie)
129 return false;
130 if (ssidie[1] != ssid_len)
131 return false;
132 return memcmp(ssidie + 2, ssid, ssid_len) == 0;
133}
134
135static bool is_mesh(struct cfg80211_bss *a,
136 const u8 *meshid, size_t meshidlen,
137 const u8 *meshcfg)
138{
139 const u8 *ie;
140
141 if (!is_zero_ether_addr(a->bssid))
142 return false;
143
144 ie = find_ie(WLAN_EID_MESH_ID,
145 a->information_elements,
146 a->len_information_elements);
147 if (!ie)
148 return false;
149 if (ie[1] != meshidlen)
150 return false;
151 if (memcmp(ie + 2, meshid, meshidlen))
152 return false;
153
154 ie = find_ie(WLAN_EID_MESH_CONFIG,
155 a->information_elements,
156 a->len_information_elements);
157 if (ie[1] != IEEE80211_MESH_CONFIG_LEN)
158 return false;
159
160 /*
161 * Ignore mesh capability (last two bytes of the IE) when
162 * comparing since that may differ between stations taking
163 * part in the same mesh.
164 */
165 return memcmp(ie + 2, meshcfg, IEEE80211_MESH_CONFIG_LEN - 2) == 0;
166}
167
168static int cmp_bss(struct cfg80211_bss *a,
169 struct cfg80211_bss *b)
170{
171 int r;
172
173 if (a->channel != b->channel)
174 return b->channel->center_freq - a->channel->center_freq;
175
176 r = memcmp(a->bssid, b->bssid, ETH_ALEN);
177 if (r)
178 return r;
179
180 if (is_zero_ether_addr(a->bssid)) {
181 r = cmp_ies(WLAN_EID_MESH_ID,
182 a->information_elements,
183 a->len_information_elements,
184 b->information_elements,
185 b->len_information_elements);
186 if (r)
187 return r;
188 return cmp_ies(WLAN_EID_MESH_CONFIG,
189 a->information_elements,
190 a->len_information_elements,
191 b->information_elements,
192 b->len_information_elements);
193 }
194
195 return cmp_ies(WLAN_EID_SSID,
196 a->information_elements,
197 a->len_information_elements,
198 b->information_elements,
199 b->len_information_elements);
200}
201
202struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
203 struct ieee80211_channel *channel,
204 const u8 *bssid,
205 const u8 *ssid, size_t ssid_len,
206 u16 capa_mask, u16 capa_val)
207{
208 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
209 struct cfg80211_internal_bss *bss, *res = NULL;
210
211 spin_lock_bh(&dev->bss_lock);
212
213 list_for_each_entry(bss, &dev->bss_list, list) {
214 if ((bss->pub.capability & capa_mask) != capa_val)
215 continue;
216 if (channel && bss->pub.channel != channel)
217 continue;
218 if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
219 res = bss;
220 kref_get(&res->ref);
221 break;
222 }
223 }
224
225 spin_unlock_bh(&dev->bss_lock);
226 if (!res)
227 return NULL;
228 return &res->pub;
229}
230EXPORT_SYMBOL(cfg80211_get_bss);
231
232struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
233 struct ieee80211_channel *channel,
234 const u8 *meshid, size_t meshidlen,
235 const u8 *meshcfg)
236{
237 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
238 struct cfg80211_internal_bss *bss, *res = NULL;
239
240 spin_lock_bh(&dev->bss_lock);
241
242 list_for_each_entry(bss, &dev->bss_list, list) {
243 if (channel && bss->pub.channel != channel)
244 continue;
245 if (is_mesh(&bss->pub, meshid, meshidlen, meshcfg)) {
246 res = bss;
247 kref_get(&res->ref);
248 break;
249 }
250 }
251
252 spin_unlock_bh(&dev->bss_lock);
253 if (!res)
254 return NULL;
255 return &res->pub;
256}
257EXPORT_SYMBOL(cfg80211_get_mesh);
258
259
260static void rb_insert_bss(struct cfg80211_registered_device *dev,
261 struct cfg80211_internal_bss *bss)
262{
263 struct rb_node **p = &dev->bss_tree.rb_node;
264 struct rb_node *parent = NULL;
265 struct cfg80211_internal_bss *tbss;
266 int cmp;
267
268 while (*p) {
269 parent = *p;
270 tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn);
271
272 cmp = cmp_bss(&bss->pub, &tbss->pub);
273
274 if (WARN_ON(!cmp)) {
275 /* will sort of leak this BSS */
276 return;
277 }
278
279 if (cmp < 0)
280 p = &(*p)->rb_left;
281 else
282 p = &(*p)->rb_right;
283 }
284
285 rb_link_node(&bss->rbn, parent, p);
286 rb_insert_color(&bss->rbn, &dev->bss_tree);
287}
288
289static struct cfg80211_internal_bss *
290rb_find_bss(struct cfg80211_registered_device *dev,
291 struct cfg80211_internal_bss *res)
292{
293 struct rb_node *n = dev->bss_tree.rb_node;
294 struct cfg80211_internal_bss *bss;
295 int r;
296
297 while (n) {
298 bss = rb_entry(n, struct cfg80211_internal_bss, rbn);
299 r = cmp_bss(&res->pub, &bss->pub);
300
301 if (r == 0)
302 return bss;
303 else if (r < 0)
304 n = n->rb_left;
305 else
306 n = n->rb_right;
307 }
308
309 return NULL;
310}
311
312static struct cfg80211_internal_bss *
313cfg80211_bss_update(struct cfg80211_registered_device *dev,
314 struct cfg80211_internal_bss *res,
315 bool overwrite)
316{
317 struct cfg80211_internal_bss *found = NULL;
318 const u8 *meshid, *meshcfg;
319
320 /*
321 * The reference to "res" is donated to this function.
322 */
323
324 if (WARN_ON(!res->pub.channel)) {
325 kref_put(&res->ref, bss_release);
326 return NULL;
327 }
328
329 res->ts = jiffies;
330
331 if (is_zero_ether_addr(res->pub.bssid)) {
332 /* must be mesh, verify */
333 meshid = find_ie(WLAN_EID_MESH_ID, res->pub.information_elements,
334 res->pub.len_information_elements);
335 meshcfg = find_ie(WLAN_EID_MESH_CONFIG,
336 res->pub.information_elements,
337 res->pub.len_information_elements);
338 if (!meshid || !meshcfg ||
339 meshcfg[1] != IEEE80211_MESH_CONFIG_LEN) {
340 /* bogus mesh */
341 kref_put(&res->ref, bss_release);
342 return NULL;
343 }
344 }
345
346 spin_lock_bh(&dev->bss_lock);
347
348 found = rb_find_bss(dev, res);
349
350 if (found && overwrite) {
351 list_replace(&found->list, &res->list);
352 rb_replace_node(&found->rbn, &res->rbn,
353 &dev->bss_tree);
354 kref_put(&found->ref, bss_release);
355 found = res;
356 } else if (found) {
357 kref_get(&found->ref);
358 found->pub.beacon_interval = res->pub.beacon_interval;
359 found->pub.tsf = res->pub.tsf;
360 found->pub.signal = res->pub.signal;
361 found->pub.signal_type = res->pub.signal_type;
362 found->pub.capability = res->pub.capability;
363 found->ts = res->ts;
364 kref_put(&res->ref, bss_release);
365 } else {
366 /* this "consumes" the reference */
367 list_add_tail(&res->list, &dev->bss_list);
368 rb_insert_bss(dev, res);
369 found = res;
370 }
371
372 dev->bss_generation++;
373 spin_unlock_bh(&dev->bss_lock);
374
375 kref_get(&found->ref);
376 return found;
377}
378
379struct cfg80211_bss *
380cfg80211_inform_bss_frame(struct wiphy *wiphy,
381 struct ieee80211_channel *channel,
382 struct ieee80211_mgmt *mgmt, size_t len,
383 s32 signal, enum cfg80211_signal_type sigtype,
384 gfp_t gfp)
385{
386 struct cfg80211_internal_bss *res;
387 size_t ielen = len - offsetof(struct ieee80211_mgmt,
388 u.probe_resp.variable);
389 bool overwrite;
390 size_t privsz = wiphy->bss_priv_size;
391
392 if (WARN_ON(sigtype == NL80211_BSS_SIGNAL_UNSPEC &&
393 (signal < 0 || signal > 100)))
394 return NULL;
395
396 if (WARN_ON(!mgmt || !wiphy ||
397 len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable)))
398 return NULL;
399
400 res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
401 if (!res)
402 return NULL;
403
404 memcpy(res->pub.bssid, mgmt->bssid, ETH_ALEN);
405 res->pub.channel = channel;
406 res->pub.signal_type = sigtype;
407 res->pub.signal = signal;
408 res->pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
409 res->pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
410 res->pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
411 /* point to after the private area */
412 res->pub.information_elements = (u8 *)res + sizeof(*res) + privsz;
413 memcpy(res->pub.information_elements, mgmt->u.probe_resp.variable, ielen);
414 res->pub.len_information_elements = ielen;
415
416 kref_init(&res->ref);
417
418 overwrite = ieee80211_is_probe_resp(mgmt->frame_control);
419
420 res = cfg80211_bss_update(wiphy_to_dev(wiphy), res, overwrite);
421 if (!res)
422 return NULL;
423
424 /* cfg80211_bss_update gives us a referenced result */
425 return &res->pub;
426}
427EXPORT_SYMBOL(cfg80211_inform_bss_frame);
428
429void cfg80211_put_bss(struct cfg80211_bss *pub)
430{
431 struct cfg80211_internal_bss *bss;
432
433 if (!pub)
434 return;
435
436 bss = container_of(pub, struct cfg80211_internal_bss, pub);
437 kref_put(&bss->ref, bss_release);
438}
439EXPORT_SYMBOL(cfg80211_put_bss);
440
441void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
442{
443 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
444 struct cfg80211_internal_bss *bss;
445
446 if (WARN_ON(!pub))
447 return;
448
449 bss = container_of(pub, struct cfg80211_internal_bss, pub);
450
451 spin_lock_bh(&dev->bss_lock);
452
453 list_del(&bss->list);
454 rb_erase(&bss->rbn, &dev->bss_tree);
455
456 spin_unlock_bh(&dev->bss_lock);
457
458 kref_put(&bss->ref, bss_release);
459}
460EXPORT_SYMBOL(cfg80211_unlink_bss);
461
462#ifdef CONFIG_WIRELESS_EXT
463int cfg80211_wext_siwscan(struct net_device *dev,
464 struct iw_request_info *info,
465 union iwreq_data *wrqu, char *extra)
466{
467 struct cfg80211_registered_device *rdev;
468 struct wiphy *wiphy;
469 struct iw_scan_req *wreq = NULL;
470 struct cfg80211_scan_request *creq;
471 int i, err, n_channels = 0;
472 enum ieee80211_band band;
473
474 if (!netif_running(dev))
475 return -ENETDOWN;
476
477 rdev = cfg80211_get_dev_from_ifindex(dev->ifindex);
478
479 if (IS_ERR(rdev))
480 return PTR_ERR(rdev);
481
482 if (rdev->scan_req) {
483 err = -EBUSY;
484 goto out;
485 }
486
487 wiphy = &rdev->wiphy;
488
489 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
490 if (wiphy->bands[band])
491 n_channels += wiphy->bands[band]->n_channels;
492
493 creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
494 n_channels * sizeof(void *),
495 GFP_ATOMIC);
496 if (!creq) {
497 err = -ENOMEM;
498 goto out;
499 }
500
501 creq->wiphy = wiphy;
502 creq->ifidx = dev->ifindex;
503 creq->ssids = (void *)(creq + 1);
504 creq->channels = (void *)(creq->ssids + 1);
505 creq->n_channels = n_channels;
506 creq->n_ssids = 1;
507
508 /* all channels */
509 i = 0;
510 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
511 int j;
512 if (!wiphy->bands[band])
513 continue;
514 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
515 creq->channels[i] = &wiphy->bands[band]->channels[j];
516 i++;
517 }
518 }
519
520 /* translate scan request */
521 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
522 wreq = (struct iw_scan_req *)extra;
523
524 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
525 if (wreq->essid_len > IEEE80211_MAX_SSID_LEN)
526 return -EINVAL;
527 memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
528 creq->ssids[0].ssid_len = wreq->essid_len;
529 }
530 if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE)
531 creq->n_ssids = 0;
532 }
533
534 rdev->scan_req = creq;
535 err = rdev->ops->scan(wiphy, dev, creq);
536 if (err) {
537 rdev->scan_req = NULL;
538 kfree(creq);
539 }
540 out:
541 cfg80211_put_dev(rdev);
542 return err;
543}
544EXPORT_SYMBOL(cfg80211_wext_siwscan);
545
546static void ieee80211_scan_add_ies(struct iw_request_info *info,
547 struct cfg80211_bss *bss,
548 char **current_ev, char *end_buf)
549{
550 u8 *pos, *end, *next;
551 struct iw_event iwe;
552
553 if (!bss->information_elements ||
554 !bss->len_information_elements)
555 return;
556
557 /*
558 * If needed, fragment the IEs buffer (at IE boundaries) into short
559 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
560 */
561 pos = bss->information_elements;
562 end = pos + bss->len_information_elements;
563
564 while (end - pos > IW_GENERIC_IE_MAX) {
565 next = pos + 2 + pos[1];
566 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
567 next = next + 2 + next[1];
568
569 memset(&iwe, 0, sizeof(iwe));
570 iwe.cmd = IWEVGENIE;
571 iwe.u.data.length = next - pos;
572 *current_ev = iwe_stream_add_point(info, *current_ev,
573 end_buf, &iwe, pos);
574
575 pos = next;
576 }
577
578 if (end > pos) {
579 memset(&iwe, 0, sizeof(iwe));
580 iwe.cmd = IWEVGENIE;
581 iwe.u.data.length = end - pos;
582 *current_ev = iwe_stream_add_point(info, *current_ev,
583 end_buf, &iwe, pos);
584 }
585}
586
587
588static char *
589ieee80211_bss(struct iw_request_info *info,
590 struct cfg80211_internal_bss *bss,
591 char *current_ev, char *end_buf)
592{
593 struct iw_event iwe;
594 u8 *buf, *cfg, *p;
595 u8 *ie = bss->pub.information_elements;
596 int rem = bss->pub.len_information_elements, i;
597 bool ismesh = false;
598
599 memset(&iwe, 0, sizeof(iwe));
600 iwe.cmd = SIOCGIWAP;
601 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
602 memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN);
603 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
604 IW_EV_ADDR_LEN);
605
606 memset(&iwe, 0, sizeof(iwe));
607 iwe.cmd = SIOCGIWFREQ;
608 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq);
609 iwe.u.freq.e = 0;
610 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
611 IW_EV_FREQ_LEN);
612
613 memset(&iwe, 0, sizeof(iwe));
614 iwe.cmd = SIOCGIWFREQ;
615 iwe.u.freq.m = bss->pub.channel->center_freq;
616 iwe.u.freq.e = 6;
617 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
618 IW_EV_FREQ_LEN);
619
620 if (bss->pub.signal_type != CFG80211_SIGNAL_TYPE_NONE) {
621 memset(&iwe, 0, sizeof(iwe));
622 iwe.cmd = IWEVQUAL;
623 iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED |
624 IW_QUAL_NOISE_INVALID |
625 IW_QUAL_QUAL_INVALID;
626 switch (bss->pub.signal_type) {
627 case CFG80211_SIGNAL_TYPE_MBM:
628 iwe.u.qual.level = bss->pub.signal / 100;
629 iwe.u.qual.updated |= IW_QUAL_DBM;
630 break;
631 case CFG80211_SIGNAL_TYPE_UNSPEC:
632 iwe.u.qual.level = bss->pub.signal;
633 break;
634 default:
635 /* not reached */
636 break;
637 }
638 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
639 &iwe, IW_EV_QUAL_LEN);
640 }
641
642 memset(&iwe, 0, sizeof(iwe));
643 iwe.cmd = SIOCGIWENCODE;
644 if (bss->pub.capability & WLAN_CAPABILITY_PRIVACY)
645 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
646 else
647 iwe.u.data.flags = IW_ENCODE_DISABLED;
648 iwe.u.data.length = 0;
649 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
650 &iwe, "");
651
652 while (rem >= 2) {
653 /* invalid data */
654 if (ie[1] > rem - 2)
655 break;
656
657 switch (ie[0]) {
658 case WLAN_EID_SSID:
659 memset(&iwe, 0, sizeof(iwe));
660 iwe.cmd = SIOCGIWESSID;
661 iwe.u.data.length = ie[1];
662 iwe.u.data.flags = 1;
663 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
664 &iwe, ie + 2);
665 break;
666 case WLAN_EID_MESH_ID:
667 memset(&iwe, 0, sizeof(iwe));
668 iwe.cmd = SIOCGIWESSID;
669 iwe.u.data.length = ie[1];
670 iwe.u.data.flags = 1;
671 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
672 &iwe, ie + 2);
673 break;
674 case WLAN_EID_MESH_CONFIG:
675 ismesh = true;
676 if (ie[1] != IEEE80211_MESH_CONFIG_LEN)
677 break;
678 buf = kmalloc(50, GFP_ATOMIC);
679 if (!buf)
680 break;
681 cfg = ie + 2;
682 memset(&iwe, 0, sizeof(iwe));
683 iwe.cmd = IWEVCUSTOM;
684 sprintf(buf, "Mesh network (version %d)", cfg[0]);
685 iwe.u.data.length = strlen(buf);
686 current_ev = iwe_stream_add_point(info, current_ev,
687 end_buf,
688 &iwe, buf);
689 sprintf(buf, "Path Selection Protocol ID: "
690 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
691 cfg[4]);
692 iwe.u.data.length = strlen(buf);
693 current_ev = iwe_stream_add_point(info, current_ev,
694 end_buf,
695 &iwe, buf);
696 sprintf(buf, "Path Selection Metric ID: "
697 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
698 cfg[8]);
699 iwe.u.data.length = strlen(buf);
700 current_ev = iwe_stream_add_point(info, current_ev,
701 end_buf,
702 &iwe, buf);
703 sprintf(buf, "Congestion Control Mode ID: "
704 "0x%02X%02X%02X%02X", cfg[9], cfg[10],
705 cfg[11], cfg[12]);
706 iwe.u.data.length = strlen(buf);
707 current_ev = iwe_stream_add_point(info, current_ev,
708 end_buf,
709 &iwe, buf);
710 sprintf(buf, "Channel Precedence: "
711 "0x%02X%02X%02X%02X", cfg[13], cfg[14],
712 cfg[15], cfg[16]);
713 iwe.u.data.length = strlen(buf);
714 current_ev = iwe_stream_add_point(info, current_ev,
715 end_buf,
716 &iwe, buf);
717 kfree(buf);
718 break;
719 case WLAN_EID_SUPP_RATES:
720 case WLAN_EID_EXT_SUPP_RATES:
721 /* display all supported rates in readable format */
722 p = current_ev + iwe_stream_lcp_len(info);
723
724 memset(&iwe, 0, sizeof(iwe));
725 iwe.cmd = SIOCGIWRATE;
726 /* Those two flags are ignored... */
727 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
728
729 for (i = 0; i < ie[1]; i++) {
730 iwe.u.bitrate.value =
731 ((ie[i + 2] & 0x7f) * 500000);
732 p = iwe_stream_add_value(info, current_ev, p,
733 end_buf, &iwe, IW_EV_PARAM_LEN);
734 }
735 current_ev = p;
736 break;
737 }
738 rem -= ie[1] + 2;
739 ie += ie[1] + 2;
740 }
741
742 if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
743 || ismesh) {
744 memset(&iwe, 0, sizeof(iwe));
745 iwe.cmd = SIOCGIWMODE;
746 if (ismesh)
747 iwe.u.mode = IW_MODE_MESH;
748 else if (bss->pub.capability & WLAN_CAPABILITY_ESS)
749 iwe.u.mode = IW_MODE_MASTER;
750 else
751 iwe.u.mode = IW_MODE_ADHOC;
752 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
753 &iwe, IW_EV_UINT_LEN);
754 }
755
756 buf = kmalloc(30, GFP_ATOMIC);
757 if (buf) {
758 memset(&iwe, 0, sizeof(iwe));
759 iwe.cmd = IWEVCUSTOM;
760 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->pub.tsf));
761 iwe.u.data.length = strlen(buf);
762 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
763 &iwe, buf);
764 memset(&iwe, 0, sizeof(iwe));
765 iwe.cmd = IWEVCUSTOM;
766 sprintf(buf, " Last beacon: %dms ago",
767 jiffies_to_msecs(jiffies - bss->ts));
768 iwe.u.data.length = strlen(buf);
769 current_ev = iwe_stream_add_point(info, current_ev,
770 end_buf, &iwe, buf);
771 kfree(buf);
772 }
773
774 ieee80211_scan_add_ies(info, &bss->pub, &current_ev, end_buf);
775
776 return current_ev;
777}
778
779
780static int ieee80211_scan_results(struct cfg80211_registered_device *dev,
781 struct iw_request_info *info,
782 char *buf, size_t len)
783{
784 char *current_ev = buf;
785 char *end_buf = buf + len;
786 struct cfg80211_internal_bss *bss;
787
788 spin_lock_bh(&dev->bss_lock);
789 cfg80211_bss_expire(dev);
790
791 list_for_each_entry(bss, &dev->bss_list, list) {
792 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
793 spin_unlock_bh(&dev->bss_lock);
794 return -E2BIG;
795 }
796 current_ev = ieee80211_bss(info, bss,
797 current_ev, end_buf);
798 }
799 spin_unlock_bh(&dev->bss_lock);
800 return current_ev - buf;
801}
802
803
804int cfg80211_wext_giwscan(struct net_device *dev,
805 struct iw_request_info *info,
806 struct iw_point *data, char *extra)
807{
808 struct cfg80211_registered_device *rdev;
809 int res;
810
811 if (!netif_running(dev))
812 return -ENETDOWN;
813
814 rdev = cfg80211_get_dev_from_ifindex(dev->ifindex);
815
816 if (IS_ERR(rdev))
817 return PTR_ERR(rdev);
818
819 if (rdev->scan_req) {
820 res = -EAGAIN;
821 goto out;
822 }
823
824 res = ieee80211_scan_results(rdev, info, extra, data->length);
825 data->length = 0;
826 if (res >= 0) {
827 data->length = res;
828 res = 0;
829 }
830
831 out:
832 cfg80211_put_dev(rdev);
833 return res;
834}
835EXPORT_SYMBOL(cfg80211_wext_giwscan);
836#endif