aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/rfkill.txt137
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig1
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c29
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c130
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c141
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c4
-rw-r--r--drivers/net/wireless/libertas/if_spi.c11
-rw-r--r--drivers/platform/x86/dell-laptop.c2
-rw-r--r--drivers/platform/x86/sony-laptop.c5
-rw-r--r--net/mac80211/debugfs.c25
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/mlme.c38
-rw-r--r--net/mac80211/util.c25
-rw-r--r--net/mac80211/wext.c31
19 files changed, 304 insertions, 297 deletions
diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt
index 1b74b5f30af4..c8acd8659e91 100644
--- a/Documentation/rfkill.txt
+++ b/Documentation/rfkill.txt
@@ -3,9 +3,8 @@ rfkill - RF kill switch support
3 3
41. Introduction 41. Introduction
52. Implementation details 52. Implementation details
63. Kernel driver guidelines 63. Kernel API
74. Kernel API 74. Userspace support
85. Userspace support
9 8
10 9
111. Introduction 101. Introduction
@@ -19,82 +18,62 @@ disable all transmitters of a certain type (or all). This is intended for
19situations where transmitters need to be turned off, for example on 18situations where transmitters need to be turned off, for example on
20aircraft. 19aircraft.
21 20
21The rfkill subsystem has a concept of "hard" and "soft" block, which
22differ little in their meaning (block == transmitters off) but rather in
23whether they can be changed or not:
24 - hard block: read-only radio block that cannot be overriden by software
25 - soft block: writable radio block (need not be readable) that is set by
26 the system software.
22 27
23 28
242. Implementation details 292. Implementation details
25 30
26The rfkill subsystem is composed of various components: the rfkill class, the 31The rfkill subsystem is composed of three main components:
27rfkill-input module (an input layer handler), and some specific input layer 32 * the rfkill core,
28events. 33 * the deprecated rfkill-input module (an input layer handler, being
29 34 replaced by userspace policy code) and
30The rfkill class is provided for kernel drivers to register their radio 35 * the rfkill drivers.
31transmitter with the kernel, provide methods for turning it on and off and,
32optionally, letting the system know about hardware-disabled states that may
33be implemented on the device. This code is enabled with the CONFIG_RFKILL
34Kconfig option, which drivers can "select".
35
36The rfkill class code also notifies userspace of state changes, this is
37achieved via uevents. It also provides some sysfs files for userspace to
38check the status of radio transmitters. See the "Userspace support" section
39below.
40 36
37The rfkill core provides API for kernel drivers to register their radio
38transmitter with the kernel, methods for turning it on and off and, letting
39the system know about hardware-disabled states that may be implemented on
40the device.
41 41
42The rfkill-input code implements a basic response to rfkill buttons -- it 42The rfkill core code also notifies userspace of state changes, and provides
43implements turning on/off all devices of a certain class (or all). 43ways for userspace to query the current states. See the "Userspace support"
44section below.
44 45
45When the device is hard-blocked (either by a call to rfkill_set_hw_state() 46When the device is hard-blocked (either by a call to rfkill_set_hw_state()
46or from query_hw_block) set_block() will be invoked but drivers can well 47or from query_hw_block) set_block() will be invoked for additional software
47ignore the method call since they can use the return value of the function 48block, but drivers can ignore the method call since they can use the return
48rfkill_set_hw_state() to sync the software state instead of keeping track 49value of the function rfkill_set_hw_state() to sync the software state
49of calls to set_block(). 50instead of keeping track of calls to set_block(). In fact, drivers should
50 51use the return value of rfkill_set_hw_state() unless the hardware actually
51 52keeps track of soft and hard block separately.
52The entire functionality is spread over more than one subsystem:
53
54 * The kernel input layer generates KEY_WWAN, KEY_WLAN etc. and
55 SW_RFKILL_ALL -- when the user presses a button. Drivers for radio
56 transmitters generally do not register to the input layer, unless the
57 device really provides an input device (i.e. a button that has no
58 effect other than generating a button press event)
59
60 * The rfkill-input code hooks up to these events and switches the soft-block
61 of the various radio transmitters, depending on the button type.
62
63 * The rfkill drivers turn off/on their transmitters as requested.
64
65 * The rfkill class will generate userspace notifications (uevents) to tell
66 userspace what the current state is.
67 53
68 54
553. Kernel API
69 56
703. Kernel driver guidelines
71 57
72 58Drivers for radio transmitters normally implement an rfkill driver.
73Drivers for radio transmitters normally implement only the rfkill class.
74These drivers may not unblock the transmitter based on own decisions, they
75should act on information provided by the rfkill class only.
76 59
77Platform drivers might implement input devices if the rfkill button is just 60Platform drivers might implement input devices if the rfkill button is just
78that, a button. If that button influences the hardware then you need to 61that, a button. If that button influences the hardware then you need to
79implement an rfkill class instead. This also applies if the platform provides 62implement an rfkill driver instead. This also applies if the platform provides
80a way to turn on/off the transmitter(s). 63a way to turn on/off the transmitter(s).
81 64
82During suspend/hibernation, transmitters should only be left enabled when 65For some platforms, it is possible that the hardware state changes during
83wake-on wlan or similar functionality requires it and the device wasn't 66suspend/hibernation, in which case it will be necessary to update the rfkill
84blocked before suspend/hibernate. Note that it may be necessary to update 67core with the current state is at resume time.
85the rfkill subsystem's idea of what the current state is at resume time if
86the state may have changed over suspend.
87
88 68
69To create an rfkill driver, driver's Kconfig needs to have
89 70
904. Kernel API 71 depends on RFKILL || !RFKILL
91 72
92To build a driver with rfkill subsystem support, the driver should depend on 73to ensure the driver cannot be built-in when rfkill is modular. The !RFKILL
93(or select) the Kconfig symbol RFKILL. 74case allows the driver to be built when rfkill is not configured, which which
94 75case all rfkill API can still be used but will be provided by static inlines
95The hardware the driver talks to may be write-only (where the current state 76which compile to almost nothing.
96of the hardware is unknown), or read-write (where the hardware can be queried
97about its current state).
98 77
99Calling rfkill_set_hw_state() when a state change happens is required from 78Calling rfkill_set_hw_state() when a state change happens is required from
100rfkill drivers that control devices that can be hard-blocked unless they also 79rfkill drivers that control devices that can be hard-blocked unless they also
@@ -105,10 +84,33 @@ device). Don't do this unless you cannot get the event in any other way.
105 84
1065. Userspace support 855. Userspace support
107 86
108The following sysfs entries exist for every rfkill device: 87The recommended userspace interface to use is /dev/rfkill, which is a misc
88character device that allows userspace to obtain and set the state of rfkill
89devices and sets of devices. It also notifies userspace about device addition
90and removal. The API is a simple read/write API that is defined in
91linux/rfkill.h, with one ioctl that allows turning off the deprecated input
92handler in the kernel for the transition period.
93
94Except for the one ioctl, communication with the kernel is done via read()
95and write() of instances of 'struct rfkill_event'. In this structure, the
96soft and hard block are properly separated (unlike sysfs, see below) and
97userspace is able to get a consistent snapshot of all rfkill devices in the
98system. Also, it is possible to switch all rfkill drivers (or all drivers of
99a specified type) into a state which also updates the default state for
100hotplugged devices.
101
102After an application opens /dev/rfkill, it can read the current state of
103all devices, and afterwards can poll the descriptor for hotplug or state
104change events.
105
106Applications must ignore operations (the "op" field) they do not handle,
107this allows the API to be extended in the future.
108
109Additionally, each rfkill device is registered in sysfs and there has the
110following attributes:
109 111
110 name: Name assigned by driver to this key (interface or driver name). 112 name: Name assigned by driver to this key (interface or driver name).
111 type: Name of the key type ("wlan", "bluetooth", etc). 113 type: Driver type string ("wlan", "bluetooth", etc).
112 state: Current state of the transmitter 114 state: Current state of the transmitter
113 0: RFKILL_STATE_SOFT_BLOCKED 115 0: RFKILL_STATE_SOFT_BLOCKED
114 transmitter is turned off by software 116 transmitter is turned off by software
@@ -117,7 +119,12 @@ The following sysfs entries exist for every rfkill device:
117 2: RFKILL_STATE_HARD_BLOCKED 119 2: RFKILL_STATE_HARD_BLOCKED
118 transmitter is forced off by something outside of 120 transmitter is forced off by something outside of
119 the driver's control. 121 the driver's control.
120 claim: 0: Kernel handles events (currently always reads that value) 122 This file is deprecated because it can only properly show
123 three of the four possible states, soft-and-hard-blocked is
124 missing.
125 claim: 0: Kernel handles events
126 This file is deprecated because there no longer is a way to
127 claim just control over a single rfkill instance.
121 128
122rfkill devices also issue uevents (with an action of "change"), with the 129rfkill devices also issue uevents (with an action of "change"), with the
123following environment variables set: 130following environment variables set:
@@ -128,9 +135,3 @@ RFKILL_TYPE
128 135
129The contents of these variables corresponds to the "name", "state" and 136The contents of these variables corresponds to the "name", "state" and
130"type" sysfs files explained above. 137"type" sysfs files explained above.
131
132An alternative userspace interface exists as a misc device /dev/rfkill,
133which allows userspace to obtain and set the state of rfkill devices and
134sets of devices. It also notifies userspace about device addition and
135removal. The API is a simple read/write API that is defined in
136linux/rfkill.h.
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index ec35503f6a40..2942f13c9c4a 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -733,8 +733,9 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
733 /* 733 /*
734 * Set the beacon register and enable all timers. 734 * Set the beacon register and enable all timers.
735 */ 735 */
736 /* When in AP mode zero timer0 to start TSF */ 736 /* When in AP or Mesh Point mode zero timer0 to start TSF */
737 if (ah->ah_op_mode == NL80211_IFTYPE_AP) 737 if (ah->ah_op_mode == NL80211_IFTYPE_AP ||
738 ah->ah_op_mode == NL80211_IFTYPE_MESH_POINT)
738 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); 739 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
739 740
740 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); 741 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 0ed1ac312aa6..2d79610bce12 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -1,7 +1,6 @@
1config ATH9K 1config ATH9K
2 tristate "Atheros 802.11n wireless cards support" 2 tristate "Atheros 802.11n wireless cards support"
3 depends on PCI && MAC80211 && WLAN_80211 3 depends on PCI && MAC80211 && WLAN_80211
4 depends on RFKILL || RFKILL=n
5 select ATH_COMMON 4 select ATH_COMMON
6 select MAC80211_LEDS 5 select MAC80211_LEDS
7 select LEDS_CLASS 6 select LEDS_CLASS
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 515880aa2116..5efc9345ca0d 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -21,7 +21,6 @@
21#include <linux/device.h> 21#include <linux/device.h>
22#include <net/mac80211.h> 22#include <net/mac80211.h>
23#include <linux/leds.h> 23#include <linux/leds.h>
24#include <linux/rfkill.h>
25 24
26#include "hw.h" 25#include "hw.h"
27#include "rc.h" 26#include "rc.h"
@@ -460,12 +459,6 @@ struct ath_led {
460 bool registered; 459 bool registered;
461}; 460};
462 461
463struct ath_rfkill {
464 struct rfkill *rfkill;
465 struct rfkill_ops ops;
466 char rfkill_name[32];
467};
468
469/********************/ 462/********************/
470/* Main driver core */ 463/* Main driver core */
471/********************/ 464/********************/
@@ -505,7 +498,6 @@ struct ath_rfkill {
505#define SC_OP_PROTECT_ENABLE BIT(6) 498#define SC_OP_PROTECT_ENABLE BIT(6)
506#define SC_OP_RXFLUSH BIT(7) 499#define SC_OP_RXFLUSH BIT(7)
507#define SC_OP_LED_ASSOCIATED BIT(8) 500#define SC_OP_LED_ASSOCIATED BIT(8)
508#define SC_OP_RFKILL_REGISTERED BIT(9)
509#define SC_OP_WAIT_FOR_BEACON BIT(12) 501#define SC_OP_WAIT_FOR_BEACON BIT(12)
510#define SC_OP_LED_ON BIT(13) 502#define SC_OP_LED_ON BIT(13)
511#define SC_OP_SCANNING BIT(14) 503#define SC_OP_SCANNING BIT(14)
@@ -591,7 +583,6 @@ struct ath_softc {
591 583
592 int beacon_interval; 584 int beacon_interval;
593 585
594 struct ath_rfkill rf_kill;
595 struct ath_ani ani; 586 struct ath_ani ani;
596 struct ath9k_node_stats nodestats; 587 struct ath9k_node_stats nodestats;
597#ifdef CONFIG_ATH9K_DEBUG 588#ifdef CONFIG_ATH9K_DEBUG
@@ -677,6 +668,7 @@ static inline void ath9k_ps_restore(struct ath_softc *sc)
677 if (atomic_dec_and_test(&sc->ps_usecount)) 668 if (atomic_dec_and_test(&sc->ps_usecount))
678 if ((sc->hw->conf.flags & IEEE80211_CONF_PS) && 669 if ((sc->hw->conf.flags & IEEE80211_CONF_PS) &&
679 !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | 670 !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
671 SC_OP_WAIT_FOR_CAB |
680 SC_OP_WAIT_FOR_PSPOLL_DATA | 672 SC_OP_WAIT_FOR_PSPOLL_DATA |
681 SC_OP_WAIT_FOR_TX_ACK))) 673 SC_OP_WAIT_FOR_TX_ACK)))
682 ath9k_hw_setpower(sc->sc_ah, 674 ath9k_hw_setpower(sc->sc_ah,
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1579c9407ed5..34935a8ee59d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2186,6 +2186,18 @@ static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan
2186 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); 2186 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
2187} 2187}
2188 2188
2189static void ath9k_enable_rfkill(struct ath_hw *ah)
2190{
2191 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
2192 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
2193
2194 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
2195 AR_GPIO_INPUT_MUX2_RFSILENT);
2196
2197 ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
2198 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
2199}
2200
2189int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, 2201int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2190 bool bChannelChange) 2202 bool bChannelChange)
2191{ 2203{
@@ -2313,10 +2325,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2313 ath9k_hw_init_interrupt_masks(ah, ah->opmode); 2325 ath9k_hw_init_interrupt_masks(ah, ah->opmode);
2314 ath9k_hw_init_qos(ah); 2326 ath9k_hw_init_qos(ah);
2315 2327
2316#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
2317 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 2328 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
2318 ath9k_enable_rfkill(ah); 2329 ath9k_enable_rfkill(ah);
2319#endif 2330
2320 ath9k_hw_init_user_settings(ah); 2331 ath9k_hw_init_user_settings(ah);
2321 2332
2322 REG_WRITE(ah, AR_STA_ID1, 2333 REG_WRITE(ah, AR_STA_ID1,
@@ -3613,20 +3624,6 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
3613 AR_GPIO_BIT(gpio)); 3624 AR_GPIO_BIT(gpio));
3614} 3625}
3615 3626
3616#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
3617void ath9k_enable_rfkill(struct ath_hw *ah)
3618{
3619 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
3620 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
3621
3622 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
3623 AR_GPIO_INPUT_MUX2_RFSILENT);
3624
3625 ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
3626 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
3627}
3628#endif
3629
3630u32 ath9k_hw_getdefantenna(struct ath_hw *ah) 3627u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
3631{ 3628{
3632 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; 3629 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index dd8508ef6e05..9d0b31ad4603 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -565,9 +565,6 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
565void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, 565void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
566 u32 ah_signal_type); 566 u32 ah_signal_type);
567void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); 567void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
568#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
569void ath9k_enable_rfkill(struct ath_hw *ah);
570#endif
571u32 ath9k_hw_getdefantenna(struct ath_hw *ah); 568u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
572void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); 569void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
573bool ath9k_hw_setantennaswitch(struct ath_hw *ah, 570bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index f7baa406918b..9f49a3251d4d 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -231,6 +231,19 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
231 } 231 }
232} 232}
233 233
234static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc,
235 struct ieee80211_hw *hw)
236{
237 struct ieee80211_channel *curchan = hw->conf.channel;
238 struct ath9k_channel *channel;
239 u8 chan_idx;
240
241 chan_idx = curchan->hw_value;
242 channel = &sc->sc_ah->channels[chan_idx];
243 ath9k_update_ichannel(sc, hw, channel);
244 return channel;
245}
246
234/* 247/*
235 * Set/change channels. If the channel is really being changed, it's done 248 * Set/change channels. If the channel is really being changed, it's done
236 * by reseting the chip. To accomplish this we must first cleanup any pending 249 * by reseting the chip. To accomplish this we must first cleanup any pending
@@ -283,7 +296,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
283 "reset status %d\n", 296 "reset status %d\n",
284 channel->center_freq, r); 297 channel->center_freq, r);
285 spin_unlock_bh(&sc->sc_resetlock); 298 spin_unlock_bh(&sc->sc_resetlock);
286 return r; 299 goto ps_restore;
287 } 300 }
288 spin_unlock_bh(&sc->sc_resetlock); 301 spin_unlock_bh(&sc->sc_resetlock);
289 302
@@ -292,14 +305,17 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
292 if (ath_startrecv(sc) != 0) { 305 if (ath_startrecv(sc) != 0) {
293 DPRINTF(sc, ATH_DBG_FATAL, 306 DPRINTF(sc, ATH_DBG_FATAL,
294 "Unable to restart recv logic\n"); 307 "Unable to restart recv logic\n");
295 return -EIO; 308 r = -EIO;
309 goto ps_restore;
296 } 310 }
297 311
298 ath_cache_conf_rate(sc, &hw->conf); 312 ath_cache_conf_rate(sc, &hw->conf);
299 ath_update_txpow(sc); 313 ath_update_txpow(sc);
300 ath9k_hw_set_interrupts(ah, sc->imask); 314 ath9k_hw_set_interrupts(ah, sc->imask);
315
316 ps_restore:
301 ath9k_ps_restore(sc); 317 ath9k_ps_restore(sc);
302 return 0; 318 return r;
303} 319}
304 320
305/* 321/*
@@ -1110,6 +1126,9 @@ void ath_radio_enable(struct ath_softc *sc)
1110 ath9k_ps_wakeup(sc); 1126 ath9k_ps_wakeup(sc);
1111 ath9k_hw_configpcipowersave(ah, 0); 1127 ath9k_hw_configpcipowersave(ah, 0);
1112 1128
1129 if (!ah->curchan)
1130 ah->curchan = ath_get_curchannel(sc, sc->hw);
1131
1113 spin_lock_bh(&sc->sc_resetlock); 1132 spin_lock_bh(&sc->sc_resetlock);
1114 r = ath9k_hw_reset(ah, ah->curchan, false); 1133 r = ath9k_hw_reset(ah, ah->curchan, false);
1115 if (r) { 1134 if (r) {
@@ -1162,6 +1181,9 @@ void ath_radio_disable(struct ath_softc *sc)
1162 ath_stoprecv(sc); /* turn off frame recv */ 1181 ath_stoprecv(sc); /* turn off frame recv */
1163 ath_flushrecv(sc); /* flush recv queue */ 1182 ath_flushrecv(sc); /* flush recv queue */
1164 1183
1184 if (!ah->curchan)
1185 ah->curchan = ath_get_curchannel(sc, sc->hw);
1186
1165 spin_lock_bh(&sc->sc_resetlock); 1187 spin_lock_bh(&sc->sc_resetlock);
1166 r = ath9k_hw_reset(ah, ah->curchan, false); 1188 r = ath9k_hw_reset(ah, ah->curchan, false);
1167 if (r) { 1189 if (r) {
@@ -1178,8 +1200,6 @@ void ath_radio_disable(struct ath_softc *sc)
1178 ath9k_ps_restore(sc); 1200 ath9k_ps_restore(sc);
1179} 1201}
1180 1202
1181#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
1182
1183/*******************/ 1203/*******************/
1184/* Rfkill */ 1204/* Rfkill */
1185/*******************/ 1205/*******************/
@@ -1192,81 +1212,27 @@ static bool ath_is_rfkill_set(struct ath_softc *sc)
1192 ah->rfkill_polarity; 1212 ah->rfkill_polarity;
1193} 1213}
1194 1214
1195/* s/w rfkill handlers */ 1215static void ath9k_rfkill_poll_state(struct ieee80211_hw *hw)
1196static int ath_rfkill_set_block(void *data, bool blocked)
1197{ 1216{
1198 struct ath_softc *sc = data; 1217 struct ath_wiphy *aphy = hw->priv;
1199 1218 struct ath_softc *sc = aphy->sc;
1200 if (blocked)
1201 ath_radio_disable(sc);
1202 else
1203 ath_radio_enable(sc);
1204
1205 return 0;
1206}
1207
1208static void ath_rfkill_poll_state(struct rfkill *rfkill, void *data)
1209{
1210 struct ath_softc *sc = data;
1211 bool blocked = !!ath_is_rfkill_set(sc); 1219 bool blocked = !!ath_is_rfkill_set(sc);
1212 1220
1213 if (rfkill_set_hw_state(rfkill, blocked)) 1221 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1222
1223 if (blocked)
1214 ath_radio_disable(sc); 1224 ath_radio_disable(sc);
1215 else 1225 else
1216 ath_radio_enable(sc); 1226 ath_radio_enable(sc);
1217} 1227}
1218 1228
1219/* Init s/w rfkill */ 1229static void ath_start_rfkill_poll(struct ath_softc *sc)
1220static int ath_init_sw_rfkill(struct ath_softc *sc)
1221{
1222 sc->rf_kill.ops.set_block = ath_rfkill_set_block;
1223 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1224 sc->rf_kill.ops.poll = ath_rfkill_poll_state;
1225
1226 snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
1227 "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy));
1228
1229 sc->rf_kill.rfkill = rfkill_alloc(sc->rf_kill.rfkill_name,
1230 wiphy_dev(sc->hw->wiphy),
1231 RFKILL_TYPE_WLAN,
1232 &sc->rf_kill.ops, sc);
1233 if (!sc->rf_kill.rfkill) {
1234 DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n");
1235 return -ENOMEM;
1236 }
1237
1238 return 0;
1239}
1240
1241/* Deinitialize rfkill */
1242static void ath_deinit_rfkill(struct ath_softc *sc)
1243{
1244 if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {
1245 rfkill_unregister(sc->rf_kill.rfkill);
1246 rfkill_destroy(sc->rf_kill.rfkill);
1247 sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED;
1248 }
1249}
1250
1251static int ath_start_rfkill_poll(struct ath_softc *sc)
1252{ 1230{
1253 if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) { 1231 struct ath_hw *ah = sc->sc_ah;
1254 if (rfkill_register(sc->rf_kill.rfkill)) {
1255 DPRINTF(sc, ATH_DBG_FATAL,
1256 "Unable to register rfkill\n");
1257 rfkill_destroy(sc->rf_kill.rfkill);
1258
1259 /* Deinitialize the device */
1260 ath_cleanup(sc);
1261 return -EIO;
1262 } else {
1263 sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
1264 }
1265 }
1266 1232
1267 return 0; 1233 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1234 wiphy_rfkill_start_polling(sc->hw->wiphy);
1268} 1235}
1269#endif /* CONFIG_RFKILL */
1270 1236
1271void ath_cleanup(struct ath_softc *sc) 1237void ath_cleanup(struct ath_softc *sc)
1272{ 1238{
@@ -1286,9 +1252,6 @@ void ath_detach(struct ath_softc *sc)
1286 1252
1287 DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); 1253 DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
1288 1254
1289#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
1290 ath_deinit_rfkill(sc);
1291#endif
1292 ath_deinit_leds(sc); 1255 ath_deinit_leds(sc);
1293 cancel_work_sync(&sc->chan_work); 1256 cancel_work_sync(&sc->chan_work);
1294 cancel_delayed_work_sync(&sc->wiphy_work); 1257 cancel_delayed_work_sync(&sc->wiphy_work);
@@ -1626,13 +1589,6 @@ int ath_attach(u16 devid, struct ath_softc *sc)
1626 if (error != 0) 1589 if (error != 0)
1627 goto error_attach; 1590 goto error_attach;
1628 1591
1629#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
1630 /* Initialize s/w rfkill */
1631 error = ath_init_sw_rfkill(sc);
1632 if (error)
1633 goto error_attach;
1634#endif
1635
1636 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); 1592 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
1637 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); 1593 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
1638 sc->wiphy_scheduler_int = msecs_to_jiffies(500); 1594 sc->wiphy_scheduler_int = msecs_to_jiffies(500);
@@ -1648,6 +1604,7 @@ int ath_attach(u16 devid, struct ath_softc *sc)
1648 /* Initialize LED control */ 1604 /* Initialize LED control */
1649 ath_init_leds(sc); 1605 ath_init_leds(sc);
1650 1606
1607 ath_start_rfkill_poll(sc);
1651 1608
1652 return 0; 1609 return 0;
1653 1610
@@ -1920,7 +1877,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
1920 struct ath_softc *sc = aphy->sc; 1877 struct ath_softc *sc = aphy->sc;
1921 struct ieee80211_channel *curchan = hw->conf.channel; 1878 struct ieee80211_channel *curchan = hw->conf.channel;
1922 struct ath9k_channel *init_channel; 1879 struct ath9k_channel *init_channel;
1923 int r, pos; 1880 int r;
1924 1881
1925 DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " 1882 DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
1926 "initial channel: %d MHz\n", curchan->center_freq); 1883 "initial channel: %d MHz\n", curchan->center_freq);
@@ -1950,11 +1907,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
1950 1907
1951 /* setup initial channel */ 1908 /* setup initial channel */
1952 1909
1953 pos = curchan->hw_value; 1910 sc->chan_idx = curchan->hw_value;
1954 1911
1955 sc->chan_idx = pos; 1912 init_channel = ath_get_curchannel(sc, hw);
1956 init_channel = &sc->sc_ah->channels[pos];
1957 ath9k_update_ichannel(sc, hw, init_channel);
1958 1913
1959 /* Reset SERDES registers */ 1914 /* Reset SERDES registers */
1960 ath9k_hw_configpcipowersave(sc->sc_ah, 0); 1915 ath9k_hw_configpcipowersave(sc->sc_ah, 0);
@@ -2018,10 +1973,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
2018 1973
2019 ieee80211_wake_queues(hw); 1974 ieee80211_wake_queues(hw);
2020 1975
2021#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
2022 r = ath_start_rfkill_poll(sc);
2023#endif
2024
2025mutex_unlock: 1976mutex_unlock:
2026 mutex_unlock(&sc->mutex); 1977 mutex_unlock(&sc->mutex);
2027 1978
@@ -2159,7 +2110,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2159 } else 2110 } else
2160 sc->rx.rxlink = NULL; 2111 sc->rx.rxlink = NULL;
2161 2112
2162 rfkill_pause_polling(sc->rf_kill.rfkill); 2113 wiphy_rfkill_stop_polling(sc->hw->wiphy);
2163 2114
2164 /* disable HAL and put h/w to sleep */ 2115 /* disable HAL and put h/w to sleep */
2165 ath9k_hw_disable(sc->sc_ah); 2116 ath9k_hw_disable(sc->sc_ah);
@@ -2765,6 +2716,7 @@ struct ieee80211_ops ath9k_ops = {
2765 .ampdu_action = ath9k_ampdu_action, 2716 .ampdu_action = ath9k_ampdu_action,
2766 .sw_scan_start = ath9k_sw_scan_start, 2717 .sw_scan_start = ath9k_sw_scan_start,
2767 .sw_scan_complete = ath9k_sw_scan_complete, 2718 .sw_scan_complete = ath9k_sw_scan_complete,
2719 .rfkill_poll = ath9k_rfkill_poll_state,
2768}; 2720};
2769 2721
2770static struct { 2722static struct {
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 5014a19b0f75..f99f3a76df3f 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -817,6 +817,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
817 } 817 }
818 818
819 if (unlikely(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | 819 if (unlikely(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
820 SC_OP_WAIT_FOR_CAB |
820 SC_OP_WAIT_FOR_PSPOLL_DATA))) 821 SC_OP_WAIT_FOR_PSPOLL_DATA)))
821 ath_rx_ps(sc, skb); 822 ath_rx_ps(sc, skb);
822 823
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index a5637c4aa85d..6d1519e1f011 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2152,7 +2152,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
2152 /* we should be verifying the device is ready to be opened */ 2152 /* we should be verifying the device is ready to be opened */
2153 mutex_lock(&priv->mutex); 2153 mutex_lock(&priv->mutex);
2154 2154
2155 memset(&priv->staging_rxon, 0, sizeof(struct iwl_rxon_cmd));
2156 /* fetch ucode file from disk, alloc and copy to bus-master buffers ... 2155 /* fetch ucode file from disk, alloc and copy to bus-master buffers ...
2157 * ucode filename and max sizes are card-specific. */ 2156 * ucode filename and max sizes are card-specific. */
2158 2157
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index f9d16ca5b3d9..6ab07165ea28 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -629,13 +629,9 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
629 if (!sta_ht_inf->ht_supported) 629 if (!sta_ht_inf->ht_supported)
630 return 0; 630 return 0;
631 } 631 }
632 632 return iwl_is_channel_extension(priv, priv->band,
633 if (iwl_ht_conf->ht_protection & IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) 633 le16_to_cpu(priv->staging_rxon.channel),
634 return 1; 634 iwl_ht_conf->extension_chan_offset);
635 else
636 return iwl_is_channel_extension(priv, priv->band,
637 le16_to_cpu(priv->staging_rxon.channel),
638 iwl_ht_conf->extension_chan_offset);
639} 635}
640EXPORT_SYMBOL(iwl_is_fat_tx_allowed); 636EXPORT_SYMBOL(iwl_is_fat_tx_allowed);
641 637
@@ -826,9 +822,18 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
826 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); 822 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
827 if (iwl_is_fat_tx_allowed(priv, NULL)) { 823 if (iwl_is_fat_tx_allowed(priv, NULL)) {
828 /* pure 40 fat */ 824 /* pure 40 fat */
829 if (rxon->flags & RXON_FLG_FAT_PROT_MSK) 825 if (ht_info->ht_protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
830 rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; 826 rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
831 else { 827 /* Note: control channel is opposite of extension channel */
828 switch (ht_info->extension_chan_offset) {
829 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
830 rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
831 break;
832 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
833 rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
834 break;
835 }
836 } else {
832 /* Note: control channel is opposite of extension channel */ 837 /* Note: control channel is opposite of extension channel */
833 switch (ht_info->extension_chan_offset) { 838 switch (ht_info->extension_chan_offset) {
834 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: 839 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
@@ -2390,39 +2395,46 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2390 priv->ibss_beacon = ieee80211_beacon_get(hw, vif); 2395 priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
2391 } 2396 }
2392 2397
2393 if ((changes & BSS_CHANGED_BSSID) && !iwl_is_rfkill(priv)) { 2398 if (changes & BSS_CHANGED_BEACON_INT) {
2394 /* If there is currently a HW scan going on in the background 2399 priv->beacon_int = bss_conf->beacon_int;
2395 * then we need to cancel it else the RXON below will fail. */ 2400 /* TODO: in AP mode, do something to make this take effect */
2401 }
2402
2403 if (changes & BSS_CHANGED_BSSID) {
2404 IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid);
2405
2406 /*
2407 * If there is currently a HW scan going on in the
2408 * background then we need to cancel it else the RXON
2409 * below/in post_associate will fail.
2410 */
2396 if (iwl_scan_cancel_timeout(priv, 100)) { 2411 if (iwl_scan_cancel_timeout(priv, 100)) {
2397 IWL_WARN(priv, "Aborted scan still in progress " 2412 IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
2398 "after 100ms\n");
2399 IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); 2413 IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
2400 mutex_unlock(&priv->mutex); 2414 mutex_unlock(&priv->mutex);
2401 return; 2415 return;
2402 } 2416 }
2403 memcpy(priv->staging_rxon.bssid_addr, 2417
2404 bss_conf->bssid, ETH_ALEN); 2418 /* mac80211 only sets assoc when in STATION mode */
2405 2419 if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
2406 /* TODO: Audit driver for usage of these members and see 2420 bss_conf->assoc) {
2407 * if mac80211 deprecates them (priv->bssid looks like it 2421 memcpy(priv->staging_rxon.bssid_addr,
2408 * shouldn't be there, but I haven't scanned the IBSS code 2422 bss_conf->bssid, ETH_ALEN);
2409 * to verify) - jpk */ 2423
2410 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); 2424 /* currently needed in a few places */
2411 2425 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
2412 if (priv->iw_mode == NL80211_IFTYPE_AP) 2426 } else {
2413 iwlcore_config_ap(priv); 2427 priv->staging_rxon.filter_flags &=
2414 else { 2428 ~RXON_FILTER_ASSOC_MSK;
2415 int rc = iwlcore_commit_rxon(priv);
2416 if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
2417 iwl_rxon_add_station(
2418 priv, priv->active_rxon.bssid_addr, 1);
2419 } 2429 }
2420 } else if (!iwl_is_rfkill(priv)) { 2430
2421 iwl_scan_cancel_timeout(priv, 100);
2422 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2423 iwlcore_commit_rxon(priv);
2424 } 2431 }
2425 2432
2433 /*
2434 * This needs to be after setting the BSSID in case
2435 * mac80211 decides to do both changes at once because
2436 * it will invoke post_associate.
2437 */
2426 if (priv->iw_mode == NL80211_IFTYPE_ADHOC && 2438 if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
2427 changes & BSS_CHANGED_BEACON) { 2439 changes & BSS_CHANGED_BEACON) {
2428 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); 2440 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
@@ -2431,8 +2443,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2431 iwl_mac_beacon_update(hw, beacon); 2443 iwl_mac_beacon_update(hw, beacon);
2432 } 2444 }
2433 2445
2434 mutex_unlock(&priv->mutex);
2435
2436 if (changes & BSS_CHANGED_ERP_PREAMBLE) { 2446 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
2437 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", 2447 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
2438 bss_conf->use_short_preamble); 2448 bss_conf->use_short_preamble);
@@ -2450,6 +2460,23 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2450 priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; 2460 priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
2451 } 2461 }
2452 2462
2463 if (changes & BSS_CHANGED_BASIC_RATES) {
2464 /* XXX use this information
2465 *
2466 * To do that, remove code from iwl_set_rate() and put something
2467 * like this here:
2468 *
2469 if (A-band)
2470 priv->staging_rxon.ofdm_basic_rates =
2471 bss_conf->basic_rates;
2472 else
2473 priv->staging_rxon.ofdm_basic_rates =
2474 bss_conf->basic_rates >> 4;
2475 priv->staging_rxon.cck_basic_rates =
2476 bss_conf->basic_rates & 0xF;
2477 */
2478 }
2479
2453 if (changes & BSS_CHANGED_HT) { 2480 if (changes & BSS_CHANGED_HT) {
2454 iwl_ht_conf(priv, bss_conf); 2481 iwl_ht_conf(priv, bss_conf);
2455 2482
@@ -2459,10 +2486,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2459 2486
2460 if (changes & BSS_CHANGED_ASSOC) { 2487 if (changes & BSS_CHANGED_ASSOC) {
2461 IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); 2488 IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
2462 /* This should never happen as this function should
2463 * never be called from interrupt context. */
2464 if (WARN_ON_ONCE(in_interrupt()))
2465 return;
2466 if (bss_conf->assoc) { 2489 if (bss_conf->assoc) {
2467 priv->assoc_id = bss_conf->aid; 2490 priv->assoc_id = bss_conf->aid;
2468 priv->beacon_int = bss_conf->beacon_int; 2491 priv->beacon_int = bss_conf->beacon_int;
@@ -2470,27 +2493,35 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2470 priv->timestamp = bss_conf->timestamp; 2493 priv->timestamp = bss_conf->timestamp;
2471 priv->assoc_capability = bss_conf->assoc_capability; 2494 priv->assoc_capability = bss_conf->assoc_capability;
2472 2495
2473 /* we have just associated, don't start scan too early 2496 /*
2474 * leave time for EAPOL exchange to complete 2497 * We have just associated, don't start scan too early
2498 * leave time for EAPOL exchange to complete.
2499 *
2500 * XXX: do this in mac80211
2475 */ 2501 */
2476 priv->next_scan_jiffies = jiffies + 2502 priv->next_scan_jiffies = jiffies +
2477 IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; 2503 IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
2478 mutex_lock(&priv->mutex); 2504 if (!iwl_is_rfkill(priv))
2479 priv->cfg->ops->lib->post_associate(priv); 2505 priv->cfg->ops->lib->post_associate(priv);
2480 mutex_unlock(&priv->mutex); 2506 } else
2481 } else {
2482 priv->assoc_id = 0; 2507 priv->assoc_id = 0;
2483 IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc); 2508
2509 }
2510
2511 if (changes && iwl_is_associated(priv) && priv->assoc_id) {
2512 IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
2513 changes);
2514 ret = iwl_send_rxon_assoc(priv);
2515 if (!ret) {
2516 /* Sync active_rxon with latest change. */
2517 memcpy((void *)&priv->active_rxon,
2518 &priv->staging_rxon,
2519 sizeof(struct iwl_rxon_cmd));
2484 } 2520 }
2485 } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
2486 IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes);
2487 ret = iwl_send_rxon_assoc(priv);
2488 if (!ret)
2489 /* Sync active_rxon with latest change. */
2490 memcpy((void *)&priv->active_rxon,
2491 &priv->staging_rxon,
2492 sizeof(struct iwl_rxon_cmd));
2493 } 2521 }
2522
2523 mutex_unlock(&priv->mutex);
2524
2494 IWL_DEBUG_MAC80211(priv, "leave\n"); 2525 IWL_DEBUG_MAC80211(priv, "leave\n");
2495} 2526}
2496EXPORT_SYMBOL(iwl_bss_info_changed); 2527EXPORT_SYMBOL(iwl_bss_info_changed);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 83d31606dd00..cb9bd4c8f25e 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2498,8 +2498,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2498 struct iwl3945_rxon_cmd *active_rxon = 2498 struct iwl3945_rxon_cmd *active_rxon =
2499 (struct iwl3945_rxon_cmd *)(&priv->active_rxon); 2499 (struct iwl3945_rxon_cmd *)(&priv->active_rxon);
2500 2500
2501 memcpy(&priv->staging_rxon, &priv->active_rxon, 2501 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
2502 sizeof(priv->staging_rxon));
2503 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2502 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2504 } else { 2503 } else {
2505 /* Initialize our rx_config data */ 2504 /* Initialize our rx_config data */
@@ -3147,7 +3146,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
3147 /* we should be verifying the device is ready to be opened */ 3146 /* we should be verifying the device is ready to be opened */
3148 mutex_lock(&priv->mutex); 3147 mutex_lock(&priv->mutex);
3149 3148
3150 memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
3151 /* fetch ucode file from disk, alloc and copy to bus-master buffers ... 3149 /* fetch ucode file from disk, alloc and copy to bus-master buffers ...
3152 * ucode filename and max sizes are card-specific. */ 3150 * ucode filename and max sizes are card-specific. */
3153 3151
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index f8c2898d82b0..923ed58d58e7 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -812,7 +812,6 @@ out:
812static void if_spi_e2h(struct if_spi_card *card) 812static void if_spi_e2h(struct if_spi_card *card)
813{ 813{
814 int err = 0; 814 int err = 0;
815 unsigned long flags;
816 u32 cause; 815 u32 cause;
817 struct lbs_private *priv = card->priv; 816 struct lbs_private *priv = card->priv;
818 817
@@ -827,10 +826,7 @@ static void if_spi_e2h(struct if_spi_card *card)
827 /* generate a card interrupt */ 826 /* generate a card interrupt */
828 spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, IF_SPI_CIC_HOST_EVENT); 827 spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, IF_SPI_CIC_HOST_EVENT);
829 828
830 spin_lock_irqsave(&priv->driver_lock, flags);
831 lbs_queue_event(priv, cause & 0xff); 829 lbs_queue_event(priv, cause & 0xff);
832 spin_unlock_irqrestore(&priv->driver_lock, flags);
833
834out: 830out:
835 if (err) 831 if (err)
836 lbs_pr_err("%s: error %d\n", __func__, err); 832 lbs_pr_err("%s: error %d\n", __func__, err);
@@ -875,7 +871,12 @@ static int lbs_spi_thread(void *data)
875 err = if_spi_c2h_data(card); 871 err = if_spi_c2h_data(card);
876 if (err) 872 if (err)
877 goto err; 873 goto err;
878 if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY) { 874
875 /* workaround: in PS mode, the card does not set the Command
876 * Download Ready bit, but it sets TX Download Ready. */
877 if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY ||
878 (card->priv->psstate != PS_STATE_FULL_POWER &&
879 (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) {
879 /* This means two things. First of all, 880 /* This means two things. First of all,
880 * if there was a previous command sent, the card has 881 * if there was a previous command sent, the card has
881 * successfully received it. 882 * successfully received it.
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 2faf0e14f05a..74909c4aaeea 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -177,7 +177,7 @@ dell_send_request(struct calling_interface_buffer *buffer, int class,
177static int dell_rfkill_set(void *data, bool blocked) 177static int dell_rfkill_set(void *data, bool blocked)
178{ 178{
179 struct calling_interface_buffer buffer; 179 struct calling_interface_buffer buffer;
180 int disable = blocked ? 0 : 1; 180 int disable = blocked ? 1 : 0;
181 unsigned long radio = (unsigned long)data; 181 unsigned long radio = (unsigned long)data;
182 182
183 memset(&buffer, 0, sizeof(struct calling_interface_buffer)); 183 memset(&buffer, 0, sizeof(struct calling_interface_buffer));
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index e48d9a4506ff..dafaa4a92df5 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1133,8 +1133,9 @@ static void sony_nc_rfkill_update()
1133 continue; 1133 continue;
1134 1134
1135 if (hwblock) { 1135 if (hwblock) {
1136 if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) 1136 if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) {
1137 sony_nc_rfkill_set((void *)i, true); 1137 /* we already know we're blocked */
1138 }
1138 continue; 1139 continue;
1139 } 1140 }
1140 1141
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 11c72311f35b..6c439cd5ccea 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -163,6 +163,29 @@ static const struct file_operations noack_ops = {
163 .open = mac80211_open_file_generic 163 .open = mac80211_open_file_generic
164}; 164};
165 165
166static ssize_t queues_read(struct file *file, char __user *user_buf,
167 size_t count, loff_t *ppos)
168{
169 struct ieee80211_local *local = file->private_data;
170 unsigned long flags;
171 char buf[IEEE80211_MAX_QUEUES * 20];
172 int q, res = 0;
173
174 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
175 for (q = 0; q < local->hw.queues; q++)
176 res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q,
177 local->queue_stop_reasons[q],
178 __netif_subqueue_stopped(local->mdev, q));
179 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
180
181 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
182}
183
184static const struct file_operations queues_ops = {
185 .read = queues_read,
186 .open = mac80211_open_file_generic
187};
188
166/* statistics stuff */ 189/* statistics stuff */
167 190
168#define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \ 191#define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \
@@ -298,6 +321,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
298 DEBUGFS_ADD(total_ps_buffered); 321 DEBUGFS_ADD(total_ps_buffered);
299 DEBUGFS_ADD(wep_iv); 322 DEBUGFS_ADD(wep_iv);
300 DEBUGFS_ADD(tsf); 323 DEBUGFS_ADD(tsf);
324 DEBUGFS_ADD(queues);
301 DEBUGFS_ADD_MODE(reset, 0200); 325 DEBUGFS_ADD_MODE(reset, 0200);
302 DEBUGFS_ADD(noack); 326 DEBUGFS_ADD(noack);
303 327
@@ -350,6 +374,7 @@ void debugfs_hw_del(struct ieee80211_local *local)
350 DEBUGFS_DEL(total_ps_buffered); 374 DEBUGFS_DEL(total_ps_buffered);
351 DEBUGFS_DEL(wep_iv); 375 DEBUGFS_DEL(wep_iv);
352 DEBUGFS_DEL(tsf); 376 DEBUGFS_DEL(tsf);
377 DEBUGFS_DEL(queues);
353 DEBUGFS_DEL(reset); 378 DEBUGFS_DEL(reset);
354 DEBUGFS_DEL(noack); 379 DEBUGFS_DEL(noack);
355 380
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4dbc28964196..68eb5052179a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -783,6 +783,7 @@ struct ieee80211_local {
783 struct dentry *total_ps_buffered; 783 struct dentry *total_ps_buffered;
784 struct dentry *wep_iv; 784 struct dentry *wep_iv;
785 struct dentry *tsf; 785 struct dentry *tsf;
786 struct dentry *queues;
786 struct dentry *reset; 787 struct dentry *reset;
787 struct dentry *noack; 788 struct dentry *noack;
788 struct dentry *statistics; 789 struct dentry *statistics;
@@ -1100,7 +1101,6 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
1100u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, 1101u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
1101 struct ieee802_11_elems *elems, 1102 struct ieee802_11_elems *elems,
1102 u64 filter, u32 crc); 1103 u64 filter, u32 crc);
1103int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq);
1104u32 ieee80211_mandatory_rates(struct ieee80211_local *local, 1104u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
1105 enum ieee80211_band band); 1105 enum ieee80211_band band);
1106 1106
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d779c57a8220..aca22b00b6a3 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1102,14 +1102,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1102 struct sta_info *sta; 1102 struct sta_info *sta;
1103 u32 changed = 0, config_changed = 0; 1103 u32 changed = 0, config_changed = 0;
1104 1104
1105 rcu_read_lock();
1106
1107 sta = sta_info_get(local, ifmgd->bssid);
1108 if (!sta) {
1109 rcu_read_unlock();
1110 return;
1111 }
1112
1113 if (deauth) { 1105 if (deauth) {
1114 ifmgd->direct_probe_tries = 0; 1106 ifmgd->direct_probe_tries = 0;
1115 ifmgd->auth_tries = 0; 1107 ifmgd->auth_tries = 0;
@@ -1120,7 +1112,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1120 netif_tx_stop_all_queues(sdata->dev); 1112 netif_tx_stop_all_queues(sdata->dev);
1121 netif_carrier_off(sdata->dev); 1113 netif_carrier_off(sdata->dev);
1122 1114
1123 ieee80211_sta_tear_down_BA_sessions(sta); 1115 rcu_read_lock();
1116 sta = sta_info_get(local, ifmgd->bssid);
1117 if (sta)
1118 ieee80211_sta_tear_down_BA_sessions(sta);
1119 rcu_read_unlock();
1124 1120
1125 bss = ieee80211_rx_bss_get(local, ifmgd->bssid, 1121 bss = ieee80211_rx_bss_get(local, ifmgd->bssid,
1126 conf->channel->center_freq, 1122 conf->channel->center_freq,
@@ -1156,8 +1152,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1156 ifmgd->ssid, ifmgd->ssid_len); 1152 ifmgd->ssid, ifmgd->ssid_len);
1157 } 1153 }
1158 1154
1159 rcu_read_unlock();
1160
1161 ieee80211_set_wmm_default(sdata); 1155 ieee80211_set_wmm_default(sdata);
1162 1156
1163 ieee80211_recalc_idle(local); 1157 ieee80211_recalc_idle(local);
@@ -2223,7 +2217,10 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata)
2223 capa_mask, capa_val); 2217 capa_mask, capa_val);
2224 2218
2225 if (bss) { 2219 if (bss) {
2226 ieee80211_set_freq(sdata, bss->cbss.channel->center_freq); 2220 local->oper_channel = bss->cbss.channel;
2221 local->oper_channel_type = NL80211_CHAN_NO_HT;
2222 ieee80211_hw_config(local, 0);
2223
2227 if (!(ifmgd->flags & IEEE80211_STA_SSID_SET)) 2224 if (!(ifmgd->flags & IEEE80211_STA_SSID_SET))
2228 ieee80211_sta_set_ssid(sdata, bss->ssid, 2225 ieee80211_sta_set_ssid(sdata, bss->ssid,
2229 bss->ssid_len); 2226 bss->ssid_len);
@@ -2445,6 +2442,14 @@ void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata)
2445 ieee80211_set_disassoc(sdata, true, true, 2442 ieee80211_set_disassoc(sdata, true, true,
2446 WLAN_REASON_DEAUTH_LEAVING); 2443 WLAN_REASON_DEAUTH_LEAVING);
2447 2444
2445 if (ifmgd->ssid_len == 0) {
2446 /*
2447 * Only allow association to be started if a valid SSID
2448 * is configured.
2449 */
2450 return;
2451 }
2452
2448 if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) || 2453 if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) ||
2449 ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE) 2454 ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE)
2450 set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request); 2455 set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request);
@@ -2476,6 +2481,10 @@ int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size
2476 ifmgd = &sdata->u.mgd; 2481 ifmgd = &sdata->u.mgd;
2477 2482
2478 if (ifmgd->ssid_len != len || memcmp(ifmgd->ssid, ssid, len) != 0) { 2483 if (ifmgd->ssid_len != len || memcmp(ifmgd->ssid, ssid, len) != 0) {
2484 if (ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)
2485 ieee80211_set_disassoc(sdata, true, true,
2486 WLAN_REASON_DEAUTH_LEAVING);
2487
2479 /* 2488 /*
2480 * Do not use reassociation if SSID is changed (different ESS). 2489 * Do not use reassociation if SSID is changed (different ESS).
2481 */ 2490 */
@@ -2500,6 +2509,11 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
2500{ 2509{
2501 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2510 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2502 2511
2512 if (compare_ether_addr(bssid, ifmgd->bssid) != 0 &&
2513 ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)
2514 ieee80211_set_disassoc(sdata, true, true,
2515 WLAN_REASON_DEAUTH_LEAVING);
2516
2503 if (is_valid_ether_addr(bssid)) { 2517 if (is_valid_ether_addr(bssid)) {
2504 memcpy(ifmgd->bssid, bssid, ETH_ALEN); 2518 memcpy(ifmgd->bssid, bssid, ETH_ALEN);
2505 ifmgd->flags |= IEEE80211_STA_BSSID_SET; 2519 ifmgd->flags |= IEEE80211_STA_BSSID_SET;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 66ce96a69f31..915e77769312 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -774,31 +774,6 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
774 dev_queue_xmit(skb); 774 dev_queue_xmit(skb);
775} 775}
776 776
777int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz)
778{
779 int ret = -EINVAL;
780 struct ieee80211_channel *chan;
781 struct ieee80211_local *local = sdata->local;
782
783 chan = ieee80211_get_channel(local->hw.wiphy, freqMHz);
784
785 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
786 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
787 chan->flags & IEEE80211_CHAN_NO_IBSS)
788 return ret;
789 local->oper_channel = chan;
790 local->oper_channel_type = NL80211_CHAN_NO_HT;
791
792 if (local->sw_scanning || local->hw_scanning)
793 ret = 0;
794 else
795 ret = ieee80211_hw_config(
796 local, IEEE80211_CONF_CHANGE_CHANNEL);
797 }
798
799 return ret;
800}
801
802u32 ieee80211_mandatory_rates(struct ieee80211_local *local, 777u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
803 enum ieee80211_band band) 778 enum ieee80211_band band)
804{ 779{
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index d2d81b103341..1da81f456744 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -55,6 +55,8 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
55 struct iw_freq *freq, char *extra) 55 struct iw_freq *freq, char *extra)
56{ 56{
57 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 57 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
58 struct ieee80211_local *local = sdata->local;
59 struct ieee80211_channel *chan;
58 60
59 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 61 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
60 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); 62 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
@@ -69,17 +71,38 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
69 IEEE80211_STA_AUTO_CHANNEL_SEL; 71 IEEE80211_STA_AUTO_CHANNEL_SEL;
70 return 0; 72 return 0;
71 } else 73 } else
72 return ieee80211_set_freq(sdata, 74 chan = ieee80211_get_channel(local->hw.wiphy,
73 ieee80211_channel_to_frequency(freq->m)); 75 ieee80211_channel_to_frequency(freq->m));
74 } else { 76 } else {
75 int i, div = 1000000; 77 int i, div = 1000000;
76 for (i = 0; i < freq->e; i++) 78 for (i = 0; i < freq->e; i++)
77 div /= 10; 79 div /= 10;
78 if (div > 0) 80 if (div <= 0)
79 return ieee80211_set_freq(sdata, freq->m / div);
80 else
81 return -EINVAL; 81 return -EINVAL;
82 chan = ieee80211_get_channel(local->hw.wiphy, freq->m / div);
82 } 83 }
84
85 if (!chan)
86 return -EINVAL;
87
88 if (chan->flags & IEEE80211_CHAN_DISABLED)
89 return -EINVAL;
90
91 /*
92 * no change except maybe auto -> fixed, ignore the HT
93 * setting so you can fix a channel you're on already
94 */
95 if (local->oper_channel == chan)
96 return 0;
97
98 if (sdata->vif.type == NL80211_IFTYPE_STATION)
99 ieee80211_sta_req_auth(sdata);
100
101 local->oper_channel = chan;
102 local->oper_channel_type = NL80211_CHAN_NO_HT;
103 ieee80211_hw_config(local, 0);
104
105 return 0;
83} 106}
84 107
85 108