mac80211: update to wireless-testing 2011-11-15
[openwrt/staging/dedeckeh.git] / package / mac80211 / patches / 300-pending_work.patch
1 --- a/drivers/net/wireless/ath/ath9k/main.c
2 +++ b/drivers/net/wireless/ath/ath9k/main.c
3 @@ -118,7 +118,7 @@ void ath9k_ps_restore(struct ath_softc *
4 if (--sc->ps_usecount != 0)
5 goto unlock;
6
7 - if (sc->ps_idle)
8 + if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK))
9 mode = ATH9K_PM_FULL_SLEEP;
10 else if (sc->ps_enabled &&
11 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
12 @@ -332,7 +332,8 @@ static int ath_reset_internal(struct ath
13 hchan = ah->curchan;
14 }
15
16 - if (fastcc && !ath9k_hw_check_alive(ah))
17 + if (fastcc && (ah->chip_fullsleep ||
18 + !ath9k_hw_check_alive(ah)))
19 fastcc = false;
20
21 if (!ath_prepare_reset(sc, retry_tx, flush))
22 @@ -882,82 +883,6 @@ chip_reset:
23 #undef SCHED_INTR
24 }
25
26 -static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
27 -{
28 - struct ath_hw *ah = sc->sc_ah;
29 - struct ath_common *common = ath9k_hw_common(ah);
30 - struct ieee80211_channel *channel = hw->conf.channel;
31 - int r;
32 -
33 - ath9k_ps_wakeup(sc);
34 - spin_lock_bh(&sc->sc_pcu_lock);
35 - atomic_set(&ah->intr_ref_cnt, -1);
36 -
37 - ath9k_hw_configpcipowersave(ah, false);
38 -
39 - if (!ah->curchan)
40 - ah->curchan = ath9k_cmn_get_curchannel(sc->hw, ah);
41 -
42 - r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
43 - if (r) {
44 - ath_err(common,
45 - "Unable to reset channel (%u MHz), reset status %d\n",
46 - channel->center_freq, r);
47 - }
48 -
49 - ath_complete_reset(sc, true);
50 -
51 - /* Enable LED */
52 - ath9k_hw_cfg_output(ah, ah->led_pin,
53 - AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
54 - ath9k_hw_set_gpio(ah, ah->led_pin, 0);
55 -
56 - spin_unlock_bh(&sc->sc_pcu_lock);
57 -
58 - ath9k_ps_restore(sc);
59 -}
60 -
61 -void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
62 -{
63 - struct ath_hw *ah = sc->sc_ah;
64 - struct ieee80211_channel *channel = hw->conf.channel;
65 - int r;
66 -
67 - ath9k_ps_wakeup(sc);
68 -
69 - ath_cancel_work(sc);
70 -
71 - spin_lock_bh(&sc->sc_pcu_lock);
72 -
73 - /*
74 - * Keep the LED on when the radio is disabled
75 - * during idle unassociated state.
76 - */
77 - if (!sc->ps_idle) {
78 - ath9k_hw_set_gpio(ah, ah->led_pin, 1);
79 - ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
80 - }
81 -
82 - ath_prepare_reset(sc, false, true);
83 -
84 - if (!ah->curchan)
85 - ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
86 -
87 - r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
88 - if (r) {
89 - ath_err(ath9k_hw_common(sc->sc_ah),
90 - "Unable to reset channel (%u MHz), reset status %d\n",
91 - channel->center_freq, r);
92 - }
93 -
94 - ath9k_hw_phy_disable(ah);
95 -
96 - ath9k_hw_configpcipowersave(ah, true);
97 -
98 - spin_unlock_bh(&sc->sc_pcu_lock);
99 - ath9k_ps_restore(sc);
100 -}
101 -
102 static int ath_reset(struct ath_softc *sc, bool retry_tx)
103 {
104 int r;
105 @@ -1093,6 +1018,9 @@ static int ath9k_start(struct ieee80211_
106 * and then setup of the interrupt mask.
107 */
108 spin_lock_bh(&sc->sc_pcu_lock);
109 +
110 + atomic_set(&ah->intr_ref_cnt, -1);
111 +
112 r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
113 if (r) {
114 ath_err(common,
115 @@ -1131,6 +1059,18 @@ static int ath9k_start(struct ieee80211_
116 goto mutex_unlock;
117 }
118
119 + if (ah->led_pin >= 0) {
120 + ath9k_hw_cfg_output(ah, ah->led_pin,
121 + AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
122 + ath9k_hw_set_gpio(ah, ah->led_pin, 0);
123 + }
124 +
125 + /*
126 + * Reset key cache to sane defaults (all entries cleared) instead of
127 + * semi-random values after suspend/resume.
128 + */
129 + ath9k_cmn_init_crypto(sc->sc_ah);
130 +
131 spin_unlock_bh(&sc->sc_pcu_lock);
132
133 if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
134 @@ -1176,6 +1116,13 @@ static void ath9k_tx(struct ieee80211_hw
135 }
136 }
137
138 + /*
139 + * Cannot tx while the hardware is in full sleep, it first needs a full
140 + * chip reset to recover from that
141 + */
142 + if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP))
143 + goto exit;
144 +
145 if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) {
146 /*
147 * We are using PS-Poll and mac80211 can request TX while in
148 @@ -1222,6 +1169,7 @@ static void ath9k_stop(struct ieee80211_
149 struct ath_softc *sc = hw->priv;
150 struct ath_hw *ah = sc->sc_ah;
151 struct ath_common *common = ath9k_hw_common(ah);
152 + bool prev_idle;
153
154 mutex_lock(&sc->mutex);
155
156 @@ -1252,35 +1200,45 @@ static void ath9k_stop(struct ieee80211_
157 * before setting the invalid flag. */
158 ath9k_hw_disable_interrupts(ah);
159
160 - if (!(sc->sc_flags & SC_OP_INVALID)) {
161 - ath_drain_all_txq(sc, false);
162 - ath_stoprecv(sc);
163 - ath9k_hw_phy_disable(ah);
164 - } else
165 - sc->rx.rxlink = NULL;
166 + spin_unlock_bh(&sc->sc_pcu_lock);
167 +
168 + /* we can now sync irq and kill any running tasklets, since we already
169 + * disabled interrupts and not holding a spin lock */
170 + synchronize_irq(sc->irq);
171 + tasklet_kill(&sc->intr_tq);
172 + tasklet_kill(&sc->bcon_tasklet);
173 +
174 + prev_idle = sc->ps_idle;
175 + sc->ps_idle = true;
176 +
177 + spin_lock_bh(&sc->sc_pcu_lock);
178 +
179 + if (ah->led_pin >= 0) {
180 + ath9k_hw_set_gpio(ah, ah->led_pin, 1);
181 + ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
182 + }
183 +
184 + ath_prepare_reset(sc, false, true);
185
186 if (sc->rx.frag) {
187 dev_kfree_skb_any(sc->rx.frag);
188 sc->rx.frag = NULL;
189 }
190
191 - /* disable HAL and put h/w to sleep */
192 - ath9k_hw_disable(ah);
193 + if (!ah->curchan)
194 + ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
195
196 - spin_unlock_bh(&sc->sc_pcu_lock);
197 + ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
198 + ath9k_hw_phy_disable(ah);
199
200 - /* we can now sync irq and kill any running tasklets, since we already
201 - * disabled interrupts and not holding a spin lock */
202 - synchronize_irq(sc->irq);
203 - tasklet_kill(&sc->intr_tq);
204 - tasklet_kill(&sc->bcon_tasklet);
205 + ath9k_hw_configpcipowersave(ah, true);
206
207 - ath9k_ps_restore(sc);
208 + spin_unlock_bh(&sc->sc_pcu_lock);
209
210 - sc->ps_idle = true;
211 - ath_radio_disable(sc, hw);
212 + ath9k_ps_restore(sc);
213
214 sc->sc_flags |= SC_OP_INVALID;
215 + sc->ps_idle = prev_idle;
216
217 mutex_unlock(&sc->mutex);
218
219 @@ -1620,8 +1578,8 @@ static int ath9k_config(struct ieee80211
220 struct ath_hw *ah = sc->sc_ah;
221 struct ath_common *common = ath9k_hw_common(ah);
222 struct ieee80211_conf *conf = &hw->conf;
223 - bool disable_radio = false;
224
225 + ath9k_ps_wakeup(sc);
226 mutex_lock(&sc->mutex);
227
228 /*
229 @@ -1632,13 +1590,8 @@ static int ath9k_config(struct ieee80211
230 */
231 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
232 sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
233 - if (!sc->ps_idle) {
234 - ath_radio_enable(sc, hw);
235 - ath_dbg(common, ATH_DBG_CONFIG,
236 - "not-idle: enabling radio\n");
237 - } else {
238 - disable_radio = true;
239 - }
240 + if (sc->ps_idle)
241 + ath_cancel_work(sc);
242 }
243
244 /*
245 @@ -1745,18 +1698,12 @@ static int ath9k_config(struct ieee80211
246 ath_dbg(common, ATH_DBG_CONFIG,
247 "Set power: %d\n", conf->power_level);
248 sc->config.txpowlimit = 2 * conf->power_level;
249 - ath9k_ps_wakeup(sc);
250 ath9k_cmn_update_txpow(ah, sc->curtxpow,
251 sc->config.txpowlimit, &sc->curtxpow);
252 - ath9k_ps_restore(sc);
253 - }
254 -
255 - if (disable_radio) {
256 - ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
257 - ath_radio_disable(sc, hw);
258 }
259
260 mutex_unlock(&sc->mutex);
261 + ath9k_ps_restore(sc);
262
263 return 0;
264 }
265 @@ -2324,9 +2271,6 @@ static void ath9k_flush(struct ieee80211
266 return;
267 }
268
269 - if (drop)
270 - timeout = 1;
271 -
272 for (j = 0; j < timeout; j++) {
273 bool npend = false;
274
275 @@ -2344,21 +2288,22 @@ static void ath9k_flush(struct ieee80211
276 }
277
278 if (!npend)
279 - goto out;
280 + break;
281 }
282
283 - ath9k_ps_wakeup(sc);
284 - spin_lock_bh(&sc->sc_pcu_lock);
285 - drain_txq = ath_drain_all_txq(sc, false);
286 - spin_unlock_bh(&sc->sc_pcu_lock);
287 + if (drop) {
288 + ath9k_ps_wakeup(sc);
289 + spin_lock_bh(&sc->sc_pcu_lock);
290 + drain_txq = ath_drain_all_txq(sc, false);
291 + spin_unlock_bh(&sc->sc_pcu_lock);
292
293 - if (!drain_txq)
294 - ath_reset(sc, false);
295 + if (!drain_txq)
296 + ath_reset(sc, false);
297
298 - ath9k_ps_restore(sc);
299 - ieee80211_wake_queues(hw);
300 + ath9k_ps_restore(sc);
301 + ieee80211_wake_queues(hw);
302 + }
303
304 -out:
305 ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
306 mutex_unlock(&sc->mutex);
307 }
308 --- a/drivers/net/wireless/ath/ath9k/pci.c
309 +++ b/drivers/net/wireless/ath/ath9k/pci.c
310 @@ -307,12 +307,11 @@ static int ath_pci_suspend(struct device
311 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
312 struct ath_softc *sc = hw->priv;
313
314 - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
315 -
316 /* The device has to be moved to FULLSLEEP forcibly.
317 * Otherwise the chip never moved to full sleep,
318 * when no interface is up.
319 */
320 + ath9k_hw_disable(sc->sc_ah);
321 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
322
323 return 0;
324 @@ -334,22 +333,6 @@ static int ath_pci_resume(struct device
325 if ((val & 0x0000ff00) != 0)
326 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
327
328 - ath9k_ps_wakeup(sc);
329 - /* Enable LED */
330 - ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
331 - AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
332 - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
333 -
334 - /*
335 - * Reset key cache to sane defaults (all entries cleared) instead of
336 - * semi-random values after suspend/resume.
337 - */
338 - ath9k_cmn_init_crypto(sc->sc_ah);
339 - ath9k_ps_restore(sc);
340 -
341 - sc->ps_idle = true;
342 - ath_radio_disable(sc, hw);
343 -
344 return 0;
345 }
346
347 --- a/drivers/net/wireless/ath/ath9k/xmit.c
348 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
349 @@ -1955,7 +1955,7 @@ static void ath_tx_complete(struct ath_s
350 skb_pull(skb, padsize);
351 }
352
353 - if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) {
354 + if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) {
355 sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK;
356 ath_dbg(common, ATH_DBG_PS,
357 "Going back to sleep after having received TX status (0x%lx)\n",
358 --- a/include/net/cfg80211.h
359 +++ b/include/net/cfg80211.h
360 @@ -1130,6 +1130,7 @@ struct cfg80211_ibss_params {
361 u8 *ssid;
362 u8 *bssid;
363 struct ieee80211_channel *channel;
364 + enum nl80211_channel_type channel_type;
365 u8 *ie;
366 u8 ssid_len, ie_len;
367 u16 beacon_interval;
368 @@ -3292,6 +3293,16 @@ void cfg80211_report_obss_beacon(struct
369 const u8 *frame, size_t len,
370 int freq, gfp_t gfp);
371
372 +/**
373 + * cfg80211_can_use_ext_chan - test if ht40 on extension channel can be used
374 + * @wiphy: the wiphy
375 + * @chan: main channel
376 + * @channel_type: HT mode
377 + */
378 +bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
379 + struct ieee80211_channel *chan,
380 + enum nl80211_channel_type channel_type);
381 +
382 /* Logging, debugging and troubleshooting/diagnostic helpers. */
383
384 /* wiphy_printk helpers, similar to dev_printk */
385 --- a/net/mac80211/agg-rx.c
386 +++ b/net/mac80211/agg-rx.c
387 @@ -182,6 +182,10 @@ static void ieee80211_send_addba_resp(st
388 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
389 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
390 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
391 + else if (sdata->vif.type == NL80211_IFTYPE_WDS)
392 + memcpy(mgmt->bssid, da, ETH_ALEN);
393 + else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
394 + memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
395
396 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
397 IEEE80211_STYPE_ACTION);
398 --- a/net/mac80211/agg-tx.c
399 +++ b/net/mac80211/agg-tx.c
400 @@ -79,10 +79,13 @@ static void ieee80211_send_addba_request
401 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
402 if (sdata->vif.type == NL80211_IFTYPE_AP ||
403 sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
404 - sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
405 + sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
406 + sdata->vif.type == NL80211_IFTYPE_WDS)
407 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
408 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
409 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
410 + else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
411 + memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
412
413 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
414 IEEE80211_STYPE_ACTION);
415 @@ -394,7 +397,9 @@ int ieee80211_start_tx_ba_session(struct
416 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
417 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
418 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
419 - sdata->vif.type != NL80211_IFTYPE_AP)
420 + sdata->vif.type != NL80211_IFTYPE_AP &&
421 + sdata->vif.type != NL80211_IFTYPE_ADHOC &&
422 + sdata->vif.type != NL80211_IFTYPE_WDS)
423 return -EINVAL;
424
425 if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
426 --- a/net/mac80211/debugfs_sta.c
427 +++ b/net/mac80211/debugfs_sta.c
428 @@ -63,11 +63,11 @@ static ssize_t sta_flags_read(struct fil
429 test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
430
431 int res = scnprintf(buf, sizeof(buf),
432 - "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
433 + "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
434 TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
435 TEST(PS_DRIVER), TEST(AUTHORIZED),
436 TEST(SHORT_PREAMBLE), TEST(ASSOC_AP),
437 - TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
438 + TEST(WME), TEST(CLEAR_PS_FILT),
439 TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
440 TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
441 TEST(TDLS_PEER_AUTH));
442 --- a/net/mac80211/ht.c
443 +++ b/net/mac80211/ht.c
444 @@ -201,6 +201,8 @@ void ieee80211_send_delba(struct ieee802
445 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
446 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
447 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
448 + else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
449 + memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
450
451 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
452 IEEE80211_STYPE_ACTION);
453 --- a/net/mac80211/ibss.c
454 +++ b/net/mac80211/ibss.c
455 @@ -77,6 +77,7 @@ static void __ieee80211_sta_join_ibss(st
456 struct cfg80211_bss *bss;
457 u32 bss_change;
458 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
459 + enum nl80211_channel_type channel_type;
460
461 lockdep_assert_held(&ifibss->mtx);
462
463 @@ -105,8 +106,16 @@ static void __ieee80211_sta_join_ibss(st
464
465 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
466
467 - local->oper_channel = chan;
468 - WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
469 + channel_type = ifibss->channel_type;
470 + if (channel_type > NL80211_CHAN_HT20 &&
471 + !cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type))
472 + channel_type = NL80211_CHAN_HT20;
473 + if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
474 + /* can only fail due to HT40+/- mismatch */
475 + channel_type = NL80211_CHAN_HT20;
476 + WARN_ON(!ieee80211_set_channel_type(local, sdata,
477 + NL80211_CHAN_HT20));
478 + }
479 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
480
481 sband = local->hw.wiphy->bands[chan->band];
482 @@ -172,6 +181,18 @@ static void __ieee80211_sta_join_ibss(st
483 memcpy(skb_put(skb, ifibss->ie_len),
484 ifibss->ie, ifibss->ie_len);
485
486 + /* add HT capability and information IEs */
487 + if (channel_type && sband->ht_cap.ht_supported) {
488 + pos = skb_put(skb, 4 +
489 + sizeof(struct ieee80211_ht_cap) +
490 + sizeof(struct ieee80211_ht_info));
491 + pos = ieee80211_ie_build_ht_cap(pos, sband, sband->ht_cap.cap);
492 + pos = ieee80211_ie_build_ht_info(pos,
493 + &sband->ht_cap,
494 + chan,
495 + channel_type);
496 + }
497 +
498 if (local->hw.queues >= 4) {
499 pos = skb_put(skb, 9);
500 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
501 @@ -195,6 +216,7 @@ static void __ieee80211_sta_join_ibss(st
502 bss_change |= BSS_CHANGED_BEACON;
503 bss_change |= BSS_CHANGED_BEACON_ENABLED;
504 bss_change |= BSS_CHANGED_BASIC_RATES;
505 + bss_change |= BSS_CHANGED_HT;
506 bss_change |= BSS_CHANGED_IBSS;
507 sdata->vif.bss_conf.ibss_joined = true;
508 ieee80211_bss_info_change_notify(sdata, bss_change);
509 @@ -268,6 +290,7 @@ static void ieee80211_rx_bss_info(struct
510 u64 beacon_timestamp, rx_timestamp;
511 u32 supp_rates = 0;
512 enum ieee80211_band band = rx_status->band;
513 + struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
514
515 if (elems->ds_params && elems->ds_params_len == 1)
516 freq = ieee80211_channel_to_frequency(elems->ds_params[0],
517 @@ -277,7 +300,10 @@ static void ieee80211_rx_bss_info(struct
518
519 channel = ieee80211_get_channel(local->hw.wiphy, freq);
520
521 - if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
522 + if (!channel ||
523 + channel->flags & (IEEE80211_CHAN_DISABLED ||
524 + IEEE80211_CHAN_NO_IBSS ||
525 + IEEE80211_CHAN_RADAR))
526 return;
527
528 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
529 @@ -315,8 +341,41 @@ static void ieee80211_rx_bss_info(struct
530 GFP_ATOMIC);
531 }
532
533 - if (sta && elems->wmm_info)
534 - set_sta_flag(sta, WLAN_STA_WME);
535 + if (sta) {
536 + if (elems->wmm_info)
537 + set_sta_flag(sta, WLAN_STA_WME);
538 +
539 + /* we both use HT */
540 + if (elems->ht_info_elem && elems->ht_cap_elem &&
541 + sdata->u.ibss.channel_type) {
542 + enum nl80211_channel_type channel_type =
543 + ieee80211_ht_info_to_channel_type(
544 + elems->ht_info_elem);
545 + struct ieee80211_sta_ht_cap sta_ht_cap_new;
546 +
547 + /*
548 + * fall back to HT20 if we don't use or use
549 + * the other extension channel
550 + */
551 + if (channel_type > NL80211_CHAN_HT20 &&
552 + channel_type != sdata->u.ibss.channel_type)
553 + channel_type = NL80211_CHAN_HT20;
554 +
555 + ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
556 + elems->ht_cap_elem,
557 + &sta_ht_cap_new);
558 + if (memcmp(&sta->sta.ht_cap, &sta_ht_cap_new,
559 + sizeof(sta_ht_cap_new))) {
560 + memcpy(&sta->sta.ht_cap,
561 + &sta_ht_cap_new,
562 + sizeof(sta_ht_cap_new));
563 + rate_control_rate_update(local, sband,
564 + sta,
565 + IEEE80211_RC_HT_CHANGED,
566 + channel_type);
567 + }
568 + }
569 + }
570
571 rcu_read_unlock();
572 }
573 @@ -898,10 +957,15 @@ int ieee80211_ibss_join(struct ieee80211
574 struct sk_buff *skb;
575
576 skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
577 - 36 /* bitrates */ +
578 - 34 /* SSID */ +
579 - 3 /* DS params */ +
580 - 4 /* IBSS params */ +
581 + sizeof(struct ieee80211_hdr_3addr) +
582 + 12 /* struct ieee80211_mgmt.u.beacon */ +
583 + 2 + IEEE80211_MAX_SSID_LEN /* max SSID */ +
584 + 2 + 8 /* max Supported Rates */ +
585 + 3 /* max DS params */ +
586 + 4 /* IBSS params */ +
587 + 2 + (IEEE80211_MAX_SUPP_RATES - 8) +
588 + 2 + sizeof(struct ieee80211_ht_cap) +
589 + 2 + sizeof(struct ieee80211_ht_info) +
590 params->ie_len);
591 if (!skb)
592 return -ENOMEM;
593 @@ -922,13 +986,15 @@ int ieee80211_ibss_join(struct ieee80211
594 sdata->vif.bss_conf.beacon_int = params->beacon_interval;
595
596 sdata->u.ibss.channel = params->channel;
597 + sdata->u.ibss.channel_type = params->channel_type;
598 sdata->u.ibss.fixed_channel = params->channel_fixed;
599
600 /* fix ourselves to that channel now already */
601 if (params->channel_fixed) {
602 sdata->local->oper_channel = params->channel;
603 - WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata,
604 - NL80211_CHAN_NO_HT));
605 + if (!ieee80211_set_channel_type(sdata->local, sdata,
606 + params->channel_type))
607 + return -EINVAL;
608 }
609
610 if (params->ie) {
611 --- a/net/mac80211/ieee80211_i.h
612 +++ b/net/mac80211/ieee80211_i.h
613 @@ -470,6 +470,7 @@ struct ieee80211_if_ibss {
614 u8 ssid_len, ie_len;
615 u8 *ie;
616 struct ieee80211_channel *channel;
617 + enum nl80211_channel_type channel_type;
618
619 unsigned long ibss_join_req;
620 /* probe response/beacon for IBSS */
621 --- a/net/mac80211/iface.c
622 +++ b/net/mac80211/iface.c
623 @@ -178,7 +178,6 @@ static int ieee80211_do_open(struct net_
624 {
625 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
626 struct ieee80211_local *local = sdata->local;
627 - struct sta_info *sta;
628 u32 changed = 0;
629 int res;
630 u32 hw_reconf_flags = 0;
631 @@ -309,27 +308,6 @@ static int ieee80211_do_open(struct net_
632
633 set_bit(SDATA_STATE_RUNNING, &sdata->state);
634
635 - if (sdata->vif.type == NL80211_IFTYPE_WDS) {
636 - /* Create STA entry for the WDS peer */
637 - sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
638 - GFP_KERNEL);
639 - if (!sta) {
640 - res = -ENOMEM;
641 - goto err_del_interface;
642 - }
643 -
644 - /* no atomic bitop required since STA is not live yet */
645 - set_sta_flag(sta, WLAN_STA_AUTHORIZED);
646 -
647 - res = sta_info_insert(sta);
648 - if (res) {
649 - /* STA has been freed */
650 - goto err_del_interface;
651 - }
652 -
653 - rate_control_rate_init(sta);
654 - }
655 -
656 /*
657 * set_multicast_list will be invoked by the networking core
658 * which will check whether any increments here were done in
659 @@ -356,8 +334,7 @@ static int ieee80211_do_open(struct net_
660 netif_tx_start_all_queues(dev);
661
662 return 0;
663 - err_del_interface:
664 - drv_remove_interface(local, sdata);
665 +
666 err_stop:
667 if (!local->open_count)
668 drv_stop(local);
669 @@ -732,6 +709,70 @@ static void ieee80211_if_setup(struct ne
670 dev->destructor = free_netdev;
671 }
672
673 +static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
674 + struct sk_buff *skb)
675 +{
676 + struct ieee80211_local *local = sdata->local;
677 + struct ieee80211_rx_status *rx_status;
678 + struct ieee802_11_elems elems;
679 + struct ieee80211_mgmt *mgmt;
680 + struct sta_info *sta;
681 + size_t baselen;
682 + u32 rates = 0;
683 + u16 stype;
684 + bool new = false;
685 + enum ieee80211_band band = local->hw.conf.channel->band;
686 + struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
687 +
688 + rx_status = IEEE80211_SKB_RXCB(skb);
689 + mgmt = (struct ieee80211_mgmt *) skb->data;
690 + stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
691 +
692 + if (stype != IEEE80211_STYPE_BEACON)
693 + return;
694 +
695 + baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
696 + if (baselen > skb->len)
697 + return;
698 +
699 + ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
700 + skb->len - baselen, &elems);
701 +
702 + rates = ieee80211_sta_get_rates(local, &elems, band);
703 +
704 + rcu_read_lock();
705 +
706 + sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
707 +
708 + if (!sta) {
709 + rcu_read_unlock();
710 + sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
711 + GFP_KERNEL);
712 + if (!sta)
713 + return;
714 +
715 + new = true;
716 + }
717 +
718 + sta->last_rx = jiffies;
719 + sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
720 +
721 + if (elems.ht_cap_elem)
722 + ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
723 + elems.ht_cap_elem, &sta->sta.ht_cap);
724 +
725 + if (elems.wmm_param)
726 + set_sta_flag(sta, WLAN_STA_WME);
727 +
728 + if (new) {
729 + set_sta_flag(sta, WLAN_STA_AUTHORIZED);
730 + rate_control_rate_init(sta);
731 + sta_info_insert_rcu(sta);
732 + }
733 +
734 + rcu_read_unlock();
735 +}
736 +
737 static void ieee80211_iface_work(struct work_struct *work)
738 {
739 struct ieee80211_sub_if_data *sdata =
740 @@ -836,6 +877,9 @@ static void ieee80211_iface_work(struct
741 break;
742 ieee80211_mesh_rx_queued_mgmt(sdata, skb);
743 break;
744 + case NL80211_IFTYPE_WDS:
745 + ieee80211_wds_rx_queued_mgmt(sdata, skb);
746 + break;
747 default:
748 WARN(1, "frame for unexpected interface type");
749 break;
750 --- a/net/mac80211/mlme.c
751 +++ b/net/mac80211/mlme.c
752 @@ -1359,9 +1359,6 @@ static void __ieee80211_connection_loss(
753 ieee80211_set_disassoc(sdata, true, true);
754 mutex_unlock(&ifmgd->mtx);
755
756 - mutex_lock(&local->mtx);
757 - ieee80211_recalc_idle(local);
758 - mutex_unlock(&local->mtx);
759 /*
760 * must be outside lock due to cfg80211,
761 * but that's not a problem.
762 @@ -1370,6 +1367,10 @@ static void __ieee80211_connection_loss(
763 IEEE80211_STYPE_DEAUTH,
764 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
765 NULL, true);
766 +
767 + mutex_lock(&local->mtx);
768 + ieee80211_recalc_idle(local);
769 + mutex_unlock(&local->mtx);
770 }
771
772 void ieee80211_beacon_connection_loss_work(struct work_struct *work)
773 @@ -2136,9 +2137,6 @@ static void ieee80211_sta_connection_los
774
775 ieee80211_set_disassoc(sdata, true, true);
776 mutex_unlock(&ifmgd->mtx);
777 - mutex_lock(&local->mtx);
778 - ieee80211_recalc_idle(local);
779 - mutex_unlock(&local->mtx);
780 /*
781 * must be outside lock due to cfg80211,
782 * but that's not a problem.
783 @@ -2146,6 +2144,11 @@ static void ieee80211_sta_connection_los
784 ieee80211_send_deauth_disassoc(sdata, bssid,
785 IEEE80211_STYPE_DEAUTH, reason,
786 NULL, true);
787 +
788 + mutex_lock(&local->mtx);
789 + ieee80211_recalc_idle(local);
790 + mutex_unlock(&local->mtx);
791 +
792 mutex_lock(&ifmgd->mtx);
793 }
794
795 --- a/net/mac80211/offchannel.c
796 +++ b/net/mac80211/offchannel.c
797 @@ -212,8 +212,6 @@ static void ieee80211_hw_roc_start(struc
798 return;
799 }
800
801 - ieee80211_recalc_idle(local);
802 -
803 if (local->hw_roc_skb) {
804 sdata = IEEE80211_DEV_TO_SUB_IF(local->hw_roc_dev);
805 ieee80211_tx_skb(sdata, local->hw_roc_skb);
806 @@ -227,6 +225,8 @@ static void ieee80211_hw_roc_start(struc
807 GFP_KERNEL);
808 }
809
810 + ieee80211_recalc_idle(local);
811 +
812 mutex_unlock(&local->mtx);
813 }
814
815 --- a/net/mac80211/rx.c
816 +++ b/net/mac80211/rx.c
817 @@ -2250,7 +2250,9 @@ ieee80211_rx_h_action(struct ieee80211_r
818 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
819 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
820 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
821 - sdata->vif.type != NL80211_IFTYPE_AP)
822 + sdata->vif.type != NL80211_IFTYPE_AP &&
823 + sdata->vif.type != NL80211_IFTYPE_ADHOC &&
824 + sdata->vif.type != NL80211_IFTYPE_WDS)
825 break;
826
827 /* verify action_code is present */
828 @@ -2465,13 +2467,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
829
830 if (!ieee80211_vif_is_mesh(&sdata->vif) &&
831 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
832 - sdata->vif.type != NL80211_IFTYPE_STATION)
833 + sdata->vif.type != NL80211_IFTYPE_STATION &&
834 + sdata->vif.type != NL80211_IFTYPE_WDS)
835 return RX_DROP_MONITOR;
836
837 switch (stype) {
838 case cpu_to_le16(IEEE80211_STYPE_BEACON):
839 case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
840 - /* process for all: mesh, mlme, ibss */
841 + /* process for all: mesh, mlme, ibss, wds */
842 break;
843 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
844 case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
845 @@ -2818,10 +2821,16 @@ static int prepare_for_handlers(struct i
846 }
847 break;
848 case NL80211_IFTYPE_WDS:
849 - if (bssid || !ieee80211_is_data(hdr->frame_control))
850 - return 0;
851 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
852 return 0;
853 +
854 + if (ieee80211_is_data(hdr->frame_control) ||
855 + ieee80211_is_action(hdr->frame_control)) {
856 + if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
857 + return 0;
858 + } else if (!ieee80211_is_beacon(hdr->frame_control))
859 + return 0;
860 +
861 break;
862 default:
863 /* should never get here */
864 --- a/net/mac80211/sta_info.h
865 +++ b/net/mac80211/sta_info.h
866 @@ -32,7 +32,6 @@
867 * frames.
868 * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP.
869 * @WLAN_STA_WME: Station is a QoS-STA.
870 - * @WLAN_STA_WDS: Station is one of our WDS peers.
871 * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
872 * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
873 * frame to this station is transmitted.
874 @@ -62,7 +61,6 @@ enum ieee80211_sta_info_flags {
875 WLAN_STA_SHORT_PREAMBLE,
876 WLAN_STA_ASSOC_AP,
877 WLAN_STA_WME,
878 - WLAN_STA_WDS,
879 WLAN_STA_CLEAR_PS_FILT,
880 WLAN_STA_MFP,
881 WLAN_STA_BLOCK_BA,
882 --- a/net/wireless/chan.c
883 +++ b/net/wireless/chan.c
884 @@ -44,9 +44,9 @@ rdev_freq_to_chan(struct cfg80211_regist
885 return chan;
886 }
887
888 -static bool can_beacon_sec_chan(struct wiphy *wiphy,
889 - struct ieee80211_channel *chan,
890 - enum nl80211_channel_type channel_type)
891 +bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
892 + struct ieee80211_channel *chan,
893 + enum nl80211_channel_type channel_type)
894 {
895 struct ieee80211_channel *sec_chan;
896 int diff;
897 @@ -75,6 +75,7 @@ static bool can_beacon_sec_chan(struct w
898
899 return true;
900 }
901 +EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan);
902
903 int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
904 struct wireless_dev *wdev, int freq,
905 @@ -109,8 +110,8 @@ int cfg80211_set_freq(struct cfg80211_re
906 switch (channel_type) {
907 case NL80211_CHAN_HT40PLUS:
908 case NL80211_CHAN_HT40MINUS:
909 - if (!can_beacon_sec_chan(&rdev->wiphy, chan,
910 - channel_type)) {
911 + if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, chan,
912 + channel_type)) {
913 printk(KERN_DEBUG
914 "cfg80211: Secondary channel not "
915 "allowed to initiate communication\n");
916 --- a/net/wireless/nl80211.c
917 +++ b/net/wireless/nl80211.c
918 @@ -4604,13 +4604,34 @@ static int nl80211_join_ibss(struct sk_b
919 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
920 }
921
922 - ibss.channel = ieee80211_get_channel(wiphy,
923 - nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
924 + if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
925 + enum nl80211_channel_type channel_type;
926 +
927 + channel_type = nla_get_u32(
928 + info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
929 + if (channel_type > NL80211_CHAN_HT40PLUS)
930 + return -EINVAL;
931 + ibss.channel_type = channel_type;
932 + } else {
933 + ibss.channel_type = NL80211_CHAN_NO_HT;
934 + }
935 +
936 + ibss.channel = rdev_freq_to_chan(rdev,
937 + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
938 + ibss.channel_type);
939 if (!ibss.channel ||
940 + ibss.channel->flags & IEEE80211_CHAN_RADAR ||
941 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
942 ibss.channel->flags & IEEE80211_CHAN_DISABLED)
943 return -EINVAL;
944
945 + /* Both channels should be able to initiate communication */
946 + if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
947 + ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
948 + !cfg80211_can_beacon_sec_chan(&rdev->wiphy, ibss.channel,
949 + ibss.channel_type))
950 + return -EINVAL;
951 +
952 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
953 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
954