mac80211: update to 2011-08-10
[openwrt/svn-archive/archive.git] / package / mac80211 / patches / 300-pending_work.patch
1 --- a/drivers/net/wireless/b43/main.c
2 +++ b/drivers/net/wireless/b43/main.c
3 @@ -320,6 +320,10 @@ static void b43_wireless_core_exit(struc
4 static int b43_wireless_core_init(struct b43_wldev *dev);
5 static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
6 static int b43_wireless_core_start(struct b43_wldev *dev);
7 +static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
8 + struct ieee80211_vif *vif,
9 + struct ieee80211_bss_conf *conf,
10 + u32 changed);
11
12 static int b43_ratelimit(struct b43_wl *wl)
13 {
14 @@ -3754,14 +3758,24 @@ static int b43_op_config(struct ieee8021
15 struct ieee80211_conf *conf = &hw->conf;
16 int antenna;
17 int err = 0;
18 + bool reload_bss = false;
19
20 mutex_lock(&wl->mutex);
21
22 + dev = wl->current_dev;
23 +
24 /* Switch the band (if necessary). This might change the active core. */
25 err = b43_switch_band(wl, conf->channel);
26 if (err)
27 goto out_unlock_mutex;
28 - dev = wl->current_dev;
29 +
30 + /* Need to reload all settings if the core changed */
31 + if (dev != wl->current_dev) {
32 + dev = wl->current_dev;
33 + changed = ~0;
34 + reload_bss = true;
35 + }
36 +
37 phy = &dev->phy;
38
39 if (conf_is_ht(conf))
40 @@ -3822,6 +3836,9 @@ out_mac_enable:
41 out_unlock_mutex:
42 mutex_unlock(&wl->mutex);
43
44 + if (wl->vif && reload_bss)
45 + b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
46 +
47 return err;
48 }
49
50 @@ -3910,7 +3927,8 @@ static void b43_op_bss_info_changed(stru
51 if (changed & BSS_CHANGED_BEACON_INT &&
52 (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
53 b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
54 - b43_is_mode(wl, NL80211_IFTYPE_ADHOC)))
55 + b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) &&
56 + conf->beacon_int)
57 b43_set_beacon_int(dev, conf->beacon_int);
58
59 if (changed & BSS_CHANGED_BASIC_RATES)
60 @@ -4691,6 +4709,9 @@ static int b43_op_add_interface(struct i
61 out_mutex_unlock:
62 mutex_unlock(&wl->mutex);
63
64 + if (err == 0)
65 + b43_op_bss_info_changed(hw, vif, &vif->bss_conf, ~0);
66 +
67 return err;
68 }
69
70 @@ -4761,6 +4782,9 @@ static int b43_op_start(struct ieee80211
71 out_mutex_unlock:
72 mutex_unlock(&wl->mutex);
73
74 + /* reload configuration */
75 + b43_op_config(hw, ~0);
76 +
77 return err;
78 }
79
80 @@ -4917,10 +4941,18 @@ out:
81 if (err)
82 wl->current_dev = NULL; /* Failed to init the dev. */
83 mutex_unlock(&wl->mutex);
84 - if (err)
85 +
86 + if (err) {
87 b43err(wl, "Controller restart FAILED\n");
88 - else
89 - b43info(wl, "Controller restarted\n");
90 + return;
91 + }
92 +
93 + /* reload configuration */
94 + b43_op_config(wl->hw, ~0);
95 + if (wl->vif)
96 + b43_op_bss_info_changed(wl->hw, wl->vif, &wl->vif->bss_conf, ~0);
97 +
98 + b43info(wl, "Controller restarted\n");
99 }
100
101 static int b43_setup_bands(struct b43_wldev *dev,
102 --- a/net/mac80211/agg-rx.c
103 +++ b/net/mac80211/agg-rx.c
104 @@ -184,6 +184,8 @@ static void ieee80211_send_addba_resp(st
105 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
106 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
107 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
108 + else if (sdata->vif.type == NL80211_IFTYPE_WDS)
109 + memcpy(mgmt->bssid, da, ETH_ALEN);
110
111 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
112 IEEE80211_STYPE_ACTION);
113 --- a/net/mac80211/agg-tx.c
114 +++ b/net/mac80211/agg-tx.c
115 @@ -79,7 +79,8 @@ static void ieee80211_send_addba_request
116 memcpy(mgmt->da, da, ETH_ALEN);
117 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
118 if (sdata->vif.type == NL80211_IFTYPE_AP ||
119 - sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
120 + sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
121 + sdata->vif.type == NL80211_IFTYPE_WDS)
122 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
123 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
124 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
125 @@ -398,7 +399,8 @@ int ieee80211_start_tx_ba_session(struct
126 */
127 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
128 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
129 - sdata->vif.type != NL80211_IFTYPE_AP)
130 + sdata->vif.type != NL80211_IFTYPE_AP &&
131 + sdata->vif.type != NL80211_IFTYPE_WDS)
132 return -EINVAL;
133
134 if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
135 --- a/net/mac80211/debugfs_sta.c
136 +++ b/net/mac80211/debugfs_sta.c
137 @@ -59,7 +59,7 @@ static ssize_t sta_flags_read(struct fil
138 char buf[100];
139 struct sta_info *sta = file->private_data;
140 u32 staflags = get_sta_flags(sta);
141 - int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
142 + int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s",
143 staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
144 staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
145 staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "",
146 @@ -67,7 +67,6 @@ static ssize_t sta_flags_read(struct fil
147 staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
148 staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
149 staflags & WLAN_STA_WME ? "WME\n" : "",
150 - staflags & WLAN_STA_WDS ? "WDS\n" : "",
151 staflags & WLAN_STA_MFP ? "MFP\n" : "");
152 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
153 }
154 --- a/net/mac80211/iface.c
155 +++ b/net/mac80211/iface.c
156 @@ -178,7 +178,6 @@ static int ieee80211_do_open(struct net_
157 {
158 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
159 struct ieee80211_local *local = sdata->local;
160 - struct sta_info *sta;
161 u32 changed = 0;
162 int res;
163 u32 hw_reconf_flags = 0;
164 @@ -290,27 +289,6 @@ static int ieee80211_do_open(struct net_
165
166 set_bit(SDATA_STATE_RUNNING, &sdata->state);
167
168 - if (sdata->vif.type == NL80211_IFTYPE_WDS) {
169 - /* Create STA entry for the WDS peer */
170 - sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
171 - GFP_KERNEL);
172 - if (!sta) {
173 - res = -ENOMEM;
174 - goto err_del_interface;
175 - }
176 -
177 - /* no locking required since STA is not live yet */
178 - sta->flags |= WLAN_STA_AUTHORIZED;
179 -
180 - res = sta_info_insert(sta);
181 - if (res) {
182 - /* STA has been freed */
183 - goto err_del_interface;
184 - }
185 -
186 - rate_control_rate_init(sta);
187 - }
188 -
189 /*
190 * set_multicast_list will be invoked by the networking core
191 * which will check whether any increments here were done in
192 @@ -344,8 +322,7 @@ static int ieee80211_do_open(struct net_
193 netif_tx_start_all_queues(dev);
194
195 return 0;
196 - err_del_interface:
197 - drv_remove_interface(local, &sdata->vif);
198 +
199 err_stop:
200 if (!local->open_count)
201 drv_stop(local);
202 @@ -718,6 +695,70 @@ static void ieee80211_if_setup(struct ne
203 dev->destructor = free_netdev;
204 }
205
206 +static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
207 + struct sk_buff *skb)
208 +{
209 + struct ieee80211_local *local = sdata->local;
210 + struct ieee80211_rx_status *rx_status;
211 + struct ieee802_11_elems elems;
212 + struct ieee80211_mgmt *mgmt;
213 + struct sta_info *sta;
214 + size_t baselen;
215 + u32 rates = 0;
216 + u16 stype;
217 + bool new = false;
218 + enum ieee80211_band band = local->hw.conf.channel->band;
219 + struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
220 +
221 + rx_status = IEEE80211_SKB_RXCB(skb);
222 + mgmt = (struct ieee80211_mgmt *) skb->data;
223 + stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
224 +
225 + if (stype != IEEE80211_STYPE_BEACON)
226 + return;
227 +
228 + baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
229 + if (baselen > skb->len)
230 + return;
231 +
232 + ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
233 + skb->len - baselen, &elems);
234 +
235 + rates = ieee80211_sta_get_rates(local, &elems, band);
236 +
237 + rcu_read_lock();
238 +
239 + sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
240 +
241 + if (!sta) {
242 + rcu_read_unlock();
243 + sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
244 + GFP_KERNEL);
245 + if (!sta)
246 + return;
247 +
248 + new = true;
249 + }
250 +
251 + sta->last_rx = jiffies;
252 + sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
253 +
254 + if (elems.ht_cap_elem)
255 + ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
256 + elems.ht_cap_elem, &sta->sta.ht_cap);
257 +
258 + if (elems.wmm_param)
259 + set_sta_flags(sta, WLAN_STA_WME);
260 +
261 + if (new) {
262 + sta->flags = WLAN_STA_AUTHORIZED;
263 + rate_control_rate_init(sta);
264 + sta_info_insert_rcu(sta);
265 + }
266 +
267 + rcu_read_unlock();
268 +}
269 +
270 static void ieee80211_iface_work(struct work_struct *work)
271 {
272 struct ieee80211_sub_if_data *sdata =
273 @@ -822,6 +863,9 @@ static void ieee80211_iface_work(struct
274 break;
275 ieee80211_mesh_rx_queued_mgmt(sdata, skb);
276 break;
277 + case NL80211_IFTYPE_WDS:
278 + ieee80211_wds_rx_queued_mgmt(sdata, skb);
279 + break;
280 default:
281 WARN(1, "frame for unexpected interface type");
282 break;
283 --- a/net/mac80211/rx.c
284 +++ b/net/mac80211/rx.c
285 @@ -2147,7 +2147,8 @@ ieee80211_rx_h_action(struct ieee80211_r
286 */
287 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
288 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
289 - sdata->vif.type != NL80211_IFTYPE_AP)
290 + sdata->vif.type != NL80211_IFTYPE_AP &&
291 + sdata->vif.type != NL80211_IFTYPE_WDS)
292 break;
293
294 /* verify action_code is present */
295 @@ -2345,13 +2346,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
296
297 if (!ieee80211_vif_is_mesh(&sdata->vif) &&
298 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
299 - sdata->vif.type != NL80211_IFTYPE_STATION)
300 + sdata->vif.type != NL80211_IFTYPE_STATION &&
301 + sdata->vif.type != NL80211_IFTYPE_WDS)
302 return RX_DROP_MONITOR;
303
304 switch (stype) {
305 case cpu_to_le16(IEEE80211_STYPE_BEACON):
306 case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
307 - /* process for all: mesh, mlme, ibss */
308 + /* process for all: mesh, mlme, ibss, wds */
309 break;
310 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
311 case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
312 @@ -2692,10 +2694,16 @@ static int prepare_for_handlers(struct i
313 }
314 break;
315 case NL80211_IFTYPE_WDS:
316 - if (bssid || !ieee80211_is_data(hdr->frame_control))
317 - return 0;
318 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
319 return 0;
320 +
321 + if (ieee80211_is_data(hdr->frame_control) ||
322 + ieee80211_is_action(hdr->frame_control)) {
323 + if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
324 + return 0;
325 + } else if (!ieee80211_is_beacon(hdr->frame_control))
326 + return 0;
327 +
328 break;
329 default:
330 /* should never get here */
331 --- a/net/mac80211/sta_info.h
332 +++ b/net/mac80211/sta_info.h
333 @@ -31,7 +31,6 @@
334 * frames.
335 * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP.
336 * @WLAN_STA_WME: Station is a QoS-STA.
337 - * @WLAN_STA_WDS: Station is one of our WDS peers.
338 * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
339 * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
340 * frame to this station is transmitted.
341 @@ -54,7 +53,6 @@ enum ieee80211_sta_info_flags {
342 WLAN_STA_SHORT_PREAMBLE = 1<<4,
343 WLAN_STA_ASSOC_AP = 1<<5,
344 WLAN_STA_WME = 1<<6,
345 - WLAN_STA_WDS = 1<<7,
346 WLAN_STA_CLEAR_PS_FILT = 1<<9,
347 WLAN_STA_MFP = 1<<10,
348 WLAN_STA_BLOCK_BA = 1<<11,
349 --- a/drivers/net/wireless/ath/ath9k/xmit.c
350 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
351 @@ -551,7 +551,8 @@ static void ath_tx_complete_aggr(struct
352 if (clear_filter)
353 tid->ac->clear_ps_filter = true;
354 list_splice(&bf_pending, &tid->buf_q);
355 - ath_tx_queue_tid(txq, tid);
356 + if (!an->sleeping)
357 + ath_tx_queue_tid(txq, tid);
358 spin_unlock_bh(&txq->axq_lock);
359 }
360
361 @@ -1413,7 +1414,8 @@ static void ath_tx_send_ampdu(struct ath
362 */
363 TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
364 list_add_tail(&bf->list, &tid->buf_q);
365 - ath_tx_queue_tid(txctl->txq, tid);
366 + if (!txctl->an || !txctl->an->sleeping)
367 + ath_tx_queue_tid(txctl->txq, tid);
368 return;
369 }
370
371 --- a/include/net/cfg80211.h
372 +++ b/include/net/cfg80211.h
373 @@ -421,6 +421,7 @@ struct station_parameters {
374 * @STATION_INFO_RX_BITRATE: @rxrate fields are filled
375 * @STATION_INFO_BSS_PARAM: @bss_param filled
376 * @STATION_INFO_CONNECTED_TIME: @connected_time filled
377 + * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
378 */
379 enum station_info_flags {
380 STATION_INFO_INACTIVE_TIME = 1<<0,
381 @@ -439,7 +440,8 @@ enum station_info_flags {
382 STATION_INFO_SIGNAL_AVG = 1<<13,
383 STATION_INFO_RX_BITRATE = 1<<14,
384 STATION_INFO_BSS_PARAM = 1<<15,
385 - STATION_INFO_CONNECTED_TIME = 1<<16
386 + STATION_INFO_CONNECTED_TIME = 1<<16,
387 + STATION_INFO_ASSOC_REQ_IES = 1<<17
388 };
389
390 /**
391 --- a/net/wireless/nl80211.c
392 +++ b/net/wireless/nl80211.c
393 @@ -2236,7 +2236,7 @@ static int nl80211_send_station(struct s
394 }
395 nla_nest_end(msg, sinfoattr);
396
397 - if (sinfo->assoc_req_ies)
398 + if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
399 NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
400 sinfo->assoc_req_ies);
401