aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-06-07 07:24:21 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-07 07:24:21 -0400
commitb1bc81a0ef86b86fa410dd303d84c8c7bd09a64d (patch)
treea0d2e6dd179e5d057776edd0ed865bc744dfa54d
parenta93958ac980f0ce594ad90657ecbc595ff157a40 (diff)
parent0c0c9e7076b69f93678e4ec711e2bf237398e623 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
-rw-r--r--Documentation/feature-removal-schedule.txt7
-rw-r--r--Documentation/rfkill.txt603
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/arm/mach-pxa/tosa-bt.c30
-rw-r--r--arch/arm/mach-pxa/tosa.c1
-rw-r--r--drivers/net/usb/hso.c42
-rw-r--r--drivers/net/wireless/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h10
-rw-r--r--drivers/net/wireless/ath/ar9170/hw.h5
-rw-r--r--drivers/net/wireless/ath/ar9170/led.c17
-rw-r--r--drivers/net/wireless/ath/ar9170/mac.c55
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c98
-rw-r--r--drivers/net/wireless/ath/ar9170/phy.c6
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c69
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c24
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c155
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c115
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c15
-rw-r--r--drivers/net/wireless/ath/regd.c29
-rw-r--r--drivers/net/wireless/b43/Kconfig2
-rw-r--r--drivers/net/wireless/b43/leds.c2
-rw-r--r--drivers/net/wireless/b43/main.c4
-rw-r--r--drivers/net/wireless/b43/phy_a.c4
-rw-r--r--drivers/net/wireless/b43/phy_common.c17
-rw-r--r--drivers/net/wireless/b43/phy_common.h4
-rw-r--r--drivers/net/wireless/b43/phy_g.c4
-rw-r--r--drivers/net/wireless/b43/phy_lp.c2
-rw-r--r--drivers/net/wireless/b43/phy_n.c2
-rw-r--r--drivers/net/wireless/b43/rfkill.c123
-rw-r--r--drivers/net/wireless/b43/rfkill.h5
-rw-r--r--drivers/net/wireless/b43legacy/Kconfig2
-rw-r--r--drivers/net/wireless/b43legacy/leds.c3
-rw-r--r--drivers/net/wireless/b43legacy/rfkill.c123
-rw-r--r--drivers/net/wireless/b43legacy/rfkill.h6
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c73
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c56
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c228
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Kconfig3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Makefile2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/fw.c2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h4
-rw-r--r--drivers/net/wireless/iwmc3200wifi/netdev.c10
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rfkill.c88
-rw-r--r--drivers/net/wireless/iwmc3200wifi/sdio.c2
-rw-r--r--drivers/net/wireless/libertas/11d.c26
-rw-r--r--drivers/net/wireless/libertas/11d.h29
-rw-r--r--drivers/net/wireless/libertas/assoc.c758
-rw-r--r--drivers/net/wireless/libertas/assoc.h13
-rw-r--r--drivers/net/wireless/libertas/cmd.c16
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c17
-rw-r--r--drivers/net/wireless/libertas/debugfs.c8
-rw-r--r--drivers/net/wireless/libertas/dev.h10
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h41
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c76
-rw-r--r--drivers/net/wireless/libertas/if_spi.c34
-rw-r--r--drivers/net/wireless/libertas/main.c20
-rw-r--r--drivers/net/wireless/libertas/scan.c63
-rw-r--r--drivers/net/wireless/libertas/types.h150
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c27
-rw-r--r--drivers/net/wireless/p54/p54usb.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
-rw-r--r--drivers/platform/x86/Kconfig14
-rw-r--r--drivers/platform/x86/acer-wmi.c50
-rw-r--r--drivers/platform/x86/dell-laptop.c101
-rw-r--r--drivers/platform/x86/eeepc-laptop.c99
-rw-r--r--drivers/platform/x86/hp-wmi.c103
-rw-r--r--drivers/platform/x86/sony-laptop.c191
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c873
-rw-r--r--drivers/platform/x86/toshiba_acpi.c159
-rw-r--r--include/asm-generic/errno.h2
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/ieee80211.h1
-rw-r--r--include/linux/notifier.h1
-rw-r--r--include/linux/rfkill.h381
-rw-r--r--include/net/cfg80211.h51
-rw-r--r--include/net/mac80211.h26
-rw-r--r--include/net/wimax.h8
-rw-r--r--net/core/dev.c7
-rw-r--r--net/mac80211/Kconfig5
-rw-r--r--net/mac80211/cfg.c65
-rw-r--r--net/mac80211/driver-ops.h7
-rw-r--r--net/mac80211/iface.c4
-rw-r--r--net/mac80211/main.c12
-rw-r--r--net/mac80211/sta_info.c9
-rw-r--r--net/mac80211/tx.c2
-rw-r--r--net/mac80211/util.c10
-rw-r--r--net/mac80211/wext.c80
-rw-r--r--net/rfkill/Kconfig21
-rw-r--r--net/rfkill/Makefile5
-rw-r--r--net/rfkill/core.c1228
-rw-r--r--net/rfkill/input.c342
-rw-r--r--net/rfkill/rfkill-input.c390
-rw-r--r--net/rfkill/rfkill.c855
-rw-r--r--net/rfkill/rfkill.h (renamed from net/rfkill/rfkill-input.h)10
-rw-r--r--net/wimax/Kconfig15
-rw-r--r--net/wimax/op-rfkill.c123
-rw-r--r--net/wireless/Kconfig3
-rw-r--r--net/wireless/core.c97
-rw-r--r--net/wireless/core.h7
-rw-r--r--net/wireless/nl80211.c57
-rw-r--r--net/wireless/reg.c8
-rw-r--r--net/wireless/scan.c3
-rw-r--r--net/wireless/util.c13
-rw-r--r--net/wireless/wext-compat.c83
133 files changed, 4465 insertions, 4698 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index de491a3e2313..edb2f0b07616 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -437,3 +437,10 @@ Why: Superseded by tdfxfb. I2C/DDC support used to live in a separate
437 driver but this caused driver conflicts. 437 driver but this caused driver conflicts.
438Who: Jean Delvare <khali@linux-fr.org> 438Who: Jean Delvare <khali@linux-fr.org>
439 Krzysztof Helt <krzysztof.h1@wp.pl> 439 Krzysztof Helt <krzysztof.h1@wp.pl>
440
441---------------------------
442
443What: CONFIG_RFKILL_INPUT
444When: 2.6.33
445Why: Should be implemented in userspace, policy daemon.
446Who: Johannes Berg <johannes@sipsolutions.net>
diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt
index 40c3a3f10816..1b74b5f30af4 100644
--- a/Documentation/rfkill.txt
+++ b/Documentation/rfkill.txt
@@ -1,571 +1,136 @@
1rfkill - RF switch subsystem support 1rfkill - RF kill switch support
2==================================== 2===============================
3 3
41 Introduction 41. Introduction
52 Implementation details 52. Implementation details
63 Kernel driver guidelines 63. Kernel driver guidelines
73.1 wireless device drivers 74. Kernel API
83.2 platform/switch drivers 85. Userspace support
93.3 input device drivers
104 Kernel API
115 Userspace support
12 9
13 10
141. Introduction: 111. Introduction
15 12
16The rfkill switch subsystem exists to add a generic interface to circuitry that 13The rfkill subsystem provides a generic interface to disabling any radio
17can enable or disable the signal output of a wireless *transmitter* of any 14transmitter in the system. When a transmitter is blocked, it shall not
18type. By far, the most common use is to disable radio-frequency transmitters. 15radiate any power.
19 16
20Note that disabling the signal output means that the the transmitter is to be 17The subsystem also provides the ability to react on button presses and
21made to not emit any energy when "blocked". rfkill is not about blocking data 18disable all transmitters of a certain type (or all). This is intended for
22transmissions, it is about blocking energy emission. 19situations where transmitters need to be turned off, for example on
20aircraft.
23 21
24The rfkill subsystem offers support for keys and switches often found on
25laptops to enable wireless devices like WiFi and Bluetooth, so that these keys
26and switches actually perform an action in all wireless devices of a given type
27attached to the system.
28 22
29The buttons to enable and disable the wireless transmitters are important in
30situations where the user is for example using his laptop on a location where
31radio-frequency transmitters _must_ be disabled (e.g. airplanes).
32 23
33Because of this requirement, userspace support for the keys should not be made 242. Implementation details
34mandatory. Because userspace might want to perform some additional smarter
35tasks when the key is pressed, rfkill provides userspace the possibility to
36take over the task to handle the key events.
37
38===============================================================================
392: Implementation details
40 25
41The rfkill subsystem is composed of various components: the rfkill class, the 26The rfkill subsystem is composed of various components: the rfkill class, the
42rfkill-input module (an input layer handler), and some specific input layer 27rfkill-input module (an input layer handler), and some specific input layer
43events. 28events.
44 29
45The rfkill class provides kernel drivers with an interface that allows them to 30The rfkill class is provided for kernel drivers to register their radio
46know when they should enable or disable a wireless network device transmitter. 31transmitter with the kernel, provide methods for turning it on and off and,
47This is enabled by the CONFIG_RFKILL Kconfig option. 32optionally, letting the system know about hardware-disabled states that may
48 33be implemented on the device. This code is enabled with the CONFIG_RFKILL
49The rfkill class support makes sure userspace will be notified of all state 34Kconfig option, which drivers can "select".
50changes on rfkill devices through uevents. It provides a notification chain
51for interested parties in the kernel to also get notified of rfkill state
52changes in other drivers. It creates several sysfs entries which can be used
53by userspace. See section "Userspace support".
54
55The rfkill-input module provides the kernel with the ability to implement a
56basic response when the user presses a key or button (or toggles a switch)
57related to rfkill functionality. It is an in-kernel implementation of default
58policy of reacting to rfkill-related input events and neither mandatory nor
59required for wireless drivers to operate. It is enabled by the
60CONFIG_RFKILL_INPUT Kconfig option.
61
62rfkill-input is a rfkill-related events input layer handler. This handler will
63listen to all rfkill key events and will change the rfkill state of the
64wireless devices accordingly. With this option enabled userspace could either
65do nothing or simply perform monitoring tasks.
66
67The rfkill-input module also provides EPO (emergency power-off) functionality
68for all wireless transmitters. This function cannot be overridden, and it is
69always active. rfkill EPO is related to *_RFKILL_ALL input layer events.
70
71
72Important terms for the rfkill subsystem:
73
74In order to avoid confusion, we avoid the term "switch" in rfkill when it is
75referring to an electronic control circuit that enables or disables a
76transmitter. We reserve it for the physical device a human manipulates
77(which is an input device, by the way):
78
79rfkill switch:
80
81 A physical device a human manipulates. Its state can be perceived by
82 the kernel either directly (through a GPIO pin, ACPI GPE) or by its
83 effect on a rfkill line of a wireless device.
84
85rfkill controller:
86
87 A hardware circuit that controls the state of a rfkill line, which a
88 kernel driver can interact with *to modify* that state (i.e. it has
89 either write-only or read/write access).
90
91rfkill line:
92
93 An input channel (hardware or software) of a wireless device, which
94 causes a wireless transmitter to stop emitting energy (BLOCK) when it
95 is active. Point of view is extremely important here: rfkill lines are
96 always seen from the PoV of a wireless device (and its driver).
97
98soft rfkill line/software rfkill line:
99
100 A rfkill line the wireless device driver can directly change the state
101 of. Related to rfkill_state RFKILL_STATE_SOFT_BLOCKED.
102
103hard rfkill line/hardware rfkill line:
104
105 A rfkill line that works fully in hardware or firmware, and that cannot
106 be overridden by the kernel driver. The hardware device or the
107 firmware just exports its status to the driver, but it is read-only.
108 Related to rfkill_state RFKILL_STATE_HARD_BLOCKED.
109
110The enum rfkill_state describes the rfkill state of a transmitter:
111
112When a rfkill line or rfkill controller is in the RFKILL_STATE_UNBLOCKED state,
113the wireless transmitter (radio TX circuit for example) is *enabled*. When the
114it is in the RFKILL_STATE_SOFT_BLOCKED or RFKILL_STATE_HARD_BLOCKED, the
115wireless transmitter is to be *blocked* from operating.
116
117RFKILL_STATE_SOFT_BLOCKED indicates that a call to toggle_radio() can change
118that state. RFKILL_STATE_HARD_BLOCKED indicates that a call to toggle_radio()
119will not be able to change the state and will return with a suitable error if
120attempts are made to set the state to RFKILL_STATE_UNBLOCKED.
121
122RFKILL_STATE_HARD_BLOCKED is used by drivers to signal that the device is
123locked in the BLOCKED state by a hardwire rfkill line (typically an input pin
124that, when active, forces the transmitter to be disabled) which the driver
125CANNOT override.
126
127Full rfkill functionality requires two different subsystems to cooperate: the
128input layer and the rfkill class. The input layer issues *commands* to the
129entire system requesting that devices registered to the rfkill class change
130state. The way this interaction happens is not complex, but it is not obvious
131either:
132
133Kernel Input layer:
134
135 * Generates KEY_WWAN, KEY_WLAN, KEY_BLUETOOTH, SW_RFKILL_ALL, and
136 other such events when the user presses certain keys, buttons, or
137 toggles certain physical switches.
138
139 THE INPUT LAYER IS NEVER USED TO PROPAGATE STATUS, NOTIFICATIONS OR THE
140 KIND OF STUFF AN ON-SCREEN-DISPLAY APPLICATION WOULD REPORT. It is
141 used to issue *commands* for the system to change behaviour, and these
142 commands may or may not be carried out by some kernel driver or
143 userspace application. It follows that doing user feedback based only
144 on input events is broken, as there is no guarantee that an input event
145 will be acted upon.
146
147 Most wireless communication device drivers implementing rfkill
148 functionality MUST NOT generate these events, and have no reason to
149 register themselves with the input layer. Doing otherwise is a common
150 misconception. There is an API to propagate rfkill status change
151 information, and it is NOT the input layer.
152
153rfkill class:
154
155 * Calls a hook in a driver to effectively change the wireless
156 transmitter state;
157 * Keeps track of the wireless transmitter state (with help from
158 the driver);
159 * Generates userspace notifications (uevents) and a call to a
160 notification chain (kernel) when there is a wireless transmitter
161 state change;
162 * Connects a wireless communications driver with the common rfkill
163 control system, which, for example, allows actions such as
164 "switch all bluetooth devices offline" to be carried out by
165 userspace or by rfkill-input.
166
167 THE RFKILL CLASS NEVER ISSUES INPUT EVENTS. THE RFKILL CLASS DOES
168 NOT LISTEN TO INPUT EVENTS. NO DRIVER USING THE RFKILL CLASS SHALL
169 EVER LISTEN TO, OR ACT ON RFKILL INPUT EVENTS. Doing otherwise is
170 a layering violation.
171
172 Most wireless data communication drivers in the kernel have just to
173 implement the rfkill class API to work properly. Interfacing to the
174 input layer is not often required (and is very often a *bug*) on
175 wireless drivers.
176
177 Platform drivers often have to attach to the input layer to *issue*
178 (but never to listen to) rfkill events for rfkill switches, and also to
179 the rfkill class to export a control interface for the platform rfkill
180 controllers to the rfkill subsystem. This does NOT mean the rfkill
181 switch is attached to a rfkill class (doing so is almost always wrong).
182 It just means the same kernel module is the driver for different
183 devices (rfkill switches and rfkill controllers).
184
185
186Userspace input handlers (uevents) or kernel input handlers (rfkill-input):
187
188 * Implements the policy of what should happen when one of the input
189 layer events related to rfkill operation is received.
190 * Uses the sysfs interface (userspace) or private rfkill API calls
191 to tell the devices registered with the rfkill class to change
192 their state (i.e. translates the input layer event into real
193 action).
194
195 * rfkill-input implements EPO by handling EV_SW SW_RFKILL_ALL 0
196 (power off all transmitters) in a special way: it ignores any
197 overrides and local state cache and forces all transmitters to the
198 RFKILL_STATE_SOFT_BLOCKED state (including those which are already
199 supposed to be BLOCKED).
200 * rfkill EPO will remain active until rfkill-input receives an
201 EV_SW SW_RFKILL_ALL 1 event. While the EPO is active, transmitters
202 are locked in the blocked state (rfkill will refuse to unblock them).
203 * rfkill-input implements different policies that the user can
204 select for handling EV_SW SW_RFKILL_ALL 1. It will unlock rfkill,
205 and either do nothing (leave transmitters blocked, but now unlocked),
206 restore the transmitters to their state before the EPO, or unblock
207 them all.
208
209Userspace uevent handler or kernel platform-specific drivers hooked to the
210rfkill notifier chain:
211
212 * Taps into the rfkill notifier chain or to KOBJ_CHANGE uevents,
213 in order to know when a device that is registered with the rfkill
214 class changes state;
215 * Issues feedback notifications to the user;
216 * In the rare platforms where this is required, synthesizes an input
217 event to command all *OTHER* rfkill devices to also change their
218 statues when a specific rfkill device changes state.
219
220
221===============================================================================
2223: Kernel driver guidelines
223
224Remember: point-of-view is everything for a driver that connects to the rfkill
225subsystem. All the details below must be measured/perceived from the point of
226view of the specific driver being modified.
227
228The first thing one needs to know is whether his driver should be talking to
229the rfkill class or to the input layer. In rare cases (platform drivers), it
230could happen that you need to do both, as platform drivers often handle a
231variety of devices in the same driver.
232
233Do not mistake input devices for rfkill controllers. The only type of "rfkill
234switch" device that is to be registered with the rfkill class are those
235directly controlling the circuits that cause a wireless transmitter to stop
236working (or the software equivalent of them), i.e. what we call a rfkill
237controller. Every other kind of "rfkill switch" is just an input device and
238MUST NOT be registered with the rfkill class.
239
240A driver should register a device with the rfkill class when ALL of the
241following conditions are met (they define a rfkill controller):
242
2431. The device is/controls a data communications wireless transmitter;
244
2452. The kernel can interact with the hardware/firmware to CHANGE the wireless
246 transmitter state (block/unblock TX operation);
247
2483. The transmitter can be made to not emit any energy when "blocked":
249 rfkill is not about blocking data transmissions, it is about blocking
250 energy emission;
251
252A driver should register a device with the input subsystem to issue
253rfkill-related events (KEY_WLAN, KEY_BLUETOOTH, KEY_WWAN, KEY_WIMAX,
254SW_RFKILL_ALL, etc) when ALL of the folowing conditions are met:
255
2561. It is directly related to some physical device the user interacts with, to
257 command the O.S./firmware/hardware to enable/disable a data communications
258 wireless transmitter.
259
260 Examples of the physical device are: buttons, keys and switches the user
261 will press/touch/slide/switch to enable or disable the wireless
262 communication device.
263
2642. It is NOT slaved to another device, i.e. there is no other device that
265 issues rfkill-related input events in preference to this one.
266
267 Please refer to the corner cases and examples section for more details.
268
269When in doubt, do not issue input events. For drivers that should generate
270input events in some platforms, but not in others (e.g. b43), the best solution
271is to NEVER generate input events in the first place. That work should be
272deferred to a platform-specific kernel module (which will know when to generate
273events through the rfkill notifier chain) or to userspace. This avoids the
274usual maintenance problems with DMI whitelisting.
275
276
277Corner cases and examples:
278====================================
279
2801. If the device is an input device that, because of hardware or firmware,
281causes wireless transmitters to be blocked regardless of the kernel's will, it
282is still just an input device, and NOT to be registered with the rfkill class.
283
2842. If the wireless transmitter switch control is read-only, it is an input
285device and not to be registered with the rfkill class (and maybe not to be made
286an input layer event source either, see below).
287
2883. If there is some other device driver *closer* to the actual hardware the
289user interacted with (the button/switch/key) to issue an input event, THAT is
290the device driver that should be issuing input events.
291
292E.g:
293 [RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input]
294 (platform driver) (wireless card driver)
295
296The user is closer to the RFKILL slide switch plaform driver, so the driver
297which must issue input events is the platform driver looking at the GPIO
298hardware, and NEVER the wireless card driver (which is just a slave). It is
299very likely that there are other leaves than just the WLAN card rf-kill input
300(e.g. a bluetooth card, etc)...
301
302On the other hand, some embedded devices do this:
303
304 [RFKILL slider switch] -- [WLAN card rf-kill input]
305 (wireless card driver)
306
307In this situation, the wireless card driver *could* register itself as an input
308device and issue rf-kill related input events... but in order to AVOID the need
309for DMI whitelisting, the wireless card driver does NOT do it. Userspace (HAL)
310or a platform driver (that exists only on these embedded devices) will do the
311dirty job of issuing the input events.
312
313
314COMMON MISTAKES in kernel drivers, related to rfkill:
315====================================
316
3171. NEVER confuse input device keys and buttons with input device switches.
318
319 1a. Switches are always set or reset. They report the current state
320 (on position or off position).
321
322 1b. Keys and buttons are either in the pressed or not-pressed state, and
323 that's it. A "button" that latches down when you press it, and
324 unlatches when you press it again is in fact a switch as far as input
325 devices go.
326
327Add the SW_* events you need for switches, do NOT try to emulate a button using
328KEY_* events just because there is no such SW_* event yet. Do NOT try to use,
329for example, KEY_BLUETOOTH when you should be using SW_BLUETOOTH instead.
330
3312. Input device switches (sources of EV_SW events) DO store their current state
332(so you *must* initialize it by issuing a gratuitous input layer event on
333driver start-up and also when resuming from sleep), and that state CAN be
334queried from userspace through IOCTLs. There is no sysfs interface for this,
335but that doesn't mean you should break things trying to hook it to the rfkill
336class to get a sysfs interface :-)
337
3383. Do not issue *_RFKILL_ALL events by default, unless you are sure it is the
339correct event for your switch/button. These events are emergency power-off
340events when they are trying to turn the transmitters off. An example of an
341input device which SHOULD generate *_RFKILL_ALL events is the wireless-kill
342switch in a laptop which is NOT a hotkey, but a real sliding/rocker switch.
343An example of an input device which SHOULD NOT generate *_RFKILL_ALL events by
344default, is any sort of hot key that is type-specific (e.g. the one for WLAN).
345
346
3473.1 Guidelines for wireless device drivers
348------------------------------------------
349
350(in this text, rfkill->foo means the foo field of struct rfkill).
351
3521. Each independent transmitter in a wireless device (usually there is only one
353transmitter per device) should have a SINGLE rfkill class attached to it.
354
3552. If the device does not have any sort of hardware assistance to allow the
356driver to rfkill the device, the driver should emulate it by taking all actions
357required to silence the transmitter.
358
3593. If it is impossible to silence the transmitter (i.e. it still emits energy,
360even if it is just in brief pulses, when there is no data to transmit and there
361is no hardware support to turn it off) do NOT lie to the users. Do not attach
362it to a rfkill class. The rfkill subsystem does not deal with data
363transmission, it deals with energy emission. If the transmitter is emitting
364energy, it is not blocked in rfkill terms.
365
3664. It doesn't matter if the device has multiple rfkill input lines affecting
367the same transmitter, their combined state is to be exported as a single state
368per transmitter (see rule 1).
369
370This rule exists because users of the rfkill subsystem expect to get (and set,
371when possible) the overall transmitter rfkill state, not of a particular rfkill
372line.
373
3745. The wireless device driver MUST NOT leave the transmitter enabled during
375suspend and hibernation unless:
376 35
377 5.1. The transmitter has to be enabled for some sort of functionality 36The rfkill class code also notifies userspace of state changes, this is
378 like wake-on-wireless-packet or autonomous packed forwarding in a mesh 37achieved via uevents. It also provides some sysfs files for userspace to
379 network, and that functionality is enabled for this suspend/hibernation 38check the status of radio transmitters. See the "Userspace support" section
380 cycle. 39below.
381 40
382AND
383 41
384 5.2. The device was not on a user-requested BLOCKED state before 42The rfkill-input code implements a basic response to rfkill buttons -- it
385 the suspend (i.e. the driver must NOT unblock a device, not even 43implements turning on/off all devices of a certain class (or all).
386 to support wake-on-wireless-packet or remain in the mesh).
387 44
388In other words, there is absolutely no allowed scenario where a driver can 45When the device is hard-blocked (either by a call to rfkill_set_hw_state()
389automatically take action to unblock a rfkill controller (obviously, this deals 46or from query_hw_block) set_block() will be invoked but drivers can well
390with scenarios where soft-blocking or both soft and hard blocking is happening. 47ignore the method call since they can use the return value of the function
391Scenarios where hardware rfkill lines are the only ones blocking the 48rfkill_set_hw_state() to sync the software state instead of keeping track
392transmitter are outside of this rule, since the wireless device driver does not 49of calls to set_block().
393control its input hardware rfkill lines in the first place).
394 50
3956. During resume, rfkill will try to restore its previous state.
396 51
3977. After a rfkill class is suspended, it will *not* call rfkill->toggle_radio 52The entire functionality is spread over more than one subsystem:
398until it is resumed.
399 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)
400 59
401Example of a WLAN wireless driver connected to the rfkill subsystem: 60 * The rfkill-input code hooks up to these events and switches the soft-block
402-------------------------------------------------------------------- 61 of the various radio transmitters, depending on the button type.
403 62
404A certain WLAN card has one input pin that causes it to block the transmitter 63 * The rfkill drivers turn off/on their transmitters as requested.
405and makes the status of that input pin available (only for reading!) to the
406kernel driver. This is a hard rfkill input line (it cannot be overridden by
407the kernel driver).
408 64
409The card also has one PCI register that, if manipulated by the driver, causes 65 * The rfkill class will generate userspace notifications (uevents) to tell
410it to block the transmitter. This is a soft rfkill input line. 66 userspace what the current state is.
411 67
412It has also a thermal protection circuitry that shuts down its transmitter if
413the card overheats, and makes the status of that protection available (only for
414reading!) to the kernel driver. This is also a hard rfkill input line.
415 68
416If either one of these rfkill lines are active, the transmitter is blocked by
417the hardware and forced offline.
418 69
419The driver should allocate and attach to its struct device *ONE* instance of 703. Kernel driver guidelines
420the rfkill class (there is only one transmitter).
421 71
422It can implement the get_state() hook, and return RFKILL_STATE_HARD_BLOCKED if
423either one of its two hard rfkill input lines are active. If the two hard
424rfkill lines are inactive, it must return RFKILL_STATE_SOFT_BLOCKED if its soft
425rfkill input line is active. Only if none of the rfkill input lines are
426active, will it return RFKILL_STATE_UNBLOCKED.
427 72
428Since the device has a hardware rfkill line, it IS subject to state changes 73Drivers for radio transmitters normally implement only the rfkill class.
429external to rfkill. Therefore, the driver must make sure that it calls 74These drivers may not unblock the transmitter based on own decisions, they
430rfkill_force_state() to keep the status always up-to-date, and it must do a 75should act on information provided by the rfkill class only.
431rfkill_force_state() on resume from sleep.
432 76
433Every time the driver gets a notification from the card that one of its rfkill 77Platform drivers might implement input devices if the rfkill button is just
434lines changed state (polling might be needed on badly designed cards that don't 78that, a button. If that button influences the hardware then you need to
435generate interrupts for such events), it recomputes the rfkill state as per 79implement an rfkill class instead. This also applies if the platform provides
436above, and calls rfkill_force_state() to update it. 80a way to turn on/off the transmitter(s).
437 81
438The driver should implement the toggle_radio() hook, that: 82During suspend/hibernation, transmitters should only be left enabled when
83wake-on wlan or similar functionality requires it and the device wasn't
84blocked before suspend/hibernate. Note that it may be necessary to update
85the rfkill subsystem's idea of what the current state is at resume time if
86the state may have changed over suspend.
439 87
4401. Returns an error if one of the hardware rfkill lines are active, and the
441caller asked for RFKILL_STATE_UNBLOCKED.
442 88
4432. Activates the soft rfkill line if the caller asked for state
444RFKILL_STATE_SOFT_BLOCKED. It should do this even if one of the hard rfkill
445lines are active, effectively double-blocking the transmitter.
446 89
4473. Deactivates the soft rfkill line if none of the hardware rfkill lines are 904. Kernel API
448active and the caller asked for RFKILL_STATE_UNBLOCKED.
449
450===============================================================================
4514: Kernel API
452 91
453To build a driver with rfkill subsystem support, the driver should depend on 92To build a driver with rfkill subsystem support, the driver should depend on
454(or select) the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT. 93(or select) the Kconfig symbol RFKILL.
455 94
456The hardware the driver talks to may be write-only (where the current state 95The hardware the driver talks to may be write-only (where the current state
457of the hardware is unknown), or read-write (where the hardware can be queried 96of the hardware is unknown), or read-write (where the hardware can be queried
458about its current state). 97about its current state).
459 98
460The rfkill class will call the get_state hook of a device every time it needs 99Calling rfkill_set_hw_state() when a state change happens is required from
461to know the *real* current state of the hardware. This can happen often, but 100rfkill drivers that control devices that can be hard-blocked unless they also
462it does not do any polling, so it is not enough on hardware that is subject 101assign the poll_hw_block() callback (then the rfkill core will poll the
463to state changes outside of the rfkill subsystem. 102device). Don't do this unless you cannot get the event in any other way.
464
465Therefore, calling rfkill_force_state() when a state change happens is
466mandatory when the device has a hardware rfkill line, or when something else
467like the firmware could cause its state to be changed without going through the
468rfkill class.
469
470Some hardware provides events when its status changes. In these cases, it is
471best for the driver to not provide a get_state hook, and instead register the
472rfkill class *already* with the correct status, and keep it updated using
473rfkill_force_state() when it gets an event from the hardware.
474
475rfkill_force_state() must be used on the device resume handlers to update the
476rfkill status, should there be any chance of the device status changing during
477the sleep.
478
479There is no provision for a statically-allocated rfkill struct. You must
480use rfkill_allocate() to allocate one.
481
482You should:
483 - rfkill_allocate()
484 - modify rfkill fields (flags, name)
485 - modify state to the current hardware state (THIS IS THE ONLY TIME
486 YOU CAN ACCESS state DIRECTLY)
487 - rfkill_register()
488
489The only way to set a device to the RFKILL_STATE_HARD_BLOCKED state is through
490a suitable return of get_state() or through rfkill_force_state().
491 103
492When a device is in the RFKILL_STATE_HARD_BLOCKED state, the only way to switch
493it to a different state is through a suitable return of get_state() or through
494rfkill_force_state().
495 104
496If toggle_radio() is called to set a device to state RFKILL_STATE_SOFT_BLOCKED
497when that device is already at the RFKILL_STATE_HARD_BLOCKED state, it should
498not return an error. Instead, it should try to double-block the transmitter,
499so that its state will change from RFKILL_STATE_HARD_BLOCKED to
500RFKILL_STATE_SOFT_BLOCKED should the hardware blocking cease.
501
502Please refer to the source for more documentation.
503
504===============================================================================
5055: Userspace support
506
507rfkill devices issue uevents (with an action of "change"), with the following
508environment variables set:
509
510RFKILL_NAME
511RFKILL_STATE
512RFKILL_TYPE
513 105
514The ABI for these variables is defined by the sysfs attributes. It is best 1065. Userspace support
515to take a quick look at the source to make sure of the possible values.
516 107
517It is expected that HAL will trap those, and bridge them to DBUS, etc. These 108The following sysfs entries exist for every rfkill device:
518events CAN and SHOULD be used to give feedback to the user about the rfkill
519status of the system.
520
521Input devices may issue events that are related to rfkill. These are the
522various KEY_* events and SW_* events supported by rfkill-input.c.
523
524Userspace may not change the state of an rfkill switch in response to an
525input event, it should refrain from changing states entirely.
526
527Userspace cannot assume it is the only source of control for rfkill switches.
528Their state can change due to firmware actions, direct user actions, and the
529rfkill-input EPO override for *_RFKILL_ALL.
530
531When rfkill-input is not active, userspace must initiate a rfkill status
532change by writing to the "state" attribute in order for anything to happen.
533
534Take particular care to implement EV_SW SW_RFKILL_ALL properly. When that
535switch is set to OFF, *every* rfkill device *MUST* be immediately put into the
536RFKILL_STATE_SOFT_BLOCKED state, no questions asked.
537
538The following sysfs entries will be created:
539 109
540 name: Name assigned by driver to this key (interface or driver name). 110 name: Name assigned by driver to this key (interface or driver name).
541 type: Name of the key type ("wlan", "bluetooth", etc). 111 type: Name of the key type ("wlan", "bluetooth", etc).
542 state: Current state of the transmitter 112 state: Current state of the transmitter
543 0: RFKILL_STATE_SOFT_BLOCKED 113 0: RFKILL_STATE_SOFT_BLOCKED
544 transmitter is forced off, but one can override it 114 transmitter is turned off by software
545 by a write to the state attribute;
546 1: RFKILL_STATE_UNBLOCKED 115 1: RFKILL_STATE_UNBLOCKED
547 transmiter is NOT forced off, and may operate if 116 transmitter is (potentially) active
548 all other conditions for such operation are met
549 (such as interface is up and configured, etc);
550 2: RFKILL_STATE_HARD_BLOCKED 117 2: RFKILL_STATE_HARD_BLOCKED
551 transmitter is forced off by something outside of 118 transmitter is forced off by something outside of
552 the driver's control. One cannot set a device to 119 the driver's control.
553 this state through writes to the state attribute; 120 claim: 0: Kernel handles events (currently always reads that value)
554 claim: 1: Userspace handles events, 0: Kernel handles events 121
555 122rfkill devices also issue uevents (with an action of "change"), with the
556Both the "state" and "claim" entries are also writable. For the "state" entry 123following environment variables set:
557this means that when 1 or 0 is written, the device rfkill state (if not yet in 124
558the requested state), will be will be toggled accordingly. 125RFKILL_NAME
559 126RFKILL_STATE
560For the "claim" entry writing 1 to it means that the kernel no longer handles 127RFKILL_TYPE
561key events even though RFKILL_INPUT input was enabled. When "claim" has been 128
562set to 0, userspace should make sure that it listens for the input events or 129The contents of these variables corresponds to the "name", "state" and
563check the sysfs "state" entry regularly to correctly perform the required tasks 130"type" sysfs files explained above.
564when the rkfill key is pressed. 131
565 132An alternative userspace interface exists as a misc device /dev/rfkill,
566A note about input devices and EV_SW events: 133which allows userspace to obtain and set the state of rfkill devices and
567 134sets of devices. It also notifies userspace about device addition and
568In order to know the current state of an input device switch (like 135removal. The API is a simple read/write API that is defined in
569SW_RFKILL_ALL), you will need to use an IOCTL. That information is not 136linux/rfkill.h.
570available through sysfs in a generic way at this time, and it is not available
571through the rfkill class AT ALL.
diff --git a/MAINTAINERS b/MAINTAINERS
index e18baa410b50..2f6a8fcfb1f2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4753,9 +4753,9 @@ S: Supported
4753F: fs/reiserfs/ 4753F: fs/reiserfs/
4754 4754
4755RFKILL 4755RFKILL
4756P: Ivo van Doorn 4756P: Johannes Berg
4757M: IvDoorn@gmail.com 4757M: johannes@sipsolutions.net
4758L: netdev@vger.kernel.org 4758L: linux-wireless@vger.kernel.org
4759S: Maintained 4759S: Maintained
4760F Documentation/rfkill.txt 4760F Documentation/rfkill.txt
4761F: net/rfkill/ 4761F: net/rfkill/
diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c
index bde42aa29374..c31e601eb49c 100644
--- a/arch/arm/mach-pxa/tosa-bt.c
+++ b/arch/arm/mach-pxa/tosa-bt.c
@@ -35,21 +35,25 @@ static void tosa_bt_off(struct tosa_bt_data *data)
35 gpio_set_value(data->gpio_reset, 0); 35 gpio_set_value(data->gpio_reset, 0);
36} 36}
37 37
38static int tosa_bt_toggle_radio(void *data, enum rfkill_state state) 38static int tosa_bt_set_block(void *data, bool blocked)
39{ 39{
40 pr_info("BT_RADIO going: %s\n", 40 pr_info("BT_RADIO going: %s\n", blocked ? "off" : "on");
41 state == RFKILL_STATE_UNBLOCKED ? "on" : "off");
42 41
43 if (state == RFKILL_STATE_UNBLOCKED) { 42 if (!blocked) {
44 pr_info("TOSA_BT: going ON\n"); 43 pr_info("TOSA_BT: going ON\n");
45 tosa_bt_on(data); 44 tosa_bt_on(data);
46 } else { 45 } else {
47 pr_info("TOSA_BT: going OFF\n"); 46 pr_info("TOSA_BT: going OFF\n");
48 tosa_bt_off(data); 47 tosa_bt_off(data);
49 } 48 }
49
50 return 0; 50 return 0;
51} 51}
52 52
53static const struct rfkill_ops tosa_bt_rfkill_ops = {
54 .set_block = tosa_bt_set_block,
55};
56
53static int tosa_bt_probe(struct platform_device *dev) 57static int tosa_bt_probe(struct platform_device *dev)
54{ 58{
55 int rc; 59 int rc;
@@ -70,18 +74,14 @@ static int tosa_bt_probe(struct platform_device *dev)
70 if (rc) 74 if (rc)
71 goto err_pwr_dir; 75 goto err_pwr_dir;
72 76
73 rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH); 77 rfk = rfkill_alloc("tosa-bt", &dev->dev, RFKILL_TYPE_BLUETOOTH,
78 &tosa_bt_rfkill_ops, data);
74 if (!rfk) { 79 if (!rfk) {
75 rc = -ENOMEM; 80 rc = -ENOMEM;
76 goto err_rfk_alloc; 81 goto err_rfk_alloc;
77 } 82 }
78 83
79 rfk->name = "tosa-bt"; 84 rfkill_set_led_trigger_name(rfk, "tosa-bt");
80 rfk->toggle_radio = tosa_bt_toggle_radio;
81 rfk->data = data;
82#ifdef CONFIG_RFKILL_LEDS
83 rfk->led_trigger.name = "tosa-bt";
84#endif
85 85
86 rc = rfkill_register(rfk); 86 rc = rfkill_register(rfk);
87 if (rc) 87 if (rc)
@@ -92,9 +92,7 @@ static int tosa_bt_probe(struct platform_device *dev)
92 return 0; 92 return 0;
93 93
94err_rfkill: 94err_rfkill:
95 if (rfk) 95 rfkill_destroy(rfk);
96 rfkill_free(rfk);
97 rfk = NULL;
98err_rfk_alloc: 96err_rfk_alloc:
99 tosa_bt_off(data); 97 tosa_bt_off(data);
100err_pwr_dir: 98err_pwr_dir:
@@ -113,8 +111,10 @@ static int __devexit tosa_bt_remove(struct platform_device *dev)
113 111
114 platform_set_drvdata(dev, NULL); 112 platform_set_drvdata(dev, NULL);
115 113
116 if (rfk) 114 if (rfk) {
117 rfkill_unregister(rfk); 115 rfkill_unregister(rfk);
116 rfkill_destroy(rfk);
117 }
118 rfk = NULL; 118 rfk = NULL;
119 119
120 tosa_bt_off(data); 120 tosa_bt_off(data);
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index afac5b6d3d78..58ce807fe440 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -31,7 +31,6 @@
31#include <linux/input.h> 31#include <linux/input.h>
32#include <linux/gpio.h> 32#include <linux/gpio.h>
33#include <linux/pda_power.h> 33#include <linux/pda_power.h>
34#include <linux/rfkill.h>
35#include <linux/spi/spi.h> 34#include <linux/spi/spi.h>
36 35
37#include <asm/setup.h> 36#include <asm/setup.h>
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 837135f0390a..5ddd8c4f9019 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -2481,10 +2481,10 @@ static int add_net_device(struct hso_device *hso_dev)
2481 return 0; 2481 return 0;
2482} 2482}
2483 2483
2484static int hso_radio_toggle(void *data, enum rfkill_state state) 2484static int hso_rfkill_set_block(void *data, bool blocked)
2485{ 2485{
2486 struct hso_device *hso_dev = data; 2486 struct hso_device *hso_dev = data;
2487 int enabled = (state == RFKILL_STATE_UNBLOCKED); 2487 int enabled = !blocked;
2488 int rv; 2488 int rv;
2489 2489
2490 mutex_lock(&hso_dev->mutex); 2490 mutex_lock(&hso_dev->mutex);
@@ -2498,6 +2498,10 @@ static int hso_radio_toggle(void *data, enum rfkill_state state)
2498 return rv; 2498 return rv;
2499} 2499}
2500 2500
2501static const struct rfkill_ops hso_rfkill_ops = {
2502 .set_block = hso_rfkill_set_block,
2503};
2504
2501/* Creates and sets up everything for rfkill */ 2505/* Creates and sets up everything for rfkill */
2502static void hso_create_rfkill(struct hso_device *hso_dev, 2506static void hso_create_rfkill(struct hso_device *hso_dev,
2503 struct usb_interface *interface) 2507 struct usb_interface *interface)
@@ -2506,29 +2510,25 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
2506 struct device *dev = &hso_net->net->dev; 2510 struct device *dev = &hso_net->net->dev;
2507 char *rfkn; 2511 char *rfkn;
2508 2512
2509 hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev,
2510 RFKILL_TYPE_WWAN);
2511 if (!hso_net->rfkill) {
2512 dev_err(dev, "%s - Out of memory\n", __func__);
2513 return;
2514 }
2515 rfkn = kzalloc(20, GFP_KERNEL); 2513 rfkn = kzalloc(20, GFP_KERNEL);
2516 if (!rfkn) { 2514 if (!rfkn)
2517 rfkill_free(hso_net->rfkill);
2518 hso_net->rfkill = NULL;
2519 dev_err(dev, "%s - Out of memory\n", __func__); 2515 dev_err(dev, "%s - Out of memory\n", __func__);
2520 return; 2516
2521 }
2522 snprintf(rfkn, 20, "hso-%d", 2517 snprintf(rfkn, 20, "hso-%d",
2523 interface->altsetting->desc.bInterfaceNumber); 2518 interface->altsetting->desc.bInterfaceNumber);
2524 hso_net->rfkill->name = rfkn; 2519
2525 hso_net->rfkill->state = RFKILL_STATE_UNBLOCKED; 2520 hso_net->rfkill = rfkill_alloc(rfkn,
2526 hso_net->rfkill->data = hso_dev; 2521 &interface_to_usbdev(interface)->dev,
2527 hso_net->rfkill->toggle_radio = hso_radio_toggle; 2522 RFKILL_TYPE_WWAN,
2523 &hso_rfkill_ops, hso_dev);
2524 if (!hso_net->rfkill) {
2525 dev_err(dev, "%s - Out of memory\n", __func__);
2526 kfree(rfkn);
2527 return;
2528 }
2528 if (rfkill_register(hso_net->rfkill) < 0) { 2529 if (rfkill_register(hso_net->rfkill) < 0) {
2530 rfkill_destroy(hso_net->rfkill);
2529 kfree(rfkn); 2531 kfree(rfkn);
2530 hso_net->rfkill->name = NULL;
2531 rfkill_free(hso_net->rfkill);
2532 hso_net->rfkill = NULL; 2532 hso_net->rfkill = NULL;
2533 dev_err(dev, "%s - Failed to register rfkill\n", __func__); 2533 dev_err(dev, "%s - Failed to register rfkill\n", __func__);
2534 return; 2534 return;
@@ -3165,8 +3165,10 @@ static void hso_free_interface(struct usb_interface *interface)
3165 hso_stop_net_device(network_table[i]); 3165 hso_stop_net_device(network_table[i]);
3166 cancel_work_sync(&network_table[i]->async_put_intf); 3166 cancel_work_sync(&network_table[i]->async_put_intf);
3167 cancel_work_sync(&network_table[i]->async_get_intf); 3167 cancel_work_sync(&network_table[i]->async_get_intf);
3168 if (rfk) 3168 if (rfk) {
3169 rfkill_unregister(rfk); 3169 rfkill_unregister(rfk);
3170 rfkill_destroy(rfk);
3171 }
3170 hso_free_net_device(network_table[i]); 3172 hso_free_net_device(network_table[i]);
3171 } 3173 }
3172 } 3174 }
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 867324163ca2..daf4c805be58 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -333,11 +333,11 @@ config USB_ZD1201
333config USB_NET_RNDIS_WLAN 333config USB_NET_RNDIS_WLAN
334 tristate "Wireless RNDIS USB support" 334 tristate "Wireless RNDIS USB support"
335 depends on USB && WLAN_80211 && EXPERIMENTAL 335 depends on USB && WLAN_80211 && EXPERIMENTAL
336 depends on CFG80211
336 select USB_USBNET 337 select USB_USBNET
337 select USB_NET_CDCETHER 338 select USB_NET_CDCETHER
338 select USB_NET_RNDIS_HOST 339 select USB_NET_RNDIS_HOST
339 select WIRELESS_EXT 340 select WIRELESS_EXT
340 select CFG80211
341 ---help--- 341 ---help---
342 This is a driver for wireless RNDIS devices. 342 This is a driver for wireless RNDIS devices.
343 These are USB based adapters found in devices such as: 343 These are USB based adapters found in devices such as:
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index 17bd3eaf3e03..c7cba66b63cb 100644
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -91,6 +91,7 @@ struct ar9170_led {
91 struct led_classdev l; 91 struct led_classdev l;
92 char name[32]; 92 char name[32];
93 unsigned int toggled; 93 unsigned int toggled;
94 bool last_state;
94 bool registered; 95 bool registered;
95}; 96};
96 97
@@ -101,7 +102,6 @@ enum ar9170_device_state {
101 AR9170_STOPPED, 102 AR9170_STOPPED,
102 AR9170_IDLE, 103 AR9170_IDLE,
103 AR9170_STARTED, 104 AR9170_STARTED,
104 AR9170_ASSOCIATED,
105}; 105};
106 106
107struct ar9170_rxstream_mpdu_merge { 107struct ar9170_rxstream_mpdu_merge {
@@ -140,7 +140,7 @@ struct ar9170 {
140 struct work_struct filter_config_work; 140 struct work_struct filter_config_work;
141 u64 cur_mc_hash, want_mc_hash; 141 u64 cur_mc_hash, want_mc_hash;
142 u32 cur_filter, want_filter; 142 u32 cur_filter, want_filter;
143 unsigned int filter_changed; 143 unsigned long filter_changed;
144 unsigned int filter_state; 144 unsigned int filter_state;
145 bool sniffer_enabled; 145 bool sniffer_enabled;
146 146
@@ -195,7 +195,7 @@ struct ar9170_sta_info {
195#define IS_STARTED(a) (a->state >= AR9170_STARTED) 195#define IS_STARTED(a) (a->state >= AR9170_STARTED)
196#define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE) 196#define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE)
197 197
198#define AR9170_FILTER_CHANGED_PROMISC BIT(0) 198#define AR9170_FILTER_CHANGED_MODE BIT(0)
199#define AR9170_FILTER_CHANGED_MULTICAST BIT(1) 199#define AR9170_FILTER_CHANGED_MULTICAST BIT(1)
200#define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2) 200#define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2)
201 201
@@ -206,6 +206,7 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
206void ar9170_unregister(struct ar9170 *ar); 206void ar9170_unregister(struct ar9170 *ar);
207void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, 207void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
208 bool update_statistics, u16 tx_status); 208 bool update_statistics, u16 tx_status);
209void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
209 210
210/* MAC */ 211/* MAC */
211int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); 212int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -215,6 +216,9 @@ int ar9170_update_multicast(struct ar9170 *ar);
215int ar9170_update_frame_filter(struct ar9170 *ar); 216int ar9170_update_frame_filter(struct ar9170 *ar);
216int ar9170_set_operating_mode(struct ar9170 *ar); 217int ar9170_set_operating_mode(struct ar9170 *ar);
217int ar9170_set_beacon_timers(struct ar9170 *ar); 218int ar9170_set_beacon_timers(struct ar9170 *ar);
219int ar9170_set_dyn_sifs_ack(struct ar9170 *ar);
220int ar9170_set_slot_time(struct ar9170 *ar);
221int ar9170_set_basic_rates(struct ar9170 *ar);
218int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry); 222int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
219int ar9170_update_beacon(struct ar9170 *ar); 223int ar9170_update_beacon(struct ar9170 *ar);
220void ar9170_new_beacon(struct work_struct *work); 224void ar9170_new_beacon(struct work_struct *work);
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h
index 3293e0fb24fb..3c8004fb7307 100644
--- a/drivers/net/wireless/ath/ar9170/hw.h
+++ b/drivers/net/wireless/ath/ar9170/hw.h
@@ -207,7 +207,8 @@ enum ar9170_cmd {
207#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44) 207#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44)
208#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48) 208#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48)
209 209
210#define AR9170_MAC_REG_AMPDU_SET (AR9170_MAC_REG_BASE + 0xba0) 210#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xB9C)
211#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xBA0)
211 212
212#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00) 213#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00)
213#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50) 214#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50)
@@ -376,7 +377,6 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t)
376#define AR9170_RX_ERROR_FATAL 0x80 377#define AR9170_RX_ERROR_FATAL 0x80
377 378
378struct ar9170_cmd_tx_status { 379struct ar9170_cmd_tx_status {
379 __le16 unkn;
380 u8 dst[ETH_ALEN]; 380 u8 dst[ETH_ALEN];
381 __le32 rate; 381 __le32 rate;
382 __le16 status; 382 __le16 status;
@@ -394,6 +394,7 @@ struct ar9170_cmd_ba_failed_count {
394struct ar9170_cmd_response { 394struct ar9170_cmd_response {
395 u8 flag; 395 u8 flag;
396 u8 type; 396 u8 type;
397 __le16 padding;
397 398
398 union { 399 union {
399 struct ar9170_cmd_tx_status tx_status; 400 struct ar9170_cmd_tx_status tx_status;
diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c
index 341cead7f606..63fda6cd2101 100644
--- a/drivers/net/wireless/ath/ar9170/led.c
+++ b/drivers/net/wireless/ath/ar9170/led.c
@@ -74,7 +74,7 @@ static void ar9170_update_leds(struct work_struct *work)
74 74
75 mutex_lock(&ar->mutex); 75 mutex_lock(&ar->mutex);
76 for (i = 0; i < AR9170_NUM_LEDS; i++) 76 for (i = 0; i < AR9170_NUM_LEDS; i++)
77 if (ar->leds[i].toggled) { 77 if (ar->leds[i].registered && ar->leds[i].toggled) {
78 led_val |= 1 << i; 78 led_val |= 1 << i;
79 79
80 tmp = 70 + 200 / (ar->leds[i].toggled); 80 tmp = 70 + 200 / (ar->leds[i].toggled);
@@ -101,9 +101,15 @@ static void ar9170_led_brightness_set(struct led_classdev *led,
101 struct ar9170_led *arl = container_of(led, struct ar9170_led, l); 101 struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
102 struct ar9170 *ar = arl->ar; 102 struct ar9170 *ar = arl->ar;
103 103
104 arl->toggled++; 104 if (unlikely(!arl->registered))
105 return ;
106
107 if (arl->last_state != !!brightness) {
108 arl->toggled++;
109 arl->last_state = !!brightness;
110 }
105 111
106 if (likely(IS_ACCEPTING_CMD(ar) && brightness)) 112 if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
107 queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10); 113 queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
108} 114}
109 115
@@ -136,13 +142,14 @@ void ar9170_unregister_leds(struct ar9170 *ar)
136{ 142{
137 int i; 143 int i;
138 144
139 cancel_delayed_work_sync(&ar->led_work);
140
141 for (i = 0; i < AR9170_NUM_LEDS; i++) 145 for (i = 0; i < AR9170_NUM_LEDS; i++)
142 if (ar->leds[i].registered) { 146 if (ar->leds[i].registered) {
143 led_classdev_unregister(&ar->leds[i].l); 147 led_classdev_unregister(&ar->leds[i].l);
144 ar->leds[i].registered = false; 148 ar->leds[i].registered = false;
149 ar->leds[i].toggled = 0;
145 } 150 }
151
152 cancel_delayed_work_sync(&ar->led_work);
146} 153}
147 154
148int ar9170_register_leds(struct ar9170 *ar) 155int ar9170_register_leds(struct ar9170 *ar)
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
index 43aeb69685d3..d9f1f46de183 100644
--- a/drivers/net/wireless/ath/ar9170/mac.c
+++ b/drivers/net/wireless/ath/ar9170/mac.c
@@ -38,6 +38,55 @@
38#include "ar9170.h" 38#include "ar9170.h"
39#include "cmd.h" 39#include "cmd.h"
40 40
41int ar9170_set_dyn_sifs_ack(struct ar9170 *ar)
42{
43 u32 val;
44
45 if (conf_is_ht40(&ar->hw->conf))
46 val = 0x010a;
47 else {
48 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
49 val = 0x105;
50 else
51 val = 0x104;
52 }
53
54 return ar9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
55}
56
57int ar9170_set_slot_time(struct ar9170 *ar)
58{
59 u32 slottime = 20;
60
61 if (!ar->vif)
62 return 0;
63
64 if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
65 ar->vif->bss_conf.use_short_slot)
66 slottime = 9;
67
68 return ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, slottime << 10);
69}
70
71int ar9170_set_basic_rates(struct ar9170 *ar)
72{
73 u8 cck, ofdm;
74
75 if (!ar->vif)
76 return 0;
77
78 ofdm = ar->vif->bss_conf.basic_rates >> 4;
79
80 /* FIXME: is still necessary? */
81 if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
82 cck = 0;
83 else
84 cck = ar->vif->bss_conf.basic_rates & 0xf;
85
86 return ar9170_write_reg(ar, AR9170_MAC_REG_BASIC_RATE,
87 ofdm << 8 | cck);
88}
89
41int ar9170_set_qos(struct ar9170 *ar) 90int ar9170_set_qos(struct ar9170 *ar)
42{ 91{
43 ar9170_regwrite_begin(ar); 92 ar9170_regwrite_begin(ar);
@@ -84,7 +133,7 @@ static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity)
84 val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0); 133 val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0);
85 134
86 ar9170_regwrite_begin(ar); 135 ar9170_regwrite_begin(ar);
87 ar9170_regwrite(AR9170_MAC_REG_AMPDU_SET, val); 136 ar9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, val);
88 ar9170_regwrite_finish(); 137 ar9170_regwrite_finish();
89 138
90 return ar9170_regwrite_result(); 139 return ar9170_regwrite_result();
@@ -398,10 +447,10 @@ int ar9170_update_beacon(struct ar9170 *ar)
398 /* XXX: use skb->cb info */ 447 /* XXX: use skb->cb info */
399 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) 448 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
400 ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP, 449 ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
401 ((skb->len + 4) << (3+16)) + 0x0400); 450 ((skb->len + 4) << (3 + 16)) + 0x0400);
402 else 451 else
403 ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP, 452 ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
404 ((skb->len + 4) << (3+16)) + 0x0400); 453 ((skb->len + 4) << 16) + 0x001b);
405 454
406 ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4); 455 ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
407 ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS); 456 ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 99df9ddae9cb..b104d7efd676 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -146,7 +146,6 @@ static struct ieee80211_channel ar9170_5ghz_chantable[] = {
146{ \ 146{ \
147 .ht_supported = true, \ 147 .ht_supported = true, \
148 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \ 148 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
149 IEEE80211_HT_CAP_SM_PS | \
150 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ 149 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
151 IEEE80211_HT_CAP_SGI_40 | \ 150 IEEE80211_HT_CAP_SGI_40 | \
152 IEEE80211_HT_CAP_DSSSCCK40 | \ 151 IEEE80211_HT_CAP_DSSSCCK40 | \
@@ -344,7 +343,6 @@ static void ar9170_tx_status_janitor(struct work_struct *work)
344 if (unlikely(!IS_STARTED(ar))) 343 if (unlikely(!IS_STARTED(ar)))
345 return ; 344 return ;
346 345
347 mutex_lock(&ar->mutex);
348 /* recycle the garbage back to mac80211... one by one. */ 346 /* recycle the garbage back to mac80211... one by one. */
349 while ((skb = skb_dequeue(&ar->global_tx_status_waste))) { 347 while ((skb = skb_dequeue(&ar->global_tx_status_waste))) {
350#ifdef AR9170_QUEUE_DEBUG 348#ifdef AR9170_QUEUE_DEBUG
@@ -370,12 +368,9 @@ static void ar9170_tx_status_janitor(struct work_struct *work)
370 if (skb_queue_len(&ar->global_tx_status_waste) > 0) 368 if (skb_queue_len(&ar->global_tx_status_waste) > 0)
371 queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor, 369 queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
372 msecs_to_jiffies(100)); 370 msecs_to_jiffies(100));
373
374 mutex_unlock(&ar->mutex);
375} 371}
376 372
377static void ar9170_handle_command_response(struct ar9170 *ar, 373void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
378 void *buf, u32 len)
379{ 374{
380 struct ar9170_cmd_response *cmd = (void *) buf; 375 struct ar9170_cmd_response *cmd = (void *) buf;
381 376
@@ -957,6 +952,8 @@ static int ar9170_op_start(struct ieee80211_hw *hw)
957 952
958 mutex_lock(&ar->mutex); 953 mutex_lock(&ar->mutex);
959 954
955 ar->filter_changed = 0;
956
960 /* reinitialize queues statistics */ 957 /* reinitialize queues statistics */
961 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); 958 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
962 for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++) 959 for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++)
@@ -1012,10 +1009,10 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
1012 1009
1013 flush_workqueue(ar->hw->workqueue); 1010 flush_workqueue(ar->hw->workqueue);
1014 1011
1015 mutex_lock(&ar->mutex);
1016 cancel_delayed_work_sync(&ar->tx_status_janitor); 1012 cancel_delayed_work_sync(&ar->tx_status_janitor);
1017 cancel_work_sync(&ar->filter_config_work); 1013 cancel_work_sync(&ar->filter_config_work);
1018 cancel_work_sync(&ar->beacon_work); 1014 cancel_work_sync(&ar->beacon_work);
1015 mutex_lock(&ar->mutex);
1019 skb_queue_purge(&ar->global_tx_status_waste); 1016 skb_queue_purge(&ar->global_tx_status_waste);
1020 skb_queue_purge(&ar->global_tx_status); 1017 skb_queue_purge(&ar->global_tx_status);
1021 1018
@@ -1306,11 +1303,6 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
1306 1303
1307 mutex_lock(&ar->mutex); 1304 mutex_lock(&ar->mutex);
1308 1305
1309 if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
1310 /* TODO */
1311 err = 0;
1312 }
1313
1314 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { 1306 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
1315 /* TODO */ 1307 /* TODO */
1316 err = 0; 1308 err = 0;
@@ -1344,15 +1336,21 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
1344 } 1336 }
1345 1337
1346 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1338 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1339
1340 /* adjust slot time for 5 GHz */
1341 err = ar9170_set_slot_time(ar);
1342 if (err)
1343 goto out;
1344
1345 err = ar9170_set_dyn_sifs_ack(ar);
1346 if (err)
1347 goto out;
1348
1347 err = ar9170_set_channel(ar, hw->conf.channel, 1349 err = ar9170_set_channel(ar, hw->conf.channel,
1348 AR9170_RFI_NONE, 1350 AR9170_RFI_NONE,
1349 nl80211_to_ar9170(hw->conf.channel_type)); 1351 nl80211_to_ar9170(hw->conf.channel_type));
1350 if (err) 1352 if (err)
1351 goto out; 1353 goto out;
1352 /* adjust slot time for 5 GHz */
1353 if (hw->conf.channel->band == IEEE80211_BAND_5GHZ)
1354 err = ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
1355 9 << 10);
1356 } 1354 }
1357 1355
1358out: 1356out:
@@ -1370,20 +1368,26 @@ static void ar9170_set_filters(struct work_struct *work)
1370 return ; 1368 return ;
1371 1369
1372 mutex_lock(&ar->mutex); 1370 mutex_lock(&ar->mutex);
1373 if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) { 1371 if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE,
1372 &ar->filter_changed)) {
1374 err = ar9170_set_operating_mode(ar); 1373 err = ar9170_set_operating_mode(ar);
1375 if (err) 1374 if (err)
1376 goto unlock; 1375 goto unlock;
1377 } 1376 }
1378 1377
1379 if (ar->filter_changed & AR9170_FILTER_CHANGED_MULTICAST) { 1378 if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST,
1379 &ar->filter_changed)) {
1380 err = ar9170_update_multicast(ar); 1380 err = ar9170_update_multicast(ar);
1381 if (err) 1381 if (err)
1382 goto unlock; 1382 goto unlock;
1383 } 1383 }
1384 1384
1385 if (ar->filter_changed & AR9170_FILTER_CHANGED_FRAMEFILTER) 1385 if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
1386 &ar->filter_changed)) {
1386 err = ar9170_update_frame_filter(ar); 1387 err = ar9170_update_frame_filter(ar);
1388 if (err)
1389 goto unlock;
1390 }
1387 1391
1388unlock: 1392unlock:
1389 mutex_unlock(&ar->mutex); 1393 mutex_unlock(&ar->mutex);
@@ -1413,7 +1417,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
1413 int i; 1417 int i;
1414 1418
1415 /* always get broadcast frames */ 1419 /* always get broadcast frames */
1416 mchash = 1ULL << (0xff>>2); 1420 mchash = 1ULL << (0xff >> 2);
1417 1421
1418 for (i = 0; i < mc_count; i++) { 1422 for (i = 0; i < mc_count; i++) {
1419 if (WARN_ON(!mclist)) 1423 if (WARN_ON(!mclist))
@@ -1423,7 +1427,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
1423 } 1427 }
1424 ar->want_mc_hash = mchash; 1428 ar->want_mc_hash = mchash;
1425 } 1429 }
1426 ar->filter_changed |= AR9170_FILTER_CHANGED_MULTICAST; 1430 set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
1427 } 1431 }
1428 1432
1429 if (changed_flags & FIF_CONTROL) { 1433 if (changed_flags & FIF_CONTROL) {
@@ -1439,12 +1443,14 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
1439 else 1443 else
1440 ar->want_filter = ar->cur_filter & ~filter; 1444 ar->want_filter = ar->cur_filter & ~filter;
1441 1445
1442 ar->filter_changed |= AR9170_FILTER_CHANGED_FRAMEFILTER; 1446 set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
1447 &ar->filter_changed);
1443 } 1448 }
1444 1449
1445 if (changed_flags & FIF_PROMISC_IN_BSS) { 1450 if (changed_flags & FIF_PROMISC_IN_BSS) {
1446 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0; 1451 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
1447 ar->filter_changed |= AR9170_FILTER_CHANGED_PROMISC; 1452 set_bit(AR9170_FILTER_CHANGED_MODE,
1453 &ar->filter_changed);
1448 } 1454 }
1449 1455
1450 if (likely(IS_STARTED(ar))) 1456 if (likely(IS_STARTED(ar)))
@@ -1464,27 +1470,32 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
1464 if (changed & BSS_CHANGED_BSSID) { 1470 if (changed & BSS_CHANGED_BSSID) {
1465 memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN); 1471 memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN);
1466 err = ar9170_set_operating_mode(ar); 1472 err = ar9170_set_operating_mode(ar);
1473 if (err)
1474 goto out;
1467 } 1475 }
1468 1476
1469 if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) { 1477 if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) {
1470 err = ar9170_update_beacon(ar); 1478 err = ar9170_update_beacon(ar);
1471 if (!err) 1479 if (err)
1472 ar9170_set_beacon_timers(ar); 1480 goto out;
1473 }
1474 1481
1475 ar9170_regwrite_begin(ar); 1482 err = ar9170_set_beacon_timers(ar);
1483 if (err)
1484 goto out;
1485 }
1476 1486
1477 if (changed & BSS_CHANGED_ASSOC) { 1487 if (changed & BSS_CHANGED_ASSOC) {
1478 ar->state = bss_conf->assoc ? AR9170_ASSOCIATED : ar->state;
1479
1480#ifndef CONFIG_AR9170_LEDS 1488#ifndef CONFIG_AR9170_LEDS
1481 /* enable assoc LED. */ 1489 /* enable assoc LED. */
1482 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0); 1490 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
1483#endif /* CONFIG_AR9170_LEDS */ 1491#endif /* CONFIG_AR9170_LEDS */
1484 } 1492 }
1485 1493
1486 if (changed & BSS_CHANGED_BEACON_INT) 1494 if (changed & BSS_CHANGED_BEACON_INT) {
1487 err = ar9170_set_beacon_timers(ar); 1495 err = ar9170_set_beacon_timers(ar);
1496 if (err)
1497 goto out;
1498 }
1488 1499
1489 if (changed & BSS_CHANGED_HT) { 1500 if (changed & BSS_CHANGED_HT) {
1490 /* TODO */ 1501 /* TODO */
@@ -1492,31 +1503,18 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
1492 } 1503 }
1493 1504
1494 if (changed & BSS_CHANGED_ERP_SLOT) { 1505 if (changed & BSS_CHANGED_ERP_SLOT) {
1495 u32 slottime = 20; 1506 err = ar9170_set_slot_time(ar);
1496 1507 if (err)
1497 if (bss_conf->use_short_slot) 1508 goto out;
1498 slottime = 9;
1499
1500 ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, slottime << 10);
1501 } 1509 }
1502 1510
1503 if (changed & BSS_CHANGED_BASIC_RATES) { 1511 if (changed & BSS_CHANGED_BASIC_RATES) {
1504 u32 cck, ofdm; 1512 err = ar9170_set_basic_rates(ar);
1505 1513 if (err)
1506 if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) { 1514 goto out;
1507 ofdm = bss_conf->basic_rates;
1508 cck = 0;
1509 } else {
1510 /* four cck rates */
1511 cck = bss_conf->basic_rates & 0xf;
1512 ofdm = bss_conf->basic_rates >> 4;
1513 }
1514 ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE,
1515 ofdm << 8 | cck);
1516 } 1515 }
1517 1516
1518 ar9170_regwrite_finish(); 1517out:
1519 err = ar9170_regwrite_result();
1520 mutex_unlock(&ar->mutex); 1518 mutex_unlock(&ar->mutex);
1521} 1519}
1522 1520
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
index 6ce20754b8e7..df86f70cd817 100644
--- a/drivers/net/wireless/ath/ar9170/phy.c
+++ b/drivers/net/wireless/ath/ar9170/phy.c
@@ -401,7 +401,7 @@ int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
401 int i, err; 401 int i, err;
402 u32 val; 402 u32 val;
403 bool is_2ghz = band == IEEE80211_BAND_2GHZ; 403 bool is_2ghz = band == IEEE80211_BAND_2GHZ;
404 bool is_40mhz = false; /* XXX: for now */ 404 bool is_40mhz = conf_is_ht40(&ar->hw->conf);
405 405
406 ar9170_regwrite_begin(ar); 406 ar9170_regwrite_begin(ar);
407 407
@@ -1200,7 +1200,7 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1200 return -ENOSYS; 1200 return -ENOSYS;
1201 } 1201 }
1202 1202
1203 if (0 /* 2 streams capable */) 1203 if (ar->eeprom.tx_mask != 1)
1204 tmp |= 0x100; 1204 tmp |= 0x100;
1205 1205
1206 err = ar9170_write_reg(ar, 0x1c5804, tmp); 1206 err = ar9170_write_reg(ar, 0x1c5804, tmp);
@@ -1214,7 +1214,7 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1214 freqpar = ar9170_get_hw_dyn_params(channel, bw); 1214 freqpar = ar9170_get_hw_dyn_params(channel, bw);
1215 1215
1216 vals[0] = cpu_to_le32(channel->center_freq * 1000); 1216 vals[0] = cpu_to_le32(channel->center_freq * 1000);
1217 vals[1] = cpu_to_le32(bw == AR9170_BW_20 ? 0 : 1); 1217 vals[1] = cpu_to_le32(conf_is_ht40(&ar->hw->conf));
1218 vals[2] = cpu_to_le32(offs << 2 | 1); 1218 vals[2] = cpu_to_le32(offs << 2 | 1);
1219 vals[3] = cpu_to_le32(freqpar->coeff_exp); 1219 vals[3] = cpu_to_le32(freqpar->coeff_exp);
1220 vals[4] = cpu_to_le32(freqpar->coeff_man); 1220 vals[4] = cpu_to_le32(freqpar->coeff_man);
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index d7c13c0177ca..f752698669d2 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -51,9 +51,14 @@ MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
51MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>"); 51MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
52MODULE_LICENSE("GPL"); 52MODULE_LICENSE("GPL");
53MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); 53MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
54MODULE_FIRMWARE("ar9170.fw");
54MODULE_FIRMWARE("ar9170-1.fw"); 55MODULE_FIRMWARE("ar9170-1.fw");
55MODULE_FIRMWARE("ar9170-2.fw"); 56MODULE_FIRMWARE("ar9170-2.fw");
56 57
58enum ar9170_requirements {
59 AR9170_REQ_FW1_ONLY = 1,
60};
61
57static struct usb_device_id ar9170_usb_ids[] = { 62static struct usb_device_id ar9170_usb_ids[] = {
58 /* Atheros 9170 */ 63 /* Atheros 9170 */
59 { USB_DEVICE(0x0cf3, 0x9170) }, 64 { USB_DEVICE(0x0cf3, 0x9170) },
@@ -81,6 +86,10 @@ static struct usb_device_id ar9170_usb_ids[] = {
81 { USB_DEVICE(0x2019, 0x5304) }, 86 { USB_DEVICE(0x2019, 0x5304) },
82 /* IO-Data WNGDNUS2 */ 87 /* IO-Data WNGDNUS2 */
83 { USB_DEVICE(0x04bb, 0x093f) }, 88 { USB_DEVICE(0x04bb, 0x093f) },
89 /* AVM FRITZ!WLAN USB Stick N */
90 { USB_DEVICE(0x057C, 0x8401) },
91 /* AVM FRITZ!WLAN USB Stick N 2.4 */
92 { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
84 93
85 /* terminate */ 94 /* terminate */
86 {} 95 {}
@@ -93,7 +102,7 @@ static void ar9170_usb_tx_urb_complete_free(struct urb *urb)
93 struct ar9170_usb *aru = (struct ar9170_usb *) 102 struct ar9170_usb *aru = (struct ar9170_usb *)
94 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); 103 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
95 104
96 if (!aru) { 105 if (unlikely(!aru)) {
97 dev_kfree_skb_irq(skb); 106 dev_kfree_skb_irq(skb);
98 return ; 107 return ;
99 } 108 }
@@ -126,8 +135,8 @@ static void ar9170_usb_irq_completed(struct urb *urb)
126 goto resubmit; 135 goto resubmit;
127 } 136 }
128 137
129 print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET, 138 ar9170_handle_command_response(&aru->common, urb->transfer_buffer,
130 urb->transfer_buffer, urb->actual_length); 139 urb->actual_length);
131 140
132resubmit: 141resubmit:
133 usb_anchor_urb(urb, &aru->rx_submitted); 142 usb_anchor_urb(urb, &aru->rx_submitted);
@@ -177,16 +186,15 @@ resubmit:
177 186
178 usb_anchor_urb(urb, &aru->rx_submitted); 187 usb_anchor_urb(urb, &aru->rx_submitted);
179 err = usb_submit_urb(urb, GFP_ATOMIC); 188 err = usb_submit_urb(urb, GFP_ATOMIC);
180 if (err) { 189 if (unlikely(err)) {
181 usb_unanchor_urb(urb); 190 usb_unanchor_urb(urb);
182 dev_kfree_skb_irq(skb); 191 goto free;
183 } 192 }
184 193
185 return ; 194 return ;
186 195
187free: 196free:
188 dev_kfree_skb_irq(skb); 197 dev_kfree_skb_irq(skb);
189 return;
190} 198}
191 199
192static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru, 200static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
@@ -337,7 +345,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
337 345
338 usb_anchor_urb(urb, &aru->tx_submitted); 346 usb_anchor_urb(urb, &aru->tx_submitted);
339 err = usb_submit_urb(urb, GFP_ATOMIC); 347 err = usb_submit_urb(urb, GFP_ATOMIC);
340 if (err) { 348 if (unlikely(err)) {
341 usb_unanchor_urb(urb); 349 usb_unanchor_urb(urb);
342 usb_free_urb(urb); 350 usb_free_urb(urb);
343 goto err_unbuf; 351 goto err_unbuf;
@@ -418,7 +426,7 @@ static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
418 unsigned long flags; 426 unsigned long flags;
419 u32 in, out; 427 u32 in, out;
420 428
421 if (!buffer) 429 if (unlikely(!buffer))
422 return ; 430 return ;
423 431
424 in = le32_to_cpup((__le32 *)buffer); 432 in = le32_to_cpup((__le32 *)buffer);
@@ -504,17 +512,29 @@ static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
504{ 512{
505 int err = 0; 513 int err = 0;
506 514
507 err = request_firmware(&aru->init_values, "ar9170-1.fw", 515 err = request_firmware(&aru->firmware, "ar9170.fw",
508 &aru->udev->dev); 516 &aru->udev->dev);
509 if (err) { 517 if (!err) {
510 dev_err(&aru->udev->dev, "file with init values not found.\n"); 518 aru->init_values = NULL;
511 return err; 519 return 0;
512 } 520 }
513 521
522 if (aru->req_one_stage_fw) {
523 dev_err(&aru->udev->dev, "ar9170.fw firmware file "
524 "not found and is required for this device\n");
525 return -EINVAL;
526 }
527
528 dev_err(&aru->udev->dev, "ar9170.fw firmware file "
529 "not found, trying old firmware...\n");
530
531 err = request_firmware(&aru->init_values, "ar9170-1.fw",
532 &aru->udev->dev);
533
514 err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev); 534 err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
515 if (err) { 535 if (err) {
516 release_firmware(aru->init_values); 536 release_firmware(aru->init_values);
517 dev_err(&aru->udev->dev, "firmware file not found.\n"); 537 dev_err(&aru->udev->dev, "file with init values not found.\n");
518 return err; 538 return err;
519 } 539 }
520 540
@@ -548,6 +568,9 @@ static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
548{ 568{
549 int err; 569 int err;
550 570
571 if (!aru->init_values)
572 goto upload_fw_start;
573
551 /* First, upload initial values to device RAM */ 574 /* First, upload initial values to device RAM */
552 err = ar9170_usb_upload(aru, aru->init_values->data, 575 err = ar9170_usb_upload(aru, aru->init_values->data,
553 aru->init_values->size, 0x102800, false); 576 aru->init_values->size, 0x102800, false);
@@ -557,6 +580,8 @@ static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
557 return err; 580 return err;
558 } 581 }
559 582
583upload_fw_start:
584
560 /* Then, upload the firmware itself and start it */ 585 /* Then, upload the firmware itself and start it */
561 return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size, 586 return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
562 0x200000, true); 587 0x200000, true);
@@ -656,6 +681,15 @@ err_out:
656 return err; 681 return err;
657} 682}
658 683
684static bool ar9170_requires_one_stage(const struct usb_device_id *id)
685{
686 if (!id->driver_info)
687 return false;
688 if (id->driver_info == AR9170_REQ_FW1_ONLY)
689 return true;
690 return false;
691}
692
659static int ar9170_usb_probe(struct usb_interface *intf, 693static int ar9170_usb_probe(struct usb_interface *intf,
660 const struct usb_device_id *id) 694 const struct usb_device_id *id)
661{ 695{
@@ -676,6 +710,8 @@ static int ar9170_usb_probe(struct usb_interface *intf,
676 aru->intf = intf; 710 aru->intf = intf;
677 ar = &aru->common; 711 ar = &aru->common;
678 712
713 aru->req_one_stage_fw = ar9170_requires_one_stage(id);
714
679 usb_set_intfdata(intf, aru); 715 usb_set_intfdata(intf, aru);
680 SET_IEEE80211_DEV(ar->hw, &udev->dev); 716 SET_IEEE80211_DEV(ar->hw, &udev->dev);
681 717
@@ -691,7 +727,7 @@ static int ar9170_usb_probe(struct usb_interface *intf,
691 727
692#ifdef CONFIG_PM 728#ifdef CONFIG_PM
693 udev->reset_resume = 1; 729 udev->reset_resume = 1;
694#endif 730#endif /* CONFIG_PM */
695 err = ar9170_usb_reset(aru); 731 err = ar9170_usb_reset(aru);
696 if (err) 732 if (err)
697 goto err_freehw; 733 goto err_freehw;
@@ -776,11 +812,6 @@ static int ar9170_resume(struct usb_interface *intf)
776 usb_unpoison_anchored_urbs(&aru->rx_submitted); 812 usb_unpoison_anchored_urbs(&aru->rx_submitted);
777 usb_unpoison_anchored_urbs(&aru->tx_submitted); 813 usb_unpoison_anchored_urbs(&aru->tx_submitted);
778 814
779 /*
780 * FIXME: firmware upload will fail on resume.
781 * but this is better than a hang!
782 */
783
784 err = ar9170_usb_init_device(aru); 815 err = ar9170_usb_init_device(aru);
785 if (err) 816 if (err)
786 goto err_unrx; 817 goto err_unrx;
diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h
index ac42586495d8..69f4bceb0af3 100644
--- a/drivers/net/wireless/ath/ar9170/usb.h
+++ b/drivers/net/wireless/ath/ar9170/usb.h
@@ -62,6 +62,8 @@ struct ar9170_usb {
62 struct usb_anchor rx_submitted; 62 struct usb_anchor rx_submitted;
63 struct usb_anchor tx_submitted; 63 struct usb_anchor tx_submitted;
64 64
65 bool req_one_stage_fw;
66
65 spinlock_t cmdlock; 67 spinlock_t cmdlock;
66 struct completion cmd_wait; 68 struct completion cmd_wait;
67 int readlen; 69 int readlen;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index fb5193764afa..85a00db4867d 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2070,6 +2070,13 @@ err_unmap:
2070 return ret; 2070 return ret;
2071} 2071}
2072 2072
2073static void ath5k_beacon_disable(struct ath5k_softc *sc)
2074{
2075 sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
2076 ath5k_hw_set_imr(sc->ah, sc->imask);
2077 ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
2078}
2079
2073/* 2080/*
2074 * Transmit a beacon frame at SWBA. Dynamic updates to the 2081 * Transmit a beacon frame at SWBA. Dynamic updates to the
2075 * frame contents are done as needed and the slot time is 2082 * frame contents are done as needed and the slot time is
@@ -2757,6 +2764,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
2757 goto end; 2764 goto end;
2758 2765
2759 ath5k_hw_set_lladdr(sc->ah, mac); 2766 ath5k_hw_set_lladdr(sc->ah, mac);
2767 ath5k_beacon_disable(sc);
2760 sc->vif = NULL; 2768 sc->vif = NULL;
2761end: 2769end:
2762 mutex_unlock(&sc->lock); 2770 mutex_unlock(&sc->lock);
@@ -2775,11 +2783,9 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2775 2783
2776 mutex_lock(&sc->lock); 2784 mutex_lock(&sc->lock);
2777 2785
2778 sc->bintval = conf->beacon_int;
2779
2780 ret = ath5k_chan_set(sc, conf->channel); 2786 ret = ath5k_chan_set(sc, conf->channel);
2781 if (ret < 0) 2787 if (ret < 0)
2782 return ret; 2788 goto unlock;
2783 2789
2784 if ((changed & IEEE80211_CONF_CHANGE_POWER) && 2790 if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
2785 (sc->power_level != conf->power_level)) { 2791 (sc->power_level != conf->power_level)) {
@@ -2808,8 +2814,9 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2808 */ 2814 */
2809 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); 2815 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
2810 2816
2817unlock:
2811 mutex_unlock(&sc->lock); 2818 mutex_unlock(&sc->lock);
2812 return 0; 2819 return ret;
2813} 2820}
2814 2821
2815#define SUPPORTED_FIF_FLAGS \ 2822#define SUPPORTED_FIF_FLAGS \
@@ -3061,7 +3068,14 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
3061{ 3068{
3062 int ret; 3069 int ret;
3063 struct ath5k_softc *sc = hw->priv; 3070 struct ath5k_softc *sc = hw->priv;
3064 struct sk_buff *skb = ieee80211_beacon_get(hw, vif); 3071 struct sk_buff *skb;
3072
3073 if (WARN_ON(!vif)) {
3074 ret = -EINVAL;
3075 goto out;
3076 }
3077
3078 skb = ieee80211_beacon_get(hw, vif);
3065 3079
3066 if (!skb) { 3080 if (!skb) {
3067 ret = -ENOMEM; 3081 ret = -ENOMEM;
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 796a3adffea0..515880aa2116 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -460,12 +460,9 @@ struct ath_led {
460 bool registered; 460 bool registered;
461}; 461};
462 462
463/* Rfkill */
464#define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */
465
466struct ath_rfkill { 463struct ath_rfkill {
467 struct rfkill *rfkill; 464 struct rfkill *rfkill;
468 struct delayed_work rfkill_poll; 465 struct rfkill_ops ops;
469 char rfkill_name[32]; 466 char rfkill_name[32];
470}; 467};
471 468
@@ -509,8 +506,6 @@ struct ath_rfkill {
509#define SC_OP_RXFLUSH BIT(7) 506#define SC_OP_RXFLUSH BIT(7)
510#define SC_OP_LED_ASSOCIATED BIT(8) 507#define SC_OP_LED_ASSOCIATED BIT(8)
511#define SC_OP_RFKILL_REGISTERED BIT(9) 508#define SC_OP_RFKILL_REGISTERED BIT(9)
512#define SC_OP_RFKILL_SW_BLOCKED BIT(10)
513#define SC_OP_RFKILL_HW_BLOCKED BIT(11)
514#define SC_OP_WAIT_FOR_BEACON BIT(12) 509#define SC_OP_WAIT_FOR_BEACON BIT(12)
515#define SC_OP_LED_ON BIT(13) 510#define SC_OP_LED_ON BIT(13)
516#define SC_OP_SCANNING BIT(14) 511#define SC_OP_SCANNING BIT(14)
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index a21b21339fbc..3639a2e6987d 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -411,6 +411,7 @@ void ath_beacon_tasklet(unsigned long data)
411 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { 411 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
412 DPRINTF(sc, ATH_DBG_BEACON, 412 DPRINTF(sc, ATH_DBG_BEACON,
413 "beacon is officially stuck\n"); 413 "beacon is officially stuck\n");
414 sc->sc_flags |= SC_OP_TSF_RESET;
414 ath_reset(sc, false); 415 ath_reset(sc, false);
415 } 416 }
416 417
@@ -673,6 +674,14 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
673 674
674 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; 675 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
675 676
677 /*
678 * It looks like mac80211 may end up using beacon interval of zero in
679 * some cases (at least for mesh point). Avoid getting into an
680 * infinite loop by using a bit safer value instead..
681 */
682 if (intval == 0)
683 intval = 100;
684
676 /* Pull nexttbtt forward to reflect the current TSF */ 685 /* Pull nexttbtt forward to reflect the current TSF */
677 686
678 nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp); 687 nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 97df20cbf528..6d20725d6451 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -44,6 +44,44 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file)
44 return 0; 44 return 0;
45} 45}
46 46
47static ssize_t read_file_debug(struct file *file, char __user *user_buf,
48 size_t count, loff_t *ppos)
49{
50 struct ath_softc *sc = file->private_data;
51 char buf[32];
52 unsigned int len;
53
54 len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.debug_mask);
55 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
56}
57
58static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
59 size_t count, loff_t *ppos)
60{
61 struct ath_softc *sc = file->private_data;
62 unsigned long mask;
63 char buf[32];
64 ssize_t len;
65
66 len = min(count, sizeof(buf) - 1);
67 if (copy_from_user(buf, user_buf, len))
68 return -EINVAL;
69
70 buf[len] = '\0';
71 if (strict_strtoul(buf, 0, &mask))
72 return -EINVAL;
73
74 sc->debug.debug_mask = mask;
75 return count;
76}
77
78static const struct file_operations fops_debug = {
79 .read = read_file_debug,
80 .write = write_file_debug,
81 .open = ath9k_debugfs_open,
82 .owner = THIS_MODULE
83};
84
47static ssize_t read_file_dma(struct file *file, char __user *user_buf, 85static ssize_t read_file_dma(struct file *file, char __user *user_buf,
48 size_t count, loff_t *ppos) 86 size_t count, loff_t *ppos)
49{ 87{
@@ -224,111 +262,66 @@ static const struct file_operations fops_interrupt = {
224 .owner = THIS_MODULE 262 .owner = THIS_MODULE
225}; 263};
226 264
227static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb) 265void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
228{
229 struct ath_tx_info_priv *tx_info_priv = NULL;
230 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
231 struct ieee80211_tx_rate *rates = tx_info->status.rates;
232 int final_ts_idx, idx;
233
234 tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
235 final_ts_idx = tx_info_priv->tx.ts_rateindex;
236 idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate;
237
238 sc->debug.stats.n_rcstats[idx].success++;
239}
240
241static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb)
242{ 266{
243 struct ath_tx_info_priv *tx_info_priv = NULL; 267 struct ath_tx_info_priv *tx_info_priv = NULL;
244 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 268 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
245 struct ieee80211_tx_rate *rates = tx_info->status.rates; 269 struct ieee80211_tx_rate *rates = tx_info->status.rates;
246 int final_ts_idx, idx; 270 int final_ts_idx, idx;
271 struct ath_rc_stats *stats;
247 272
248 tx_info_priv = ATH_TX_INFO_PRIV(tx_info); 273 tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
249 final_ts_idx = tx_info_priv->tx.ts_rateindex; 274 final_ts_idx = tx_info_priv->tx.ts_rateindex;
250 idx = rates[final_ts_idx].idx; 275 idx = rates[final_ts_idx].idx;
251 276 stats = &sc->debug.stats.rcstats[idx];
252 sc->debug.stats.legacy_rcstats[idx].success++; 277 stats->success++;
253}
254
255void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
256{
257 if (conf_is_ht(&sc->hw->conf))
258 ath_debug_stat_11n_rc(sc, skb);
259 else
260 ath_debug_stat_legacy_rc(sc, skb);
261} 278}
262 279
263/* FIXME: legacy rates, later on .. */
264void ath_debug_stat_retries(struct ath_softc *sc, int rix, 280void ath_debug_stat_retries(struct ath_softc *sc, int rix,
265 int xretries, int retries, u8 per) 281 int xretries, int retries, u8 per)
266{ 282{
267 if (conf_is_ht(&sc->hw->conf)) { 283 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix];
268 int idx = sc->cur_rate_table->info[rix].dot11rate;
269 284
270 sc->debug.stats.n_rcstats[idx].xretries += xretries; 285 stats->xretries += xretries;
271 sc->debug.stats.n_rcstats[idx].retries += retries; 286 stats->retries += retries;
272 sc->debug.stats.n_rcstats[idx].per = per; 287 stats->per = per;
273 }
274} 288}
275 289
276static ssize_t ath_read_file_stat_11n_rc(struct file *file, 290static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
277 char __user *user_buf, 291 size_t count, loff_t *ppos)
278 size_t count, loff_t *ppos)
279{ 292{
280 struct ath_softc *sc = file->private_data; 293 struct ath_softc *sc = file->private_data;
281 char buf[1024]; 294 char *buf;
282 unsigned int len = 0; 295 unsigned int len = 0, max;
283 int i = 0; 296 int i = 0;
297 ssize_t retval;
284 298
285 len += sprintf(buf, "%7s %13s %8s %8s %6s\n\n", "Rate", "Success", 299 if (sc->cur_rate_table == NULL)
286 "Retries", "XRetries", "PER"); 300 return 0;
287
288 for (i = 0; i <= 15; i++) {
289 len += snprintf(buf + len, sizeof(buf) - len,
290 "%5s%3d: %8u %8u %8u %8u\n", "MCS", i,
291 sc->debug.stats.n_rcstats[i].success,
292 sc->debug.stats.n_rcstats[i].retries,
293 sc->debug.stats.n_rcstats[i].xretries,
294 sc->debug.stats.n_rcstats[i].per);
295 }
296
297 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
298}
299 301
300static ssize_t ath_read_file_stat_legacy_rc(struct file *file, 302 max = 80 + sc->cur_rate_table->rate_cnt * 64;
301 char __user *user_buf, 303 buf = kmalloc(max + 1, GFP_KERNEL);
302 size_t count, loff_t *ppos) 304 if (buf == NULL)
303{ 305 return 0;
304 struct ath_softc *sc = file->private_data; 306 buf[max] = 0;
305 char buf[512];
306 unsigned int len = 0;
307 int i = 0;
308 307
309 len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success"); 308 len += sprintf(buf, "%5s %15s %8s %9s %3s\n\n", "Rate", "Success",
309 "Retries", "XRetries", "PER");
310 310
311 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { 311 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
312 len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n", 312 u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
313 sc->cur_rate_table->info[i].ratekbps / 1000, 313 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
314 sc->debug.stats.legacy_rcstats[i].success); 314
315 len += snprintf(buf + len, max - len,
316 "%3u.%d: %8u %8u %8u %8u\n", ratekbps / 1000,
317 (ratekbps % 1000) / 100, stats->success,
318 stats->retries, stats->xretries,
319 stats->per);
315 } 320 }
316 321
317 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 322 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
318} 323 kfree(buf);
319 324 return retval;
320static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
321 size_t count, loff_t *ppos)
322{
323 struct ath_softc *sc = file->private_data;
324
325 if (sc->cur_rate_table == NULL)
326 return 0;
327
328 if (conf_is_ht(&sc->hw->conf))
329 return ath_read_file_stat_11n_rc(file, user_buf, count, ppos);
330 else
331 return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos);
332} 325}
333 326
334static const struct file_operations fops_rcstat = { 327static const struct file_operations fops_rcstat = {
@@ -506,6 +499,11 @@ int ath9k_init_debug(struct ath_softc *sc)
506 if (!sc->debug.debugfs_phy) 499 if (!sc->debug.debugfs_phy)
507 goto err; 500 goto err;
508 501
502 sc->debug.debugfs_debug = debugfs_create_file("debug",
503 S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug);
504 if (!sc->debug.debugfs_debug)
505 goto err;
506
509 sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO, 507 sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
510 sc->debug.debugfs_phy, sc, &fops_dma); 508 sc->debug.debugfs_phy, sc, &fops_dma);
511 if (!sc->debug.debugfs_dma) 509 if (!sc->debug.debugfs_dma)
@@ -543,6 +541,7 @@ void ath9k_exit_debug(struct ath_softc *sc)
543 debugfs_remove(sc->debug.debugfs_rcstat); 541 debugfs_remove(sc->debug.debugfs_rcstat);
544 debugfs_remove(sc->debug.debugfs_interrupt); 542 debugfs_remove(sc->debug.debugfs_interrupt);
545 debugfs_remove(sc->debug.debugfs_dma); 543 debugfs_remove(sc->debug.debugfs_dma);
544 debugfs_remove(sc->debug.debugfs_debug);
546 debugfs_remove(sc->debug.debugfs_phy); 545 debugfs_remove(sc->debug.debugfs_phy);
547} 546}
548 547
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index db845cf960c9..edda15bf2c15 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -80,11 +80,7 @@ struct ath_interrupt_stats {
80 u32 dtim; 80 u32 dtim;
81}; 81};
82 82
83struct ath_legacy_rc_stats { 83struct ath_rc_stats {
84 u32 success;
85};
86
87struct ath_11n_rc_stats {
88 u32 success; 84 u32 success;
89 u32 retries; 85 u32 retries;
90 u32 xretries; 86 u32 xretries;
@@ -93,13 +89,13 @@ struct ath_11n_rc_stats {
93 89
94struct ath_stats { 90struct ath_stats {
95 struct ath_interrupt_stats istats; 91 struct ath_interrupt_stats istats;
96 struct ath_legacy_rc_stats legacy_rcstats[12]; /* max(11a,11b,11g) */ 92 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
97 struct ath_11n_rc_stats n_rcstats[16]; /* 0..15 MCS rates */
98}; 93};
99 94
100struct ath9k_debug { 95struct ath9k_debug {
101 int debug_mask; 96 int debug_mask;
102 struct dentry *debugfs_phy; 97 struct dentry *debugfs_phy;
98 struct dentry *debugfs_debug;
103 struct dentry *debugfs_dma; 99 struct dentry *debugfs_dma;
104 struct dentry *debugfs_interrupt; 100 struct dentry *debugfs_interrupt;
105 struct dentry *debugfs_rcstat; 101 struct dentry *debugfs_rcstat;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 61da08a1648c..f7baa406918b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1192,120 +1192,69 @@ static bool ath_is_rfkill_set(struct ath_softc *sc)
1192 ah->rfkill_polarity; 1192 ah->rfkill_polarity;
1193} 1193}
1194 1194
1195/* h/w rfkill poll function */ 1195/* s/w rfkill handlers */
1196static void ath_rfkill_poll(struct work_struct *work) 1196static int ath_rfkill_set_block(void *data, bool blocked)
1197{ 1197{
1198 struct ath_softc *sc = container_of(work, struct ath_softc, 1198 struct ath_softc *sc = data;
1199 rf_kill.rfkill_poll.work);
1200 bool radio_on;
1201
1202 if (sc->sc_flags & SC_OP_INVALID)
1203 return;
1204
1205 radio_on = !ath_is_rfkill_set(sc);
1206
1207 /*
1208 * enable/disable radio only when there is a
1209 * state change in RF switch
1210 */
1211 if (radio_on == !!(sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED)) {
1212 enum rfkill_state state;
1213
1214 if (sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED) {
1215 state = radio_on ? RFKILL_STATE_SOFT_BLOCKED
1216 : RFKILL_STATE_HARD_BLOCKED;
1217 } else if (radio_on) {
1218 ath_radio_enable(sc);
1219 state = RFKILL_STATE_UNBLOCKED;
1220 } else {
1221 ath_radio_disable(sc);
1222 state = RFKILL_STATE_HARD_BLOCKED;
1223 }
1224
1225 if (state == RFKILL_STATE_HARD_BLOCKED)
1226 sc->sc_flags |= SC_OP_RFKILL_HW_BLOCKED;
1227 else
1228 sc->sc_flags &= ~SC_OP_RFKILL_HW_BLOCKED;
1229 1199
1230 rfkill_force_state(sc->rf_kill.rfkill, state); 1200 if (blocked)
1231 } 1201 ath_radio_disable(sc);
1202 else
1203 ath_radio_enable(sc);
1232 1204
1233 queue_delayed_work(sc->hw->workqueue, &sc->rf_kill.rfkill_poll, 1205 return 0;
1234 msecs_to_jiffies(ATH_RFKILL_POLL_INTERVAL));
1235} 1206}
1236 1207
1237/* s/w rfkill handler */ 1208static void ath_rfkill_poll_state(struct rfkill *rfkill, void *data)
1238static int ath_sw_toggle_radio(void *data, enum rfkill_state state)
1239{ 1209{
1240 struct ath_softc *sc = data; 1210 struct ath_softc *sc = data;
1211 bool blocked = !!ath_is_rfkill_set(sc);
1241 1212
1242 switch (state) { 1213 if (rfkill_set_hw_state(rfkill, blocked))
1243 case RFKILL_STATE_SOFT_BLOCKED: 1214 ath_radio_disable(sc);
1244 if (!(sc->sc_flags & (SC_OP_RFKILL_HW_BLOCKED | 1215 else
1245 SC_OP_RFKILL_SW_BLOCKED))) 1216 ath_radio_enable(sc);
1246 ath_radio_disable(sc);
1247 sc->sc_flags |= SC_OP_RFKILL_SW_BLOCKED;
1248 return 0;
1249 case RFKILL_STATE_UNBLOCKED:
1250 if ((sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED)) {
1251 sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED;
1252 if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) {
1253 DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the"
1254 "radio as it is disabled by h/w\n");
1255 return -EPERM;
1256 }
1257 ath_radio_enable(sc);
1258 }
1259 return 0;
1260 default:
1261 return -EINVAL;
1262 }
1263} 1217}
1264 1218
1265/* Init s/w rfkill */ 1219/* Init s/w rfkill */
1266static int ath_init_sw_rfkill(struct ath_softc *sc) 1220static int ath_init_sw_rfkill(struct ath_softc *sc)
1267{ 1221{
1268 sc->rf_kill.rfkill = rfkill_allocate(wiphy_dev(sc->hw->wiphy), 1222 sc->rf_kill.ops.set_block = ath_rfkill_set_block;
1269 RFKILL_TYPE_WLAN); 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);
1270 if (!sc->rf_kill.rfkill) { 1233 if (!sc->rf_kill.rfkill) {
1271 DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n"); 1234 DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n");
1272 return -ENOMEM; 1235 return -ENOMEM;
1273 } 1236 }
1274 1237
1275 snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
1276 "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy));
1277 sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name;
1278 sc->rf_kill.rfkill->data = sc;
1279 sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio;
1280 sc->rf_kill.rfkill->state = RFKILL_STATE_UNBLOCKED;
1281
1282 return 0; 1238 return 0;
1283} 1239}
1284 1240
1285/* Deinitialize rfkill */ 1241/* Deinitialize rfkill */
1286static void ath_deinit_rfkill(struct ath_softc *sc) 1242static void ath_deinit_rfkill(struct ath_softc *sc)
1287{ 1243{
1288 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1289 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
1290
1291 if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) { 1244 if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {
1292 rfkill_unregister(sc->rf_kill.rfkill); 1245 rfkill_unregister(sc->rf_kill.rfkill);
1246 rfkill_destroy(sc->rf_kill.rfkill);
1293 sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED; 1247 sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED;
1294 sc->rf_kill.rfkill = NULL;
1295 } 1248 }
1296} 1249}
1297 1250
1298static int ath_start_rfkill_poll(struct ath_softc *sc) 1251static int ath_start_rfkill_poll(struct ath_softc *sc)
1299{ 1252{
1300 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1301 queue_delayed_work(sc->hw->workqueue,
1302 &sc->rf_kill.rfkill_poll, 0);
1303
1304 if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) { 1253 if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {
1305 if (rfkill_register(sc->rf_kill.rfkill)) { 1254 if (rfkill_register(sc->rf_kill.rfkill)) {
1306 DPRINTF(sc, ATH_DBG_FATAL, 1255 DPRINTF(sc, ATH_DBG_FATAL,
1307 "Unable to register rfkill\n"); 1256 "Unable to register rfkill\n");
1308 rfkill_free(sc->rf_kill.rfkill); 1257 rfkill_destroy(sc->rf_kill.rfkill);
1309 1258
1310 /* Deinitialize the device */ 1259 /* Deinitialize the device */
1311 ath_cleanup(sc); 1260 ath_cleanup(sc);
@@ -1678,10 +1627,6 @@ int ath_attach(u16 devid, struct ath_softc *sc)
1678 goto error_attach; 1627 goto error_attach;
1679 1628
1680#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 1629#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
1681 /* Initialze h/w Rfkill */
1682 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1683 INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll);
1684
1685 /* Initialize s/w rfkill */ 1630 /* Initialize s/w rfkill */
1686 error = ath_init_sw_rfkill(sc); 1631 error = ath_init_sw_rfkill(sc);
1687 if (error) 1632 if (error)
@@ -2214,10 +2159,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2214 } else 2159 } else
2215 sc->rx.rxlink = NULL; 2160 sc->rx.rxlink = NULL;
2216 2161
2217#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 2162 rfkill_pause_polling(sc->rf_kill.rfkill);
2218 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 2163
2219 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
2220#endif
2221 /* disable HAL and put h/w to sleep */ 2164 /* disable HAL and put h/w to sleep */
2222 ath9k_hw_disable(sc->sc_ah); 2165 ath9k_hw_disable(sc->sc_ah);
2223 ath9k_hw_configpcipowersave(sc->sc_ah, 1); 2166 ath9k_hw_configpcipowersave(sc->sc_ah, 1);
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 168411d322a2..ccdf20a2e9be 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -227,11 +227,6 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
227 227
228 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); 228 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
229 229
230#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
231 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
232 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
233#endif
234
235 pci_save_state(pdev); 230 pci_save_state(pdev);
236 pci_disable_device(pdev); 231 pci_disable_device(pdev);
237 pci_set_power_state(pdev, PCI_D3hot); 232 pci_set_power_state(pdev, PCI_D3hot);
@@ -256,16 +251,6 @@ static int ath_pci_resume(struct pci_dev *pdev)
256 AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 251 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
257 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); 252 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
258 253
259#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
260 /*
261 * check the h/w rfkill state on resume
262 * and start the rfkill poll timer
263 */
264 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
265 queue_delayed_work(sc->hw->workqueue,
266 &sc->rf_kill.rfkill_poll, 0);
267#endif
268
269 return 0; 254 return 0;
270} 255}
271 256
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 7a89f9fac7d4..eef370bd1211 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -366,11 +366,17 @@ static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
366 if (rd & COUNTRY_ERD_FLAG) { 366 if (rd & COUNTRY_ERD_FLAG) {
367 /* EEPROM value is a country code */ 367 /* EEPROM value is a country code */
368 u16 cc = rd & ~COUNTRY_ERD_FLAG; 368 u16 cc = rd & ~COUNTRY_ERD_FLAG;
369 printk(KERN_DEBUG
370 "ath: EEPROM indicates we should expect "
371 "a country code\n");
369 for (i = 0; i < ARRAY_SIZE(allCountries); i++) 372 for (i = 0; i < ARRAY_SIZE(allCountries); i++)
370 if (allCountries[i].countryCode == cc) 373 if (allCountries[i].countryCode == cc)
371 return true; 374 return true;
372 } else { 375 } else {
373 /* EEPROM value is a regpair value */ 376 /* EEPROM value is a regpair value */
377 if (rd != CTRY_DEFAULT)
378 printk(KERN_DEBUG "ath: EEPROM indicates we "
379 "should expect a direct regpair map\n");
374 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) 380 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
375 if (regDomainPairs[i].regDmnEnum == rd) 381 if (regDomainPairs[i].regDmnEnum == rd)
376 return true; 382 return true;
@@ -477,6 +483,11 @@ ath_regd_init(struct ath_regulatory *reg,
477 struct country_code_to_enum_rd *country = NULL; 483 struct country_code_to_enum_rd *country = NULL;
478 u16 regdmn; 484 u16 regdmn;
479 485
486 if (!reg)
487 return -EINVAL;
488
489 printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);
490
480 if (!ath_regd_is_eeprom_valid(reg)) { 491 if (!ath_regd_is_eeprom_valid(reg)) {
481 printk(KERN_ERR "ath: Invalid EEPROM contents\n"); 492 printk(KERN_ERR "ath: Invalid EEPROM contents\n");
482 return -EINVAL; 493 return -EINVAL;
@@ -486,20 +497,30 @@ ath_regd_init(struct ath_regulatory *reg,
486 reg->country_code = ath_regd_get_default_country(regdmn); 497 reg->country_code = ath_regd_get_default_country(regdmn);
487 498
488 if (reg->country_code == CTRY_DEFAULT && 499 if (reg->country_code == CTRY_DEFAULT &&
489 regdmn == CTRY_DEFAULT) 500 regdmn == CTRY_DEFAULT) {
501 printk(KERN_DEBUG "ath: EEPROM indicates default "
502 "country code should be used\n");
490 reg->country_code = CTRY_UNITED_STATES; 503 reg->country_code = CTRY_UNITED_STATES;
504 }
491 505
492 if (reg->country_code == CTRY_DEFAULT) { 506 if (reg->country_code == CTRY_DEFAULT) {
493 country = NULL; 507 country = NULL;
494 } else { 508 } else {
509 printk(KERN_DEBUG "ath: doing EEPROM country->regdmn "
510 "map search\n");
495 country = ath_regd_find_country(reg->country_code); 511 country = ath_regd_find_country(reg->country_code);
496 if (country == NULL) { 512 if (country == NULL) {
497 printk(KERN_DEBUG 513 printk(KERN_DEBUG
498 "ath: Country is NULL!!!!, cc= %d\n", 514 "ath: no valid country maps found for "
515 "country code: 0x%0x\n",
499 reg->country_code); 516 reg->country_code);
500 return -EINVAL; 517 return -EINVAL;
501 } else 518 } else {
502 regdmn = country->regDmnEnum; 519 regdmn = country->regDmnEnum;
520 printk(KERN_DEBUG "ath: country maps to "
521 "regdmn code: 0x%0x\n",
522 regdmn);
523 }
503 } 524 }
504 525
505 reg->regpair = ath_get_regpair(regdmn); 526 reg->regpair = ath_get_regpair(regdmn);
@@ -523,7 +544,7 @@ ath_regd_init(struct ath_regulatory *reg,
523 544
524 printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n", 545 printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n",
525 reg->alpha2[0], reg->alpha2[1]); 546 reg->alpha2[0], reg->alpha2[1]);
526 printk(KERN_DEBUG "ath: Regpair detected: 0x%0x\n", 547 printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n",
527 reg->regpair->regDmnEnum); 548 reg->regpair->regDmnEnum);
528 549
529 ath_regd_init_wiphy(reg, wiphy, reg_notifier); 550 ath_regd_init_wiphy(reg, wiphy, reg_notifier);
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 21572e40b79d..07a99e3faf94 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -102,7 +102,7 @@ config B43_LEDS
102# if it's possible. 102# if it's possible.
103config B43_RFKILL 103config B43_RFKILL
104 bool 104 bool
105 depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43) 105 depends on B43 && (RFKILL = y || RFKILL = B43)
106 default y 106 default y
107 107
108# This config option automatically enables b43 HW-RNG support, 108# This config option automatically enables b43 HW-RNG support,
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c
index 76f4c7bad8b8..9a498d3fc653 100644
--- a/drivers/net/wireless/b43/leds.c
+++ b/drivers/net/wireless/b43/leds.c
@@ -87,7 +87,7 @@ static void b43_led_brightness_set(struct led_classdev *led_dev,
87} 87}
88 88
89static int b43_register_led(struct b43_wldev *dev, struct b43_led *led, 89static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
90 const char *name, char *default_trigger, 90 const char *name, const char *default_trigger,
91 u8 led_index, bool activelow) 91 u8 led_index, bool activelow)
92{ 92{
93 int err; 93 int err;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index cb4a8712946a..1d3e40095ada 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3470,7 +3470,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3470 3470
3471 if (!!conf->radio_enabled != phy->radio_on) { 3471 if (!!conf->radio_enabled != phy->radio_on) {
3472 if (conf->radio_enabled) { 3472 if (conf->radio_enabled) {
3473 b43_software_rfkill(dev, RFKILL_STATE_UNBLOCKED); 3473 b43_software_rfkill(dev, false);
3474 b43info(dev->wl, "Radio turned on by software\n"); 3474 b43info(dev->wl, "Radio turned on by software\n");
3475 if (!dev->radio_hw_enable) { 3475 if (!dev->radio_hw_enable) {
3476 b43info(dev->wl, "The hardware RF-kill button " 3476 b43info(dev->wl, "The hardware RF-kill button "
@@ -3478,7 +3478,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3478 "Press the button to turn it on.\n"); 3478 "Press the button to turn it on.\n");
3479 } 3479 }
3480 } else { 3480 } else {
3481 b43_software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); 3481 b43_software_rfkill(dev, true);
3482 b43info(dev->wl, "Radio turned off by software\n"); 3482 b43info(dev->wl, "Radio turned off by software\n");
3483 } 3483 }
3484 } 3484 }
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index c836c077d51d..816e028a2620 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -480,11 +480,11 @@ static bool b43_aphy_op_supports_hwpctl(struct b43_wldev *dev)
480} 480}
481 481
482static void b43_aphy_op_software_rfkill(struct b43_wldev *dev, 482static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,
483 enum rfkill_state state) 483 bool blocked)
484{ 484{
485 struct b43_phy *phy = &dev->phy; 485 struct b43_phy *phy = &dev->phy;
486 486
487 if (state == RFKILL_STATE_UNBLOCKED) { 487 if (!blocked) {
488 if (phy->radio_on) 488 if (phy->radio_on)
489 return; 489 return;
490 b43_radio_write16(dev, 0x0004, 0x00C0); 490 b43_radio_write16(dev, 0x0004, 0x00C0);
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index e176b6e0d9cf..6d241622210e 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -84,7 +84,7 @@ int b43_phy_init(struct b43_wldev *dev)
84 84
85 phy->channel = ops->get_default_chan(dev); 85 phy->channel = ops->get_default_chan(dev);
86 86
87 ops->software_rfkill(dev, RFKILL_STATE_UNBLOCKED); 87 ops->software_rfkill(dev, false);
88 err = ops->init(dev); 88 err = ops->init(dev);
89 if (err) { 89 if (err) {
90 b43err(dev->wl, "PHY init failed\n"); 90 b43err(dev->wl, "PHY init failed\n");
@@ -104,7 +104,7 @@ err_phy_exit:
104 if (ops->exit) 104 if (ops->exit)
105 ops->exit(dev); 105 ops->exit(dev);
106err_block_rf: 106err_block_rf:
107 ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); 107 ops->software_rfkill(dev, true);
108 108
109 return err; 109 return err;
110} 110}
@@ -113,7 +113,7 @@ void b43_phy_exit(struct b43_wldev *dev)
113{ 113{
114 const struct b43_phy_operations *ops = dev->phy.ops; 114 const struct b43_phy_operations *ops = dev->phy.ops;
115 115
116 ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); 116 ops->software_rfkill(dev, true);
117 if (ops->exit) 117 if (ops->exit)
118 ops->exit(dev); 118 ops->exit(dev);
119} 119}
@@ -295,18 +295,13 @@ err_restore_cookie:
295 return err; 295 return err;
296} 296}
297 297
298void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state) 298void b43_software_rfkill(struct b43_wldev *dev, bool blocked)
299{ 299{
300 struct b43_phy *phy = &dev->phy; 300 struct b43_phy *phy = &dev->phy;
301 301
302 if (state == RFKILL_STATE_HARD_BLOCKED) {
303 /* We cannot hardware-block the device */
304 state = RFKILL_STATE_SOFT_BLOCKED;
305 }
306
307 b43_mac_suspend(dev); 302 b43_mac_suspend(dev);
308 phy->ops->software_rfkill(dev, state); 303 phy->ops->software_rfkill(dev, blocked);
309 phy->radio_on = (state == RFKILL_STATE_UNBLOCKED); 304 phy->radio_on = !blocked;
310 b43_mac_enable(dev); 305 b43_mac_enable(dev);
311} 306}
312 307
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index b2d99101947b..f4c2d79cbc89 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -159,7 +159,7 @@ struct b43_phy_operations {
159 159
160 /* Radio */ 160 /* Radio */
161 bool (*supports_hwpctl)(struct b43_wldev *dev); 161 bool (*supports_hwpctl)(struct b43_wldev *dev);
162 void (*software_rfkill)(struct b43_wldev *dev, enum rfkill_state state); 162 void (*software_rfkill)(struct b43_wldev *dev, bool blocked);
163 void (*switch_analog)(struct b43_wldev *dev, bool on); 163 void (*switch_analog)(struct b43_wldev *dev, bool on);
164 int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel); 164 int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel);
165 unsigned int (*get_default_chan)(struct b43_wldev *dev); 165 unsigned int (*get_default_chan)(struct b43_wldev *dev);
@@ -364,7 +364,7 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
364/** 364/**
365 * b43_software_rfkill - Turn the radio ON or OFF in software. 365 * b43_software_rfkill - Turn the radio ON or OFF in software.
366 */ 366 */
367void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state); 367void b43_software_rfkill(struct b43_wldev *dev, bool blocked);
368 368
369/** 369/**
370 * b43_phy_txpower_check - Check TX power output. 370 * b43_phy_txpower_check - Check TX power output.
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index e7b98f013b0f..5300232449f6 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -2592,7 +2592,7 @@ static bool b43_gphy_op_supports_hwpctl(struct b43_wldev *dev)
2592} 2592}
2593 2593
2594static void b43_gphy_op_software_rfkill(struct b43_wldev *dev, 2594static void b43_gphy_op_software_rfkill(struct b43_wldev *dev,
2595 enum rfkill_state state) 2595 bool blocked)
2596{ 2596{
2597 struct b43_phy *phy = &dev->phy; 2597 struct b43_phy *phy = &dev->phy;
2598 struct b43_phy_g *gphy = phy->g; 2598 struct b43_phy_g *gphy = phy->g;
@@ -2600,7 +2600,7 @@ static void b43_gphy_op_software_rfkill(struct b43_wldev *dev,
2600 2600
2601 might_sleep(); 2601 might_sleep();
2602 2602
2603 if (state == RFKILL_STATE_UNBLOCKED) { 2603 if (!blocked) {
2604 /* Turn radio ON */ 2604 /* Turn radio ON */
2605 if (phy->radio_on) 2605 if (phy->radio_on)
2606 return; 2606 return;
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 58e319d6b1ed..ea0d3a3a6a64 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -488,7 +488,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
488} 488}
489 489
490static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev, 490static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev,
491 enum rfkill_state state) 491 bool blocked)
492{ 492{
493 //TODO 493 //TODO
494} 494}
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 8bcfda5f3f07..be7b5604947b 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -579,7 +579,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
579} 579}
580 580
581static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, 581static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
582 enum rfkill_state state) 582 bool blocked)
583{//TODO 583{//TODO
584} 584}
585 585
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 9e1d00bc24d3..96047843cd56 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -45,12 +45,11 @@ static bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
45} 45}
46 46
47/* The poll callback for the hardware button. */ 47/* The poll callback for the hardware button. */
48static void b43_rfkill_poll(struct input_polled_dev *poll_dev) 48static void b43_rfkill_poll(struct rfkill *rfkill, void *data)
49{ 49{
50 struct b43_wldev *dev = poll_dev->private; 50 struct b43_wldev *dev = data;
51 struct b43_wl *wl = dev->wl; 51 struct b43_wl *wl = dev->wl;
52 bool enabled; 52 bool enabled;
53 bool report_change = 0;
54 53
55 mutex_lock(&wl->mutex); 54 mutex_lock(&wl->mutex);
56 if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { 55 if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) {
@@ -60,68 +59,55 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
60 enabled = b43_is_hw_radio_enabled(dev); 59 enabled = b43_is_hw_radio_enabled(dev);
61 if (unlikely(enabled != dev->radio_hw_enable)) { 60 if (unlikely(enabled != dev->radio_hw_enable)) {
62 dev->radio_hw_enable = enabled; 61 dev->radio_hw_enable = enabled;
63 report_change = 1;
64 b43info(wl, "Radio hardware status changed to %s\n", 62 b43info(wl, "Radio hardware status changed to %s\n",
65 enabled ? "ENABLED" : "DISABLED"); 63 enabled ? "ENABLED" : "DISABLED");
64 enabled = !rfkill_set_hw_state(rfkill, !enabled);
65 if (enabled != dev->phy.radio_on)
66 b43_software_rfkill(dev, !enabled);
66 } 67 }
67 mutex_unlock(&wl->mutex); 68 mutex_unlock(&wl->mutex);
68
69 /* send the radio switch event to the system - note both a key press
70 * and a release are required */
71 if (unlikely(report_change)) {
72 input_report_key(poll_dev->input, KEY_WLAN, 1);
73 input_report_key(poll_dev->input, KEY_WLAN, 0);
74 }
75} 69}
76 70
77/* Called when the RFKILL toggled in software. */ 71/* Called when the RFKILL toggled in software. */
78static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) 72static int b43_rfkill_soft_set(void *data, bool blocked)
79{ 73{
80 struct b43_wldev *dev = data; 74 struct b43_wldev *dev = data;
81 struct b43_wl *wl = dev->wl; 75 struct b43_wl *wl = dev->wl;
82 int err = -EBUSY; 76 int err = -EINVAL;
83 77
84 if (!wl->rfkill.registered) 78 if (WARN_ON(!wl->rfkill.registered))
85 return 0; 79 return -EINVAL;
86 80
87 mutex_lock(&wl->mutex); 81 mutex_lock(&wl->mutex);
82
88 if (b43_status(dev) < B43_STAT_INITIALIZED) 83 if (b43_status(dev) < B43_STAT_INITIALIZED)
89 goto out_unlock; 84 goto out_unlock;
85
86 if (!dev->radio_hw_enable)
87 goto out_unlock;
88
89 if (!blocked != dev->phy.radio_on)
90 b43_software_rfkill(dev, blocked);
90 err = 0; 91 err = 0;
91 switch (state) {
92 case RFKILL_STATE_UNBLOCKED:
93 if (!dev->radio_hw_enable) {
94 /* No luck. We can't toggle the hardware RF-kill
95 * button from software. */
96 err = -EBUSY;
97 goto out_unlock;
98 }
99 if (!dev->phy.radio_on)
100 b43_software_rfkill(dev, state);
101 break;
102 case RFKILL_STATE_SOFT_BLOCKED:
103 if (dev->phy.radio_on)
104 b43_software_rfkill(dev, state);
105 break;
106 default:
107 b43warn(wl, "Received unexpected rfkill state %d.\n", state);
108 break;
109 }
110out_unlock: 92out_unlock:
111 mutex_unlock(&wl->mutex); 93 mutex_unlock(&wl->mutex);
112
113 return err; 94 return err;
114} 95}
115 96
116char *b43_rfkill_led_name(struct b43_wldev *dev) 97const char *b43_rfkill_led_name(struct b43_wldev *dev)
117{ 98{
118 struct b43_rfkill *rfk = &(dev->wl->rfkill); 99 struct b43_rfkill *rfk = &(dev->wl->rfkill);
119 100
120 if (!rfk->registered) 101 if (!rfk->registered)
121 return NULL; 102 return NULL;
122 return rfkill_get_led_name(rfk->rfkill); 103 return rfkill_get_led_trigger_name(rfk->rfkill);
123} 104}
124 105
106static const struct rfkill_ops b43_rfkill_ops = {
107 .set_block = b43_rfkill_soft_set,
108 .poll = b43_rfkill_poll,
109};
110
125void b43_rfkill_init(struct b43_wldev *dev) 111void b43_rfkill_init(struct b43_wldev *dev)
126{ 112{
127 struct b43_wl *wl = dev->wl; 113 struct b43_wl *wl = dev->wl;
@@ -130,65 +116,26 @@ void b43_rfkill_init(struct b43_wldev *dev)
130 116
131 rfk->registered = 0; 117 rfk->registered = 0;
132 118
133 rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
134 if (!rfk->rfkill)
135 goto out_error;
136 snprintf(rfk->name, sizeof(rfk->name), 119 snprintf(rfk->name, sizeof(rfk->name),
137 "b43-%s", wiphy_name(wl->hw->wiphy)); 120 "b43-%s", wiphy_name(wl->hw->wiphy));
138 rfk->rfkill->name = rfk->name;
139 rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
140 rfk->rfkill->data = dev;
141 rfk->rfkill->toggle_radio = b43_rfkill_soft_toggle;
142
143 rfk->poll_dev = input_allocate_polled_device();
144 if (!rfk->poll_dev) {
145 rfkill_free(rfk->rfkill);
146 goto err_freed_rfk;
147 }
148
149 rfk->poll_dev->private = dev;
150 rfk->poll_dev->poll = b43_rfkill_poll;
151 rfk->poll_dev->poll_interval = 1000; /* msecs */
152 121
153 rfk->poll_dev->input->name = rfk->name; 122 rfk->rfkill = rfkill_alloc(rfk->name,
154 rfk->poll_dev->input->id.bustype = BUS_HOST; 123 dev->dev->dev,
155 rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor; 124 RFKILL_TYPE_WLAN,
156 rfk->poll_dev->input->evbit[0] = BIT(EV_KEY); 125 &b43_rfkill_ops, dev);
157 set_bit(KEY_WLAN, rfk->poll_dev->input->keybit); 126 if (!rfk->rfkill)
127 goto out_error;
158 128
159 err = rfkill_register(rfk->rfkill); 129 err = rfkill_register(rfk->rfkill);
160 if (err) 130 if (err)
161 goto err_free_polldev; 131 goto err_free;
162
163#ifdef CONFIG_RFKILL_INPUT_MODULE
164 /* B43 RF-kill isn't useful without the rfkill-input subsystem.
165 * Try to load the module. */
166 err = request_module("rfkill-input");
167 if (err)
168 b43warn(wl, "Failed to load the rfkill-input module. "
169 "The built-in radio LED will not work.\n");
170#endif /* CONFIG_RFKILL_INPUT */
171
172#if !defined(CONFIG_RFKILL_INPUT) && !defined(CONFIG_RFKILL_INPUT_MODULE)
173 b43warn(wl, "The rfkill-input subsystem is not available. "
174 "The built-in radio LED will not work.\n");
175#endif
176
177 err = input_register_polled_device(rfk->poll_dev);
178 if (err)
179 goto err_unreg_rfk;
180 132
181 rfk->registered = 1; 133 rfk->registered = 1;
182 134
183 return; 135 return;
184err_unreg_rfk: 136 err_free:
185 rfkill_unregister(rfk->rfkill); 137 rfkill_destroy(rfk->rfkill);
186err_free_polldev: 138 out_error:
187 input_free_polled_device(rfk->poll_dev);
188 rfk->poll_dev = NULL;
189err_freed_rfk:
190 rfk->rfkill = NULL;
191out_error:
192 rfk->registered = 0; 139 rfk->registered = 0;
193 b43warn(wl, "RF-kill button init failed\n"); 140 b43warn(wl, "RF-kill button init failed\n");
194} 141}
@@ -201,9 +148,7 @@ void b43_rfkill_exit(struct b43_wldev *dev)
201 return; 148 return;
202 rfk->registered = 0; 149 rfk->registered = 0;
203 150
204 input_unregister_polled_device(rfk->poll_dev);
205 rfkill_unregister(rfk->rfkill); 151 rfkill_unregister(rfk->rfkill);
206 input_free_polled_device(rfk->poll_dev); 152 rfkill_destroy(rfk->rfkill);
207 rfk->poll_dev = NULL;
208 rfk->rfkill = NULL; 153 rfk->rfkill = NULL;
209} 154}
diff --git a/drivers/net/wireless/b43/rfkill.h b/drivers/net/wireless/b43/rfkill.h
index adacf936d815..da497e01bbb1 100644
--- a/drivers/net/wireless/b43/rfkill.h
+++ b/drivers/net/wireless/b43/rfkill.h
@@ -7,14 +7,11 @@ struct b43_wldev;
7#ifdef CONFIG_B43_RFKILL 7#ifdef CONFIG_B43_RFKILL
8 8
9#include <linux/rfkill.h> 9#include <linux/rfkill.h>
10#include <linux/input-polldev.h>
11 10
12 11
13struct b43_rfkill { 12struct b43_rfkill {
14 /* The RFKILL subsystem data structure */ 13 /* The RFKILL subsystem data structure */
15 struct rfkill *rfkill; 14 struct rfkill *rfkill;
16 /* The poll device for the RFKILL input button */
17 struct input_polled_dev *poll_dev;
18 /* Did initialization succeed? Used for freeing. */ 15 /* Did initialization succeed? Used for freeing. */
19 bool registered; 16 bool registered;
20 /* The unique name of this rfkill switch */ 17 /* The unique name of this rfkill switch */
@@ -26,7 +23,7 @@ struct b43_rfkill {
26void b43_rfkill_init(struct b43_wldev *dev); 23void b43_rfkill_init(struct b43_wldev *dev);
27void b43_rfkill_exit(struct b43_wldev *dev); 24void b43_rfkill_exit(struct b43_wldev *dev);
28 25
29char * b43_rfkill_led_name(struct b43_wldev *dev); 26const char *b43_rfkill_led_name(struct b43_wldev *dev);
30 27
31 28
32#else /* CONFIG_B43_RFKILL */ 29#else /* CONFIG_B43_RFKILL */
diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig
index d4f628a74bbd..6893f439df70 100644
--- a/drivers/net/wireless/b43legacy/Kconfig
+++ b/drivers/net/wireless/b43legacy/Kconfig
@@ -47,7 +47,7 @@ config B43LEGACY_LEDS
47# if it's possible. 47# if it's possible.
48config B43LEGACY_RFKILL 48config B43LEGACY_RFKILL
49 bool 49 bool
50 depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43LEGACY) 50 depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY)
51 default y 51 default y
52 52
53# This config option automatically enables b43 HW-RNG support, 53# This config option automatically enables b43 HW-RNG support,
diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c
index 3ea55b18c700..538d3117594b 100644
--- a/drivers/net/wireless/b43legacy/leds.c
+++ b/drivers/net/wireless/b43legacy/leds.c
@@ -86,7 +86,8 @@ static void b43legacy_led_brightness_set(struct led_classdev *led_dev,
86 86
87static int b43legacy_register_led(struct b43legacy_wldev *dev, 87static int b43legacy_register_led(struct b43legacy_wldev *dev,
88 struct b43legacy_led *led, 88 struct b43legacy_led *led,
89 const char *name, char *default_trigger, 89 const char *name,
90 const char *default_trigger,
90 u8 led_index, bool activelow) 91 u8 led_index, bool activelow)
91{ 92{
92 int err; 93 int err;
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c
index 4b0c7d27a51f..c6230a64505a 100644
--- a/drivers/net/wireless/b43legacy/rfkill.c
+++ b/drivers/net/wireless/b43legacy/rfkill.c
@@ -45,12 +45,11 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
45} 45}
46 46
47/* The poll callback for the hardware button. */ 47/* The poll callback for the hardware button. */
48static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) 48static void b43legacy_rfkill_poll(struct rfkill *rfkill, void *data)
49{ 49{
50 struct b43legacy_wldev *dev = poll_dev->private; 50 struct b43legacy_wldev *dev = data;
51 struct b43legacy_wl *wl = dev->wl; 51 struct b43legacy_wl *wl = dev->wl;
52 bool enabled; 52 bool enabled;
53 bool report_change = 0;
54 53
55 mutex_lock(&wl->mutex); 54 mutex_lock(&wl->mutex);
56 if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { 55 if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) {
@@ -60,71 +59,64 @@ static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)
60 enabled = b43legacy_is_hw_radio_enabled(dev); 59 enabled = b43legacy_is_hw_radio_enabled(dev);
61 if (unlikely(enabled != dev->radio_hw_enable)) { 60 if (unlikely(enabled != dev->radio_hw_enable)) {
62 dev->radio_hw_enable = enabled; 61 dev->radio_hw_enable = enabled;
63 report_change = 1;
64 b43legacyinfo(wl, "Radio hardware status changed to %s\n", 62 b43legacyinfo(wl, "Radio hardware status changed to %s\n",
65 enabled ? "ENABLED" : "DISABLED"); 63 enabled ? "ENABLED" : "DISABLED");
64 enabled = !rfkill_set_hw_state(rfkill, !enabled);
65 if (enabled != dev->phy.radio_on) {
66 if (enabled)
67 b43legacy_radio_turn_on(dev);
68 else
69 b43legacy_radio_turn_off(dev, 0);
70 }
66 } 71 }
67 mutex_unlock(&wl->mutex); 72 mutex_unlock(&wl->mutex);
68
69 /* send the radio switch event to the system - note both a key press
70 * and a release are required */
71 if (unlikely(report_change)) {
72 input_report_key(poll_dev->input, KEY_WLAN, 1);
73 input_report_key(poll_dev->input, KEY_WLAN, 0);
74 }
75} 73}
76 74
77/* Called when the RFKILL toggled in software. 75/* Called when the RFKILL toggled in software.
78 * This is called without locking. */ 76 * This is called without locking. */
79static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) 77static int b43legacy_rfkill_soft_set(void *data, bool blocked)
80{ 78{
81 struct b43legacy_wldev *dev = data; 79 struct b43legacy_wldev *dev = data;
82 struct b43legacy_wl *wl = dev->wl; 80 struct b43legacy_wl *wl = dev->wl;
83 int err = -EBUSY; 81 int ret = -EINVAL;
84 82
85 if (!wl->rfkill.registered) 83 if (!wl->rfkill.registered)
86 return 0; 84 return -EINVAL;
87 85
88 mutex_lock(&wl->mutex); 86 mutex_lock(&wl->mutex);
89 if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) 87 if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)
90 goto out_unlock; 88 goto out_unlock;
91 err = 0; 89
92 switch (state) { 90 if (!dev->radio_hw_enable)
93 case RFKILL_STATE_UNBLOCKED: 91 goto out_unlock;
94 if (!dev->radio_hw_enable) { 92
95 /* No luck. We can't toggle the hardware RF-kill 93 if (!blocked != dev->phy.radio_on) {
96 * button from software. */ 94 if (!blocked)
97 err = -EBUSY;
98 goto out_unlock;
99 }
100 if (!dev->phy.radio_on)
101 b43legacy_radio_turn_on(dev); 95 b43legacy_radio_turn_on(dev);
102 break; 96 else
103 case RFKILL_STATE_SOFT_BLOCKED:
104 if (dev->phy.radio_on)
105 b43legacy_radio_turn_off(dev, 0); 97 b43legacy_radio_turn_off(dev, 0);
106 break;
107 default:
108 b43legacywarn(wl, "Received unexpected rfkill state %d.\n",
109 state);
110 break;
111 } 98 }
99 ret = 0;
112 100
113out_unlock: 101out_unlock:
114 mutex_unlock(&wl->mutex); 102 mutex_unlock(&wl->mutex);
115 103 return ret;
116 return err;
117} 104}
118 105
119char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) 106const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev)
120{ 107{
121 struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); 108 struct b43legacy_rfkill *rfk = &(dev->wl->rfkill);
122 109
123 if (!rfk->registered) 110 if (!rfk->registered)
124 return NULL; 111 return NULL;
125 return rfkill_get_led_name(rfk->rfkill); 112 return rfkill_get_led_trigger_name(rfk->rfkill);
126} 113}
127 114
115static const struct rfkill_ops b43legacy_rfkill_ops = {
116 .set_block = b43legacy_rfkill_soft_set,
117 .poll = b43legacy_rfkill_poll,
118};
119
128void b43legacy_rfkill_init(struct b43legacy_wldev *dev) 120void b43legacy_rfkill_init(struct b43legacy_wldev *dev)
129{ 121{
130 struct b43legacy_wl *wl = dev->wl; 122 struct b43legacy_wl *wl = dev->wl;
@@ -133,60 +125,25 @@ void b43legacy_rfkill_init(struct b43legacy_wldev *dev)
133 125
134 rfk->registered = 0; 126 rfk->registered = 0;
135 127
136 rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
137 if (!rfk->rfkill)
138 goto out_error;
139 snprintf(rfk->name, sizeof(rfk->name), 128 snprintf(rfk->name, sizeof(rfk->name),
140 "b43legacy-%s", wiphy_name(wl->hw->wiphy)); 129 "b43legacy-%s", wiphy_name(wl->hw->wiphy));
141 rfk->rfkill->name = rfk->name; 130 rfk->rfkill = rfkill_alloc(rfk->name,
142 rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; 131 dev->dev->dev,
143 rfk->rfkill->data = dev; 132 RFKILL_TYPE_WLAN,
144 rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle; 133 &b43legacy_rfkill_ops, dev);
145 134 if (!rfk->rfkill)
146 rfk->poll_dev = input_allocate_polled_device(); 135 goto out_error;
147 if (!rfk->poll_dev) {
148 rfkill_free(rfk->rfkill);
149 goto err_freed_rfk;
150 }
151
152 rfk->poll_dev->private = dev;
153 rfk->poll_dev->poll = b43legacy_rfkill_poll;
154 rfk->poll_dev->poll_interval = 1000; /* msecs */
155
156 rfk->poll_dev->input->name = rfk->name;
157 rfk->poll_dev->input->id.bustype = BUS_HOST;
158 rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor;
159 rfk->poll_dev->input->evbit[0] = BIT(EV_KEY);
160 set_bit(KEY_WLAN, rfk->poll_dev->input->keybit);
161 136
162 err = rfkill_register(rfk->rfkill); 137 err = rfkill_register(rfk->rfkill);
163 if (err) 138 if (err)
164 goto err_free_polldev; 139 goto err_free;
165
166#ifdef CONFIG_RFKILL_INPUT_MODULE
167 /* B43legacy RF-kill isn't useful without the rfkill-input subsystem.
168 * Try to load the module. */
169 err = request_module("rfkill-input");
170 if (err)
171 b43legacywarn(wl, "Failed to load the rfkill-input module."
172 "The built-in radio LED will not work.\n");
173#endif /* CONFIG_RFKILL_INPUT */
174
175 err = input_register_polled_device(rfk->poll_dev);
176 if (err)
177 goto err_unreg_rfk;
178 140
179 rfk->registered = 1; 141 rfk->registered = 1;
180 142
181 return; 143 return;
182err_unreg_rfk: 144 err_free:
183 rfkill_unregister(rfk->rfkill); 145 rfkill_destroy(rfk->rfkill);
184err_free_polldev: 146 out_error:
185 input_free_polled_device(rfk->poll_dev);
186 rfk->poll_dev = NULL;
187err_freed_rfk:
188 rfk->rfkill = NULL;
189out_error:
190 rfk->registered = 0; 147 rfk->registered = 0;
191 b43legacywarn(wl, "RF-kill button init failed\n"); 148 b43legacywarn(wl, "RF-kill button init failed\n");
192} 149}
@@ -199,10 +156,8 @@ void b43legacy_rfkill_exit(struct b43legacy_wldev *dev)
199 return; 156 return;
200 rfk->registered = 0; 157 rfk->registered = 0;
201 158
202 input_unregister_polled_device(rfk->poll_dev);
203 rfkill_unregister(rfk->rfkill); 159 rfkill_unregister(rfk->rfkill);
204 input_free_polled_device(rfk->poll_dev); 160 rfkill_destroy(rfk->rfkill);
205 rfk->poll_dev = NULL;
206 rfk->rfkill = NULL; 161 rfk->rfkill = NULL;
207} 162}
208 163
diff --git a/drivers/net/wireless/b43legacy/rfkill.h b/drivers/net/wireless/b43legacy/rfkill.h
index 11150a8032f0..adffc503a6a1 100644
--- a/drivers/net/wireless/b43legacy/rfkill.h
+++ b/drivers/net/wireless/b43legacy/rfkill.h
@@ -6,16 +6,12 @@ struct b43legacy_wldev;
6#ifdef CONFIG_B43LEGACY_RFKILL 6#ifdef CONFIG_B43LEGACY_RFKILL
7 7
8#include <linux/rfkill.h> 8#include <linux/rfkill.h>
9#include <linux/workqueue.h>
10#include <linux/input-polldev.h>
11 9
12 10
13 11
14struct b43legacy_rfkill { 12struct b43legacy_rfkill {
15 /* The RFKILL subsystem data structure */ 13 /* The RFKILL subsystem data structure */
16 struct rfkill *rfkill; 14 struct rfkill *rfkill;
17 /* The poll device for the RFKILL input button */
18 struct input_polled_dev *poll_dev;
19 /* Did initialization succeed? Used for freeing. */ 15 /* Did initialization succeed? Used for freeing. */
20 bool registered; 16 bool registered;
21 /* The unique name of this rfkill switch */ 17 /* The unique name of this rfkill switch */
@@ -27,7 +23,7 @@ struct b43legacy_rfkill {
27void b43legacy_rfkill_init(struct b43legacy_wldev *dev); 23void b43legacy_rfkill_init(struct b43legacy_wldev *dev);
28void b43legacy_rfkill_exit(struct b43legacy_wldev *dev); 24void b43legacy_rfkill_exit(struct b43legacy_wldev *dev);
29 25
30char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev); 26const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev);
31 27
32 28
33#else /* CONFIG_B43LEGACY_RFKILL */ 29#else /* CONFIG_B43LEGACY_RFKILL */
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 8304f6406a17..6fe259fcfb8f 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -5,15 +5,14 @@ config IWLWIFI
5 select FW_LOADER 5 select FW_LOADER
6 select MAC80211_LEDS if IWLWIFI_LEDS 6 select MAC80211_LEDS if IWLWIFI_LEDS
7 select LEDS_CLASS if IWLWIFI_LEDS 7 select LEDS_CLASS if IWLWIFI_LEDS
8 select RFKILL if IWLWIFI_RFKILL
9 8
10config IWLWIFI_LEDS 9config IWLWIFI_LEDS
11 bool "Enable LED support in iwlagn and iwl3945 drivers" 10 bool "Enable LED support in iwlagn and iwl3945 drivers"
12 depends on IWLWIFI 11 depends on IWLWIFI
13 12
14config IWLWIFI_RFKILL 13config IWLWIFI_RFKILL
15 bool "Enable RF kill support in iwlagn and iwl3945 drivers" 14 def_bool y
16 depends on IWLWIFI 15 depends on IWLWIFI && RFKILL
17 16
18config IWLWIFI_SPECTRUM_MEASUREMENT 17config IWLWIFI_SPECTRUM_MEASUREMENT
19 bool "Enable Spectrum Measurement in iwlagn driver" 18 bool "Enable Spectrum Measurement in iwlagn driver"
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index bd7e520d98c2..225e5f889346 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -167,10 +167,6 @@ static int iwl3945_led_disassociate(struct iwl_priv *priv, int led_id)
167 IWL_DEBUG_LED(priv, "Disassociated\n"); 167 IWL_DEBUG_LED(priv, "Disassociated\n");
168 168
169 priv->allow_blinking = 0; 169 priv->allow_blinking = 0;
170 if (iwl_is_rfkill(priv))
171 iwl3945_led_off(priv, led_id);
172 else
173 iwl3945_led_on(priv, led_id);
174 170
175 return 0; 171 return 0;
176} 172}
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 814afaf6d10b..5eb538d18a80 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -38,6 +38,7 @@
38 38
39#include "iwl-commands.h" 39#include "iwl-commands.h"
40#include "iwl-3945.h" 40#include "iwl-3945.h"
41#include "iwl-sta.h"
41 42
42#define RS_NAME "iwl-3945-rs" 43#define RS_NAME "iwl-3945-rs"
43 44
@@ -714,13 +715,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
714 715
715 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && 716 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
716 !rs_sta->ibss_sta_added) { 717 !rs_sta->ibss_sta_added) {
717 u8 sta_id = iwl3945_hw_find_station(priv, hdr->addr1); 718 u8 sta_id = iwl_find_station(priv, hdr->addr1);
718 719
719 if (sta_id == IWL_INVALID_STATION) { 720 if (sta_id == IWL_INVALID_STATION) {
720 IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n", 721 IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n",
721 hdr->addr1); 722 hdr->addr1);
722 sta_id = iwl3945_add_station(priv, 723 sta_id = iwl_add_station(priv, hdr->addr1, false,
723 hdr->addr1, 0, CMD_ASYNC, NULL); 724 CMD_ASYNC, NULL);
724 } 725 }
725 if (sta_id != IWL_INVALID_STATION) 726 if (sta_id != IWL_INVALID_STATION)
726 rs_sta->ibss_sta_added = 1; 727 rs_sta->ibss_sta_added = 1;
@@ -975,7 +976,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
975 976
976 rcu_read_lock(); 977 rcu_read_lock();
977 978
978 sta = ieee80211_find_sta(hw, priv->stations_39[sta_id].sta.sta.addr); 979 sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr);
979 if (!sta) { 980 if (!sta) {
980 rcu_read_unlock(); 981 rcu_read_unlock();
981 return; 982 return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index fd65e1c3e055..46288e724889 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -769,35 +769,6 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
769 return ; 769 return ;
770} 770}
771 771
772u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr)
773{
774 int i, start = IWL_AP_ID;
775 int ret = IWL_INVALID_STATION;
776 unsigned long flags;
777
778 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
779 (priv->iw_mode == NL80211_IFTYPE_AP))
780 start = IWL_STA_ID;
781
782 if (is_broadcast_ether_addr(addr))
783 return priv->hw_params.bcast_sta_id;
784
785 spin_lock_irqsave(&priv->sta_lock, flags);
786 for (i = start; i < priv->hw_params.max_stations; i++)
787 if ((priv->stations_39[i].used) &&
788 (!compare_ether_addr
789 (priv->stations_39[i].sta.sta.addr, addr))) {
790 ret = i;
791 goto out;
792 }
793
794 IWL_DEBUG_INFO(priv, "can not find STA %pM (total %d)\n",
795 addr, priv->num_stations);
796 out:
797 spin_unlock_irqrestore(&priv->sta_lock, flags);
798 return ret;
799}
800
801/** 772/**
802 * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: 773 * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
803 * 774 *
@@ -875,13 +846,13 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
875u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) 846u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
876{ 847{
877 unsigned long flags_spin; 848 unsigned long flags_spin;
878 struct iwl3945_station_entry *station; 849 struct iwl_station_entry *station;
879 850
880 if (sta_id == IWL_INVALID_STATION) 851 if (sta_id == IWL_INVALID_STATION)
881 return IWL_INVALID_STATION; 852 return IWL_INVALID_STATION;
882 853
883 spin_lock_irqsave(&priv->sta_lock, flags_spin); 854 spin_lock_irqsave(&priv->sta_lock, flags_spin);
884 station = &priv->stations_39[sta_id]; 855 station = &priv->stations[sta_id];
885 856
886 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; 857 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
887 station->sta.rate_n_flags = cpu_to_le16(tx_rate); 858 station->sta.rate_n_flags = cpu_to_le16(tx_rate);
@@ -889,8 +860,7 @@ u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
889 860
890 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 861 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
891 862
892 iwl_send_add_sta(priv, 863 iwl_send_add_sta(priv, &station->sta, flags);
893 (struct iwl_addsta_cmd *)&station->sta, flags);
894 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", 864 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
895 sta_id, tx_rate); 865 sta_id, tx_rate);
896 return sta_id; 866 return sta_id;
@@ -2029,7 +1999,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
2029 1999
2030 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); 2000 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
2031 2001
2032 priv->cfg->ops->smgmt->clear_station_table(priv); 2002 iwl_clear_stations_table(priv);
2033 2003
2034 /* If we issue a new RXON command which required a tune then we must 2004 /* If we issue a new RXON command which required a tune then we must
2035 * send a new TXPOWER command or we won't be able to Tx any frames */ 2005 * send a new TXPOWER command or we won't be able to Tx any frames */
@@ -2040,7 +2010,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
2040 } 2010 }
2041 2011
2042 /* Add the broadcast address so we can send broadcast frames */ 2012 /* Add the broadcast address so we can send broadcast frames */
2043 if (priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL) == 2013 if (iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL) ==
2044 IWL_INVALID_STATION) { 2014 IWL_INVALID_STATION) {
2045 IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n"); 2015 IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
2046 return -EIO; 2016 return -EIO;
@@ -2050,9 +2020,8 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
2050 * add the IWL_AP_ID to the station rate table */ 2020 * add the IWL_AP_ID to the station rate table */
2051 if (iwl_is_associated(priv) && 2021 if (iwl_is_associated(priv) &&
2052 (priv->iw_mode == NL80211_IFTYPE_STATION)) 2022 (priv->iw_mode == NL80211_IFTYPE_STATION))
2053 if (priv->cfg->ops->smgmt->add_station(priv, 2023 if (iwl_add_station(priv, priv->active_rxon.bssid_addr,
2054 priv->active_rxon.bssid_addr, 1, 0, NULL) 2024 true, CMD_SYNC, NULL) == IWL_INVALID_STATION) {
2055 == IWL_INVALID_STATION) {
2056 IWL_ERR(priv, "Error adding AP address for transmit\n"); 2025 IWL_ERR(priv, "Error adding AP address for transmit\n");
2057 return -EIO; 2026 return -EIO;
2058 } 2027 }
@@ -2466,13 +2435,25 @@ static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
2466 } 2435 }
2467} 2436}
2468 2437
2438
2469static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) 2439static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
2470{ 2440{
2471 u16 size = (u16)sizeof(struct iwl3945_addsta_cmd); 2441 struct iwl3945_addsta_cmd *addsta = (struct iwl3945_addsta_cmd *)data;
2472 memcpy(data, cmd, size); 2442 addsta->mode = cmd->mode;
2473 return size; 2443 memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));
2444 memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo));
2445 addsta->station_flags = cmd->station_flags;
2446 addsta->station_flags_msk = cmd->station_flags_msk;
2447 addsta->tid_disable_tx = cpu_to_le16(0);
2448 addsta->rate_n_flags = cmd->rate_n_flags;
2449 addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
2450 addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
2451 addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
2452
2453 return (u16)sizeof(struct iwl3945_addsta_cmd);
2474} 2454}
2475 2455
2456
2476/** 2457/**
2477 * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table 2458 * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
2478 */ 2459 */
@@ -2842,15 +2823,6 @@ static struct iwl_lib_ops iwl3945_lib = {
2842 .config_ap = iwl3945_config_ap, 2823 .config_ap = iwl3945_config_ap,
2843}; 2824};
2844 2825
2845static struct iwl_station_mgmt_ops iwl3945_station_mgmt = {
2846 .add_station = iwl3945_add_station,
2847#if 0
2848 .remove_station = iwl3945_remove_station,
2849#endif
2850 .find_station = iwl3945_hw_find_station,
2851 .clear_station_table = iwl3945_clear_stations_table,
2852};
2853
2854static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { 2826static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2855 .get_hcmd_size = iwl3945_get_hcmd_size, 2827 .get_hcmd_size = iwl3945_get_hcmd_size,
2856 .build_addsta_hcmd = iwl3945_build_addsta_hcmd, 2828 .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
@@ -2860,7 +2832,6 @@ static struct iwl_ops iwl3945_ops = {
2860 .lib = &iwl3945_lib, 2832 .lib = &iwl3945_lib,
2861 .hcmd = &iwl3945_hcmd, 2833 .hcmd = &iwl3945_hcmd,
2862 .utils = &iwl3945_hcmd_utils, 2834 .utils = &iwl3945_hcmd_utils,
2863 .smgmt = &iwl3945_station_mgmt,
2864}; 2835};
2865 2836
2866static struct iwl_cfg iwl3945_bg_cfg = { 2837static struct iwl_cfg iwl3945_bg_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index da87528f355f..4d8a325ea9d8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -202,12 +202,6 @@ struct iwl3945_ibss_seq {
202 * for use by iwl-*.c 202 * for use by iwl-*.c
203 * 203 *
204 *****************************************************************************/ 204 *****************************************************************************/
205struct iwl3945_addsta_cmd;
206extern int iwl3945_send_add_station(struct iwl_priv *priv,
207 struct iwl3945_addsta_cmd *sta, u8 flags);
208extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid,
209 int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info);
210extern void iwl3945_clear_stations_table(struct iwl_priv *priv);
211extern int iwl3945_power_init_handle(struct iwl_priv *priv); 205extern int iwl3945_power_init_handle(struct iwl_priv *priv);
212extern int iwl3945_eeprom_init(struct iwl_priv *priv); 206extern int iwl3945_eeprom_init(struct iwl_priv *priv);
213extern int iwl3945_calc_db_from_ratio(int sig_ratio); 207extern int iwl3945_calc_db_from_ratio(int sig_ratio);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index a0b29411a4b3..8f3d4bc6a03f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2221,13 +2221,6 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
2221 cancel_work_sync(&priv->txpower_work); 2221 cancel_work_sync(&priv->txpower_work);
2222} 2222}
2223 2223
2224static struct iwl_station_mgmt_ops iwl4965_station_mgmt = {
2225 .add_station = iwl_add_station_flags,
2226 .remove_station = iwl_remove_station,
2227 .find_station = iwl_find_station,
2228 .clear_station_table = iwl_clear_stations_table,
2229};
2230
2231static struct iwl_hcmd_ops iwl4965_hcmd = { 2224static struct iwl_hcmd_ops iwl4965_hcmd = {
2232 .rxon_assoc = iwl4965_send_rxon_assoc, 2225 .rxon_assoc = iwl4965_send_rxon_assoc,
2233 .commit_rxon = iwl_commit_rxon, 2226 .commit_rxon = iwl_commit_rxon,
@@ -2297,7 +2290,6 @@ static struct iwl_ops iwl4965_ops = {
2297 .lib = &iwl4965_lib, 2290 .lib = &iwl4965_lib,
2298 .hcmd = &iwl4965_hcmd, 2291 .hcmd = &iwl4965_hcmd,
2299 .utils = &iwl4965_hcmd_utils, 2292 .utils = &iwl4965_hcmd_utils,
2300 .smgmt = &iwl4965_station_mgmt,
2301}; 2293};
2302 2294
2303struct iwl_cfg iwl4965_agn_cfg = { 2295struct iwl_cfg iwl4965_agn_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index ab29aab6b2d5..b3c648ce8c7b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -651,7 +651,7 @@ static void iwl5000_init_alive_start(struct iwl_priv *priv)
651 goto restart; 651 goto restart;
652 } 652 }
653 653
654 priv->cfg->ops->smgmt->clear_station_table(priv); 654 iwl_clear_stations_table(priv);
655 ret = priv->cfg->ops->lib->alive_notify(priv); 655 ret = priv->cfg->ops->lib->alive_notify(priv);
656 if (ret) { 656 if (ret) {
657 IWL_WARN(priv, 657 IWL_WARN(priv,
@@ -1049,7 +1049,10 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
1049u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) 1049u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
1050{ 1050{
1051 u16 size = (u16)sizeof(struct iwl_addsta_cmd); 1051 u16 size = (u16)sizeof(struct iwl_addsta_cmd);
1052 memcpy(data, cmd, size); 1052 struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
1053 memcpy(addsta, cmd, size);
1054 /* resrved in 5000 */
1055 addsta->rate_n_flags = cpu_to_le16(0);
1053 return size; 1056 return size;
1054} 1057}
1055 1058
@@ -1423,13 +1426,6 @@ int iwl5000_calc_rssi(struct iwl_priv *priv,
1423 return max_rssi - agc - IWL49_RSSI_OFFSET; 1426 return max_rssi - agc - IWL49_RSSI_OFFSET;
1424} 1427}
1425 1428
1426struct iwl_station_mgmt_ops iwl5000_station_mgmt = {
1427 .add_station = iwl_add_station_flags,
1428 .remove_station = iwl_remove_station,
1429 .find_station = iwl_find_station,
1430 .clear_station_table = iwl_clear_stations_table,
1431};
1432
1433struct iwl_hcmd_ops iwl5000_hcmd = { 1429struct iwl_hcmd_ops iwl5000_hcmd = {
1434 .rxon_assoc = iwl5000_send_rxon_assoc, 1430 .rxon_assoc = iwl5000_send_rxon_assoc,
1435 .commit_rxon = iwl_commit_rxon, 1431 .commit_rxon = iwl_commit_rxon,
@@ -1549,14 +1545,12 @@ struct iwl_ops iwl5000_ops = {
1549 .lib = &iwl5000_lib, 1545 .lib = &iwl5000_lib,
1550 .hcmd = &iwl5000_hcmd, 1546 .hcmd = &iwl5000_hcmd,
1551 .utils = &iwl5000_hcmd_utils, 1547 .utils = &iwl5000_hcmd_utils,
1552 .smgmt = &iwl5000_station_mgmt,
1553}; 1548};
1554 1549
1555static struct iwl_ops iwl5150_ops = { 1550static struct iwl_ops iwl5150_ops = {
1556 .lib = &iwl5150_lib, 1551 .lib = &iwl5150_lib,
1557 .hcmd = &iwl5000_hcmd, 1552 .hcmd = &iwl5000_hcmd,
1558 .utils = &iwl5000_hcmd_utils, 1553 .utils = &iwl5000_hcmd_utils,
1559 .smgmt = &iwl5000_station_mgmt,
1560}; 1554};
1561 1555
1562struct iwl_mod_params iwl50_mod_params = { 1556struct iwl_mod_params iwl50_mod_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 7236382aeaa6..bd438d8acf55 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -72,7 +72,6 @@ static struct iwl_ops iwl6000_ops = {
72 .lib = &iwl5000_lib, 72 .lib = &iwl5000_lib,
73 .hcmd = &iwl5000_hcmd, 73 .hcmd = &iwl5000_hcmd,
74 .utils = &iwl6000_hcmd_utils, 74 .utils = &iwl6000_hcmd_utils,
75 .smgmt = &iwl5000_station_mgmt,
76}; 75};
77 76
78struct iwl_cfg iwl6000_2ag_cfg = { 77struct iwl_cfg iwl6000_2ag_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 23a58b00f180..ff20e5048a55 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -2502,15 +2502,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2502 2502
2503 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && 2503 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
2504 !lq_sta->ibss_sta_added) { 2504 !lq_sta->ibss_sta_added) {
2505 u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, 2505 u8 sta_id = iwl_find_station(priv, hdr->addr1);
2506 hdr->addr1);
2507 2506
2508 if (sta_id == IWL_INVALID_STATION) { 2507 if (sta_id == IWL_INVALID_STATION) {
2509 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", 2508 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
2510 hdr->addr1); 2509 hdr->addr1);
2511 sta_id = priv->cfg->ops->smgmt->add_station(priv, 2510 sta_id = iwl_add_station(priv, hdr->addr1,
2512 hdr->addr1, 0, 2511 false, CMD_ASYNC, NULL);
2513 CMD_ASYNC, NULL);
2514 } 2512 }
2515 if ((sta_id != IWL_INVALID_STATION)) { 2513 if ((sta_id != IWL_INVALID_STATION)) {
2516 lq_sta->lq.sta_id = sta_id; 2514 lq_sta->lq.sta_id = sta_id;
@@ -2598,7 +2596,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2598 2596
2599 lq_sta->ibss_sta_added = 0; 2597 lq_sta->ibss_sta_added = 0;
2600 if (priv->iw_mode == NL80211_IFTYPE_AP) { 2598 if (priv->iw_mode == NL80211_IFTYPE_AP) {
2601 u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, 2599 u8 sta_id = iwl_find_station(priv,
2602 sta->addr); 2600 sta->addr);
2603 2601
2604 /* for IBSS the call are from tasklet */ 2602 /* for IBSS the call are from tasklet */
@@ -2606,9 +2604,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2606 2604
2607 if (sta_id == IWL_INVALID_STATION) { 2605 if (sta_id == IWL_INVALID_STATION) {
2608 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr); 2606 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
2609 sta_id = priv->cfg->ops->smgmt->add_station(priv, 2607 sta_id = iwl_add_station(priv, sta->addr, false,
2610 sta->addr, 0, 2608 CMD_ASYNC, NULL);
2611 CMD_ASYNC, NULL);
2612 } 2609 }
2613 if ((sta_id != IWL_INVALID_STATION)) { 2610 if ((sta_id != IWL_INVALID_STATION)) {
2614 lq_sta->lq.sta_id = sta_id; 2611 lq_sta->lq.sta_id = sta_id;
@@ -2790,9 +2787,10 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
2790 repeat_rate--; 2787 repeat_rate--;
2791 } 2788 }
2792 2789
2793 lq_cmd->agg_params.agg_frame_cnt_limit = 64; 2790 lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_MAX;
2794 lq_cmd->agg_params.agg_dis_start_th = 3; 2791 lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
2795 lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000); 2792 lq_cmd->agg_params.agg_time_limit =
2793 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
2796} 2794}
2797 2795
2798static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 2796static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 0a5507cbeb3f..b77208de92ad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -188,7 +188,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
188 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); 188 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
189 } 189 }
190 190
191 priv->cfg->ops->smgmt->clear_station_table(priv); 191 iwl_clear_stations_table(priv);
192 192
193 priv->start_calib = 0; 193 priv->start_calib = 0;
194 194
@@ -1617,7 +1617,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
1617 goto restart; 1617 goto restart;
1618 } 1618 }
1619 1619
1620 priv->cfg->ops->smgmt->clear_station_table(priv); 1620 iwl_clear_stations_table(priv);
1621 ret = priv->cfg->ops->lib->alive_notify(priv); 1621 ret = priv->cfg->ops->lib->alive_notify(priv);
1622 if (ret) { 1622 if (ret) {
1623 IWL_WARN(priv, 1623 IWL_WARN(priv,
@@ -1703,7 +1703,7 @@ static void __iwl_down(struct iwl_priv *priv)
1703 1703
1704 iwl_leds_unregister(priv); 1704 iwl_leds_unregister(priv);
1705 1705
1706 priv->cfg->ops->smgmt->clear_station_table(priv); 1706 iwl_clear_stations_table(priv);
1707 1707
1708 /* Unblock any waiting calls */ 1708 /* Unblock any waiting calls */
1709 wake_up_interruptible_all(&priv->wait_command_queue); 1709 wake_up_interruptible_all(&priv->wait_command_queue);
@@ -1887,8 +1887,6 @@ static int __iwl_up(struct iwl_priv *priv)
1887 1887
1888 /* clear (again), then enable host interrupts */ 1888 /* clear (again), then enable host interrupts */
1889 iwl_write32(priv, CSR_INT, 0xFFFFFFFF); 1889 iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
1890 /* enable dram interrupt */
1891 iwl_reset_ict(priv);
1892 iwl_enable_interrupts(priv); 1890 iwl_enable_interrupts(priv);
1893 1891
1894 /* really make sure rfkill handshake bits are cleared */ 1892 /* really make sure rfkill handshake bits are cleared */
@@ -1903,7 +1901,7 @@ static int __iwl_up(struct iwl_priv *priv)
1903 1901
1904 for (i = 0; i < MAX_HW_RESTARTS; i++) { 1902 for (i = 0; i < MAX_HW_RESTARTS; i++) {
1905 1903
1906 priv->cfg->ops->smgmt->clear_station_table(priv); 1904 iwl_clear_stations_table(priv);
1907 1905
1908 /* load bootstrap state machine, 1906 /* load bootstrap state machine,
1909 * load bootstrap program into processor's memory, 1907 * load bootstrap program into processor's memory,
@@ -1962,6 +1960,9 @@ static void iwl_bg_alive_start(struct work_struct *data)
1962 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 1960 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
1963 return; 1961 return;
1964 1962
1963 /* enable dram interrupt */
1964 iwl_reset_ict(priv);
1965
1965 mutex_lock(&priv->mutex); 1966 mutex_lock(&priv->mutex);
1966 iwl_alive_start(priv); 1967 iwl_alive_start(priv);
1967 mutex_unlock(&priv->mutex); 1968 mutex_unlock(&priv->mutex);
@@ -2348,7 +2349,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2348 return -EOPNOTSUPP; 2349 return -EOPNOTSUPP;
2349 } 2350 }
2350 addr = sta ? sta->addr : iwl_bcast_addr; 2351 addr = sta ? sta->addr : iwl_bcast_addr;
2351 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 2352 sta_id = iwl_find_station(priv, addr);
2352 if (sta_id == IWL_INVALID_STATION) { 2353 if (sta_id == IWL_INVALID_STATION) {
2353 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", 2354 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
2354 addr); 2355 addr);
@@ -3121,7 +3122,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
3121 iwl_rx_queue_free(priv, &priv->rxq); 3122 iwl_rx_queue_free(priv, &priv->rxq);
3122 iwl_hw_txq_ctx_free(priv); 3123 iwl_hw_txq_ctx_free(priv);
3123 3124
3124 priv->cfg->ops->smgmt->clear_station_table(priv); 3125 iwl_clear_stations_table(priv);
3125 iwl_eeprom_free(priv); 3126 iwl_eeprom_free(priv);
3126 3127
3127 3128
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index e581dc323f0a..c87033bf3ad2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1067,7 +1067,7 @@ struct iwl_addsta_cmd {
1067 * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ 1067 * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
1068 __le16 tid_disable_tx; 1068 __le16 tid_disable_tx;
1069 1069
1070 __le16 reserved1; 1070 __le16 rate_n_flags; /* 3945 only */
1071 1071
1072 /* TID for which to add block-ack support. 1072 /* TID for which to add block-ack support.
1073 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ 1073 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
@@ -1913,6 +1913,18 @@ struct iwl_link_qual_general_params {
1913 u8 start_rate_index[LINK_QUAL_AC_NUM]; 1913 u8 start_rate_index[LINK_QUAL_AC_NUM];
1914} __attribute__ ((packed)); 1914} __attribute__ ((packed));
1915 1915
1916#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
1917#define LINK_QUAL_AGG_TIME_LIMIT_MAX (65535)
1918#define LINK_QUAL_AGG_TIME_LIMIT_MIN (0)
1919
1920#define LINK_QUAL_AGG_DISABLE_START_DEF (3)
1921#define LINK_QUAL_AGG_DISABLE_START_MAX (255)
1922#define LINK_QUAL_AGG_DISABLE_START_MIN (0)
1923
1924#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (31)
1925#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (64)
1926#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0)
1927
1916/** 1928/**
1917 * struct iwl_link_qual_agg_params 1929 * struct iwl_link_qual_agg_params
1918 * 1930 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index e93ddb74457e..51cae4ec26a5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1389,7 +1389,7 @@ int iwl_init_drv(struct iwl_priv *priv)
1389 mutex_init(&priv->mutex); 1389 mutex_init(&priv->mutex);
1390 1390
1391 /* Clear the driver's (not device's) station table */ 1391 /* Clear the driver's (not device's) station table */
1392 priv->cfg->ops->smgmt->clear_station_table(priv); 1392 iwl_clear_stations_table(priv);
1393 1393
1394 priv->data_retry_limit = -1; 1394 priv->data_retry_limit = -1;
1395 priv->ieee_channels = NULL; 1395 priv->ieee_channels = NULL;
@@ -1704,8 +1704,9 @@ static irqreturn_t iwl_isr(int irq, void *data)
1704{ 1704{
1705 struct iwl_priv *priv = data; 1705 struct iwl_priv *priv = data;
1706 u32 inta, inta_mask; 1706 u32 inta, inta_mask;
1707#ifdef CONFIG_IWLWIFI_DEBUG
1707 u32 inta_fh; 1708 u32 inta_fh;
1708 1709#endif
1709 if (!priv) 1710 if (!priv)
1710 return IRQ_NONE; 1711 return IRQ_NONE;
1711 1712
@@ -2679,19 +2680,12 @@ int iwl_set_mode(struct iwl_priv *priv, int mode)
2679 2680
2680 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); 2681 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
2681 2682
2682 priv->cfg->ops->smgmt->clear_station_table(priv); 2683 iwl_clear_stations_table(priv);
2683 2684
2684 /* dont commit rxon if rf-kill is on*/ 2685 /* dont commit rxon if rf-kill is on*/
2685 if (!iwl_is_ready_rf(priv)) 2686 if (!iwl_is_ready_rf(priv))
2686 return -EAGAIN; 2687 return -EAGAIN;
2687 2688
2688 cancel_delayed_work(&priv->scan_check);
2689 if (iwl_scan_cancel_timeout(priv, 100)) {
2690 IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
2691 IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
2692 return -EAGAIN;
2693 }
2694
2695 iwlcore_commit_rxon(priv); 2689 iwlcore_commit_rxon(priv);
2696 2690
2697 return 0; 2691 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 87df1b767941..b52d0fb16060 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -83,15 +83,6 @@ struct iwl_cmd;
83#define IWL_SKU_A 0x2 83#define IWL_SKU_A 0x2
84#define IWL_SKU_N 0x8 84#define IWL_SKU_N 0x8
85 85
86struct iwl_station_mgmt_ops {
87 u8 (*add_station)(struct iwl_priv *priv, const u8 *addr,
88 int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info);
89 int (*remove_station)(struct iwl_priv *priv, const u8 *addr,
90 int is_ap);
91 u8 (*find_station)(struct iwl_priv *priv, const u8 *addr);
92 void (*clear_station_table)(struct iwl_priv *priv);
93};
94
95struct iwl_hcmd_ops { 86struct iwl_hcmd_ops {
96 int (*rxon_assoc)(struct iwl_priv *priv); 87 int (*rxon_assoc)(struct iwl_priv *priv);
97 int (*commit_rxon)(struct iwl_priv *priv); 88 int (*commit_rxon)(struct iwl_priv *priv);
@@ -183,7 +174,6 @@ struct iwl_ops {
183 const struct iwl_lib_ops *lib; 174 const struct iwl_lib_ops *lib;
184 const struct iwl_hcmd_ops *hcmd; 175 const struct iwl_hcmd_ops *hcmd;
185 const struct iwl_hcmd_utils_ops *utils; 176 const struct iwl_hcmd_utils_ops *utils;
186 const struct iwl_station_mgmt_ops *smgmt;
187}; 177};
188 178
189struct iwl_mod_params { 179struct iwl_mod_params {
@@ -192,7 +182,7 @@ struct iwl_mod_params {
192 int disable_hw_scan; /* def: 0 = use h/w scan */ 182 int disable_hw_scan; /* def: 0 = use h/w scan */
193 int num_of_queues; /* def: HW dependent */ 183 int num_of_queues; /* def: HW dependent */
194 int num_of_ampdu_queues;/* def: HW dependent */ 184 int num_of_ampdu_queues;/* def: HW dependent */
195 int disable_11n; /* def: 0 = disable 11n capabilities */ 185 int disable_11n; /* def: 0 = 11n capabilities enabled */
196 int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ 186 int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
197 int antenna; /* def: 0 = both antennas (use diversity) */ 187 int antenna; /* def: 0 = both antennas (use diversity) */
198 int restart_fw; /* def: 1 = restart firmware */ 188 int restart_fw; /* def: 1 = restart firmware */
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 2dafc26fb6a8..28c39cf8b126 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -70,7 +70,6 @@ extern struct iwl_ops iwl5000_ops;
70extern struct iwl_lib_ops iwl5000_lib; 70extern struct iwl_lib_ops iwl5000_lib;
71extern struct iwl_hcmd_ops iwl5000_hcmd; 71extern struct iwl_hcmd_ops iwl5000_hcmd;
72extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils; 72extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils;
73extern struct iwl_station_mgmt_ops iwl5000_station_mgmt;
74 73
75/* shared functions from iwl-5000.c */ 74/* shared functions from iwl-5000.c */
76extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len); 75extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len);
@@ -290,11 +289,11 @@ struct iwl_frame {
290#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) 289#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
291 290
292enum { 291enum {
293 /* CMD_SIZE_NORMAL = 0, */ 292 CMD_SYNC = 0,
293 CMD_SIZE_NORMAL = 0,
294 CMD_NO_SKB = 0,
294 CMD_SIZE_HUGE = (1 << 0), 295 CMD_SIZE_HUGE = (1 << 0),
295 /* CMD_SYNC = 0, */
296 CMD_ASYNC = (1 << 1), 296 CMD_ASYNC = (1 << 1),
297 /* CMD_NO_SKB = 0, */
298 CMD_WANT_SKB = (1 << 2), 297 CMD_WANT_SKB = (1 << 2),
299}; 298};
300 299
@@ -1119,8 +1118,6 @@ struct iwl_priv {
1119 1118
1120 struct iwl3945_notif_statistics statistics_39; 1119 struct iwl3945_notif_statistics statistics_39;
1121 1120
1122 struct iwl3945_station_entry stations_39[IWL_STATION_COUNT];
1123
1124 u32 sta_supp_rates; 1121 u32 sta_supp_rates;
1125}; /*iwl_priv */ 1122}; /*iwl_priv */
1126 1123
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index cefa501e5971..7d7554a2f341 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -240,13 +240,11 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
240 if (ret < 0) 240 if (ret < 0)
241 IWL_ERR(priv, "Time out access OTP\n"); 241 IWL_ERR(priv, "Time out access OTP\n");
242 else { 242 else {
243 if (!ret) { 243 iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
244 iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, 244 APMG_PS_CTRL_VAL_RESET_REQ);
245 APMG_PS_CTRL_VAL_RESET_REQ); 245 udelay(5);
246 udelay(5); 246 iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
247 iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, 247 APMG_PS_CTRL_VAL_RESET_REQ);
248 APMG_PS_CTRL_VAL_RESET_REQ);
249 }
250 } 248 }
251 return ret; 249 return ret;
252} 250}
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 19680f72087f..5e64252f80f6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -176,10 +176,6 @@ static int iwl_led_associate(struct iwl_priv *priv, int led_id)
176static int iwl_led_disassociate(struct iwl_priv *priv, int led_id) 176static int iwl_led_disassociate(struct iwl_priv *priv, int led_id)
177{ 177{
178 priv->allow_blinking = 0; 178 priv->allow_blinking = 0;
179 if (iwl_is_rfkill(priv))
180 iwl4965_led_off_reg(priv, led_id);
181 else
182 iwl4965_led_on_reg(priv, led_id);
183 179
184 return 0; 180 return 0;
185} 181}
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
index 65605ad44e4b..13149936fd26 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
@@ -36,42 +36,37 @@
36#include "iwl-core.h" 36#include "iwl-core.h"
37 37
38/* software rf-kill from user */ 38/* software rf-kill from user */
39static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) 39static int iwl_rfkill_soft_rf_kill(void *data, bool blocked)
40{ 40{
41 struct iwl_priv *priv = data; 41 struct iwl_priv *priv = data;
42 int err = 0;
43 42
44 if (!priv->rfkill) 43 if (!priv->rfkill)
45 return 0; 44 return -EINVAL;
46 45
47 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 46 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
48 return 0; 47 return 0;
49 48
50 IWL_DEBUG_RF_KILL(priv, "we received soft RFKILL set to state %d\n", state); 49 IWL_DEBUG_RF_KILL(priv, "received soft RFKILL: block=%d\n", blocked);
50
51 mutex_lock(&priv->mutex); 51 mutex_lock(&priv->mutex);
52 52
53 switch (state) { 53 if (iwl_is_rfkill_hw(priv))
54 case RFKILL_STATE_UNBLOCKED: 54 goto out_unlock;
55 if (iwl_is_rfkill_hw(priv)) { 55
56 err = -EBUSY; 56 if (!blocked)
57 goto out_unlock;
58 }
59 iwl_radio_kill_sw_enable_radio(priv); 57 iwl_radio_kill_sw_enable_radio(priv);
60 break; 58 else
61 case RFKILL_STATE_SOFT_BLOCKED:
62 iwl_radio_kill_sw_disable_radio(priv); 59 iwl_radio_kill_sw_disable_radio(priv);
63 break; 60
64 default:
65 IWL_WARN(priv, "we received unexpected RFKILL state %d\n",
66 state);
67 break;
68 }
69out_unlock: 61out_unlock:
70 mutex_unlock(&priv->mutex); 62 mutex_unlock(&priv->mutex);
71 63 return 0;
72 return err;
73} 64}
74 65
66static const struct rfkill_ops iwl_rfkill_ops = {
67 .set_block = iwl_rfkill_soft_rf_kill,
68};
69
75int iwl_rfkill_init(struct iwl_priv *priv) 70int iwl_rfkill_init(struct iwl_priv *priv)
76{ 71{
77 struct device *device = wiphy_dev(priv->hw->wiphy); 72 struct device *device = wiphy_dev(priv->hw->wiphy);
@@ -80,21 +75,16 @@ int iwl_rfkill_init(struct iwl_priv *priv)
80 BUG_ON(device == NULL); 75 BUG_ON(device == NULL);
81 76
82 IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n"); 77 IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n");
83 priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); 78 priv->rfkill = rfkill_alloc(priv->cfg->name,
79 device,
80 RFKILL_TYPE_WLAN,
81 &iwl_rfkill_ops, priv);
84 if (!priv->rfkill) { 82 if (!priv->rfkill) {
85 IWL_ERR(priv, "Unable to allocate RFKILL device.\n"); 83 IWL_ERR(priv, "Unable to allocate RFKILL device.\n");
86 ret = -ENOMEM; 84 ret = -ENOMEM;
87 goto error; 85 goto error;
88 } 86 }
89 87
90 priv->rfkill->name = priv->cfg->name;
91 priv->rfkill->data = priv;
92 priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
93 priv->rfkill->toggle_radio = iwl_rfkill_soft_rf_kill;
94
95 priv->rfkill->dev.class->suspend = NULL;
96 priv->rfkill->dev.class->resume = NULL;
97
98 ret = rfkill_register(priv->rfkill); 88 ret = rfkill_register(priv->rfkill);
99 if (ret) { 89 if (ret) {
100 IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret); 90 IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret);
@@ -102,11 +92,10 @@ int iwl_rfkill_init(struct iwl_priv *priv)
102 } 92 }
103 93
104 IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); 94 IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n");
105 return ret; 95 return 0;
106 96
107free_rfkill: 97free_rfkill:
108 if (priv->rfkill != NULL) 98 rfkill_destroy(priv->rfkill);
109 rfkill_free(priv->rfkill);
110 priv->rfkill = NULL; 99 priv->rfkill = NULL;
111 100
112error: 101error:
@@ -118,8 +107,10 @@ EXPORT_SYMBOL(iwl_rfkill_init);
118void iwl_rfkill_unregister(struct iwl_priv *priv) 107void iwl_rfkill_unregister(struct iwl_priv *priv)
119{ 108{
120 109
121 if (priv->rfkill) 110 if (priv->rfkill) {
122 rfkill_unregister(priv->rfkill); 111 rfkill_unregister(priv->rfkill);
112 rfkill_destroy(priv->rfkill);
113 }
123 114
124 priv->rfkill = NULL; 115 priv->rfkill = NULL;
125} 116}
@@ -131,14 +122,10 @@ void iwl_rfkill_set_hw_state(struct iwl_priv *priv)
131 if (!priv->rfkill) 122 if (!priv->rfkill)
132 return; 123 return;
133 124
134 if (iwl_is_rfkill_hw(priv)) { 125 if (rfkill_set_hw_state(priv->rfkill,
135 rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED); 126 !!iwl_is_rfkill_hw(priv)))
136 return; 127 iwl_radio_kill_sw_disable_radio(priv);
137 }
138
139 if (!iwl_is_rfkill_sw(priv))
140 rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
141 else 128 else
142 rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED); 129 iwl_radio_kill_sw_enable_radio(priv);
143} 130}
144EXPORT_SYMBOL(iwl_rfkill_set_hw_state); 131EXPORT_SYMBOL(iwl_rfkill_set_hw_state);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 0eb939c40ac1..2addf735b193 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -75,7 +75,7 @@ int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
75 return IWL_AP_ID; 75 return IWL_AP_ID;
76 } else { 76 } else {
77 u8 *da = ieee80211_get_DA(hdr); 77 u8 *da = ieee80211_get_DA(hdr);
78 return priv->cfg->ops->smgmt->find_station(priv, da); 78 return iwl_find_station(priv, da);
79 } 79 }
80} 80}
81EXPORT_SYMBOL(iwl_get_ra_sta_id); 81EXPORT_SYMBOL(iwl_get_ra_sta_id);
@@ -86,8 +86,7 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
86 86
87 spin_lock_irqsave(&priv->sta_lock, flags); 87 spin_lock_irqsave(&priv->sta_lock, flags);
88 88
89 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) && 89 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
90 !(priv->stations_39[sta_id].used & IWL_STA_DRIVER_ACTIVE))
91 IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n", 90 IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n",
92 sta_id); 91 sta_id);
93 92
@@ -228,15 +227,16 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
228} 227}
229 228
230/** 229/**
231 * iwl_add_station_flags - Add station to tables in driver and device 230 * iwl_add_station - Add station to tables in driver and device
232 */ 231 */
233u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, 232u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
234 u8 flags, struct ieee80211_sta_ht_cap *ht_info) 233 struct ieee80211_sta_ht_cap *ht_info)
235{ 234{
236 int i;
237 int sta_id = IWL_INVALID_STATION;
238 struct iwl_station_entry *station; 235 struct iwl_station_entry *station;
239 unsigned long flags_spin; 236 unsigned long flags_spin;
237 int i;
238 int sta_id = IWL_INVALID_STATION;
239 u16 rate;
240 240
241 spin_lock_irqsave(&priv->sta_lock, flags_spin); 241 spin_lock_irqsave(&priv->sta_lock, flags_spin);
242 if (is_ap) 242 if (is_ap)
@@ -288,6 +288,12 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
288 priv->iw_mode != NL80211_IFTYPE_ADHOC) 288 priv->iw_mode != NL80211_IFTYPE_ADHOC)
289 iwl_set_ht_add_station(priv, sta_id, ht_info); 289 iwl_set_ht_add_station(priv, sta_id, ht_info);
290 290
291 /* 3945 only */
292 rate = (priv->band == IEEE80211_BAND_5GHZ) ?
293 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP;
294 /* Turn on both antennas for the station... */
295 station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
296
291 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 297 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
292 298
293 /* Add station to device's station table */ 299 /* Add station to device's station table */
@@ -295,12 +301,12 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
295 return sta_id; 301 return sta_id;
296 302
297} 303}
298EXPORT_SYMBOL(iwl_add_station_flags); 304EXPORT_SYMBOL(iwl_add_station);
299 305
300static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) 306static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
301{ 307{
302 unsigned long flags; 308 unsigned long flags;
303 u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 309 u8 sta_id = iwl_find_station(priv, addr);
304 310
305 BUG_ON(sta_id == IWL_INVALID_STATION); 311 BUG_ON(sta_id == IWL_INVALID_STATION);
306 312
@@ -408,7 +414,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
408/** 414/**
409 * iwl_remove_station - Remove driver's knowledge of station. 415 * iwl_remove_station - Remove driver's knowledge of station.
410 */ 416 */
411int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) 417int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
412{ 418{
413 int sta_id = IWL_INVALID_STATION; 419 int sta_id = IWL_INVALID_STATION;
414 int i, ret = -EINVAL; 420 int i, ret = -EINVAL;
@@ -767,7 +773,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
767 unsigned long flags; 773 unsigned long flags;
768 int i; 774 int i;
769 775
770 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 776 sta_id = iwl_find_station(priv, addr);
771 if (sta_id == IWL_INVALID_STATION) { 777 if (sta_id == IWL_INVALID_STATION) {
772 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", 778 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
773 addr); 779 addr);
@@ -946,7 +952,7 @@ EXPORT_SYMBOL(iwl_send_lq_cmd);
946 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD, 952 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
947 * which requires station table entry to exist). 953 * which requires station table entry to exist).
948 */ 954 */
949static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap) 955static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
950{ 956{
951 int i, r; 957 int i, r;
952 struct iwl_link_quality_cmd link_cmd = { 958 struct iwl_link_quality_cmd link_cmd = {
@@ -979,8 +985,9 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
979 link_cmd.general_params.single_stream_ant_msk = 985 link_cmd.general_params.single_stream_ant_msk =
980 first_antenna(priv->hw_params.valid_tx_ant); 986 first_antenna(priv->hw_params.valid_tx_ant);
981 link_cmd.general_params.dual_stream_ant_msk = 3; 987 link_cmd.general_params.dual_stream_ant_msk = 3;
982 link_cmd.agg_params.agg_dis_start_th = 3; 988 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
983 link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000); 989 link_cmd.agg_params.agg_time_limit =
990 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
984 991
985 /* Update the rate scaling for control frame Tx to AP */ 992 /* Update the rate scaling for control frame Tx to AP */
986 link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id; 993 link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
@@ -995,7 +1002,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
995 * there is only one AP station with id= IWL_AP_ID 1002 * there is only one AP station with id= IWL_AP_ID
996 * NOTE: mutex must be held before calling this function 1003 * NOTE: mutex must be held before calling this function
997 */ 1004 */
998int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) 1005int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
999{ 1006{
1000 struct ieee80211_sta *sta; 1007 struct ieee80211_sta *sta;
1001 struct ieee80211_sta_ht_cap ht_config; 1008 struct ieee80211_sta_ht_cap ht_config;
@@ -1020,8 +1027,7 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
1020 rcu_read_unlock(); 1027 rcu_read_unlock();
1021 } 1028 }
1022 1029
1023 sta_id = priv->cfg->ops->smgmt->add_station(priv, addr, is_ap, 1030 sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config);
1024 0, cur_ht_config);
1025 1031
1026 /* Set up default rate scaling table in device's station table */ 1032 /* Set up default rate scaling table in device's station table */
1027 iwl_sta_init_lq(priv, addr, is_ap); 1033 iwl_sta_init_lq(priv, addr, is_ap);
@@ -1054,7 +1060,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1054 1060
1055 /* If we are an AP, then find the station, or use BCAST */ 1061 /* If we are an AP, then find the station, or use BCAST */
1056 case NL80211_IFTYPE_AP: 1062 case NL80211_IFTYPE_AP:
1057 sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1); 1063 sta_id = iwl_find_station(priv, hdr->addr1);
1058 if (sta_id != IWL_INVALID_STATION) 1064 if (sta_id != IWL_INVALID_STATION)
1059 return sta_id; 1065 return sta_id;
1060 return priv->hw_params.bcast_sta_id; 1066 return priv->hw_params.bcast_sta_id;
@@ -1062,13 +1068,13 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1062 /* If this frame is going out to an IBSS network, find the station, 1068 /* If this frame is going out to an IBSS network, find the station,
1063 * or create a new station table entry */ 1069 * or create a new station table entry */
1064 case NL80211_IFTYPE_ADHOC: 1070 case NL80211_IFTYPE_ADHOC:
1065 sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1); 1071 sta_id = iwl_find_station(priv, hdr->addr1);
1066 if (sta_id != IWL_INVALID_STATION) 1072 if (sta_id != IWL_INVALID_STATION)
1067 return sta_id; 1073 return sta_id;
1068 1074
1069 /* Create new station table entry */ 1075 /* Create new station table entry */
1070 sta_id = priv->cfg->ops->smgmt->add_station(priv, hdr->addr1, 1076 sta_id = iwl_add_station(priv, hdr->addr1, false,
1071 0, CMD_ASYNC, NULL); 1077 CMD_ASYNC, NULL);
1072 1078
1073 if (sta_id != IWL_INVALID_STATION) 1079 if (sta_id != IWL_INVALID_STATION)
1074 return sta_id; 1080 return sta_id;
@@ -1111,7 +1117,7 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv,
1111 unsigned long flags; 1117 unsigned long flags;
1112 int sta_id; 1118 int sta_id;
1113 1119
1114 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 1120 sta_id = iwl_find_station(priv, addr);
1115 if (sta_id == IWL_INVALID_STATION) 1121 if (sta_id == IWL_INVALID_STATION)
1116 return -ENXIO; 1122 return -ENXIO;
1117 1123
@@ -1133,7 +1139,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid)
1133 unsigned long flags; 1139 unsigned long flags;
1134 int sta_id; 1140 int sta_id;
1135 1141
1136 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 1142 sta_id = iwl_find_station(priv, addr);
1137 if (sta_id == IWL_INVALID_STATION) { 1143 if (sta_id == IWL_INVALID_STATION) {
1138 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); 1144 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
1139 return -ENXIO; 1145 return -ENXIO;
@@ -1168,7 +1174,7 @@ static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
1168void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) 1174void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr)
1169{ 1175{
1170 /* FIXME: need locking over ps_status ??? */ 1176 /* FIXME: need locking over ps_status ??? */
1171 u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 1177 u8 sta_id = iwl_find_station(priv, addr);
1172 1178
1173 if (sta_id != IWL_INVALID_STATION) { 1179 if (sta_id != IWL_INVALID_STATION) {
1174 u8 sta_awake = priv->stations[sta_id]. 1180 u8 sta_awake = priv->stations[sta_id].
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 59a586b6b56c..6deebade6361 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -51,16 +51,15 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
51 struct ieee80211_key_conf *keyconf, 51 struct ieee80211_key_conf *keyconf,
52 const u8 *addr, u32 iv32, u16 *phase1key); 52 const u8 *addr, u32 iv32, u16 *phase1key);
53 53
54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap); 54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
55int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap); 55int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
56void iwl_clear_stations_table(struct iwl_priv *priv); 56void iwl_clear_stations_table(struct iwl_priv *priv);
57int iwl_get_free_ucode_key_index(struct iwl_priv *priv); 57int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
58int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); 58int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
59int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); 59int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
60int iwl_send_add_sta(struct iwl_priv *priv, 60int iwl_send_add_sta(struct iwl_priv *priv,
61 struct iwl_addsta_cmd *sta, u8 flags); 61 struct iwl_addsta_cmd *sta, u8 flags);
62u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, 62u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
63 int is_ap, u8 flags,
64 struct ieee80211_sta_ht_cap *ht_info); 63 struct ieee80211_sta_ht_cap *ht_info);
65void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); 64void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
66int iwl_sta_rx_agg_start(struct iwl_priv *priv, 65int iwl_sta_rx_agg_start(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 5c10b87d0336..92fa1a39c446 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -95,144 +95,6 @@ struct iwl_mod_params iwl3945_mod_params = {
95 /* the rest are 0 by default */ 95 /* the rest are 0 by default */
96}; 96};
97 97
98/*************** STATION TABLE MANAGEMENT ****
99 * mac80211 should be examined to determine if sta_info is duplicating
100 * the functionality provided here
101 */
102
103/**************************************************************/
104#if 0 /* temporary disable till we add real remove station */
105/**
106 * iwl3945_remove_station - Remove driver's knowledge of station.
107 *
108 * NOTE: This does not remove station from device's station table.
109 */
110static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
111{
112 int index = IWL_INVALID_STATION;
113 int i;
114 unsigned long flags;
115
116 spin_lock_irqsave(&priv->sta_lock, flags);
117
118 if (is_ap)
119 index = IWL_AP_ID;
120 else if (is_broadcast_ether_addr(addr))
121 index = priv->hw_params.bcast_sta_id;
122 else
123 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
124 if (priv->stations_39[i].used &&
125 !compare_ether_addr(priv->stations_39[i].sta.sta.addr,
126 addr)) {
127 index = i;
128 break;
129 }
130
131 if (unlikely(index == IWL_INVALID_STATION))
132 goto out;
133
134 if (priv->stations_39[index].used) {
135 priv->stations_39[index].used = 0;
136 priv->num_stations--;
137 }
138
139 BUG_ON(priv->num_stations < 0);
140
141out:
142 spin_unlock_irqrestore(&priv->sta_lock, flags);
143 return 0;
144}
145#endif
146
147/**
148 * iwl3945_clear_stations_table - Clear the driver's station table
149 *
150 * NOTE: This does not clear or otherwise alter the device's station table.
151 */
152void iwl3945_clear_stations_table(struct iwl_priv *priv)
153{
154 unsigned long flags;
155
156 spin_lock_irqsave(&priv->sta_lock, flags);
157
158 priv->num_stations = 0;
159 memset(priv->stations_39, 0, sizeof(priv->stations_39));
160
161 spin_unlock_irqrestore(&priv->sta_lock, flags);
162}
163
164/**
165 * iwl3945_add_station - Add station to station tables in driver and device
166 */
167u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info)
168{
169 int i;
170 int index = IWL_INVALID_STATION;
171 struct iwl3945_station_entry *station;
172 unsigned long flags_spin;
173 u8 rate;
174
175 spin_lock_irqsave(&priv->sta_lock, flags_spin);
176 if (is_ap)
177 index = IWL_AP_ID;
178 else if (is_broadcast_ether_addr(addr))
179 index = priv->hw_params.bcast_sta_id;
180 else
181 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
182 if (!compare_ether_addr(priv->stations_39[i].sta.sta.addr,
183 addr)) {
184 index = i;
185 break;
186 }
187
188 if (!priv->stations_39[i].used &&
189 index == IWL_INVALID_STATION)
190 index = i;
191 }
192
193 /* These two conditions has the same outcome but keep them separate
194 since they have different meaning */
195 if (unlikely(index == IWL_INVALID_STATION)) {
196 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
197 return index;
198 }
199
200 if (priv->stations_39[index].used &&
201 !compare_ether_addr(priv->stations_39[index].sta.sta.addr, addr)) {
202 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
203 return index;
204 }
205
206 IWL_DEBUG_ASSOC(priv, "Add STA ID %d: %pM\n", index, addr);
207 station = &priv->stations_39[index];
208 station->used = 1;
209 priv->num_stations++;
210
211 /* Set up the REPLY_ADD_STA command to send to device */
212 memset(&station->sta, 0, sizeof(struct iwl3945_addsta_cmd));
213 memcpy(station->sta.sta.addr, addr, ETH_ALEN);
214 station->sta.mode = 0;
215 station->sta.sta.sta_id = index;
216 station->sta.station_flags = 0;
217
218 if (priv->band == IEEE80211_BAND_5GHZ)
219 rate = IWL_RATE_6M_PLCP;
220 else
221 rate = IWL_RATE_1M_PLCP;
222
223 /* Turn on both antennas for the station... */
224 station->sta.rate_n_flags =
225 iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
226
227 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
228
229 /* Add station to device's station table */
230 iwl_send_add_sta(priv,
231 (struct iwl_addsta_cmd *)&station->sta, flags);
232 return index;
233
234}
235
236/** 98/**
237 * iwl3945_get_antenna_flags - Get antenna flags for RXON command 99 * iwl3945_get_antenna_flags - Get antenna flags for RXON command
238 * @priv: eeprom and antenna fields are used to determine antenna flags 100 * @priv: eeprom and antenna fields are used to determine antenna flags
@@ -289,32 +151,31 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
289 key_flags &= ~STA_KEY_FLG_INVALID; 151 key_flags &= ~STA_KEY_FLG_INVALID;
290 152
291 spin_lock_irqsave(&priv->sta_lock, flags); 153 spin_lock_irqsave(&priv->sta_lock, flags);
292 priv->stations_39[sta_id].keyinfo.alg = keyconf->alg; 154 priv->stations[sta_id].keyinfo.alg = keyconf->alg;
293 priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen; 155 priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
294 memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key, 156 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
295 keyconf->keylen); 157 keyconf->keylen);
296 158
297 memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key, 159 memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
298 keyconf->keylen); 160 keyconf->keylen);
299 161
300 if ((priv->stations_39[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) 162 if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
301 == STA_KEY_FLG_NO_ENC) 163 == STA_KEY_FLG_NO_ENC)
302 priv->stations_39[sta_id].sta.key.key_offset = 164 priv->stations[sta_id].sta.key.key_offset =
303 iwl_get_free_ucode_key_index(priv); 165 iwl_get_free_ucode_key_index(priv);
304 /* else, we are overriding an existing key => no need to allocated room 166 /* else, we are overriding an existing key => no need to allocated room
305 * in uCode. */ 167 * in uCode. */
306 168
307 WARN(priv->stations_39[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, 169 WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
308 "no space for a new key"); 170 "no space for a new key");
309 171
310 priv->stations_39[sta_id].sta.key.key_flags = key_flags; 172 priv->stations[sta_id].sta.key.key_flags = key_flags;
311 priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 173 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
312 priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 174 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
313 175
314 IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n"); 176 IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");
315 177
316 ret = iwl_send_add_sta(priv, 178 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
317 (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC);
318 179
319 spin_unlock_irqrestore(&priv->sta_lock, flags); 180 spin_unlock_irqrestore(&priv->sta_lock, flags);
320 181
@@ -340,17 +201,16 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
340 unsigned long flags; 201 unsigned long flags;
341 202
342 spin_lock_irqsave(&priv->sta_lock, flags); 203 spin_lock_irqsave(&priv->sta_lock, flags);
343 memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); 204 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
344 memset(&priv->stations_39[sta_id].sta.key, 0, 205 memset(&priv->stations[sta_id].sta.key, 0,
345 sizeof(struct iwl4965_keyinfo)); 206 sizeof(struct iwl4965_keyinfo));
346 priv->stations_39[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; 207 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
347 priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 208 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
348 priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 209 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
349 spin_unlock_irqrestore(&priv->sta_lock, flags); 210 spin_unlock_irqrestore(&priv->sta_lock, flags);
350 211
351 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); 212 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
352 iwl_send_add_sta(priv, 213 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0);
353 (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
354 return 0; 214 return 0;
355} 215}
356 216
@@ -578,7 +438,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
578 int sta_id) 438 int sta_id)
579{ 439{
580 struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload; 440 struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
581 struct iwl_hw_key *keyinfo = &priv->stations_39[sta_id].keyinfo; 441 struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
582 442
583 switch (keyinfo->alg) { 443 switch (keyinfo->alg) {
584 case ALG_CCMP: 444 case ALG_CCMP:
@@ -753,7 +613,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
753 if (ieee80211_is_data_qos(fc)) { 613 if (ieee80211_is_data_qos(fc)) {
754 qc = ieee80211_get_qos_ctl(hdr); 614 qc = ieee80211_get_qos_ctl(hdr);
755 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 615 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
756 seq_number = priv->stations_39[sta_id].tid[tid].seq_number & 616 seq_number = priv->stations[sta_id].tid[tid].seq_number &
757 IEEE80211_SCTL_SEQ; 617 IEEE80211_SCTL_SEQ;
758 hdr->seq_ctrl = cpu_to_le16(seq_number) | 618 hdr->seq_ctrl = cpu_to_le16(seq_number) |
759 (hdr->seq_ctrl & 619 (hdr->seq_ctrl &
@@ -813,7 +673,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
813 if (!ieee80211_has_morefrags(hdr->frame_control)) { 673 if (!ieee80211_has_morefrags(hdr->frame_control)) {
814 txq->need_update = 1; 674 txq->need_update = 1;
815 if (qc) 675 if (qc)
816 priv->stations_39[sta_id].tid[tid].seq_number = seq_number; 676 priv->stations[sta_id].tid[tid].seq_number = seq_number;
817 } else { 677 } else {
818 wait_write_ptr = 1; 678 wait_write_ptr = 1;
819 txq->need_update = 0; 679 txq->need_update = 0;
@@ -1316,7 +1176,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
1316 1176
1317 /* If we've added more space for the firmware to place data, tell it. 1177 /* If we've added more space for the firmware to place data, tell it.
1318 * Increment device's write pointer in multiples of 8. */ 1178 * Increment device's write pointer in multiples of 8. */
1319 if ((write != (rxq->write & ~0x7)) 1179 if ((rxq->write_actual != (rxq->write & ~0x7))
1320 || (abs(rxq->write - rxq->read) > 7)) { 1180 || (abs(rxq->write - rxq->read) > 7)) {
1321 spin_lock_irqsave(&rxq->lock, flags); 1181 spin_lock_irqsave(&rxq->lock, flags);
1322 rxq->need_update = 1; 1182 rxq->need_update = 1;
@@ -1337,7 +1197,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
1337 * Also restock the Rx queue via iwl3945_rx_queue_restock. 1197 * Also restock the Rx queue via iwl3945_rx_queue_restock.
1338 * This is called as a scheduled work item (except for during initialization) 1198 * This is called as a scheduled work item (except for during initialization)
1339 */ 1199 */
1340static void iwl3945_rx_allocate(struct iwl_priv *priv) 1200static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
1341{ 1201{
1342 struct iwl_rx_queue *rxq = &priv->rxq; 1202 struct iwl_rx_queue *rxq = &priv->rxq;
1343 struct list_head *element; 1203 struct list_head *element;
@@ -1360,7 +1220,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv)
1360 /* Alloc a new receive buffer */ 1220 /* Alloc a new receive buffer */
1361 rxb->skb = 1221 rxb->skb =
1362 alloc_skb(priv->hw_params.rx_buf_size, 1222 alloc_skb(priv->hw_params.rx_buf_size,
1363 GFP_KERNEL); 1223 priority);
1364 if (!rxb->skb) { 1224 if (!rxb->skb) {
1365 if (net_ratelimit()) 1225 if (net_ratelimit())
1366 IWL_CRIT(priv, ": Can not allocate SKB buffers\n"); 1226 IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
@@ -1419,6 +1279,7 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
1419 * not restocked the Rx queue with fresh buffers */ 1279 * not restocked the Rx queue with fresh buffers */
1420 rxq->read = rxq->write = 0; 1280 rxq->read = rxq->write = 0;
1421 rxq->free_count = 0; 1281 rxq->free_count = 0;
1282 rxq->write_actual = 0;
1422 spin_unlock_irqrestore(&rxq->lock, flags); 1283 spin_unlock_irqrestore(&rxq->lock, flags);
1423} 1284}
1424 1285
@@ -1427,13 +1288,21 @@ void iwl3945_rx_replenish(void *data)
1427 struct iwl_priv *priv = data; 1288 struct iwl_priv *priv = data;
1428 unsigned long flags; 1289 unsigned long flags;
1429 1290
1430 iwl3945_rx_allocate(priv); 1291 iwl3945_rx_allocate(priv, GFP_KERNEL);
1431 1292
1432 spin_lock_irqsave(&priv->lock, flags); 1293 spin_lock_irqsave(&priv->lock, flags);
1433 iwl3945_rx_queue_restock(priv); 1294 iwl3945_rx_queue_restock(priv);
1434 spin_unlock_irqrestore(&priv->lock, flags); 1295 spin_unlock_irqrestore(&priv->lock, flags);
1435} 1296}
1436 1297
1298static void iwl3945_rx_replenish_now(struct iwl_priv *priv)
1299{
1300 iwl3945_rx_allocate(priv, GFP_ATOMIC);
1301
1302 iwl3945_rx_queue_restock(priv);
1303}
1304
1305
1437/* Assumes that the skb field of the buffers in 'pool' is kept accurate. 1306/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
1438 * If an SKB has been detached, the POOL needs to have its SKB set to NULL 1307 * If an SKB has been detached, the POOL needs to have its SKB set to NULL
1439 * This free routine walks the list of POOL entries and if SKB is set to 1308 * This free routine walks the list of POOL entries and if SKB is set to
@@ -1556,13 +1425,19 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1556 unsigned long flags; 1425 unsigned long flags;
1557 u8 fill_rx = 0; 1426 u8 fill_rx = 0;
1558 u32 count = 8; 1427 u32 count = 8;
1428 int total_empty = 0;
1559 1429
1560 /* uCode's read index (stored in shared DRAM) indicates the last Rx 1430 /* uCode's read index (stored in shared DRAM) indicates the last Rx
1561 * buffer that the driver may process (last buffer filled by ucode). */ 1431 * buffer that the driver may process (last buffer filled by ucode). */
1562 r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; 1432 r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
1563 i = rxq->read; 1433 i = rxq->read;
1564 1434
1565 if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) 1435 /* calculate total frames need to be restock after handling RX */
1436 total_empty = r - priv->rxq.write_actual;
1437 if (total_empty < 0)
1438 total_empty += RX_QUEUE_SIZE;
1439
1440 if (total_empty > (RX_QUEUE_SIZE / 2))
1566 fill_rx = 1; 1441 fill_rx = 1;
1567 /* Rx interrupt, but nothing sent from uCode */ 1442 /* Rx interrupt, but nothing sent from uCode */
1568 if (i == r) 1443 if (i == r)
@@ -1639,7 +1514,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1639 count++; 1514 count++;
1640 if (count >= 8) { 1515 if (count >= 8) {
1641 priv->rxq.read = i; 1516 priv->rxq.read = i;
1642 iwl3945_rx_queue_restock(priv); 1517 iwl3945_rx_replenish_now(priv);
1643 count = 0; 1518 count = 0;
1644 } 1519 }
1645 } 1520 }
@@ -1647,7 +1522,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1647 1522
1648 /* Backtrack one entry */ 1523 /* Backtrack one entry */
1649 priv->rxq.read = i; 1524 priv->rxq.read = i;
1650 iwl3945_rx_queue_restock(priv); 1525 if (fill_rx)
1526 iwl3945_rx_replenish_now(priv);
1527 else
1528 iwl3945_rx_queue_restock(priv);
1651} 1529}
1652 1530
1653/* call this function to flush any scheduled tasklet */ 1531/* call this function to flush any scheduled tasklet */
@@ -2589,7 +2467,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2589 goto restart; 2467 goto restart;
2590 } 2468 }
2591 2469
2592 priv->cfg->ops->smgmt->clear_station_table(priv); 2470 iwl_clear_stations_table(priv);
2593 2471
2594 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); 2472 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
2595 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); 2473 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);
@@ -2681,7 +2559,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
2681 set_bit(STATUS_EXIT_PENDING, &priv->status); 2559 set_bit(STATUS_EXIT_PENDING, &priv->status);
2682 2560
2683 iwl3945_led_unregister(priv); 2561 iwl3945_led_unregister(priv);
2684 priv->cfg->ops->smgmt->clear_station_table(priv); 2562 iwl_clear_stations_table(priv);
2685 2563
2686 /* Unblock any waiting calls */ 2564 /* Unblock any waiting calls */
2687 wake_up_interruptible_all(&priv->wait_command_queue); 2565 wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2833,7 +2711,7 @@ static int __iwl3945_up(struct iwl_priv *priv)
2833 2711
2834 for (i = 0; i < MAX_HW_RESTARTS; i++) { 2712 for (i = 0; i < MAX_HW_RESTARTS; i++) {
2835 2713
2836 priv->cfg->ops->smgmt->clear_station_table(priv); 2714 iwl_clear_stations_table(priv);
2837 2715
2838 /* load bootstrap state machine, 2716 /* load bootstrap state machine,
2839 * load bootstrap program into processor's memory, 2717 * load bootstrap program into processor's memory,
@@ -3247,7 +3125,7 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3247 case NL80211_IFTYPE_ADHOC: 3125 case NL80211_IFTYPE_ADHOC:
3248 3126
3249 priv->assoc_id = 1; 3127 priv->assoc_id = 1;
3250 priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 0, 0, NULL); 3128 iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL);
3251 iwl3945_sync_sta(priv, IWL_STA_ID, 3129 iwl3945_sync_sta(priv, IWL_STA_ID,
3252 (priv->band == IEEE80211_BAND_5GHZ) ? 3130 (priv->band == IEEE80211_BAND_5GHZ) ?
3253 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, 3131 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
@@ -3438,7 +3316,7 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3438 /* restore RXON assoc */ 3316 /* restore RXON assoc */
3439 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3317 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
3440 iwlcore_commit_rxon(priv); 3318 iwlcore_commit_rxon(priv);
3441 priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL); 3319 iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL);
3442 } 3320 }
3443 iwl3945_send_beacon_cmd(priv); 3321 iwl3945_send_beacon_cmd(priv);
3444 3322
@@ -3469,7 +3347,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3469 static_key = !iwl_is_associated(priv); 3347 static_key = !iwl_is_associated(priv);
3470 3348
3471 if (!static_key) { 3349 if (!static_key) {
3472 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 3350 sta_id = iwl_find_station(priv, addr);
3473 if (sta_id == IWL_INVALID_STATION) { 3351 if (sta_id == IWL_INVALID_STATION) {
3474 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", 3352 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
3475 addr); 3353 addr);
@@ -4044,7 +3922,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
4044 mutex_init(&priv->mutex); 3922 mutex_init(&priv->mutex);
4045 3923
4046 /* Clear the driver's (not device's) station table */ 3924 /* Clear the driver's (not device's) station table */
4047 priv->cfg->ops->smgmt->clear_station_table(priv); 3925 iwl_clear_stations_table(priv);
4048 3926
4049 priv->data_retry_limit = -1; 3927 priv->data_retry_limit = -1;
4050 priv->ieee_channels = NULL; 3928 priv->ieee_channels = NULL;
@@ -4407,7 +4285,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
4407 iwl3945_hw_txq_ctx_free(priv); 4285 iwl3945_hw_txq_ctx_free(priv);
4408 4286
4409 iwl3945_unset_hw_params(priv); 4287 iwl3945_unset_hw_params(priv);
4410 priv->cfg->ops->smgmt->clear_station_table(priv); 4288 iwl_clear_stations_table(priv);
4411 4289
4412 /*netif_stop_queue(dev); */ 4290 /*netif_stop_queue(dev); */
4413 flush_workqueue(priv->workqueue); 4291 flush_workqueue(priv->workqueue);
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig
index 41bd4b2b5411..1eccb6df46dd 100644
--- a/drivers/net/wireless/iwmc3200wifi/Kconfig
+++ b/drivers/net/wireless/iwmc3200wifi/Kconfig
@@ -1,10 +1,9 @@
1config IWM 1config IWM
2 tristate "Intel Wireless Multicomm 3200 WiFi driver" 2 tristate "Intel Wireless Multicomm 3200 WiFi driver"
3 depends on MMC && WLAN_80211 && EXPERIMENTAL 3 depends on MMC && WLAN_80211 && EXPERIMENTAL
4 depends on CFG80211
4 select WIRELESS_EXT 5 select WIRELESS_EXT
5 select CFG80211
6 select FW_LOADER 6 select FW_LOADER
7 select RFKILL
8 7
9config IWM_DEBUG 8config IWM_DEBUG
10 bool "Enable full debugging output in iwmc3200wifi" 9 bool "Enable full debugging output in iwmc3200wifi"
diff --git a/drivers/net/wireless/iwmc3200wifi/Makefile b/drivers/net/wireless/iwmc3200wifi/Makefile
index 7cb415e5c11b..927f022545c1 100644
--- a/drivers/net/wireless/iwmc3200wifi/Makefile
+++ b/drivers/net/wireless/iwmc3200wifi/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_IWM) := iwmc3200wifi.o 1obj-$(CONFIG_IWM) := iwmc3200wifi.o
2iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o 2iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o
3iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o rfkill.o 3iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o
4 4
5iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o 5iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 3256ad2c96ce..96f714e6e12b 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -268,7 +268,7 @@ static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
268 268
269 iwm->conf.frag_threshold = wiphy->frag_threshold; 269 iwm->conf.frag_threshold = wiphy->frag_threshold;
270 270
271 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, 271 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
272 CFG_FRAG_THRESHOLD, 272 CFG_FRAG_THRESHOLD,
273 iwm->conf.frag_threshold); 273 iwm->conf.frag_threshold);
274 if (ret < 0) 274 if (ret < 0)
diff --git a/drivers/net/wireless/iwmc3200wifi/fw.c b/drivers/net/wireless/iwmc3200wifi/fw.c
index db4ba0864730..ec1a15a5a0e4 100644
--- a/drivers/net/wireless/iwmc3200wifi/fw.c
+++ b/drivers/net/wireless/iwmc3200wifi/fw.c
@@ -72,7 +72,7 @@ static int iwm_fw_op_offset(struct iwm_priv *iwm, const struct firmware *fw,
72 } 72 }
73 73
74 if (fw->size < IWM_HDR_LEN) { 74 if (fw->size < IWM_HDR_LEN) {
75 IWM_ERR(iwm, "FW is too small (%d)\n", fw->size); 75 IWM_ERR(iwm, "FW is too small (%zu)\n", fw->size);
76 return -EINVAL; 76 return -EINVAL;
77 } 77 }
78 78
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 3b29681792bb..635c16ee6186 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -343,8 +343,4 @@ int iwm_rx_handle_resp(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size,
343 struct iwm_wifi_cmd *cmd); 343 struct iwm_wifi_cmd *cmd);
344void iwm_rx_free(struct iwm_priv *iwm); 344void iwm_rx_free(struct iwm_priv *iwm);
345 345
346/* RF Kill API */
347int iwm_rfkill_init(struct iwm_priv *iwm);
348void iwm_rfkill_exit(struct iwm_priv *iwm);
349
350#endif 346#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c
index eec7201e91a8..68e2c3b6c7a1 100644
--- a/drivers/net/wireless/iwmc3200wifi/netdev.c
+++ b/drivers/net/wireless/iwmc3200wifi/netdev.c
@@ -136,17 +136,8 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
136 136
137 wdev->netdev = ndev; 137 wdev->netdev = ndev;
138 138
139 ret = iwm_rfkill_init(iwm);
140 if (ret) {
141 dev_err(dev, "Failed to init rfkill\n");
142 goto out_rfkill;
143 }
144
145 return iwm; 139 return iwm;
146 140
147 out_rfkill:
148 unregister_netdev(ndev);
149
150 out_ndev: 141 out_ndev:
151 free_netdev(ndev); 142 free_netdev(ndev);
152 143
@@ -162,7 +153,6 @@ void iwm_if_free(struct iwm_priv *iwm)
162 if (!iwm_to_ndev(iwm)) 153 if (!iwm_to_ndev(iwm))
163 return; 154 return;
164 155
165 iwm_rfkill_exit(iwm);
166 unregister_netdev(iwm_to_ndev(iwm)); 156 unregister_netdev(iwm_to_ndev(iwm));
167 free_netdev(iwm_to_ndev(iwm)); 157 free_netdev(iwm_to_ndev(iwm));
168 iwm_wdev_free(iwm); 158 iwm_wdev_free(iwm);
diff --git a/drivers/net/wireless/iwmc3200wifi/rfkill.c b/drivers/net/wireless/iwmc3200wifi/rfkill.c
deleted file mode 100644
index 4ca8b495f82d..000000000000
--- a/drivers/net/wireless/iwmc3200wifi/rfkill.c
+++ /dev/null
@@ -1,88 +0,0 @@
1/*
2 * Intel Wireless Multicomm 3200 WiFi driver
3 *
4 * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
5 * Samuel Ortiz <samuel.ortiz@intel.com>
6 * Zhu Yi <yi.zhu@intel.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 *
22 */
23
24#include <linux/rfkill.h>
25
26#include "iwm.h"
27
28static int iwm_rfkill_soft_toggle(void *data, enum rfkill_state state)
29{
30 struct iwm_priv *iwm = data;
31
32 switch (state) {
33 case RFKILL_STATE_UNBLOCKED:
34 if (test_bit(IWM_RADIO_RFKILL_HW, &iwm->radio))
35 return -EBUSY;
36
37 if (test_and_clear_bit(IWM_RADIO_RFKILL_SW, &iwm->radio) &&
38 (iwm_to_ndev(iwm)->flags & IFF_UP))
39 iwm_up(iwm);
40
41 break;
42 case RFKILL_STATE_SOFT_BLOCKED:
43 if (!test_and_set_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))
44 iwm_down(iwm);
45
46 break;
47 default:
48 break;
49 }
50
51 return 0;
52}
53
54int iwm_rfkill_init(struct iwm_priv *iwm)
55{
56 int ret;
57
58 iwm->rfkill = rfkill_allocate(iwm_to_dev(iwm), RFKILL_TYPE_WLAN);
59 if (!iwm->rfkill) {
60 IWM_ERR(iwm, "Unable to allocate rfkill device\n");
61 return -ENOMEM;
62 }
63
64 iwm->rfkill->name = KBUILD_MODNAME;
65 iwm->rfkill->data = iwm;
66 iwm->rfkill->state = RFKILL_STATE_UNBLOCKED;
67 iwm->rfkill->toggle_radio = iwm_rfkill_soft_toggle;
68
69 ret = rfkill_register(iwm->rfkill);
70 if (ret) {
71 IWM_ERR(iwm, "Failed to register rfkill device\n");
72 goto fail;
73 }
74
75 return 0;
76 fail:
77 rfkill_free(iwm->rfkill);
78 return ret;
79}
80
81void iwm_rfkill_exit(struct iwm_priv *iwm)
82{
83 if (iwm->rfkill)
84 rfkill_unregister(iwm->rfkill);
85
86 rfkill_free(iwm->rfkill);
87 iwm->rfkill = NULL;
88}
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c
index edc0a0091058..b54da677b371 100644
--- a/drivers/net/wireless/iwmc3200wifi/sdio.c
+++ b/drivers/net/wireless/iwmc3200wifi/sdio.c
@@ -395,7 +395,7 @@ static struct iwm_if_ops if_sdio_ops = {
395 .debugfs_init = if_sdio_debugfs_init, 395 .debugfs_init = if_sdio_debugfs_init,
396 .debugfs_exit = if_sdio_debugfs_exit, 396 .debugfs_exit = if_sdio_debugfs_exit,
397 .umac_name = "iwmc3200wifi-umac-sdio.bin", 397 .umac_name = "iwmc3200wifi-umac-sdio.bin",
398 .calib_lmac_name = "iwmc3200wifi-lmac-calib-sdio.bin", 398 .calib_lmac_name = "iwmc3200wifi-calib-sdio.bin",
399 .lmac_name = "iwmc3200wifi-lmac-sdio.bin", 399 .lmac_name = "iwmc3200wifi-lmac-sdio.bin",
400}; 400};
401 401
diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c
index 4bc46a60ae2f..9a5408e7d94a 100644
--- a/drivers/net/wireless/libertas/11d.c
+++ b/drivers/net/wireless/libertas/11d.c
@@ -207,7 +207,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d
207 lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband); 207 lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband);
208 lbs_deb_hex(LBS_DEB_11D, "domaininfo", (char *)domaininfo, 208 lbs_deb_hex(LBS_DEB_11D, "domaininfo", (char *)domaininfo,
209 COUNTRY_CODE_LEN + 1 + 209 COUNTRY_CODE_LEN + 1 +
210 sizeof(struct ieeetypes_subbandset) * nr_subband); 210 sizeof(struct ieee_subbandset) * nr_subband);
211 return 0; 211 return 0;
212} 212}
213 213
@@ -302,11 +302,9 @@ done:
302 * @param parsed_region_chan pointer to parsed_region_chan_11d 302 * @param parsed_region_chan pointer to parsed_region_chan_11d
303 * @return 0 303 * @return 0
304*/ 304*/
305static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* 305static int parse_domain_info_11d(struct ieee_ie_country_info_full_set *countryinfo,
306 countryinfo,
307 u8 band, 306 u8 band,
308 struct parsed_region_chan_11d * 307 struct parsed_region_chan_11d *parsed_region_chan)
309 parsed_region_chan)
310{ 308{
311 u8 nr_subband, nrchan; 309 u8 nr_subband, nrchan;
312 u8 lastchan, firstchan; 310 u8 lastchan, firstchan;
@@ -331,7 +329,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
331 lbs_deb_hex(LBS_DEB_11D, "countryinfo", (u8 *) countryinfo, 30); 329 lbs_deb_hex(LBS_DEB_11D, "countryinfo", (u8 *) countryinfo, 30);
332 330
333 if ((*(countryinfo->countrycode)) == 0 331 if ((*(countryinfo->countrycode)) == 0
334 || (countryinfo->len <= COUNTRY_CODE_LEN)) { 332 || (countryinfo->header.len <= COUNTRY_CODE_LEN)) {
335 /* No region Info or Wrong region info: treat as No 11D info */ 333 /* No region Info or Wrong region info: treat as No 11D info */
336 goto done; 334 goto done;
337 } 335 }
@@ -349,8 +347,8 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
349 memcpy(parsed_region_chan->countrycode, countryinfo->countrycode, 347 memcpy(parsed_region_chan->countrycode, countryinfo->countrycode,
350 COUNTRY_CODE_LEN); 348 COUNTRY_CODE_LEN);
351 349
352 nr_subband = (countryinfo->len - COUNTRY_CODE_LEN) / 350 nr_subband = (countryinfo->header.len - COUNTRY_CODE_LEN) /
353 sizeof(struct ieeetypes_subbandset); 351 sizeof(struct ieee_subbandset);
354 352
355 for (j = 0, lastchan = 0; j < nr_subband; j++) { 353 for (j = 0, lastchan = 0; j < nr_subband; j++) {
356 354
@@ -502,7 +500,7 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
502{ 500{
503 struct cmd_ds_802_11d_domain_info *pdomaininfo = 501 struct cmd_ds_802_11d_domain_info *pdomaininfo =
504 &cmd->params.domaininfo; 502 &cmd->params.domaininfo;
505 struct mrvlietypes_domainparamset *domain = &pdomaininfo->domain; 503 struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain;
506 u8 nr_subband = priv->domainreg.nr_subband; 504 u8 nr_subband = priv->domainreg.nr_subband;
507 505
508 lbs_deb_enter(LBS_DEB_11D); 506 lbs_deb_enter(LBS_DEB_11D);
@@ -524,16 +522,16 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
524 sizeof(domain->countrycode)); 522 sizeof(domain->countrycode));
525 523
526 domain->header.len = 524 domain->header.len =
527 cpu_to_le16(nr_subband * sizeof(struct ieeetypes_subbandset) + 525 cpu_to_le16(nr_subband * sizeof(struct ieee_subbandset) +
528 sizeof(domain->countrycode)); 526 sizeof(domain->countrycode));
529 527
530 if (nr_subband) { 528 if (nr_subband) {
531 memcpy(domain->subband, priv->domainreg.subband, 529 memcpy(domain->subband, priv->domainreg.subband,
532 nr_subband * sizeof(struct ieeetypes_subbandset)); 530 nr_subband * sizeof(struct ieee_subbandset));
533 531
534 cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + 532 cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
535 le16_to_cpu(domain->header.len) + 533 le16_to_cpu(domain->header.len) +
536 sizeof(struct mrvlietypesheader) + 534 sizeof(struct mrvl_ie_header) +
537 S_DS_GEN); 535 S_DS_GEN);
538 } else { 536 } else {
539 cmd->size = 537 cmd->size =
@@ -556,7 +554,7 @@ done:
556int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp) 554int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
557{ 555{
558 struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp; 556 struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp;
559 struct mrvlietypes_domainparamset *domain = &domaininfo->domain; 557 struct mrvl_ie_domain_param_set *domain = &domaininfo->domain;
560 u16 action = le16_to_cpu(domaininfo->action); 558 u16 action = le16_to_cpu(domaininfo->action);
561 s16 ret = 0; 559 s16 ret = 0;
562 u8 nr_subband = 0; 560 u8 nr_subband = 0;
@@ -567,7 +565,7 @@ int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
567 (int)le16_to_cpu(resp->size)); 565 (int)le16_to_cpu(resp->size));
568 566
569 nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) / 567 nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) /
570 sizeof(struct ieeetypes_subbandset); 568 sizeof(struct ieee_subbandset);
571 569
572 lbs_deb_11d("domain info resp: nr_subband %d\n", nr_subband); 570 lbs_deb_11d("domain info resp: nr_subband %d\n", nr_subband);
573 571
diff --git a/drivers/net/wireless/libertas/11d.h b/drivers/net/wireless/libertas/11d.h
index 4f4f47f0f878..fb75d3e321a0 100644
--- a/drivers/net/wireless/libertas/11d.h
+++ b/drivers/net/wireless/libertas/11d.h
@@ -20,35 +20,36 @@
20struct cmd_ds_command; 20struct cmd_ds_command;
21 21
22/** Data structure for Country IE*/ 22/** Data structure for Country IE*/
23struct ieeetypes_subbandset { 23struct ieee_subbandset {
24 u8 firstchan; 24 u8 firstchan;
25 u8 nrchan; 25 u8 nrchan;
26 u8 maxtxpwr; 26 u8 maxtxpwr;
27} __attribute__ ((packed)); 27} __attribute__ ((packed));
28 28
29struct ieeetypes_countryinfoset { 29struct ieee_ie_country_info_set {
30 u8 element_id; 30 struct ieee_ie_header header;
31 u8 len; 31
32 u8 countrycode[COUNTRY_CODE_LEN]; 32 u8 countrycode[COUNTRY_CODE_LEN];
33 struct ieeetypes_subbandset subband[1]; 33 struct ieee_subbandset subband[1];
34}; 34};
35 35
36struct ieeetypes_countryinfofullset { 36struct ieee_ie_country_info_full_set {
37 u8 element_id; 37 struct ieee_ie_header header;
38 u8 len; 38
39 u8 countrycode[COUNTRY_CODE_LEN]; 39 u8 countrycode[COUNTRY_CODE_LEN];
40 struct ieeetypes_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D]; 40 struct ieee_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
41} __attribute__ ((packed)); 41} __attribute__ ((packed));
42 42
43struct mrvlietypes_domainparamset { 43struct mrvl_ie_domain_param_set {
44 struct mrvlietypesheader header; 44 struct mrvl_ie_header header;
45
45 u8 countrycode[COUNTRY_CODE_LEN]; 46 u8 countrycode[COUNTRY_CODE_LEN];
46 struct ieeetypes_subbandset subband[1]; 47 struct ieee_subbandset subband[1];
47} __attribute__ ((packed)); 48} __attribute__ ((packed));
48 49
49struct cmd_ds_802_11d_domain_info { 50struct cmd_ds_802_11d_domain_info {
50 __le16 action; 51 __le16 action;
51 struct mrvlietypes_domainparamset domain; 52 struct mrvl_ie_domain_param_set domain;
52} __attribute__ ((packed)); 53} __attribute__ ((packed));
53 54
54/** domain regulatory information */ 55/** domain regulatory information */
@@ -57,7 +58,7 @@ struct lbs_802_11d_domain_reg {
57 u8 countrycode[COUNTRY_CODE_LEN]; 58 u8 countrycode[COUNTRY_CODE_LEN];
58 /** No. of subband*/ 59 /** No. of subband*/
59 u8 nr_subband; 60 u8 nr_subband;
60 struct ieeetypes_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D]; 61 struct ieee_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
61}; 62};
62 63
63struct chan_power_11d { 64struct chan_power_11d {
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index a0e440cd8967..b9b374119033 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -12,15 +12,14 @@
12#include "scan.h" 12#include "scan.h"
13#include "cmd.h" 13#include "cmd.h"
14 14
15static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp);
16
17static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) = 15static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) =
18 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 16 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
19static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) = 17static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
20 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 18 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
21 19
22/* The firmware needs certain bits masked out of the beacon-derviced capability 20/* The firmware needs the following bits masked out of the beacon-derived
23 * field when associating/joining to BSSs. 21 * capability field when associating/joining to a BSS:
22 * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused)
24 */ 23 */
25#define CAPINFO_MASK (~(0xda00)) 24#define CAPINFO_MASK (~(0xda00))
26 25
@@ -102,6 +101,295 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
102} 101}
103 102
104 103
104static u8 iw_auth_to_ieee_auth(u8 auth)
105{
106 if (auth == IW_AUTH_ALG_OPEN_SYSTEM)
107 return 0x00;
108 else if (auth == IW_AUTH_ALG_SHARED_KEY)
109 return 0x01;
110 else if (auth == IW_AUTH_ALG_LEAP)
111 return 0x80;
112
113 lbs_deb_join("%s: invalid auth alg 0x%X\n", __func__, auth);
114 return 0;
115}
116
117/**
118 * @brief This function prepares the authenticate command. AUTHENTICATE only
119 * sets the authentication suite for future associations, as the firmware
120 * handles authentication internally during the ASSOCIATE command.
121 *
122 * @param priv A pointer to struct lbs_private structure
123 * @param bssid The peer BSSID with which to authenticate
124 * @param auth The authentication mode to use (from wireless.h)
125 *
126 * @return 0 or -1
127 */
128static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth)
129{
130 struct cmd_ds_802_11_authenticate cmd;
131 int ret = -1;
132 DECLARE_MAC_BUF(mac);
133
134 lbs_deb_enter(LBS_DEB_JOIN);
135
136 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
137 memcpy(cmd.bssid, bssid, ETH_ALEN);
138
139 cmd.authtype = iw_auth_to_ieee_auth(auth);
140
141 lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
142 print_mac(mac, bssid), cmd.authtype);
143
144 ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
145
146 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
147 return ret;
148}
149
150
151static int lbs_assoc_post(struct lbs_private *priv,
152 struct cmd_ds_802_11_associate_response *resp)
153{
154 int ret = 0;
155 union iwreq_data wrqu;
156 struct bss_descriptor *bss;
157 u16 status_code;
158
159 lbs_deb_enter(LBS_DEB_ASSOC);
160
161 if (!priv->in_progress_assoc_req) {
162 lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
163 ret = -1;
164 goto done;
165 }
166 bss = &priv->in_progress_assoc_req->bss;
167
168 /*
169 * Older FW versions map the IEEE 802.11 Status Code in the association
170 * response to the following values returned in resp->statuscode:
171 *
172 * IEEE Status Code Marvell Status Code
173 * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
174 * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
175 * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
176 * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
177 * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
178 * others -> 0x0003 ASSOC_RESULT_REFUSED
179 *
180 * Other response codes:
181 * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
182 * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
183 * association response from the AP)
184 */
185
186 status_code = le16_to_cpu(resp->statuscode);
187 if (priv->fwrelease < 0x09000000) {
188 switch (status_code) {
189 case 0x00:
190 break;
191 case 0x01:
192 lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
193 break;
194 case 0x02:
195 lbs_deb_assoc("ASSOC_RESP: internal timer "
196 "expired while waiting for the AP\n");
197 break;
198 case 0x03:
199 lbs_deb_assoc("ASSOC_RESP: association "
200 "refused by AP\n");
201 break;
202 case 0x04:
203 lbs_deb_assoc("ASSOC_RESP: authentication "
204 "refused by AP\n");
205 break;
206 default:
207 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
208 " unknown\n", status_code);
209 break;
210 }
211 } else {
212 /* v9+ returns the AP's association response */
213 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x\n", status_code);
214 }
215
216 if (status_code) {
217 lbs_mac_event_disconnected(priv);
218 ret = -1;
219 goto done;
220 }
221
222 lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP",
223 (void *) (resp + sizeof (resp->hdr)),
224 le16_to_cpu(resp->hdr.size) - sizeof (resp->hdr));
225
226 /* Send a Media Connected event, according to the Spec */
227 priv->connect_status = LBS_CONNECTED;
228
229 /* Update current SSID and BSSID */
230 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
231 priv->curbssparams.ssid_len = bss->ssid_len;
232 memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
233
234 priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
235 priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
236
237 memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
238 memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
239 priv->nextSNRNF = 0;
240 priv->numSNRNF = 0;
241
242 netif_carrier_on(priv->dev);
243 if (!priv->tx_pending_len)
244 netif_wake_queue(priv->dev);
245
246 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
247 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
248 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
249
250done:
251 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
252 return ret;
253}
254
255/**
256 * @brief This function prepares an association-class command.
257 *
258 * @param priv A pointer to struct lbs_private structure
259 * @param assoc_req The association request describing the BSS to associate
260 * or reassociate with
261 * @param command The actual command, either CMD_802_11_ASSOCIATE or
262 * CMD_802_11_REASSOCIATE
263 *
264 * @return 0 or -1
265 */
266static int lbs_associate(struct lbs_private *priv,
267 struct assoc_request *assoc_req,
268 u16 command)
269{
270 struct cmd_ds_802_11_associate cmd;
271 int ret = 0;
272 struct bss_descriptor *bss = &assoc_req->bss;
273 u8 *pos = &(cmd.iebuf[0]);
274 u16 tmpcap, tmplen, tmpauth;
275 struct mrvl_ie_ssid_param_set *ssid;
276 struct mrvl_ie_ds_param_set *ds;
277 struct mrvl_ie_cf_param_set *cf;
278 struct mrvl_ie_rates_param_set *rates;
279 struct mrvl_ie_rsn_param_set *rsn;
280 struct mrvl_ie_auth_type *auth;
281
282 lbs_deb_enter(LBS_DEB_ASSOC);
283
284 BUG_ON((command != CMD_802_11_ASSOCIATE) &&
285 (command != CMD_802_11_REASSOCIATE));
286
287 memset(&cmd, 0, sizeof(cmd));
288 cmd.hdr.command = cpu_to_le16(command);
289
290 /* Fill in static fields */
291 memcpy(cmd.bssid, bss->bssid, ETH_ALEN);
292 cmd.listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
293
294 /* Capability info */
295 tmpcap = (bss->capability & CAPINFO_MASK);
296 if (bss->mode == IW_MODE_INFRA)
297 tmpcap |= WLAN_CAPABILITY_ESS;
298 cmd.capability = cpu_to_le16(tmpcap);
299 lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
300
301 /* SSID */
302 ssid = (struct mrvl_ie_ssid_param_set *) pos;
303 ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
304 tmplen = bss->ssid_len;
305 ssid->header.len = cpu_to_le16(tmplen);
306 memcpy(ssid->ssid, bss->ssid, tmplen);
307 pos += sizeof(ssid->header) + tmplen;
308
309 ds = (struct mrvl_ie_ds_param_set *) pos;
310 ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
311 ds->header.len = cpu_to_le16(1);
312 ds->channel = bss->phy.ds.channel;
313 pos += sizeof(ds->header) + 1;
314
315 cf = (struct mrvl_ie_cf_param_set *) pos;
316 cf->header.type = cpu_to_le16(TLV_TYPE_CF);
317 tmplen = sizeof(*cf) - sizeof (cf->header);
318 cf->header.len = cpu_to_le16(tmplen);
319 /* IE payload should be zeroed, firmware fills it in for us */
320 pos += sizeof(*cf);
321
322 rates = (struct mrvl_ie_rates_param_set *) pos;
323 rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
324 memcpy(&rates->rates, &bss->rates, MAX_RATES);
325 tmplen = MAX_RATES;
326 if (get_common_rates(priv, rates->rates, &tmplen)) {
327 ret = -1;
328 goto done;
329 }
330 pos += sizeof(rates->header) + tmplen;
331 rates->header.len = cpu_to_le16(tmplen);
332 lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
333
334 /* Copy the infra. association rates into Current BSS state structure */
335 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
336 memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
337
338 /* Set MSB on basic rates as the firmware requires, but _after_
339 * copying to current bss rates.
340 */
341 lbs_set_basic_rate_flags(rates->rates, tmplen);
342
343 /* Firmware v9+ indicate authentication suites as a TLV */
344 if (priv->fwrelease >= 0x09000000) {
345 DECLARE_MAC_BUF(mac);
346
347 auth = (struct mrvl_ie_auth_type *) pos;
348 auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
349 auth->header.len = cpu_to_le16(2);
350 tmpauth = iw_auth_to_ieee_auth(priv->secinfo.auth_mode);
351 auth->auth = cpu_to_le16(tmpauth);
352 pos += sizeof(auth->header) + 2;
353
354 lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
355 print_mac(mac, bss->bssid), priv->secinfo.auth_mode);
356 }
357
358 /* WPA/WPA2 IEs */
359 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
360 rsn = (struct mrvl_ie_rsn_param_set *) pos;
361 /* WPA_IE or WPA2_IE */
362 rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
363 tmplen = (u16) assoc_req->wpa_ie[1];
364 rsn->header.len = cpu_to_le16(tmplen);
365 memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
366 lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: WPA/RSN IE", (u8 *) rsn,
367 sizeof(rsn->header) + tmplen);
368 pos += sizeof(rsn->header) + tmplen;
369 }
370
371 cmd.hdr.size = cpu_to_le16((sizeof(cmd) - sizeof(cmd.iebuf)) +
372 (u16)(pos - (u8 *) &cmd.iebuf));
373
374 /* update curbssparams */
375 priv->curbssparams.channel = bss->phy.ds.channel;
376
377 if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
378 ret = -1;
379 goto done;
380 }
381
382 ret = lbs_cmd_with_response(priv, command, &cmd);
383 if (ret == 0) {
384 ret = lbs_assoc_post(priv,
385 (struct cmd_ds_802_11_associate_response *) &cmd);
386 }
387
388done:
389 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
390 return ret;
391}
392
105/** 393/**
106 * @brief Associate to a specific BSS discovered in a scan 394 * @brief Associate to a specific BSS discovered in a scan
107 * 395 *
@@ -110,7 +398,7 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
110 * 398 *
111 * @return 0-success, otherwise fail 399 * @return 0-success, otherwise fail
112 */ 400 */
113static int lbs_associate(struct lbs_private *priv, 401static int lbs_try_associate(struct lbs_private *priv,
114 struct assoc_request *assoc_req) 402 struct assoc_request *assoc_req)
115{ 403{
116 int ret; 404 int ret;
@@ -118,11 +406,15 @@ static int lbs_associate(struct lbs_private *priv,
118 406
119 lbs_deb_enter(LBS_DEB_ASSOC); 407 lbs_deb_enter(LBS_DEB_ASSOC);
120 408
121 ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE, 409 /* FW v9 and higher indicate authentication suites as a TLV in the
122 0, CMD_OPTION_WAITFORRSP, 410 * association command, not as a separate authentication command.
123 0, assoc_req->bss.bssid); 411 */
124 if (ret) 412 if (priv->fwrelease < 0x09000000) {
125 goto out; 413 ret = lbs_set_authentication(priv, assoc_req->bss.bssid,
414 priv->secinfo.auth_mode);
415 if (ret)
416 goto out;
417 }
126 418
127 /* Use short preamble only when both the BSS and firmware support it */ 419 /* Use short preamble only when both the BSS and firmware support it */
128 if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && 420 if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
@@ -133,14 +425,78 @@ static int lbs_associate(struct lbs_private *priv,
133 if (ret) 425 if (ret)
134 goto out; 426 goto out;
135 427
136 ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE, 428 ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE);
137 0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
138 429
139out: 430out:
140 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 431 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
141 return ret; 432 return ret;
142} 433}
143 434
435static int lbs_adhoc_post(struct lbs_private *priv,
436 struct cmd_ds_802_11_ad_hoc_result *resp)
437{
438 int ret = 0;
439 u16 command = le16_to_cpu(resp->hdr.command);
440 u16 result = le16_to_cpu(resp->hdr.result);
441 union iwreq_data wrqu;
442 struct bss_descriptor *bss;
443 DECLARE_SSID_BUF(ssid);
444
445 lbs_deb_enter(LBS_DEB_JOIN);
446
447 if (!priv->in_progress_assoc_req) {
448 lbs_deb_join("ADHOC_RESP: no in-progress association "
449 "request\n");
450 ret = -1;
451 goto done;
452 }
453 bss = &priv->in_progress_assoc_req->bss;
454
455 /*
456 * Join result code 0 --> SUCCESS
457 */
458 if (result) {
459 lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result);
460 if (priv->connect_status == LBS_CONNECTED)
461 lbs_mac_event_disconnected(priv);
462 ret = -1;
463 goto done;
464 }
465
466 /* Send a Media Connected event, according to the Spec */
467 priv->connect_status = LBS_CONNECTED;
468
469 if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
470 /* Update the created network descriptor with the new BSSID */
471 memcpy(bss->bssid, resp->bssid, ETH_ALEN);
472 }
473
474 /* Set the BSSID from the joined/started descriptor */
475 memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
476
477 /* Set the new SSID to current SSID */
478 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
479 priv->curbssparams.ssid_len = bss->ssid_len;
480
481 netif_carrier_on(priv->dev);
482 if (!priv->tx_pending_len)
483 netif_wake_queue(priv->dev);
484
485 memset(&wrqu, 0, sizeof(wrqu));
486 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
487 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
488 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
489
490 lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
491 print_ssid(ssid, bss->ssid, bss->ssid_len),
492 priv->curbssparams.bssid,
493 priv->curbssparams.channel);
494
495done:
496 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
497 return ret;
498}
499
144/** 500/**
145 * @brief Join an adhoc network found in a previous scan 501 * @brief Join an adhoc network found in a previous scan
146 * 502 *
@@ -219,11 +575,10 @@ static int lbs_adhoc_join(struct lbs_private *priv,
219 memcpy(&cmd.bss.bssid, &bss->bssid, ETH_ALEN); 575 memcpy(&cmd.bss.bssid, &bss->bssid, ETH_ALEN);
220 memcpy(&cmd.bss.ssid, &bss->ssid, bss->ssid_len); 576 memcpy(&cmd.bss.ssid, &bss->ssid, bss->ssid_len);
221 577
222 memcpy(&cmd.bss.phyparamset, &bss->phyparamset, 578 memcpy(&cmd.bss.ds, &bss->phy.ds, sizeof(struct ieee_ie_ds_param_set));
223 sizeof(union ieeetypes_phyparamset));
224 579
225 memcpy(&cmd.bss.ssparamset, &bss->ssparamset, 580 memcpy(&cmd.bss.ibss, &bss->ss.ibss,
226 sizeof(union IEEEtypes_ssparamset)); 581 sizeof(struct ieee_ie_ibss_param_set));
227 582
228 cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK); 583 cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
229 lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", 584 lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
@@ -260,7 +615,7 @@ static int lbs_adhoc_join(struct lbs_private *priv,
260 */ 615 */
261 lbs_set_basic_rate_flags(cmd.bss.rates, ratesize); 616 lbs_set_basic_rate_flags(cmd.bss.rates, ratesize);
262 617
263 cmd.bss.ssparamset.ibssparamset.atimwindow = cpu_to_le16(bss->atimwindow); 618 cmd.bss.ibss.atimwindow = bss->atimwindow;
264 619
265 if (assoc_req->secinfo.wep_enabled) { 620 if (assoc_req->secinfo.wep_enabled) {
266 u16 tmp = le16_to_cpu(cmd.bss.capability); 621 u16 tmp = le16_to_cpu(cmd.bss.capability);
@@ -287,8 +642,10 @@ static int lbs_adhoc_join(struct lbs_private *priv,
287 } 642 }
288 643
289 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd); 644 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
290 if (ret == 0) 645 if (ret == 0) {
291 ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd); 646 ret = lbs_adhoc_post(priv,
647 (struct cmd_ds_802_11_ad_hoc_result *)&cmd);
648 }
292 649
293out: 650out:
294 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 651 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -343,22 +700,24 @@ static int lbs_adhoc_start(struct lbs_private *priv,
343 WARN_ON(!assoc_req->channel); 700 WARN_ON(!assoc_req->channel);
344 701
345 /* set Physical parameter set */ 702 /* set Physical parameter set */
346 cmd.phyparamset.dsparamset.elementid = WLAN_EID_DS_PARAMS; 703 cmd.ds.header.id = WLAN_EID_DS_PARAMS;
347 cmd.phyparamset.dsparamset.len = 1; 704 cmd.ds.header.len = 1;
348 cmd.phyparamset.dsparamset.currentchan = assoc_req->channel; 705 cmd.ds.channel = assoc_req->channel;
349 706
350 /* set IBSS parameter set */ 707 /* set IBSS parameter set */
351 cmd.ssparamset.ibssparamset.elementid = WLAN_EID_IBSS_PARAMS; 708 cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS;
352 cmd.ssparamset.ibssparamset.len = 2; 709 cmd.ibss.header.len = 2;
353 cmd.ssparamset.ibssparamset.atimwindow = 0; 710 cmd.ibss.atimwindow = cpu_to_le16(0);
354 711
355 /* set capability info */ 712 /* set capability info */
356 tmpcap = WLAN_CAPABILITY_IBSS; 713 tmpcap = WLAN_CAPABILITY_IBSS;
357 if (assoc_req->secinfo.wep_enabled) { 714 if (assoc_req->secinfo.wep_enabled ||
358 lbs_deb_join("ADHOC_START: WEP enabled, setting privacy on\n"); 715 assoc_req->secinfo.WPAenabled ||
716 assoc_req->secinfo.WPA2enabled) {
717 lbs_deb_join("ADHOC_START: WEP/WPA enabled, privacy on\n");
359 tmpcap |= WLAN_CAPABILITY_PRIVACY; 718 tmpcap |= WLAN_CAPABILITY_PRIVACY;
360 } else 719 } else
361 lbs_deb_join("ADHOC_START: WEP disabled, setting privacy off\n"); 720 lbs_deb_join("ADHOC_START: WEP disabled, privacy off\n");
362 721
363 cmd.capability = cpu_to_le16(tmpcap); 722 cmd.capability = cpu_to_le16(tmpcap);
364 723
@@ -395,7 +754,8 @@ static int lbs_adhoc_start(struct lbs_private *priv,
395 754
396 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd); 755 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd);
397 if (ret == 0) 756 if (ret == 0)
398 ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd); 757 ret = lbs_adhoc_post(priv,
758 (struct cmd_ds_802_11_ad_hoc_result *)&cmd);
399 759
400out: 760out:
401 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 761 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -720,7 +1080,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
720 assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); 1080 assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
721 if (bss != NULL) { 1081 if (bss != NULL) {
722 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); 1082 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
723 ret = lbs_associate(priv, assoc_req); 1083 ret = lbs_try_associate(priv, assoc_req);
724 } else { 1084 } else {
725 lbs_deb_assoc("SSID not found; cannot associate\n"); 1085 lbs_deb_assoc("SSID not found; cannot associate\n");
726 } 1086 }
@@ -772,8 +1132,9 @@ static int assoc_helper_bssid(struct lbs_private *priv,
772 1132
773 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); 1133 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
774 if (assoc_req->mode == IW_MODE_INFRA) { 1134 if (assoc_req->mode == IW_MODE_INFRA) {
775 ret = lbs_associate(priv, assoc_req); 1135 ret = lbs_try_associate(priv, assoc_req);
776 lbs_deb_assoc("ASSOC: lbs_associate(bssid) returned %d\n", ret); 1136 lbs_deb_assoc("ASSOC: lbs_try_associate(bssid) returned %d\n",
1137 ret);
777 } else if (assoc_req->mode == IW_MODE_ADHOC) { 1138 } else if (assoc_req->mode == IW_MODE_ADHOC) {
778 lbs_adhoc_join(priv, assoc_req); 1139 lbs_adhoc_join(priv, assoc_req);
779 } 1140 }
@@ -1467,57 +1828,6 @@ struct assoc_request *lbs_get_association_request(struct lbs_private *priv)
1467 1828
1468 1829
1469/** 1830/**
1470 * @brief This function prepares command of authenticate.
1471 *
1472 * @param priv A pointer to struct lbs_private structure
1473 * @param cmd A pointer to cmd_ds_command structure
1474 * @param pdata_buf Void cast of pointer to a BSSID to authenticate with
1475 *
1476 * @return 0 or -1
1477 */
1478int lbs_cmd_80211_authenticate(struct lbs_private *priv,
1479 struct cmd_ds_command *cmd,
1480 void *pdata_buf)
1481{
1482 struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth;
1483 int ret = -1;
1484 u8 *bssid = pdata_buf;
1485
1486 lbs_deb_enter(LBS_DEB_JOIN);
1487
1488 cmd->command = cpu_to_le16(CMD_802_11_AUTHENTICATE);
1489 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
1490 + S_DS_GEN);
1491
1492 /* translate auth mode to 802.11 defined wire value */
1493 switch (priv->secinfo.auth_mode) {
1494 case IW_AUTH_ALG_OPEN_SYSTEM:
1495 pauthenticate->authtype = 0x00;
1496 break;
1497 case IW_AUTH_ALG_SHARED_KEY:
1498 pauthenticate->authtype = 0x01;
1499 break;
1500 case IW_AUTH_ALG_LEAP:
1501 pauthenticate->authtype = 0x80;
1502 break;
1503 default:
1504 lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n",
1505 priv->secinfo.auth_mode);
1506 goto out;
1507 }
1508
1509 memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
1510
1511 lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n",
1512 bssid, pauthenticate->authtype);
1513 ret = 0;
1514
1515out:
1516 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
1517 return ret;
1518}
1519
1520/**
1521 * @brief Deauthenticate from a specific BSS 1831 * @brief Deauthenticate from a specific BSS
1522 * 1832 *
1523 * @param priv A pointer to struct lbs_private structure 1833 * @param priv A pointer to struct lbs_private structure
@@ -1550,285 +1860,3 @@ int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, u8 bssid[ETH_ALEN],
1550 return ret; 1860 return ret;
1551} 1861}
1552 1862
1553int lbs_cmd_80211_associate(struct lbs_private *priv,
1554 struct cmd_ds_command *cmd, void *pdata_buf)
1555{
1556 struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
1557 int ret = 0;
1558 struct assoc_request *assoc_req = pdata_buf;
1559 struct bss_descriptor *bss = &assoc_req->bss;
1560 u8 *pos;
1561 u16 tmpcap, tmplen;
1562 struct mrvlietypes_ssidparamset *ssid;
1563 struct mrvlietypes_phyparamset *phy;
1564 struct mrvlietypes_ssparamset *ss;
1565 struct mrvlietypes_ratesparamset *rates;
1566 struct mrvlietypes_rsnparamset *rsn;
1567
1568 lbs_deb_enter(LBS_DEB_ASSOC);
1569
1570 pos = (u8 *) passo;
1571
1572 if (!priv) {
1573 ret = -1;
1574 goto done;
1575 }
1576
1577 cmd->command = cpu_to_le16(CMD_802_11_ASSOCIATE);
1578
1579 memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr));
1580 pos += sizeof(passo->peerstaaddr);
1581
1582 /* set the listen interval */
1583 passo->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
1584
1585 pos += sizeof(passo->capability);
1586 pos += sizeof(passo->listeninterval);
1587 pos += sizeof(passo->bcnperiod);
1588 pos += sizeof(passo->dtimperiod);
1589
1590 ssid = (struct mrvlietypes_ssidparamset *) pos;
1591 ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
1592 tmplen = bss->ssid_len;
1593 ssid->header.len = cpu_to_le16(tmplen);
1594 memcpy(ssid->ssid, bss->ssid, tmplen);
1595 pos += sizeof(ssid->header) + tmplen;
1596
1597 phy = (struct mrvlietypes_phyparamset *) pos;
1598 phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
1599 tmplen = sizeof(phy->fh_ds.dsparamset);
1600 phy->header.len = cpu_to_le16(tmplen);
1601 memcpy(&phy->fh_ds.dsparamset,
1602 &bss->phyparamset.dsparamset.currentchan,
1603 tmplen);
1604 pos += sizeof(phy->header) + tmplen;
1605
1606 ss = (struct mrvlietypes_ssparamset *) pos;
1607 ss->header.type = cpu_to_le16(TLV_TYPE_CF);
1608 tmplen = sizeof(ss->cf_ibss.cfparamset);
1609 ss->header.len = cpu_to_le16(tmplen);
1610 pos += sizeof(ss->header) + tmplen;
1611
1612 rates = (struct mrvlietypes_ratesparamset *) pos;
1613 rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
1614 memcpy(&rates->rates, &bss->rates, MAX_RATES);
1615 tmplen = MAX_RATES;
1616 if (get_common_rates(priv, rates->rates, &tmplen)) {
1617 ret = -1;
1618 goto done;
1619 }
1620 pos += sizeof(rates->header) + tmplen;
1621 rates->header.len = cpu_to_le16(tmplen);
1622 lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
1623
1624 /* Copy the infra. association rates into Current BSS state structure */
1625 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
1626 memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
1627
1628 /* Set MSB on basic rates as the firmware requires, but _after_
1629 * copying to current bss rates.
1630 */
1631 lbs_set_basic_rate_flags(rates->rates, tmplen);
1632
1633 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
1634 rsn = (struct mrvlietypes_rsnparamset *) pos;
1635 /* WPA_IE or WPA2_IE */
1636 rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
1637 tmplen = (u16) assoc_req->wpa_ie[1];
1638 rsn->header.len = cpu_to_le16(tmplen);
1639 memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
1640 lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: RSN IE", (u8 *) rsn,
1641 sizeof(rsn->header) + tmplen);
1642 pos += sizeof(rsn->header) + tmplen;
1643 }
1644
1645 /* update curbssparams */
1646 priv->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
1647
1648 if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
1649 ret = -1;
1650 goto done;
1651 }
1652
1653 cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN);
1654
1655 /* set the capability info */
1656 tmpcap = (bss->capability & CAPINFO_MASK);
1657 if (bss->mode == IW_MODE_INFRA)
1658 tmpcap |= WLAN_CAPABILITY_ESS;
1659 passo->capability = cpu_to_le16(tmpcap);
1660 lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
1661
1662done:
1663 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1664 return ret;
1665}
1666
1667int lbs_ret_80211_associate(struct lbs_private *priv,
1668 struct cmd_ds_command *resp)
1669{
1670 int ret = 0;
1671 union iwreq_data wrqu;
1672 struct ieeetypes_assocrsp *passocrsp;
1673 struct bss_descriptor *bss;
1674 u16 status_code;
1675
1676 lbs_deb_enter(LBS_DEB_ASSOC);
1677
1678 if (!priv->in_progress_assoc_req) {
1679 lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
1680 ret = -1;
1681 goto done;
1682 }
1683 bss = &priv->in_progress_assoc_req->bss;
1684
1685 passocrsp = (struct ieeetypes_assocrsp *) &resp->params;
1686
1687 /*
1688 * Older FW versions map the IEEE 802.11 Status Code in the association
1689 * response to the following values returned in passocrsp->statuscode:
1690 *
1691 * IEEE Status Code Marvell Status Code
1692 * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
1693 * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1694 * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1695 * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1696 * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1697 * others -> 0x0003 ASSOC_RESULT_REFUSED
1698 *
1699 * Other response codes:
1700 * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
1701 * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
1702 * association response from the AP)
1703 */
1704
1705 status_code = le16_to_cpu(passocrsp->statuscode);
1706 switch (status_code) {
1707 case 0x00:
1708 break;
1709 case 0x01:
1710 lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
1711 break;
1712 case 0x02:
1713 lbs_deb_assoc("ASSOC_RESP: internal timer "
1714 "expired while waiting for the AP\n");
1715 break;
1716 case 0x03:
1717 lbs_deb_assoc("ASSOC_RESP: association "
1718 "refused by AP\n");
1719 break;
1720 case 0x04:
1721 lbs_deb_assoc("ASSOC_RESP: authentication "
1722 "refused by AP\n");
1723 break;
1724 default:
1725 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
1726 " unknown\n", status_code);
1727 break;
1728 }
1729
1730 if (status_code) {
1731 lbs_mac_event_disconnected(priv);
1732 ret = -1;
1733 goto done;
1734 }
1735
1736 lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", (void *)&resp->params,
1737 le16_to_cpu(resp->size) - S_DS_GEN);
1738
1739 /* Send a Media Connected event, according to the Spec */
1740 priv->connect_status = LBS_CONNECTED;
1741
1742 /* Update current SSID and BSSID */
1743 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
1744 priv->curbssparams.ssid_len = bss->ssid_len;
1745 memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
1746
1747 priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
1748 priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
1749
1750 memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
1751 memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
1752 priv->nextSNRNF = 0;
1753 priv->numSNRNF = 0;
1754
1755 netif_carrier_on(priv->dev);
1756 if (!priv->tx_pending_len)
1757 netif_wake_queue(priv->dev);
1758
1759 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
1760 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1761 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1762
1763done:
1764 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1765 return ret;
1766}
1767
1768static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp)
1769{
1770 int ret = 0;
1771 u16 command = le16_to_cpu(resp->command);
1772 u16 result = le16_to_cpu(resp->result);
1773 struct cmd_ds_802_11_ad_hoc_result *adhoc_resp;
1774 union iwreq_data wrqu;
1775 struct bss_descriptor *bss;
1776 DECLARE_SSID_BUF(ssid);
1777
1778 lbs_deb_enter(LBS_DEB_JOIN);
1779
1780 adhoc_resp = (struct cmd_ds_802_11_ad_hoc_result *) resp;
1781
1782 if (!priv->in_progress_assoc_req) {
1783 lbs_deb_join("ADHOC_RESP: no in-progress association "
1784 "request\n");
1785 ret = -1;
1786 goto done;
1787 }
1788 bss = &priv->in_progress_assoc_req->bss;
1789
1790 /*
1791 * Join result code 0 --> SUCCESS
1792 */
1793 if (result) {
1794 lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result);
1795 if (priv->connect_status == LBS_CONNECTED)
1796 lbs_mac_event_disconnected(priv);
1797 ret = -1;
1798 goto done;
1799 }
1800
1801 /* Send a Media Connected event, according to the Spec */
1802 priv->connect_status = LBS_CONNECTED;
1803
1804 if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
1805 /* Update the created network descriptor with the new BSSID */
1806 memcpy(bss->bssid, adhoc_resp->bssid, ETH_ALEN);
1807 }
1808
1809 /* Set the BSSID from the joined/started descriptor */
1810 memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
1811
1812 /* Set the new SSID to current SSID */
1813 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
1814 priv->curbssparams.ssid_len = bss->ssid_len;
1815
1816 netif_carrier_on(priv->dev);
1817 if (!priv->tx_pending_len)
1818 netif_wake_queue(priv->dev);
1819
1820 memset(&wrqu, 0, sizeof(wrqu));
1821 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
1822 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1823 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1824
1825 lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
1826 print_ssid(ssid, bss->ssid, bss->ssid_len),
1827 priv->curbssparams.bssid,
1828 priv->curbssparams.channel);
1829
1830done:
1831 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
1832 return ret;
1833}
1834
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h
index 8b7336dd02a3..6e765e9f91a3 100644
--- a/drivers/net/wireless/libertas/assoc.h
+++ b/drivers/net/wireless/libertas/assoc.h
@@ -8,22 +8,9 @@
8void lbs_association_worker(struct work_struct *work); 8void lbs_association_worker(struct work_struct *work);
9struct assoc_request *lbs_get_association_request(struct lbs_private *priv); 9struct assoc_request *lbs_get_association_request(struct lbs_private *priv);
10 10
11struct cmd_ds_command;
12int lbs_cmd_80211_authenticate(struct lbs_private *priv,
13 struct cmd_ds_command *cmd,
14 void *pdata_buf);
15
16int lbs_adhoc_stop(struct lbs_private *priv); 11int lbs_adhoc_stop(struct lbs_private *priv);
17 12
18int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, 13int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
19 u8 bssid[ETH_ALEN], u16 reason); 14 u8 bssid[ETH_ALEN], u16 reason);
20int lbs_cmd_80211_associate(struct lbs_private *priv,
21 struct cmd_ds_command *cmd,
22 void *pdata_buf);
23
24int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
25 struct cmd_ds_command *resp);
26int lbs_ret_80211_associate(struct lbs_private *priv,
27 struct cmd_ds_command *resp);
28 15
29#endif /* _LBS_ASSOC_H */ 16#endif /* _LBS_ASSOC_H */
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index c455b9abbfc0..01db705a38ec 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1220,8 +1220,7 @@ static void lbs_submit_command(struct lbs_private *priv,
1220 command = le16_to_cpu(cmd->command); 1220 command = le16_to_cpu(cmd->command);
1221 1221
1222 /* These commands take longer */ 1222 /* These commands take longer */
1223 if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE || 1223 if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE)
1224 command == CMD_802_11_AUTHENTICATE)
1225 timeo = 5 * HZ; 1224 timeo = 5 * HZ;
1226 1225
1227 lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n", 1226 lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
@@ -1415,15 +1414,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1415 ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action); 1414 ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action);
1416 break; 1415 break;
1417 1416
1418 case CMD_802_11_ASSOCIATE:
1419 case CMD_802_11_REASSOCIATE:
1420 ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf);
1421 break;
1422
1423 case CMD_802_11_AUTHENTICATE:
1424 ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf);
1425 break;
1426
1427 case CMD_MAC_REG_ACCESS: 1417 case CMD_MAC_REG_ACCESS:
1428 case CMD_BBP_REG_ACCESS: 1418 case CMD_BBP_REG_ACCESS:
1429 case CMD_RF_REG_ACCESS: 1419 case CMD_RF_REG_ACCESS:
@@ -1470,8 +1460,8 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1470 break; 1460 break;
1471 case CMD_802_11_LED_GPIO_CTRL: 1461 case CMD_802_11_LED_GPIO_CTRL:
1472 { 1462 {
1473 struct mrvlietypes_ledgpio *gpio = 1463 struct mrvl_ie_ledgpio *gpio =
1474 (struct mrvlietypes_ledgpio*) 1464 (struct mrvl_ie_ledgpio*)
1475 cmdptr->params.ledgpio.data; 1465 cmdptr->params.ledgpio.data;
1476 1466
1477 memmove(&cmdptr->params.ledgpio, 1467 memmove(&cmdptr->params.ledgpio,
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index bcf2a9756fb6..c42d3faa2660 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -5,7 +5,7 @@
5#include <linux/delay.h> 5#include <linux/delay.h>
6#include <linux/if_arp.h> 6#include <linux/if_arp.h>
7#include <linux/netdevice.h> 7#include <linux/netdevice.h>
8 8#include <asm/unaligned.h>
9#include <net/iw_handler.h> 9#include <net/iw_handler.h>
10 10
11#include "host.h" 11#include "host.h"
@@ -154,11 +154,11 @@ static int lbs_ret_802_11_rssi(struct lbs_private *priv,
154 lbs_deb_enter(LBS_DEB_CMD); 154 lbs_deb_enter(LBS_DEB_CMD);
155 155
156 /* store the non average value */ 156 /* store the non average value */
157 priv->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR); 157 priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR);
158 priv->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor); 158 priv->NF[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->noisefloor);
159 159
160 priv->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR); 160 priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR);
161 priv->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor); 161 priv->NF[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgnoisefloor);
162 162
163 priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 163 priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
164 CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG], 164 CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
@@ -210,12 +210,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
210 ret = lbs_ret_reg_access(priv, respcmd, resp); 210 ret = lbs_ret_reg_access(priv, respcmd, resp);
211 break; 211 break;
212 212
213 case CMD_RET_802_11_ASSOCIATE:
214 case CMD_RET(CMD_802_11_ASSOCIATE):
215 case CMD_RET(CMD_802_11_REASSOCIATE):
216 ret = lbs_ret_80211_associate(priv, resp);
217 break;
218
219 case CMD_RET(CMD_802_11_SET_AFC): 213 case CMD_RET(CMD_802_11_SET_AFC):
220 case CMD_RET(CMD_802_11_GET_AFC): 214 case CMD_RET(CMD_802_11_GET_AFC):
221 spin_lock_irqsave(&priv->driver_lock, flags); 215 spin_lock_irqsave(&priv->driver_lock, flags);
@@ -225,7 +219,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
225 219
226 break; 220 break;
227 221
228 case CMD_RET(CMD_802_11_AUTHENTICATE):
229 case CMD_RET(CMD_802_11_BEACON_STOP): 222 case CMD_RET(CMD_802_11_BEACON_STOP):
230 break; 223 break;
231 224
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 50e28a0cdfee..811ffc3ef414 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -183,12 +183,12 @@ out_unlock:
183 */ 183 */
184static void *lbs_tlv_find(uint16_t tlv_type, const uint8_t *tlv, uint16_t size) 184static void *lbs_tlv_find(uint16_t tlv_type, const uint8_t *tlv, uint16_t size)
185{ 185{
186 struct mrvlietypesheader *tlv_h; 186 struct mrvl_ie_header *tlv_h;
187 uint16_t length; 187 uint16_t length;
188 ssize_t pos = 0; 188 ssize_t pos = 0;
189 189
190 while (pos < size) { 190 while (pos < size) {
191 tlv_h = (struct mrvlietypesheader *) tlv; 191 tlv_h = (struct mrvl_ie_header *) tlv;
192 if (!tlv_h->len) 192 if (!tlv_h->len)
193 return NULL; 193 return NULL;
194 if (tlv_h->type == cpu_to_le16(tlv_type)) 194 if (tlv_h->type == cpu_to_le16(tlv_type))
@@ -206,7 +206,7 @@ static ssize_t lbs_threshold_read(uint16_t tlv_type, uint16_t event_mask,
206 size_t count, loff_t *ppos) 206 size_t count, loff_t *ppos)
207{ 207{
208 struct cmd_ds_802_11_subscribe_event *subscribed; 208 struct cmd_ds_802_11_subscribe_event *subscribed;
209 struct mrvlietypes_thresholds *got; 209 struct mrvl_ie_thresholds *got;
210 struct lbs_private *priv = file->private_data; 210 struct lbs_private *priv = file->private_data;
211 ssize_t ret = 0; 211 ssize_t ret = 0;
212 size_t pos = 0; 212 size_t pos = 0;
@@ -259,7 +259,7 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask,
259 loff_t *ppos) 259 loff_t *ppos)
260{ 260{
261 struct cmd_ds_802_11_subscribe_event *events; 261 struct cmd_ds_802_11_subscribe_event *events;
262 struct mrvlietypes_thresholds *tlv; 262 struct mrvl_ie_thresholds *tlv;
263 struct lbs_private *priv = file->private_data; 263 struct lbs_private *priv = file->private_data;
264 ssize_t buf_size; 264 ssize_t buf_size;
265 int value, freq, new_mask; 265 int value, freq, new_mask;
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index a4455ec7c354..f9ec69e04734 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -321,8 +321,6 @@ struct lbs_private {
321 321
322 u32 monitormode; 322 u32 monitormode;
323 u8 fw_ready; 323 u8 fw_ready;
324 u8 fn_init_required;
325 u8 fn_shutdown_required;
326}; 324};
327 325
328extern struct cmd_confirm_sleep confirm_sleep; 326extern struct cmd_confirm_sleep confirm_sleep;
@@ -340,7 +338,7 @@ struct bss_descriptor {
340 u32 rssi; 338 u32 rssi;
341 u32 channel; 339 u32 channel;
342 u16 beaconperiod; 340 u16 beaconperiod;
343 u32 atimwindow; 341 __le16 atimwindow;
344 342
345 /* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */ 343 /* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */
346 u8 mode; 344 u8 mode;
@@ -350,10 +348,10 @@ struct bss_descriptor {
350 348
351 unsigned long last_scanned; 349 unsigned long last_scanned;
352 350
353 union ieeetypes_phyparamset phyparamset; 351 union ieee_phy_param_set phy;
354 union IEEEtypes_ssparamset ssparamset; 352 union ieee_ss_param_set ss;
355 353
356 struct ieeetypes_countryinfofullset countryinfo; 354 struct ieee_ie_country_info_full_set countryinfo;
357 355
358 u8 wpa_ie[MAX_WPA_IE_LEN]; 356 u8 wpa_ie[MAX_WPA_IE_LEN];
359 size_t wpa_ie_len; 357 size_t wpa_ie_len;
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index 391c54ab2b09..0a2e29140add 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -250,7 +250,9 @@ struct cmd_ds_gspi_bus_config {
250} __attribute__ ((packed)); 250} __attribute__ ((packed));
251 251
252struct cmd_ds_802_11_authenticate { 252struct cmd_ds_802_11_authenticate {
253 u8 macaddr[ETH_ALEN]; 253 struct cmd_header hdr;
254
255 u8 bssid[ETH_ALEN];
254 u8 authtype; 256 u8 authtype;
255 u8 reserved[10]; 257 u8 reserved[10];
256} __attribute__ ((packed)); 258} __attribute__ ((packed));
@@ -263,22 +265,23 @@ struct cmd_ds_802_11_deauthenticate {
263} __attribute__ ((packed)); 265} __attribute__ ((packed));
264 266
265struct cmd_ds_802_11_associate { 267struct cmd_ds_802_11_associate {
266 u8 peerstaaddr[6]; 268 struct cmd_header hdr;
269
270 u8 bssid[6];
267 __le16 capability; 271 __le16 capability;
268 __le16 listeninterval; 272 __le16 listeninterval;
269 __le16 bcnperiod; 273 __le16 bcnperiod;
270 u8 dtimperiod; 274 u8 dtimperiod;
271 275 u8 iebuf[512]; /* Enough for required and most optional IEs */
272#if 0
273 mrvlietypes_ssidparamset_t ssidParamSet;
274 mrvlietypes_phyparamset_t phyparamset;
275 mrvlietypes_ssparamset_t ssparamset;
276 mrvlietypes_ratesparamset_t ratesParamSet;
277#endif
278} __attribute__ ((packed)); 276} __attribute__ ((packed));
279 277
280struct cmd_ds_802_11_associate_rsp { 278struct cmd_ds_802_11_associate_response {
281 struct ieeetypes_assocrsp assocRsp; 279 struct cmd_header hdr;
280
281 __le16 capability;
282 __le16 statuscode;
283 __le16 aid;
284 u8 iebuf[512];
282} __attribute__ ((packed)); 285} __attribute__ ((packed));
283 286
284struct cmd_ds_802_11_set_wep { 287struct cmd_ds_802_11_set_wep {
@@ -535,9 +538,11 @@ struct cmd_ds_802_11_ad_hoc_start {
535 u8 bsstype; 538 u8 bsstype;
536 __le16 beaconperiod; 539 __le16 beaconperiod;
537 u8 dtimperiod; /* Reserved on v9 and later */ 540 u8 dtimperiod; /* Reserved on v9 and later */
538 union IEEEtypes_ssparamset ssparamset; 541 struct ieee_ie_ibss_param_set ibss;
539 union ieeetypes_phyparamset phyparamset; 542 u8 reserved1[4];
540 __le16 probedelay; 543 struct ieee_ie_ds_param_set ds;
544 u8 reserved2[4];
545 __le16 probedelay; /* Reserved on v9 and later */
541 __le16 capability; 546 __le16 capability;
542 u8 rates[MAX_RATES]; 547 u8 rates[MAX_RATES];
543 u8 tlv_memory_size_pad[100]; 548 u8 tlv_memory_size_pad[100];
@@ -558,8 +563,10 @@ struct adhoc_bssdesc {
558 u8 dtimperiod; 563 u8 dtimperiod;
559 __le64 timestamp; 564 __le64 timestamp;
560 __le64 localtime; 565 __le64 localtime;
561 union ieeetypes_phyparamset phyparamset; 566 struct ieee_ie_ds_param_set ds;
562 union IEEEtypes_ssparamset ssparamset; 567 u8 reserved1[4];
568 struct ieee_ie_ibss_param_set ibss;
569 u8 reserved2[4];
563 __le16 capability; 570 __le16 capability;
564 u8 rates[MAX_RATES]; 571 u8 rates[MAX_RATES];
565 572
@@ -765,8 +772,6 @@ struct cmd_ds_command {
765 /* command Body */ 772 /* command Body */
766 union { 773 union {
767 struct cmd_ds_802_11_ps_mode psmode; 774 struct cmd_ds_802_11_ps_mode psmode;
768 struct cmd_ds_802_11_associate associate;
769 struct cmd_ds_802_11_authenticate auth;
770 struct cmd_ds_802_11_get_stat gstat; 775 struct cmd_ds_802_11_get_stat gstat;
771 struct cmd_ds_802_3_get_stat gstat_8023; 776 struct cmd_ds_802_3_get_stat gstat_8023;
772 struct cmd_ds_802_11_rf_antenna rant; 777 struct cmd_ds_802_11_rf_antenna rant;
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index a7e3fc119b70..8cdb88c6ca28 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -39,8 +39,24 @@
39#include "decl.h" 39#include "decl.h"
40#include "defs.h" 40#include "defs.h"
41#include "dev.h" 41#include "dev.h"
42#include "cmd.h"
42#include "if_sdio.h" 43#include "if_sdio.h"
43 44
45/* The if_sdio_remove() callback function is called when
46 * user removes this module from kernel space or ejects
47 * the card from the slot. The driver handles these 2 cases
48 * differently for SD8688 combo chip.
49 * If the user is removing the module, the FUNC_SHUTDOWN
50 * command for SD8688 is sent to the firmware.
51 * If the card is removed, there is no need to send this command.
52 *
53 * The variable 'user_rmmod' is used to distinguish these two
54 * scenarios. This flag is initialized as FALSE in case the card
55 * is removed, and will be set to TRUE for module removal when
56 * module_exit function is called.
57 */
58static u8 user_rmmod;
59
44static char *lbs_helper_name = NULL; 60static char *lbs_helper_name = NULL;
45module_param_named(helper_name, lbs_helper_name, charp, 0644); 61module_param_named(helper_name, lbs_helper_name, charp, 0644);
46 62
@@ -61,7 +77,6 @@ struct if_sdio_model {
61 int model; 77 int model;
62 const char *helper; 78 const char *helper;
63 const char *firmware; 79 const char *firmware;
64 struct if_sdio_card *card;
65}; 80};
66 81
67static struct if_sdio_model if_sdio_models[] = { 82static struct if_sdio_model if_sdio_models[] = {
@@ -70,21 +85,18 @@ static struct if_sdio_model if_sdio_models[] = {
70 .model = IF_SDIO_MODEL_8385, 85 .model = IF_SDIO_MODEL_8385,
71 .helper = "sd8385_helper.bin", 86 .helper = "sd8385_helper.bin",
72 .firmware = "sd8385.bin", 87 .firmware = "sd8385.bin",
73 .card = NULL,
74 }, 88 },
75 { 89 {
76 /* 8686 */ 90 /* 8686 */
77 .model = IF_SDIO_MODEL_8686, 91 .model = IF_SDIO_MODEL_8686,
78 .helper = "sd8686_helper.bin", 92 .helper = "sd8686_helper.bin",
79 .firmware = "sd8686.bin", 93 .firmware = "sd8686.bin",
80 .card = NULL,
81 }, 94 },
82 { 95 {
83 /* 8688 */ 96 /* 8688 */
84 .model = IF_SDIO_MODEL_8688, 97 .model = IF_SDIO_MODEL_8688,
85 .helper = "sd8688_helper.bin", 98 .helper = "sd8688_helper.bin",
86 .firmware = "sd8688.bin", 99 .firmware = "sd8688.bin",
87 .card = NULL,
88 }, 100 },
89}; 101};
90 102
@@ -927,8 +939,6 @@ static int if_sdio_probe(struct sdio_func *func,
927 goto free; 939 goto free;
928 } 940 }
929 941
930 if_sdio_models[i].card = card;
931
932 card->helper = if_sdio_models[i].helper; 942 card->helper = if_sdio_models[i].helper;
933 card->firmware = if_sdio_models[i].firmware; 943 card->firmware = if_sdio_models[i].firmware;
934 944
@@ -1014,8 +1024,16 @@ static int if_sdio_probe(struct sdio_func *func,
1014 /* 1024 /*
1015 * FUNC_INIT is required for SD8688 WLAN/BT multiple functions 1025 * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
1016 */ 1026 */
1017 priv->fn_init_required = 1027 if (card->model == IF_SDIO_MODEL_8688) {
1018 (card->model == IF_SDIO_MODEL_8688) ? 1 : 0; 1028 struct cmd_header cmd;
1029
1030 memset(&cmd, 0, sizeof(cmd));
1031
1032 lbs_deb_sdio("send function INIT command\n");
1033 if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
1034 lbs_cmd_copyback, (unsigned long) &cmd))
1035 lbs_pr_alert("CMD_FUNC_INIT cmd failed\n");
1036 }
1019 1037
1020 ret = lbs_start_card(priv); 1038 ret = lbs_start_card(priv);
1021 if (ret) 1039 if (ret)
@@ -1057,30 +1075,39 @@ static void if_sdio_remove(struct sdio_func *func)
1057{ 1075{
1058 struct if_sdio_card *card; 1076 struct if_sdio_card *card;
1059 struct if_sdio_packet *packet; 1077 struct if_sdio_packet *packet;
1060 int ret;
1061 1078
1062 lbs_deb_enter(LBS_DEB_SDIO); 1079 lbs_deb_enter(LBS_DEB_SDIO);
1063 1080
1064 card = sdio_get_drvdata(func); 1081 card = sdio_get_drvdata(func);
1065 1082
1066 lbs_stop_card(card->priv); 1083 if (user_rmmod && (card->model == IF_SDIO_MODEL_8688)) {
1084 /*
1085 * FUNC_SHUTDOWN is required for SD8688 WLAN/BT
1086 * multiple functions
1087 */
1088 struct cmd_header cmd;
1089
1090 memset(&cmd, 0, sizeof(cmd));
1091
1092 lbs_deb_sdio("send function SHUTDOWN command\n");
1093 if (__lbs_cmd(card->priv, CMD_FUNC_SHUTDOWN,
1094 &cmd, sizeof(cmd), lbs_cmd_copyback,
1095 (unsigned long) &cmd))
1096 lbs_pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
1097 }
1067 1098
1068 card->priv->surpriseremoved = 1; 1099 card->priv->surpriseremoved = 1;
1069 1100
1070 lbs_deb_sdio("call remove card\n"); 1101 lbs_deb_sdio("call remove card\n");
1102 lbs_stop_card(card->priv);
1071 lbs_remove_card(card->priv); 1103 lbs_remove_card(card->priv);
1072 1104
1073 flush_workqueue(card->workqueue); 1105 flush_workqueue(card->workqueue);
1074 destroy_workqueue(card->workqueue); 1106 destroy_workqueue(card->workqueue);
1075 1107
1076 sdio_claim_host(func); 1108 sdio_claim_host(func);
1077
1078 /* Disable interrupts */
1079 sdio_writeb(func, 0x00, IF_SDIO_H_INT_MASK, &ret);
1080
1081 sdio_release_irq(func); 1109 sdio_release_irq(func);
1082 sdio_disable_func(func); 1110 sdio_disable_func(func);
1083
1084 sdio_release_host(func); 1111 sdio_release_host(func);
1085 1112
1086 while (card->packets) { 1113 while (card->packets) {
@@ -1116,6 +1143,9 @@ static int __init if_sdio_init_module(void)
1116 1143
1117 ret = sdio_register_driver(&if_sdio_driver); 1144 ret = sdio_register_driver(&if_sdio_driver);
1118 1145
1146 /* Clear the flag in case user removes the card. */
1147 user_rmmod = 0;
1148
1119 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 1149 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
1120 1150
1121 return ret; 1151 return ret;
@@ -1123,22 +1153,10 @@ static int __init if_sdio_init_module(void)
1123 1153
1124static void __exit if_sdio_exit_module(void) 1154static void __exit if_sdio_exit_module(void)
1125{ 1155{
1126 int i;
1127 struct if_sdio_card *card;
1128
1129 lbs_deb_enter(LBS_DEB_SDIO); 1156 lbs_deb_enter(LBS_DEB_SDIO);
1130 1157
1131 for (i = 0; i < ARRAY_SIZE(if_sdio_models); i++) { 1158 /* Set the flag as user is removing this module. */
1132 card = if_sdio_models[i].card; 1159 user_rmmod = 1;
1133
1134 /*
1135 * FUNC_SHUTDOWN is required for SD8688 WLAN/BT
1136 * multiple functions
1137 */
1138 if (card && card->priv)
1139 card->priv->fn_shutdown_required =
1140 (card->model == IF_SDIO_MODEL_8688) ? 1 : 0;
1141 }
1142 1160
1143 sdio_unregister_driver(&if_sdio_driver); 1161 sdio_unregister_driver(&if_sdio_driver);
1144 1162
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 5fa55fe1f860..ea23c5de1420 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -119,9 +119,6 @@ static struct chip_ident chip_id_to_device_name[] = {
119 * First we have to put a SPU register name on the bus. Then we can 119 * First we have to put a SPU register name on the bus. Then we can
120 * either read from or write to that register. 120 * either read from or write to that register.
121 * 121 *
122 * For 16-bit transactions, byte order on the bus is big-endian.
123 * We don't have to worry about that here, though.
124 * The translation takes place in the SPI routines.
125 */ 122 */
126 123
127static void spu_transaction_init(struct if_spi_card *card) 124static void spu_transaction_init(struct if_spi_card *card)
@@ -147,7 +144,7 @@ static void spu_transaction_finish(struct if_spi_card *card)
147static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) 144static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
148{ 145{
149 int err = 0; 146 int err = 0;
150 u16 reg_out = reg | IF_SPI_WRITE_OPERATION_MASK; 147 u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK);
151 148
152 /* You must give an even number of bytes to the SPU, even if it 149 /* You must give an even number of bytes to the SPU, even if it
153 * doesn't care about the last one. */ 150 * doesn't care about the last one. */
@@ -169,16 +166,10 @@ out:
169 166
170static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val) 167static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val)
171{ 168{
172 return spu_write(card, reg, (u8 *)&val, sizeof(u16)); 169 u16 buff;
173}
174 170
175static inline int spu_write_u32(struct if_spi_card *card, u16 reg, u32 val) 171 buff = cpu_to_le16(val);
176{ 172 return spu_write(card, reg, (u8 *)&buff, sizeof(u16));
177 /* The lower 16 bits are written first. */
178 u16 out[2];
179 out[0] = val & 0xffff;
180 out[1] = (val & 0xffff0000) >> 16;
181 return spu_write(card, reg, (u8 *)&out, sizeof(u32));
182} 173}
183 174
184static inline int spu_reg_is_port_reg(u16 reg) 175static inline int spu_reg_is_port_reg(u16 reg)
@@ -198,7 +189,7 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
198 unsigned int i, delay; 189 unsigned int i, delay;
199 int err = 0; 190 int err = 0;
200 u16 zero = 0; 191 u16 zero = 0;
201 u16 reg_out = reg | IF_SPI_READ_OPERATION_MASK; 192 u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK);
202 193
203 /* You must take an even number of bytes from the SPU, even if you 194 /* You must take an even number of bytes from the SPU, even if you
204 * don't care about the last one. */ 195 * don't care about the last one. */
@@ -236,18 +227,25 @@ out:
236/* Read 16 bits from an SPI register */ 227/* Read 16 bits from an SPI register */
237static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) 228static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
238{ 229{
239 return spu_read(card, reg, (u8 *)val, sizeof(u16)); 230 u16 buf;
231 int ret;
232
233 ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
234 if (ret == 0)
235 *val = le16_to_cpup(&buf);
236 return ret;
240} 237}
241 238
242/* Read 32 bits from an SPI register. 239/* Read 32 bits from an SPI register.
243 * The low 16 bits are read first. */ 240 * The low 16 bits are read first. */
244static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) 241static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
245{ 242{
246 u16 buf[2]; 243 u32 buf;
247 int err; 244 int err;
248 err = spu_read(card, reg, (u8 *)buf, sizeof(u32)); 245
246 err = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
249 if (!err) 247 if (!err)
250 *val = buf[0] | (buf[1] << 16); 248 *val = le32_to_cpup(&buf);
251 return err; 249 return err;
252} 250}
253 251
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index a58a12352672..89575e448015 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1002,17 +1002,9 @@ static int lbs_setup_firmware(struct lbs_private *priv)
1002{ 1002{
1003 int ret = -1; 1003 int ret = -1;
1004 s16 curlevel = 0, minlevel = 0, maxlevel = 0; 1004 s16 curlevel = 0, minlevel = 0, maxlevel = 0;
1005 struct cmd_header cmd;
1006 1005
1007 lbs_deb_enter(LBS_DEB_FW); 1006 lbs_deb_enter(LBS_DEB_FW);
1008 1007
1009 if (priv->fn_init_required) {
1010 memset(&cmd, 0, sizeof(cmd));
1011 if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
1012 lbs_cmd_copyback, (unsigned long) &cmd))
1013 lbs_pr_alert("CMD_FUNC_INIT command failed\n");
1014 }
1015
1016 /* Read MAC address from firmware */ 1008 /* Read MAC address from firmware */
1017 memset(priv->current_addr, 0xff, ETH_ALEN); 1009 memset(priv->current_addr, 0xff, ETH_ALEN);
1018 ret = lbs_update_hw_spec(priv); 1010 ret = lbs_update_hw_spec(priv);
@@ -1200,9 +1192,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
1200 priv->mesh_open = 0; 1192 priv->mesh_open = 0;
1201 priv->infra_open = 0; 1193 priv->infra_open = 0;
1202 1194
1203 priv->fn_init_required = 0;
1204 priv->fn_shutdown_required = 0;
1205
1206 /* Setup the OS Interface to our functions */ 1195 /* Setup the OS Interface to our functions */
1207 dev->netdev_ops = &lbs_netdev_ops; 1196 dev->netdev_ops = &lbs_netdev_ops;
1208 dev->watchdog_timeo = 5 * HZ; 1197 dev->watchdog_timeo = 5 * HZ;
@@ -1384,20 +1373,11 @@ void lbs_stop_card(struct lbs_private *priv)
1384 struct net_device *dev; 1373 struct net_device *dev;
1385 struct cmd_ctrl_node *cmdnode; 1374 struct cmd_ctrl_node *cmdnode;
1386 unsigned long flags; 1375 unsigned long flags;
1387 struct cmd_header cmd;
1388 1376
1389 lbs_deb_enter(LBS_DEB_MAIN); 1377 lbs_deb_enter(LBS_DEB_MAIN);
1390 1378
1391 if (!priv) 1379 if (!priv)
1392 goto out; 1380 goto out;
1393
1394 if (priv->fn_shutdown_required) {
1395 memset(&cmd, 0, sizeof(cmd));
1396 if (__lbs_cmd(priv, CMD_FUNC_SHUTDOWN, &cmd, sizeof(cmd),
1397 lbs_cmd_copyback, (unsigned long) &cmd))
1398 lbs_pr_alert("CMD_FUNC_SHUTDOWN command failed\n");
1399 }
1400
1401 dev = priv->dev; 1381 dev = priv->dev;
1402 1382
1403 netif_stop_queue(dev); 1383 netif_stop_queue(dev);
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 8124db36aaff..601b54249677 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -27,12 +27,12 @@
27 + 40) /* 40 for WPAIE */ 27 + 40) /* 40 for WPAIE */
28 28
29//! Memory needed to store a max sized channel List TLV for a firmware scan 29//! Memory needed to store a max sized channel List TLV for a firmware scan
30#define CHAN_TLV_MAX_SIZE (sizeof(struct mrvlietypesheader) \ 30#define CHAN_TLV_MAX_SIZE (sizeof(struct mrvl_ie_header) \
31 + (MRVDRV_MAX_CHANNELS_PER_SCAN \ 31 + (MRVDRV_MAX_CHANNELS_PER_SCAN \
32 * sizeof(struct chanscanparamset))) 32 * sizeof(struct chanscanparamset)))
33 33
34//! Memory needed to store a max number/size SSID TLV for a firmware scan 34//! Memory needed to store a max number/size SSID TLV for a firmware scan
35#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvlietypes_ssidparamset)) 35#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvl_ie_ssid_param_set))
36 36
37//! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max 37//! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max
38#define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan) \ 38#define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan) \
@@ -211,7 +211,7 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv,
211 */ 211 */
212static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv) 212static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv)
213{ 213{
214 struct mrvlietypes_ssidparamset *ssid_tlv = (void *)tlv; 214 struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv;
215 215
216 ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID); 216 ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
217 ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len); 217 ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len);
@@ -249,7 +249,7 @@ static int lbs_scan_add_chanlist_tlv(uint8_t *tlv,
249 int chan_count) 249 int chan_count)
250{ 250{
251 size_t size = sizeof(struct chanscanparamset) *chan_count; 251 size_t size = sizeof(struct chanscanparamset) *chan_count;
252 struct mrvlietypes_chanlistparamset *chan_tlv = (void *)tlv; 252 struct mrvl_ie_chanlist_param_set *chan_tlv = (void *)tlv;
253 253
254 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); 254 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
255 memcpy(chan_tlv->chanscanparam, chan_list, size); 255 memcpy(chan_tlv->chanscanparam, chan_list, size);
@@ -270,7 +270,7 @@ static int lbs_scan_add_chanlist_tlv(uint8_t *tlv,
270static int lbs_scan_add_rates_tlv(uint8_t *tlv) 270static int lbs_scan_add_rates_tlv(uint8_t *tlv)
271{ 271{
272 int i; 272 int i;
273 struct mrvlietypes_ratesparamset *rate_tlv = (void *)tlv; 273 struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
274 274
275 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); 275 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
276 tlv += sizeof(rate_tlv->header); 276 tlv += sizeof(rate_tlv->header);
@@ -513,12 +513,12 @@ void lbs_scan_worker(struct work_struct *work)
513static int lbs_process_bss(struct bss_descriptor *bss, 513static int lbs_process_bss(struct bss_descriptor *bss,
514 uint8_t **pbeaconinfo, int *bytesleft) 514 uint8_t **pbeaconinfo, int *bytesleft)
515{ 515{
516 struct ieeetypes_fhparamset *pFH; 516 struct ieee_ie_fh_param_set *fh;
517 struct ieeetypes_dsparamset *pDS; 517 struct ieee_ie_ds_param_set *ds;
518 struct ieeetypes_cfparamset *pCF; 518 struct ieee_ie_cf_param_set *cf;
519 struct ieeetypes_ibssparamset *pibss; 519 struct ieee_ie_ibss_param_set *ibss;
520 DECLARE_SSID_BUF(ssid); 520 DECLARE_SSID_BUF(ssid);
521 struct ieeetypes_countryinfoset *pcountryinfo; 521 struct ieee_ie_country_info_set *pcountryinfo;
522 uint8_t *pos, *end, *p; 522 uint8_t *pos, *end, *p;
523 uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0; 523 uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0;
524 uint16_t beaconsize = 0; 524 uint16_t beaconsize = 0;
@@ -616,50 +616,49 @@ static int lbs_process_bss(struct bss_descriptor *bss,
616 break; 616 break;
617 617
618 case WLAN_EID_FH_PARAMS: 618 case WLAN_EID_FH_PARAMS:
619 pFH = (struct ieeetypes_fhparamset *) pos; 619 fh = (struct ieee_ie_fh_param_set *) pos;
620 memmove(&bss->phyparamset.fhparamset, pFH, 620 memcpy(&bss->phy.fh, fh, sizeof(*fh));
621 sizeof(struct ieeetypes_fhparamset));
622 lbs_deb_scan("got FH IE\n"); 621 lbs_deb_scan("got FH IE\n");
623 break; 622 break;
624 623
625 case WLAN_EID_DS_PARAMS: 624 case WLAN_EID_DS_PARAMS:
626 pDS = (struct ieeetypes_dsparamset *) pos; 625 ds = (struct ieee_ie_ds_param_set *) pos;
627 bss->channel = pDS->currentchan; 626 bss->channel = ds->channel;
628 memcpy(&bss->phyparamset.dsparamset, pDS, 627 memcpy(&bss->phy.ds, ds, sizeof(*ds));
629 sizeof(struct ieeetypes_dsparamset));
630 lbs_deb_scan("got DS IE, channel %d\n", bss->channel); 628 lbs_deb_scan("got DS IE, channel %d\n", bss->channel);
631 break; 629 break;
632 630
633 case WLAN_EID_CF_PARAMS: 631 case WLAN_EID_CF_PARAMS:
634 pCF = (struct ieeetypes_cfparamset *) pos; 632 cf = (struct ieee_ie_cf_param_set *) pos;
635 memcpy(&bss->ssparamset.cfparamset, pCF, 633 memcpy(&bss->ss.cf, cf, sizeof(*cf));
636 sizeof(struct ieeetypes_cfparamset));
637 lbs_deb_scan("got CF IE\n"); 634 lbs_deb_scan("got CF IE\n");
638 break; 635 break;
639 636
640 case WLAN_EID_IBSS_PARAMS: 637 case WLAN_EID_IBSS_PARAMS:
641 pibss = (struct ieeetypes_ibssparamset *) pos; 638 ibss = (struct ieee_ie_ibss_param_set *) pos;
642 bss->atimwindow = le16_to_cpu(pibss->atimwindow); 639 bss->atimwindow = ibss->atimwindow;
643 memmove(&bss->ssparamset.ibssparamset, pibss, 640 memcpy(&bss->ss.ibss, ibss, sizeof(*ibss));
644 sizeof(struct ieeetypes_ibssparamset));
645 lbs_deb_scan("got IBSS IE\n"); 641 lbs_deb_scan("got IBSS IE\n");
646 break; 642 break;
647 643
648 case WLAN_EID_COUNTRY: 644 case WLAN_EID_COUNTRY:
649 pcountryinfo = (struct ieeetypes_countryinfoset *) pos; 645 pcountryinfo = (struct ieee_ie_country_info_set *) pos;
650 lbs_deb_scan("got COUNTRY IE\n"); 646 lbs_deb_scan("got COUNTRY IE\n");
651 if (pcountryinfo->len < sizeof(pcountryinfo->countrycode) 647 if (pcountryinfo->header.len < sizeof(pcountryinfo->countrycode)
652 || pcountryinfo->len > 254) { 648 || pcountryinfo->header.len > 254) {
653 lbs_deb_scan("process_bss: 11D- Err CountryInfo len %d, min %zd, max 254\n", 649 lbs_deb_scan("%s: 11D- Err CountryInfo len %d, min %zd, max 254\n",
654 pcountryinfo->len, sizeof(pcountryinfo->countrycode)); 650 __func__,
651 pcountryinfo->header.len,
652 sizeof(pcountryinfo->countrycode));
655 ret = -1; 653 ret = -1;
656 goto done; 654 goto done;
657 } 655 }
658 656
659 memcpy(&bss->countryinfo, pcountryinfo, pcountryinfo->len + 2); 657 memcpy(&bss->countryinfo, pcountryinfo,
658 pcountryinfo->header.len + 2);
660 lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo", 659 lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo",
661 (uint8_t *) pcountryinfo, 660 (uint8_t *) pcountryinfo,
662 (int) (pcountryinfo->len + 2)); 661 (int) (pcountryinfo->header.len + 2));
663 break; 662 break;
664 663
665 case WLAN_EID_EXT_SUPP_RATES: 664 case WLAN_EID_EXT_SUPP_RATES:
@@ -1130,7 +1129,7 @@ static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
1130 goto done; 1129 goto done;
1131 } 1130 }
1132 1131
1133 bytesleft = le16_to_cpu(scanresp->bssdescriptsize); 1132 bytesleft = get_unaligned_le16(&scanresp->bssdescriptsize);
1134 lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft); 1133 lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft);
1135 1134
1136 scanrespsize = le16_to_cpu(resp->size); 1135 scanrespsize = le16_to_cpu(resp->size);
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
index de03b9c9c204..99905df65b25 100644
--- a/drivers/net/wireless/libertas/types.h
+++ b/drivers/net/wireless/libertas/types.h
@@ -8,9 +8,14 @@
8#include <asm/byteorder.h> 8#include <asm/byteorder.h>
9#include <linux/wireless.h> 9#include <linux/wireless.h>
10 10
11struct ieeetypes_cfparamset { 11struct ieee_ie_header {
12 u8 elementid; 12 u8 id;
13 u8 len; 13 u8 len;
14} __attribute__ ((packed));
15
16struct ieee_ie_cf_param_set {
17 struct ieee_ie_header header;
18
14 u8 cfpcnt; 19 u8 cfpcnt;
15 u8 cfpperiod; 20 u8 cfpperiod;
16 __le16 cfpmaxduration; 21 __le16 cfpmaxduration;
@@ -18,42 +23,35 @@ struct ieeetypes_cfparamset {
18} __attribute__ ((packed)); 23} __attribute__ ((packed));
19 24
20 25
21struct ieeetypes_ibssparamset { 26struct ieee_ie_ibss_param_set {
22 u8 elementid; 27 struct ieee_ie_header header;
23 u8 len; 28
24 __le16 atimwindow; 29 __le16 atimwindow;
25} __attribute__ ((packed)); 30} __attribute__ ((packed));
26 31
27union IEEEtypes_ssparamset { 32union ieee_ss_param_set {
28 struct ieeetypes_cfparamset cfparamset; 33 struct ieee_ie_cf_param_set cf;
29 struct ieeetypes_ibssparamset ibssparamset; 34 struct ieee_ie_ibss_param_set ibss;
30} __attribute__ ((packed)); 35} __attribute__ ((packed));
31 36
32struct ieeetypes_fhparamset { 37struct ieee_ie_fh_param_set {
33 u8 elementid; 38 struct ieee_ie_header header;
34 u8 len; 39
35 __le16 dwelltime; 40 __le16 dwelltime;
36 u8 hopset; 41 u8 hopset;
37 u8 hoppattern; 42 u8 hoppattern;
38 u8 hopindex; 43 u8 hopindex;
39} __attribute__ ((packed)); 44} __attribute__ ((packed));
40 45
41struct ieeetypes_dsparamset { 46struct ieee_ie_ds_param_set {
42 u8 elementid; 47 struct ieee_ie_header header;
43 u8 len;
44 u8 currentchan;
45} __attribute__ ((packed));
46 48
47union ieeetypes_phyparamset { 49 u8 channel;
48 struct ieeetypes_fhparamset fhparamset;
49 struct ieeetypes_dsparamset dsparamset;
50} __attribute__ ((packed)); 50} __attribute__ ((packed));
51 51
52struct ieeetypes_assocrsp { 52union ieee_phy_param_set {
53 __le16 capability; 53 struct ieee_ie_fh_param_set fh;
54 __le16 statuscode; 54 struct ieee_ie_ds_param_set ds;
55 __le16 aid;
56 u8 iebuffer[1];
57} __attribute__ ((packed)); 55} __attribute__ ((packed));
58 56
59/** TLV type ID definition */ 57/** TLV type ID definition */
@@ -94,32 +92,33 @@ struct ieeetypes_assocrsp {
94#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19) 92#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19)
95#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22) 93#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22)
96#define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23) 94#define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23)
95#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31)
97#define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37) 96#define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37)
98#define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291) 97#define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291)
99 98
100/** TLV related data structures*/ 99/** TLV related data structures*/
101struct mrvlietypesheader { 100struct mrvl_ie_header {
102 __le16 type; 101 __le16 type;
103 __le16 len; 102 __le16 len;
104} __attribute__ ((packed)); 103} __attribute__ ((packed));
105 104
106struct mrvlietypes_data { 105struct mrvl_ie_data {
107 struct mrvlietypesheader header; 106 struct mrvl_ie_header header;
108 u8 Data[1]; 107 u8 Data[1];
109} __attribute__ ((packed)); 108} __attribute__ ((packed));
110 109
111struct mrvlietypes_ratesparamset { 110struct mrvl_ie_rates_param_set {
112 struct mrvlietypesheader header; 111 struct mrvl_ie_header header;
113 u8 rates[1]; 112 u8 rates[1];
114} __attribute__ ((packed)); 113} __attribute__ ((packed));
115 114
116struct mrvlietypes_ssidparamset { 115struct mrvl_ie_ssid_param_set {
117 struct mrvlietypesheader header; 116 struct mrvl_ie_header header;
118 u8 ssid[1]; 117 u8 ssid[1];
119} __attribute__ ((packed)); 118} __attribute__ ((packed));
120 119
121struct mrvlietypes_wildcardssidparamset { 120struct mrvl_ie_wildcard_ssid_param_set {
122 struct mrvlietypesheader header; 121 struct mrvl_ie_header header;
123 u8 MaxSsidlength; 122 u8 MaxSsidlength;
124 u8 ssid[1]; 123 u8 ssid[1];
125} __attribute__ ((packed)); 124} __attribute__ ((packed));
@@ -144,91 +143,72 @@ struct chanscanparamset {
144 __le16 maxscantime; 143 __le16 maxscantime;
145} __attribute__ ((packed)); 144} __attribute__ ((packed));
146 145
147struct mrvlietypes_chanlistparamset { 146struct mrvl_ie_chanlist_param_set {
148 struct mrvlietypesheader header; 147 struct mrvl_ie_header header;
149 struct chanscanparamset chanscanparam[1]; 148 struct chanscanparamset chanscanparam[1];
150} __attribute__ ((packed)); 149} __attribute__ ((packed));
151 150
152struct cfparamset { 151struct mrvl_ie_cf_param_set {
152 struct mrvl_ie_header header;
153 u8 cfpcnt; 153 u8 cfpcnt;
154 u8 cfpperiod; 154 u8 cfpperiod;
155 __le16 cfpmaxduration; 155 __le16 cfpmaxduration;
156 __le16 cfpdurationremaining; 156 __le16 cfpdurationremaining;
157} __attribute__ ((packed)); 157} __attribute__ ((packed));
158 158
159struct ibssparamset { 159struct mrvl_ie_ds_param_set {
160 __le16 atimwindow; 160 struct mrvl_ie_header header;
161} __attribute__ ((packed)); 161 u8 channel;
162
163struct mrvlietypes_ssparamset {
164 struct mrvlietypesheader header;
165 union {
166 struct cfparamset cfparamset[1];
167 struct ibssparamset ibssparamset[1];
168 } cf_ibss;
169} __attribute__ ((packed)); 162} __attribute__ ((packed));
170 163
171struct fhparamset { 164struct mrvl_ie_rsn_param_set {
172 __le16 dwelltime; 165 struct mrvl_ie_header header;
173 u8 hopset;
174 u8 hoppattern;
175 u8 hopindex;
176} __attribute__ ((packed));
177
178struct dsparamset {
179 u8 currentchan;
180} __attribute__ ((packed));
181
182struct mrvlietypes_phyparamset {
183 struct mrvlietypesheader header;
184 union {
185 struct fhparamset fhparamset[1];
186 struct dsparamset dsparamset[1];
187 } fh_ds;
188} __attribute__ ((packed));
189
190struct mrvlietypes_rsnparamset {
191 struct mrvlietypesheader header;
192 u8 rsnie[1]; 166 u8 rsnie[1];
193} __attribute__ ((packed)); 167} __attribute__ ((packed));
194 168
195struct mrvlietypes_tsftimestamp { 169struct mrvl_ie_tsf_timestamp {
196 struct mrvlietypesheader header; 170 struct mrvl_ie_header header;
197 __le64 tsftable[1]; 171 __le64 tsftable[1];
198} __attribute__ ((packed)); 172} __attribute__ ((packed));
199 173
174/* v9 and later firmware only */
175struct mrvl_ie_auth_type {
176 struct mrvl_ie_header header;
177 __le16 auth;
178} __attribute__ ((packed));
179
200/** Local Power capability */ 180/** Local Power capability */
201struct mrvlietypes_powercapability { 181struct mrvl_ie_power_capability {
202 struct mrvlietypesheader header; 182 struct mrvl_ie_header header;
203 s8 minpower; 183 s8 minpower;
204 s8 maxpower; 184 s8 maxpower;
205} __attribute__ ((packed)); 185} __attribute__ ((packed));
206 186
207/* used in CMD_802_11_SUBSCRIBE_EVENT for SNR, RSSI and Failure */ 187/* used in CMD_802_11_SUBSCRIBE_EVENT for SNR, RSSI and Failure */
208struct mrvlietypes_thresholds { 188struct mrvl_ie_thresholds {
209 struct mrvlietypesheader header; 189 struct mrvl_ie_header header;
210 u8 value; 190 u8 value;
211 u8 freq; 191 u8 freq;
212} __attribute__ ((packed)); 192} __attribute__ ((packed));
213 193
214struct mrvlietypes_beaconsmissed { 194struct mrvl_ie_beacons_missed {
215 struct mrvlietypesheader header; 195 struct mrvl_ie_header header;
216 u8 beaconmissed; 196 u8 beaconmissed;
217 u8 reserved; 197 u8 reserved;
218} __attribute__ ((packed)); 198} __attribute__ ((packed));
219 199
220struct mrvlietypes_numprobes { 200struct mrvl_ie_num_probes {
221 struct mrvlietypesheader header; 201 struct mrvl_ie_header header;
222 __le16 numprobes; 202 __le16 numprobes;
223} __attribute__ ((packed)); 203} __attribute__ ((packed));
224 204
225struct mrvlietypes_bcastprobe { 205struct mrvl_ie_bcast_probe {
226 struct mrvlietypesheader header; 206 struct mrvl_ie_header header;
227 __le16 bcastprobe; 207 __le16 bcastprobe;
228} __attribute__ ((packed)); 208} __attribute__ ((packed));
229 209
230struct mrvlietypes_numssidprobe { 210struct mrvl_ie_num_ssid_probe {
231 struct mrvlietypesheader header; 211 struct mrvl_ie_header header;
232 __le16 numssidprobe; 212 __le16 numssidprobe;
233} __attribute__ ((packed)); 213} __attribute__ ((packed));
234 214
@@ -237,8 +217,8 @@ struct led_pin {
237 u8 pin; 217 u8 pin;
238} __attribute__ ((packed)); 218} __attribute__ ((packed));
239 219
240struct mrvlietypes_ledgpio { 220struct mrvl_ie_ledgpio {
241 struct mrvlietypesheader header; 221 struct mrvl_ie_header header;
242 struct led_pin ledpin[1]; 222 struct led_pin ledpin[1];
243} __attribute__ ((packed)); 223} __attribute__ ((packed));
244 224
@@ -250,8 +230,8 @@ struct led_bhv {
250} __attribute__ ((packed)); 230} __attribute__ ((packed));
251 231
252 232
253struct mrvlietypes_ledbhv { 233struct mrvl_ie_ledbhv {
254 struct mrvlietypesheader header; 234 struct mrvl_ie_header header;
255 struct led_bhv ledbhv[1]; 235 struct led_bhv ledbhv[1];
256} __attribute__ ((packed)); 236} __attribute__ ((packed));
257 237
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 574b8bb121e1..e789c6e9938c 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -280,7 +280,6 @@ struct mac80211_hwsim_data {
280 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; 280 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
281 281
282 struct ieee80211_channel *channel; 282 struct ieee80211_channel *channel;
283 int radio_enabled;
284 unsigned long beacon_int; /* in jiffies unit */ 283 unsigned long beacon_int; /* in jiffies unit */
285 unsigned int rx_filter; 284 unsigned int rx_filter;
286 int started; 285 int started;
@@ -418,8 +417,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
418 if (data == data2) 417 if (data == data2)
419 continue; 418 continue;
420 419
421 if (!data2->started || !data2->radio_enabled || 420 if (!data2->started || !hwsim_ps_rx_ok(data2, skb) ||
422 !hwsim_ps_rx_ok(data2, skb) ||
423 data->channel->center_freq != data2->channel->center_freq || 421 data->channel->center_freq != data2->channel->center_freq ||
424 !(data->group & data2->group)) 422 !(data->group & data2->group))
425 continue; 423 continue;
@@ -441,7 +439,6 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
441 439
442static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 440static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
443{ 441{
444 struct mac80211_hwsim_data *data = hw->priv;
445 bool ack; 442 bool ack;
446 struct ieee80211_tx_info *txi; 443 struct ieee80211_tx_info *txi;
447 444
@@ -453,13 +450,6 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
453 return NETDEV_TX_OK; 450 return NETDEV_TX_OK;
454 } 451 }
455 452
456 if (!data->radio_enabled) {
457 printk(KERN_DEBUG "%s: dropped TX frame since radio "
458 "disabled\n", wiphy_name(hw->wiphy));
459 dev_kfree_skb(skb);
460 return NETDEV_TX_OK;
461 }
462
463 ack = mac80211_hwsim_tx_frame(hw, skb); 453 ack = mac80211_hwsim_tx_frame(hw, skb);
464 454
465 txi = IEEE80211_SKB_CB(skb); 455 txi = IEEE80211_SKB_CB(skb);
@@ -546,7 +536,7 @@ static void mac80211_hwsim_beacon(unsigned long arg)
546 struct ieee80211_hw *hw = (struct ieee80211_hw *) arg; 536 struct ieee80211_hw *hw = (struct ieee80211_hw *) arg;
547 struct mac80211_hwsim_data *data = hw->priv; 537 struct mac80211_hwsim_data *data = hw->priv;
548 538
549 if (!data->started || !data->radio_enabled) 539 if (!data->started)
550 return; 540 return;
551 541
552 ieee80211_iterate_active_interfaces_atomic( 542 ieee80211_iterate_active_interfaces_atomic(
@@ -562,15 +552,14 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
562 struct mac80211_hwsim_data *data = hw->priv; 552 struct mac80211_hwsim_data *data = hw->priv;
563 struct ieee80211_conf *conf = &hw->conf; 553 struct ieee80211_conf *conf = &hw->conf;
564 554
565 printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d idle=%d ps=%d)\n", 555 printk(KERN_DEBUG "%s:%s (freq=%d idle=%d ps=%d)\n",
566 wiphy_name(hw->wiphy), __func__, 556 wiphy_name(hw->wiphy), __func__,
567 conf->channel->center_freq, conf->radio_enabled, 557 conf->channel->center_freq,
568 !!(conf->flags & IEEE80211_CONF_IDLE), 558 !!(conf->flags & IEEE80211_CONF_IDLE),
569 !!(conf->flags & IEEE80211_CONF_PS)); 559 !!(conf->flags & IEEE80211_CONF_PS));
570 560
571 data->channel = conf->channel; 561 data->channel = conf->channel;
572 data->radio_enabled = conf->radio_enabled; 562 if (!data->started || !data->beacon_int)
573 if (!data->started || !data->radio_enabled || !data->beacon_int)
574 del_timer(&data->beacon_timer); 563 del_timer(&data->beacon_timer);
575 else 564 else
576 mod_timer(&data->beacon_timer, jiffies + data->beacon_int); 565 mod_timer(&data->beacon_timer, jiffies + data->beacon_int);
@@ -787,8 +776,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
787 pspoll->aid = cpu_to_le16(0xc000 | vp->aid); 776 pspoll->aid = cpu_to_le16(0xc000 | vp->aid);
788 memcpy(pspoll->bssid, vp->bssid, ETH_ALEN); 777 memcpy(pspoll->bssid, vp->bssid, ETH_ALEN);
789 memcpy(pspoll->ta, mac, ETH_ALEN); 778 memcpy(pspoll->ta, mac, ETH_ALEN);
790 if (data->radio_enabled && 779 if (!mac80211_hwsim_tx_frame(data->hw, skb))
791 !mac80211_hwsim_tx_frame(data->hw, skb))
792 printk(KERN_DEBUG "%s: PS-Poll frame not ack'ed\n", __func__); 780 printk(KERN_DEBUG "%s: PS-Poll frame not ack'ed\n", __func__);
793 dev_kfree_skb(skb); 781 dev_kfree_skb(skb);
794} 782}
@@ -819,8 +807,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
819 memcpy(hdr->addr1, vp->bssid, ETH_ALEN); 807 memcpy(hdr->addr1, vp->bssid, ETH_ALEN);
820 memcpy(hdr->addr2, mac, ETH_ALEN); 808 memcpy(hdr->addr2, mac, ETH_ALEN);
821 memcpy(hdr->addr3, vp->bssid, ETH_ALEN); 809 memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
822 if (data->radio_enabled && 810 if (!mac80211_hwsim_tx_frame(data->hw, skb))
823 !mac80211_hwsim_tx_frame(data->hw, skb))
824 printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__); 811 printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__);
825 dev_kfree_skb(skb); 812 dev_kfree_skb(skb);
826} 813}
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index f40c0f468b27..0e877a104a89 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -84,8 +84,8 @@ MODULE_DEVICE_TABLE(usb, p54u_table);
84static const struct { 84static const struct {
85 u32 intf; 85 u32 intf;
86 enum p54u_hw_type type; 86 enum p54u_hw_type type;
87 char fw[FIRMWARE_NAME_MAX]; 87 const char *fw;
88 char fw_legacy[FIRMWARE_NAME_MAX]; 88 const char *fw_legacy;
89 char hw[20]; 89 char hw[20];
90} p54u_fwlist[__NUM_P54U_HWTYPES] = { 90} p54u_fwlist[__NUM_P54U_HWTYPES] = {
91 { 91 {
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 0197531bd88c..435f945fe64d 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -520,7 +520,7 @@ static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev,
520 if (state == STATE_SLEEP) { 520 if (state == STATE_SLEEP) {
521 rt2x00pci_register_read(rt2x00dev, CSR20, &reg); 521 rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
522 rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN, 522 rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
523 (libconf->conf->beacon_int - 20) * 16); 523 (rt2x00dev->beacon_int - 20) * 16);
524 rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP, 524 rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
525 libconf->conf->listen_interval - 1); 525 libconf->conf->listen_interval - 1);
526 526
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index f95cb646f85a..08b30d01e67d 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -569,7 +569,7 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev,
569 if (state == STATE_SLEEP) { 569 if (state == STATE_SLEEP) {
570 rt2x00pci_register_read(rt2x00dev, CSR20, &reg); 570 rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
571 rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN, 571 rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
572 (libconf->conf->beacon_int - 20) * 16); 572 (rt2x00dev->beacon_int - 20) * 16);
573 rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP, 573 rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
574 libconf->conf->listen_interval - 1); 574 libconf->conf->listen_interval - 1);
575 575
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 69f966f1ce54..66daf68ff0ee 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -647,7 +647,7 @@ static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev,
647 if (state == STATE_SLEEP) { 647 if (state == STATE_SLEEP) {
648 rt2500usb_register_read(rt2x00dev, MAC_CSR18, &reg); 648 rt2500usb_register_read(rt2x00dev, MAC_CSR18, &reg);
649 rt2x00_set_field16(&reg, MAC_CSR18_DELAY_AFTER_BEACON, 649 rt2x00_set_field16(&reg, MAC_CSR18_DELAY_AFTER_BEACON,
650 libconf->conf->beacon_int - 20); 650 rt2x00dev->beacon_int - 20);
651 rt2x00_set_field16(&reg, MAC_CSR18_BEACONS_BEFORE_WAKEUP, 651 rt2x00_set_field16(&reg, MAC_CSR18_BEACONS_BEFORE_WAKEUP,
652 libconf->conf->listen_interval - 1); 652 libconf->conf->listen_interval - 1);
653 653
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 142ad34fdc49..37561667925b 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -2927,12 +2927,17 @@ static struct usb_device_id rt2800usb_device_table[] = {
2927 { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, 2927 { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
2928 { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) }, 2928 { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
2929 { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) }, 2929 { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
2930 { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
2931 { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
2932 { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
2930 { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, 2933 { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
2931 { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) }, 2934 { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
2932 /* Edimax */ 2935 /* Edimax */
2933 { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, 2936 { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
2934 { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, 2937 { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
2935 { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, 2938 { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
2939 /* Encore */
2940 { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
2936 /* EnGenius */ 2941 /* EnGenius */
2937 { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, 2942 { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
2938 { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, 2943 { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -2951,6 +2956,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
2951 { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) }, 2956 { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
2952 { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) }, 2957 { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
2953 { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) }, 2958 { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
2959 /* I-O DATA */
2960 { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
2954 /* LevelOne */ 2961 /* LevelOne */
2955 { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) }, 2962 { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
2956 { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) }, 2963 { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -2970,6 +2977,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
2970 /* Pegatron */ 2977 /* Pegatron */
2971 { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, 2978 { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
2972 { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, 2979 { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
2980 { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
2973 /* Philips */ 2981 /* Philips */
2974 { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) }, 2982 { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
2975 /* Planex */ 2983 /* Planex */
@@ -2981,6 +2989,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
2981 /* Quanta */ 2989 /* Quanta */
2982 { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) }, 2990 { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
2983 /* Ralink */ 2991 /* Ralink */
2992 { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
2984 { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) }, 2993 { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
2985 { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, 2994 { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
2986 { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, 2995 { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -3005,6 +3014,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
3005 { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) }, 3014 { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
3006 { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, 3015 { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
3007 { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) }, 3016 { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
3017 { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
3008 /* SMC */ 3018 /* SMC */
3009 { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) }, 3019 { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
3010 { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) }, 3020 { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -3029,6 +3039,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
3029 /* Zinwell */ 3039 /* Zinwell */
3030 { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) }, 3040 { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
3031 { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) }, 3041 { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
3042 { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
3043 { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
3032 /* Zyxel */ 3044 /* Zyxel */
3033 { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, 3045 { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
3034 { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) }, 3046 { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) },
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 2b64a6198698..a498dde024e1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -802,6 +802,11 @@ struct rt2x00_dev {
802 u8 calibration[2]; 802 u8 calibration[2];
803 803
804 /* 804 /*
805 * Beacon interval.
806 */
807 u16 beacon_int;
808
809 /*
805 * Low level statistics which will have 810 * Low level statistics which will have
806 * to be kept up to date while device is running. 811 * to be kept up to date while device is running.
807 */ 812 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index c5bbf0b6e207..3e019a12df2e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -108,6 +108,9 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
108 erp.basic_rates = bss_conf->basic_rates; 108 erp.basic_rates = bss_conf->basic_rates;
109 erp.beacon_int = bss_conf->beacon_int; 109 erp.beacon_int = bss_conf->beacon_int;
110 110
111 /* Update global beacon interval time, this is needed for PS support */
112 rt2x00dev->beacon_int = bss_conf->beacon_int;
113
111 rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); 114 rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp);
112} 115}
113 116
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index a8bf5c432858..49b29ff90c47 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -956,7 +956,7 @@ static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev,
956 if (state == STATE_SLEEP) { 956 if (state == STATE_SLEEP) {
957 rt2x00pci_register_read(rt2x00dev, MAC_CSR11, &reg); 957 rt2x00pci_register_read(rt2x00dev, MAC_CSR11, &reg);
958 rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 958 rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
959 libconf->conf->beacon_int - 10); 959 rt2x00dev->beacon_int - 10);
960 rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 960 rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
961 libconf->conf->listen_interval - 1); 961 libconf->conf->listen_interval - 1);
962 rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5); 962 rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 211a3d6bc054..c18848836f2d 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -852,7 +852,7 @@ static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
852 if (state == STATE_SLEEP) { 852 if (state == STATE_SLEEP) {
853 rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg); 853 rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
854 rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 854 rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
855 libconf->conf->beacon_int - 10); 855 rt2x00dev->beacon_int - 10);
856 rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 856 rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
857 libconf->conf->listen_interval - 1); 857 libconf->conf->listen_interval - 1);
858 rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5); 858 rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 284ebaca6e45..c682ac536415 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -21,7 +21,7 @@ config ACER_WMI
21 depends on NEW_LEDS 21 depends on NEW_LEDS
22 depends on BACKLIGHT_CLASS_DEVICE 22 depends on BACKLIGHT_CLASS_DEVICE
23 depends on SERIO_I8042 23 depends on SERIO_I8042
24 depends on RFKILL 24 depends on RFKILL || RFKILL = n
25 select ACPI_WMI 25 select ACPI_WMI
26 ---help--- 26 ---help---
27 This is a driver for newer Acer (and Wistron) laptops. It adds 27 This is a driver for newer Acer (and Wistron) laptops. It adds
@@ -60,7 +60,7 @@ config DELL_LAPTOP
60 depends on DCDBAS 60 depends on DCDBAS
61 depends on EXPERIMENTAL 61 depends on EXPERIMENTAL
62 depends on BACKLIGHT_CLASS_DEVICE 62 depends on BACKLIGHT_CLASS_DEVICE
63 depends on RFKILL 63 depends on RFKILL || RFKILL = n
64 depends on POWER_SUPPLY 64 depends on POWER_SUPPLY
65 default n 65 default n
66 ---help--- 66 ---help---
@@ -117,7 +117,7 @@ config HP_WMI
117 tristate "HP WMI extras" 117 tristate "HP WMI extras"
118 depends on ACPI_WMI 118 depends on ACPI_WMI
119 depends on INPUT 119 depends on INPUT
120 depends on RFKILL 120 depends on RFKILL || RFKILL = n
121 help 121 help
122 Say Y here if you want to support WMI-based hotkeys on HP laptops and 122 Say Y here if you want to support WMI-based hotkeys on HP laptops and
123 to read data from WMI such as docking or ambient light sensor state. 123 to read data from WMI such as docking or ambient light sensor state.
@@ -196,14 +196,13 @@ config THINKPAD_ACPI
196 tristate "ThinkPad ACPI Laptop Extras" 196 tristate "ThinkPad ACPI Laptop Extras"
197 depends on ACPI 197 depends on ACPI
198 depends on INPUT 198 depends on INPUT
199 depends on RFKILL || RFKILL = n
199 select BACKLIGHT_LCD_SUPPORT 200 select BACKLIGHT_LCD_SUPPORT
200 select BACKLIGHT_CLASS_DEVICE 201 select BACKLIGHT_CLASS_DEVICE
201 select HWMON 202 select HWMON
202 select NVRAM 203 select NVRAM
203 select NEW_LEDS 204 select NEW_LEDS
204 select LEDS_CLASS 205 select LEDS_CLASS
205 select NET
206 select RFKILL
207 ---help--- 206 ---help---
208 This is a driver for the IBM and Lenovo ThinkPad laptops. It adds 207 This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
209 support for Fn-Fx key combinations, Bluetooth control, video 208 support for Fn-Fx key combinations, Bluetooth control, video
@@ -338,9 +337,9 @@ config EEEPC_LAPTOP
338 depends on ACPI 337 depends on ACPI
339 depends on INPUT 338 depends on INPUT
340 depends on EXPERIMENTAL 339 depends on EXPERIMENTAL
340 depends on RFKILL || RFKILL = n
341 select BACKLIGHT_CLASS_DEVICE 341 select BACKLIGHT_CLASS_DEVICE
342 select HWMON 342 select HWMON
343 select RFKILL
344 ---help--- 343 ---help---
345 This driver supports the Fn-Fx keys on Eee PC laptops. 344 This driver supports the Fn-Fx keys on Eee PC laptops.
346 It also adds the ability to switch camera/wlan on/off. 345 It also adds the ability to switch camera/wlan on/off.
@@ -405,9 +404,8 @@ config ACPI_TOSHIBA
405 tristate "Toshiba Laptop Extras" 404 tristate "Toshiba Laptop Extras"
406 depends on ACPI 405 depends on ACPI
407 depends on INPUT 406 depends on INPUT
407 depends on RFKILL || RFKILL = n
408 select INPUT_POLLDEV 408 select INPUT_POLLDEV
409 select NET
410 select RFKILL
411 select BACKLIGHT_CLASS_DEVICE 409 select BACKLIGHT_CLASS_DEVICE
412 ---help--- 410 ---help---
413 This driver adds support for access to certain system settings 411 This driver adds support for access to certain system settings
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 62d02b3c998e..b618fa51db2d 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -958,58 +958,50 @@ static void acer_rfkill_update(struct work_struct *ignored)
958 958
959 status = get_u32(&state, ACER_CAP_WIRELESS); 959 status = get_u32(&state, ACER_CAP_WIRELESS);
960 if (ACPI_SUCCESS(status)) 960 if (ACPI_SUCCESS(status))
961 rfkill_force_state(wireless_rfkill, state ? 961 rfkill_set_sw_state(wireless_rfkill, !!state);
962 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED);
963 962
964 if (has_cap(ACER_CAP_BLUETOOTH)) { 963 if (has_cap(ACER_CAP_BLUETOOTH)) {
965 status = get_u32(&state, ACER_CAP_BLUETOOTH); 964 status = get_u32(&state, ACER_CAP_BLUETOOTH);
966 if (ACPI_SUCCESS(status)) 965 if (ACPI_SUCCESS(status))
967 rfkill_force_state(bluetooth_rfkill, state ? 966 rfkill_set_sw_state(bluetooth_rfkill, !!state);
968 RFKILL_STATE_UNBLOCKED :
969 RFKILL_STATE_SOFT_BLOCKED);
970 } 967 }
971 968
972 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); 969 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
973} 970}
974 971
975static int acer_rfkill_set(void *data, enum rfkill_state state) 972static int acer_rfkill_set(void *data, bool blocked)
976{ 973{
977 acpi_status status; 974 acpi_status status;
978 u32 *cap = data; 975 u32 cap = (unsigned long)data;
979 status = set_u32((u32) (state == RFKILL_STATE_UNBLOCKED), *cap); 976 status = set_u32(!!blocked, cap);
980 if (ACPI_FAILURE(status)) 977 if (ACPI_FAILURE(status))
981 return -ENODEV; 978 return -ENODEV;
982 return 0; 979 return 0;
983} 980}
984 981
985static struct rfkill * acer_rfkill_register(struct device *dev, 982static const struct rfkill_ops acer_rfkill_ops = {
986enum rfkill_type type, char *name, u32 cap) 983 .set_block = acer_rfkill_set,
984};
985
986static struct rfkill *acer_rfkill_register(struct device *dev,
987 enum rfkill_type type,
988 char *name, u32 cap)
987{ 989{
988 int err; 990 int err;
989 u32 state; 991 u32 state;
990 u32 *data;
991 struct rfkill *rfkill_dev; 992 struct rfkill *rfkill_dev;
992 993
993 rfkill_dev = rfkill_allocate(dev, type); 994 rfkill_dev = rfkill_alloc(name, dev, type,
995 &acer_rfkill_ops,
996 (void *)(unsigned long)cap);
994 if (!rfkill_dev) 997 if (!rfkill_dev)
995 return ERR_PTR(-ENOMEM); 998 return ERR_PTR(-ENOMEM);
996 rfkill_dev->name = name;
997 get_u32(&state, cap); 999 get_u32(&state, cap);
998 rfkill_dev->state = state ? RFKILL_STATE_UNBLOCKED : 1000 rfkill_set_sw_state(rfkill_dev, !state);
999 RFKILL_STATE_SOFT_BLOCKED;
1000 data = kzalloc(sizeof(u32), GFP_KERNEL);
1001 if (!data) {
1002 rfkill_free(rfkill_dev);
1003 return ERR_PTR(-ENOMEM);
1004 }
1005 *data = cap;
1006 rfkill_dev->data = data;
1007 rfkill_dev->toggle_radio = acer_rfkill_set;
1008 1001
1009 err = rfkill_register(rfkill_dev); 1002 err = rfkill_register(rfkill_dev);
1010 if (err) { 1003 if (err) {
1011 kfree(rfkill_dev->data); 1004 rfkill_destroy(rfkill_dev);
1012 rfkill_free(rfkill_dev);
1013 return ERR_PTR(err); 1005 return ERR_PTR(err);
1014 } 1006 }
1015 return rfkill_dev; 1007 return rfkill_dev;
@@ -1027,8 +1019,8 @@ static int acer_rfkill_init(struct device *dev)
1027 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth", 1019 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
1028 ACER_CAP_BLUETOOTH); 1020 ACER_CAP_BLUETOOTH);
1029 if (IS_ERR(bluetooth_rfkill)) { 1021 if (IS_ERR(bluetooth_rfkill)) {
1030 kfree(wireless_rfkill->data);
1031 rfkill_unregister(wireless_rfkill); 1022 rfkill_unregister(wireless_rfkill);
1023 rfkill_destroy(wireless_rfkill);
1032 return PTR_ERR(bluetooth_rfkill); 1024 return PTR_ERR(bluetooth_rfkill);
1033 } 1025 }
1034 } 1026 }
@@ -1041,11 +1033,13 @@ static int acer_rfkill_init(struct device *dev)
1041static void acer_rfkill_exit(void) 1033static void acer_rfkill_exit(void)
1042{ 1034{
1043 cancel_delayed_work_sync(&acer_rfkill_work); 1035 cancel_delayed_work_sync(&acer_rfkill_work);
1044 kfree(wireless_rfkill->data); 1036
1045 rfkill_unregister(wireless_rfkill); 1037 rfkill_unregister(wireless_rfkill);
1038 rfkill_destroy(wireless_rfkill);
1039
1046 if (has_cap(ACER_CAP_BLUETOOTH)) { 1040 if (has_cap(ACER_CAP_BLUETOOTH)) {
1047 kfree(bluetooth_rfkill->data);
1048 rfkill_unregister(bluetooth_rfkill); 1041 rfkill_unregister(bluetooth_rfkill);
1042 rfkill_destroy(bluetooth_rfkill);
1049 } 1043 }
1050 return; 1044 return;
1051} 1045}
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index af9f43021172..2faf0e14f05a 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -174,10 +174,11 @@ dell_send_request(struct calling_interface_buffer *buffer, int class,
174 result[3]: NVRAM format version number 174 result[3]: NVRAM format version number
175*/ 175*/
176 176
177static int dell_rfkill_set(int radio, enum rfkill_state state) 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 = (state == RFKILL_STATE_UNBLOCKED) ? 0 : 1; 180 int disable = blocked ? 0 : 1;
181 unsigned long radio = (unsigned long)data;
181 182
182 memset(&buffer, 0, sizeof(struct calling_interface_buffer)); 183 memset(&buffer, 0, sizeof(struct calling_interface_buffer));
183 buffer.input[0] = (1 | (radio<<8) | (disable << 16)); 184 buffer.input[0] = (1 | (radio<<8) | (disable << 16));
@@ -186,56 +187,24 @@ static int dell_rfkill_set(int radio, enum rfkill_state state)
186 return 0; 187 return 0;
187} 188}
188 189
189static int dell_wifi_set(void *data, enum rfkill_state state) 190static void dell_rfkill_query(struct rfkill *rfkill, void *data)
190{
191 return dell_rfkill_set(1, state);
192}
193
194static int dell_bluetooth_set(void *data, enum rfkill_state state)
195{
196 return dell_rfkill_set(2, state);
197}
198
199static int dell_wwan_set(void *data, enum rfkill_state state)
200{
201 return dell_rfkill_set(3, state);
202}
203
204static int dell_rfkill_get(int bit, enum rfkill_state *state)
205{ 191{
206 struct calling_interface_buffer buffer; 192 struct calling_interface_buffer buffer;
207 int status; 193 int status;
208 int new_state = RFKILL_STATE_HARD_BLOCKED; 194 int bit = (unsigned long)data + 16;
209 195
210 memset(&buffer, 0, sizeof(struct calling_interface_buffer)); 196 memset(&buffer, 0, sizeof(struct calling_interface_buffer));
211 dell_send_request(&buffer, 17, 11); 197 dell_send_request(&buffer, 17, 11);
212 status = buffer.output[1]; 198 status = buffer.output[1];
213 199
214 if (status & (1<<16)) 200 if (status & BIT(bit))
215 new_state = RFKILL_STATE_SOFT_BLOCKED; 201 rfkill_set_hw_state(rfkill, !!(status & BIT(16)));
216
217 if (status & (1<<bit))
218 *state = new_state;
219 else
220 *state = RFKILL_STATE_UNBLOCKED;
221
222 return 0;
223}
224
225static int dell_wifi_get(void *data, enum rfkill_state *state)
226{
227 return dell_rfkill_get(17, state);
228}
229
230static int dell_bluetooth_get(void *data, enum rfkill_state *state)
231{
232 return dell_rfkill_get(18, state);
233} 202}
234 203
235static int dell_wwan_get(void *data, enum rfkill_state *state) 204static const struct rfkill_ops dell_rfkill_ops = {
236{ 205 .set_block = dell_rfkill_set,
237 return dell_rfkill_get(19, state); 206 .query = dell_rfkill_query,
238} 207};
239 208
240static int dell_setup_rfkill(void) 209static int dell_setup_rfkill(void)
241{ 210{
@@ -248,36 +217,37 @@ static int dell_setup_rfkill(void)
248 status = buffer.output[1]; 217 status = buffer.output[1];
249 218
250 if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { 219 if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {
251 wifi_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WLAN); 220 wifi_rfkill = rfkill_alloc("dell-wifi", NULL, RFKILL_TYPE_WLAN,
252 if (!wifi_rfkill) 221 &dell_rfkill_ops, (void *) 1);
222 if (!wifi_rfkill) {
223 ret = -ENOMEM;
253 goto err_wifi; 224 goto err_wifi;
254 wifi_rfkill->name = "dell-wifi"; 225 }
255 wifi_rfkill->toggle_radio = dell_wifi_set;
256 wifi_rfkill->get_state = dell_wifi_get;
257 ret = rfkill_register(wifi_rfkill); 226 ret = rfkill_register(wifi_rfkill);
258 if (ret) 227 if (ret)
259 goto err_wifi; 228 goto err_wifi;
260 } 229 }
261 230
262 if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { 231 if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) {
263 bluetooth_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_BLUETOOTH); 232 bluetooth_rfkill = rfkill_alloc("dell-bluetooth", NULL,
264 if (!bluetooth_rfkill) 233 RFKILL_TYPE_BLUETOOTH,
234 &dell_rfkill_ops, (void *) 2);
235 if (!bluetooth_rfkill) {
236 ret = -ENOMEM;
265 goto err_bluetooth; 237 goto err_bluetooth;
266 bluetooth_rfkill->name = "dell-bluetooth"; 238 }
267 bluetooth_rfkill->toggle_radio = dell_bluetooth_set;
268 bluetooth_rfkill->get_state = dell_bluetooth_get;
269 ret = rfkill_register(bluetooth_rfkill); 239 ret = rfkill_register(bluetooth_rfkill);
270 if (ret) 240 if (ret)
271 goto err_bluetooth; 241 goto err_bluetooth;
272 } 242 }
273 243
274 if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { 244 if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) {
275 wwan_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WWAN); 245 wwan_rfkill = rfkill_alloc("dell-wwan", NULL, RFKILL_TYPE_WWAN,
276 if (!wwan_rfkill) 246 &dell_rfkill_ops, (void *) 3);
247 if (!wwan_rfkill) {
248 ret = -ENOMEM;
277 goto err_wwan; 249 goto err_wwan;
278 wwan_rfkill->name = "dell-wwan"; 250 }
279 wwan_rfkill->toggle_radio = dell_wwan_set;
280 wwan_rfkill->get_state = dell_wwan_get;
281 ret = rfkill_register(wwan_rfkill); 251 ret = rfkill_register(wwan_rfkill);
282 if (ret) 252 if (ret)
283 goto err_wwan; 253 goto err_wwan;
@@ -285,22 +255,15 @@ static int dell_setup_rfkill(void)
285 255
286 return 0; 256 return 0;
287err_wwan: 257err_wwan:
288 if (wwan_rfkill) 258 rfkill_destroy(wwan_rfkill);
289 rfkill_free(wwan_rfkill); 259 if (bluetooth_rfkill)
290 if (bluetooth_rfkill) {
291 rfkill_unregister(bluetooth_rfkill); 260 rfkill_unregister(bluetooth_rfkill);
292 bluetooth_rfkill = NULL;
293 }
294err_bluetooth: 261err_bluetooth:
295 if (bluetooth_rfkill) 262 rfkill_destroy(bluetooth_rfkill);
296 rfkill_free(bluetooth_rfkill); 263 if (wifi_rfkill)
297 if (wifi_rfkill) {
298 rfkill_unregister(wifi_rfkill); 264 rfkill_unregister(wifi_rfkill);
299 wifi_rfkill = NULL;
300 }
301err_wifi: 265err_wifi:
302 if (wifi_rfkill) 266 rfkill_destroy(wifi_rfkill);
303 rfkill_free(wifi_rfkill);
304 267
305 return ret; 268 return ret;
306} 269}
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 353a898c3693..1208d0cedd15 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -299,39 +299,22 @@ static int update_bl_status(struct backlight_device *bd)
299 * Rfkill helpers 299 * Rfkill helpers
300 */ 300 */
301 301
302static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state) 302static bool eeepc_wlan_rfkill_blocked(void)
303{
304 if (state == RFKILL_STATE_SOFT_BLOCKED)
305 return set_acpi(CM_ASL_WLAN, 0);
306 else
307 return set_acpi(CM_ASL_WLAN, 1);
308}
309
310static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state)
311{ 303{
312 if (get_acpi(CM_ASL_WLAN) == 1) 304 if (get_acpi(CM_ASL_WLAN) == 1)
313 *state = RFKILL_STATE_UNBLOCKED; 305 return false;
314 else 306 return true;
315 *state = RFKILL_STATE_SOFT_BLOCKED;
316 return 0;
317} 307}
318 308
319static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state) 309static int eeepc_rfkill_set(void *data, bool blocked)
320{ 310{
321 if (state == RFKILL_STATE_SOFT_BLOCKED) 311 unsigned long asl = (unsigned long)data;
322 return set_acpi(CM_ASL_BLUETOOTH, 0); 312 return set_acpi(asl, !blocked);
323 else
324 return set_acpi(CM_ASL_BLUETOOTH, 1);
325} 313}
326 314
327static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state) 315static const struct rfkill_ops eeepc_rfkill_ops = {
328{ 316 .set_block = eeepc_rfkill_set,
329 if (get_acpi(CM_ASL_BLUETOOTH) == 1) 317};
330 *state = RFKILL_STATE_UNBLOCKED;
331 else
332 *state = RFKILL_STATE_SOFT_BLOCKED;
333 return 0;
334}
335 318
336/* 319/*
337 * Sys helpers 320 * Sys helpers
@@ -531,9 +514,9 @@ static int notify_brn(void)
531 514
532static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) 515static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
533{ 516{
534 enum rfkill_state state;
535 struct pci_dev *dev; 517 struct pci_dev *dev;
536 struct pci_bus *bus = pci_find_bus(0, 1); 518 struct pci_bus *bus = pci_find_bus(0, 1);
519 bool blocked;
537 520
538 if (event != ACPI_NOTIFY_BUS_CHECK) 521 if (event != ACPI_NOTIFY_BUS_CHECK)
539 return; 522 return;
@@ -543,9 +526,8 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
543 return; 526 return;
544 } 527 }
545 528
546 eeepc_wlan_rfkill_state(ehotk->eeepc_wlan_rfkill, &state); 529 blocked = eeepc_wlan_rfkill_blocked();
547 530 if (!blocked) {
548 if (state == RFKILL_STATE_UNBLOCKED) {
549 dev = pci_get_slot(bus, 0); 531 dev = pci_get_slot(bus, 0);
550 if (dev) { 532 if (dev) {
551 /* Device already present */ 533 /* Device already present */
@@ -566,7 +548,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
566 } 548 }
567 } 549 }
568 550
569 rfkill_force_state(ehotk->eeepc_wlan_rfkill, state); 551 rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked);
570} 552}
571 553
572static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) 554static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
@@ -684,26 +666,17 @@ static int eeepc_hotk_add(struct acpi_device *device)
684 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); 666 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
685 667
686 if (get_acpi(CM_ASL_WLAN) != -1) { 668 if (get_acpi(CM_ASL_WLAN) != -1) {
687 ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, 669 ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan",
688 RFKILL_TYPE_WLAN); 670 &device->dev,
671 RFKILL_TYPE_WLAN,
672 &eeepc_rfkill_ops,
673 (void *)CM_ASL_WLAN);
689 674
690 if (!ehotk->eeepc_wlan_rfkill) 675 if (!ehotk->eeepc_wlan_rfkill)
691 goto wlan_fail; 676 goto wlan_fail;
692 677
693 ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; 678 rfkill_set_global_sw_state(RFKILL_TYPE_WLAN,
694 ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; 679 get_acpi(CM_ASL_WLAN) != 1);
695 ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
696 if (get_acpi(CM_ASL_WLAN) == 1) {
697 ehotk->eeepc_wlan_rfkill->state =
698 RFKILL_STATE_UNBLOCKED;
699 rfkill_set_default(RFKILL_TYPE_WLAN,
700 RFKILL_STATE_UNBLOCKED);
701 } else {
702 ehotk->eeepc_wlan_rfkill->state =
703 RFKILL_STATE_SOFT_BLOCKED;
704 rfkill_set_default(RFKILL_TYPE_WLAN,
705 RFKILL_STATE_SOFT_BLOCKED);
706 }
707 result = rfkill_register(ehotk->eeepc_wlan_rfkill); 680 result = rfkill_register(ehotk->eeepc_wlan_rfkill);
708 if (result) 681 if (result)
709 goto wlan_fail; 682 goto wlan_fail;
@@ -711,28 +684,17 @@ static int eeepc_hotk_add(struct acpi_device *device)
711 684
712 if (get_acpi(CM_ASL_BLUETOOTH) != -1) { 685 if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
713 ehotk->eeepc_bluetooth_rfkill = 686 ehotk->eeepc_bluetooth_rfkill =
714 rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); 687 rfkill_alloc("eeepc-bluetooth",
688 &device->dev,
689 RFKILL_TYPE_BLUETOOTH,
690 &eeepc_rfkill_ops,
691 (void *)CM_ASL_BLUETOOTH);
715 692
716 if (!ehotk->eeepc_bluetooth_rfkill) 693 if (!ehotk->eeepc_bluetooth_rfkill)
717 goto bluetooth_fail; 694 goto bluetooth_fail;
718 695
719 ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; 696 rfkill_set_global_sw_state(RFKILL_TYPE_BLUETOOTH,
720 ehotk->eeepc_bluetooth_rfkill->toggle_radio = 697 get_acpi(CM_ASL_BLUETOOTH) != 1);
721 eeepc_bluetooth_rfkill_set;
722 ehotk->eeepc_bluetooth_rfkill->get_state =
723 eeepc_bluetooth_rfkill_state;
724 if (get_acpi(CM_ASL_BLUETOOTH) == 1) {
725 ehotk->eeepc_bluetooth_rfkill->state =
726 RFKILL_STATE_UNBLOCKED;
727 rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
728 RFKILL_STATE_UNBLOCKED);
729 } else {
730 ehotk->eeepc_bluetooth_rfkill->state =
731 RFKILL_STATE_SOFT_BLOCKED;
732 rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
733 RFKILL_STATE_SOFT_BLOCKED);
734 }
735
736 result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); 698 result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
737 if (result) 699 if (result)
738 goto bluetooth_fail; 700 goto bluetooth_fail;
@@ -741,13 +703,10 @@ static int eeepc_hotk_add(struct acpi_device *device)
741 return 0; 703 return 0;
742 704
743 bluetooth_fail: 705 bluetooth_fail:
744 if (ehotk->eeepc_bluetooth_rfkill) 706 rfkill_destroy(ehotk->eeepc_bluetooth_rfkill);
745 rfkill_free(ehotk->eeepc_bluetooth_rfkill);
746 rfkill_unregister(ehotk->eeepc_wlan_rfkill); 707 rfkill_unregister(ehotk->eeepc_wlan_rfkill);
747 ehotk->eeepc_wlan_rfkill = NULL;
748 wlan_fail: 708 wlan_fail:
749 if (ehotk->eeepc_wlan_rfkill) 709 rfkill_destroy(ehotk->eeepc_wlan_rfkill);
750 rfkill_free(ehotk->eeepc_wlan_rfkill);
751 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); 710 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
752 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); 711 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
753 ehotk_fail: 712 ehotk_fail:
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index fe171fad12cf..8d931145cbfa 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -154,58 +154,46 @@ static int hp_wmi_dock_state(void)
154 return hp_wmi_perform_query(HPWMI_DOCK_QUERY, 0, 0); 154 return hp_wmi_perform_query(HPWMI_DOCK_QUERY, 0, 0);
155} 155}
156 156
157static int hp_wmi_wifi_set(void *data, enum rfkill_state state) 157static int hp_wmi_set_block(void *data, bool blocked)
158{ 158{
159 if (state) 159 unsigned long b = (unsigned long) data;
160 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x101); 160 int query = BIT(b + 8) | ((!!blocked) << b);
161 else
162 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x100);
163}
164 161
165static int hp_wmi_bluetooth_set(void *data, enum rfkill_state state) 162 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query);
166{
167 if (state)
168 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x202);
169 else
170 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x200);
171} 163}
172 164
173static int hp_wmi_wwan_set(void *data, enum rfkill_state state) 165static const struct rfkill_ops hp_wmi_rfkill_ops = {
174{ 166 .set_block = hp_wmi_set_block,
175 if (state) 167};
176 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x404);
177 else
178 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x400);
179}
180 168
181static int hp_wmi_wifi_state(void) 169static bool hp_wmi_wifi_state(void)
182{ 170{
183 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); 171 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
184 172
185 if (wireless & 0x100) 173 if (wireless & 0x100)
186 return RFKILL_STATE_UNBLOCKED; 174 return false;
187 else 175 else
188 return RFKILL_STATE_SOFT_BLOCKED; 176 return true;
189} 177}
190 178
191static int hp_wmi_bluetooth_state(void) 179static bool hp_wmi_bluetooth_state(void)
192{ 180{
193 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); 181 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
194 182
195 if (wireless & 0x10000) 183 if (wireless & 0x10000)
196 return RFKILL_STATE_UNBLOCKED; 184 return false;
197 else 185 else
198 return RFKILL_STATE_SOFT_BLOCKED; 186 return true;
199} 187}
200 188
201static int hp_wmi_wwan_state(void) 189static bool hp_wmi_wwan_state(void)
202{ 190{
203 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); 191 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
204 192
205 if (wireless & 0x1000000) 193 if (wireless & 0x1000000)
206 return RFKILL_STATE_UNBLOCKED; 194 return false;
207 else 195 else
208 return RFKILL_STATE_SOFT_BLOCKED; 196 return true;
209} 197}
210 198
211static ssize_t show_display(struct device *dev, struct device_attribute *attr, 199static ssize_t show_display(struct device *dev, struct device_attribute *attr,
@@ -347,14 +335,14 @@ static void hp_wmi_notify(u32 value, void *context)
347 } 335 }
348 } else if (eventcode == 0x5) { 336 } else if (eventcode == 0x5) {
349 if (wifi_rfkill) 337 if (wifi_rfkill)
350 rfkill_force_state(wifi_rfkill, 338 rfkill_set_sw_state(wifi_rfkill,
351 hp_wmi_wifi_state()); 339 hp_wmi_wifi_state());
352 if (bluetooth_rfkill) 340 if (bluetooth_rfkill)
353 rfkill_force_state(bluetooth_rfkill, 341 rfkill_set_sw_state(bluetooth_rfkill,
354 hp_wmi_bluetooth_state()); 342 hp_wmi_bluetooth_state());
355 if (wwan_rfkill) 343 if (wwan_rfkill)
356 rfkill_force_state(wwan_rfkill, 344 rfkill_set_sw_state(wwan_rfkill,
357 hp_wmi_wwan_state()); 345 hp_wmi_wwan_state());
358 } else 346 } else
359 printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", 347 printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n",
360 eventcode); 348 eventcode);
@@ -430,31 +418,34 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
430 goto add_sysfs_error; 418 goto add_sysfs_error;
431 419
432 if (wireless & 0x1) { 420 if (wireless & 0x1) {
433 wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN); 421 wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
434 wifi_rfkill->name = "hp-wifi"; 422 RFKILL_TYPE_WLAN,
435 wifi_rfkill->state = hp_wmi_wifi_state(); 423 &hp_wmi_rfkill_ops,
436 wifi_rfkill->toggle_radio = hp_wmi_wifi_set; 424 (void *) 0);
425 rfkill_set_sw_state(wifi_rfkill, hp_wmi_wifi_state());
437 err = rfkill_register(wifi_rfkill); 426 err = rfkill_register(wifi_rfkill);
438 if (err) 427 if (err)
439 goto add_sysfs_error; 428 goto register_wifi_error;
440 } 429 }
441 430
442 if (wireless & 0x2) { 431 if (wireless & 0x2) {
443 bluetooth_rfkill = rfkill_allocate(&device->dev, 432 bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev,
444 RFKILL_TYPE_BLUETOOTH); 433 RFKILL_TYPE_BLUETOOTH,
445 bluetooth_rfkill->name = "hp-bluetooth"; 434 &hp_wmi_rfkill_ops,
446 bluetooth_rfkill->state = hp_wmi_bluetooth_state(); 435 (void *) 1);
447 bluetooth_rfkill->toggle_radio = hp_wmi_bluetooth_set; 436 rfkill_set_sw_state(bluetooth_rfkill,
437 hp_wmi_bluetooth_state());
448 err = rfkill_register(bluetooth_rfkill); 438 err = rfkill_register(bluetooth_rfkill);
449 if (err) 439 if (err)
450 goto register_bluetooth_error; 440 goto register_bluetooth_error;
451 } 441 }
452 442
453 if (wireless & 0x4) { 443 if (wireless & 0x4) {
454 wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN); 444 wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev,
455 wwan_rfkill->name = "hp-wwan"; 445 RFKILL_TYPE_WWAN,
456 wwan_rfkill->state = hp_wmi_wwan_state(); 446 &hp_wmi_rfkill_ops,
457 wwan_rfkill->toggle_radio = hp_wmi_wwan_set; 447 (void *) 2);
448 rfkill_set_sw_state(wwan_rfkill, hp_wmi_wwan_state());
458 err = rfkill_register(wwan_rfkill); 449 err = rfkill_register(wwan_rfkill);
459 if (err) 450 if (err)
460 goto register_wwan_err; 451 goto register_wwan_err;
@@ -462,11 +453,15 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
462 453
463 return 0; 454 return 0;
464register_wwan_err: 455register_wwan_err:
456 rfkill_destroy(wwan_rfkill);
465 if (bluetooth_rfkill) 457 if (bluetooth_rfkill)
466 rfkill_unregister(bluetooth_rfkill); 458 rfkill_unregister(bluetooth_rfkill);
467register_bluetooth_error: 459register_bluetooth_error:
460 rfkill_destroy(bluetooth_rfkill);
468 if (wifi_rfkill) 461 if (wifi_rfkill)
469 rfkill_unregister(wifi_rfkill); 462 rfkill_unregister(wifi_rfkill);
463register_wifi_error:
464 rfkill_destroy(wifi_rfkill);
470add_sysfs_error: 465add_sysfs_error:
471 cleanup_sysfs(device); 466 cleanup_sysfs(device);
472 return err; 467 return err;
@@ -476,12 +471,18 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device)
476{ 471{
477 cleanup_sysfs(device); 472 cleanup_sysfs(device);
478 473
479 if (wifi_rfkill) 474 if (wifi_rfkill) {
480 rfkill_unregister(wifi_rfkill); 475 rfkill_unregister(wifi_rfkill);
481 if (bluetooth_rfkill) 476 rfkill_destroy(wifi_rfkill);
477 }
478 if (bluetooth_rfkill) {
482 rfkill_unregister(bluetooth_rfkill); 479 rfkill_unregister(bluetooth_rfkill);
483 if (wwan_rfkill) 480 rfkill_destroy(wifi_rfkill);
481 }
482 if (wwan_rfkill) {
484 rfkill_unregister(wwan_rfkill); 483 rfkill_unregister(wwan_rfkill);
484 rfkill_destroy(wwan_rfkill);
485 }
485 486
486 return 0; 487 return 0;
487} 488}
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index f1963b05175b..aec0b27fd774 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -128,11 +128,11 @@ enum sony_nc_rfkill {
128 SONY_BLUETOOTH, 128 SONY_BLUETOOTH,
129 SONY_WWAN, 129 SONY_WWAN,
130 SONY_WIMAX, 130 SONY_WIMAX,
131 SONY_RFKILL_MAX, 131 N_SONY_RFKILL,
132}; 132};
133 133
134static struct rfkill *sony_rfkill_devices[SONY_RFKILL_MAX]; 134static struct rfkill *sony_rfkill_devices[N_SONY_RFKILL];
135static int sony_rfkill_address[SONY_RFKILL_MAX] = {0x300, 0x500, 0x700, 0x900}; 135static int sony_rfkill_address[N_SONY_RFKILL] = {0x300, 0x500, 0x700, 0x900};
136static void sony_nc_rfkill_update(void); 136static void sony_nc_rfkill_update(void);
137 137
138/*********** Input Devices ***********/ 138/*********** Input Devices ***********/
@@ -1051,147 +1051,98 @@ static void sony_nc_rfkill_cleanup(void)
1051{ 1051{
1052 int i; 1052 int i;
1053 1053
1054 for (i = 0; i < SONY_RFKILL_MAX; i++) { 1054 for (i = 0; i < N_SONY_RFKILL; i++) {
1055 if (sony_rfkill_devices[i]) 1055 if (sony_rfkill_devices[i]) {
1056 rfkill_unregister(sony_rfkill_devices[i]); 1056 rfkill_unregister(sony_rfkill_devices[i]);
1057 rfkill_destroy(sony_rfkill_devices[i]);
1058 }
1057 } 1059 }
1058} 1060}
1059 1061
1060static int sony_nc_rfkill_get(void *data, enum rfkill_state *state) 1062static int sony_nc_rfkill_set(void *data, bool blocked)
1061{
1062 int result;
1063 int argument = sony_rfkill_address[(long) data];
1064
1065 sony_call_snc_handle(0x124, 0x200, &result);
1066 if (result & 0x1) {
1067 sony_call_snc_handle(0x124, argument, &result);
1068 if (result & 0xf)
1069 *state = RFKILL_STATE_UNBLOCKED;
1070 else
1071 *state = RFKILL_STATE_SOFT_BLOCKED;
1072 } else {
1073 *state = RFKILL_STATE_HARD_BLOCKED;
1074 }
1075
1076 return 0;
1077}
1078
1079static int sony_nc_rfkill_set(void *data, enum rfkill_state state)
1080{ 1063{
1081 int result; 1064 int result;
1082 int argument = sony_rfkill_address[(long) data] + 0x100; 1065 int argument = sony_rfkill_address[(long) data] + 0x100;
1083 1066
1084 if (state == RFKILL_STATE_UNBLOCKED) 1067 if (!blocked)
1085 argument |= 0xff0000; 1068 argument |= 0xff0000;
1086 1069
1087 return sony_call_snc_handle(0x124, argument, &result); 1070 return sony_call_snc_handle(0x124, argument, &result);
1088} 1071}
1089 1072
1090static int sony_nc_setup_wifi_rfkill(struct acpi_device *device) 1073static const struct rfkill_ops sony_rfkill_ops = {
1091{ 1074 .set_block = sony_nc_rfkill_set,
1092 int err = 0; 1075};
1093 struct rfkill *sony_wifi_rfkill;
1094
1095 sony_wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN);
1096 if (!sony_wifi_rfkill)
1097 return -1;
1098 sony_wifi_rfkill->name = "sony-wifi";
1099 sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set;
1100 sony_wifi_rfkill->get_state = sony_nc_rfkill_get;
1101 sony_wifi_rfkill->data = (void *)SONY_WIFI;
1102 err = rfkill_register(sony_wifi_rfkill);
1103 if (err)
1104 rfkill_free(sony_wifi_rfkill);
1105 else {
1106 sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
1107 sony_nc_rfkill_set(sony_wifi_rfkill->data,
1108 RFKILL_STATE_UNBLOCKED);
1109 }
1110 return err;
1111}
1112 1076
1113static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device) 1077static int sony_nc_setup_rfkill(struct acpi_device *device,
1078 enum sony_nc_rfkill nc_type)
1114{ 1079{
1115 int err = 0; 1080 int err = 0;
1116 struct rfkill *sony_bluetooth_rfkill; 1081 struct rfkill *rfk;
1117 1082 enum rfkill_type type;
1118 sony_bluetooth_rfkill = rfkill_allocate(&device->dev, 1083 const char *name;
1119 RFKILL_TYPE_BLUETOOTH); 1084
1120 if (!sony_bluetooth_rfkill) 1085 switch (nc_type) {
1121 return -1; 1086 case SONY_WIFI:
1122 sony_bluetooth_rfkill->name = "sony-bluetooth"; 1087 type = RFKILL_TYPE_WLAN;
1123 sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set; 1088 name = "sony-wifi";
1124 sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get; 1089 break;
1125 sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH; 1090 case SONY_BLUETOOTH:
1126 err = rfkill_register(sony_bluetooth_rfkill); 1091 type = RFKILL_TYPE_BLUETOOTH;
1127 if (err) 1092 name = "sony-bluetooth";
1128 rfkill_free(sony_bluetooth_rfkill); 1093 break;
1129 else { 1094 case SONY_WWAN:
1130 sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill; 1095 type = RFKILL_TYPE_WWAN;
1131 sony_nc_rfkill_set(sony_bluetooth_rfkill->data, 1096 name = "sony-wwan";
1132 RFKILL_STATE_UNBLOCKED); 1097 break;
1098 case SONY_WIMAX:
1099 type = RFKILL_TYPE_WIMAX;
1100 name = "sony-wimax";
1101 break;
1102 default:
1103 return -EINVAL;
1133 } 1104 }
1134 return err;
1135}
1136 1105
1137static int sony_nc_setup_wwan_rfkill(struct acpi_device *device) 1106 rfk = rfkill_alloc(name, &device->dev, type,
1138{ 1107 &sony_rfkill_ops, (void *)nc_type);
1139 int err = 0; 1108 if (!rfk)
1140 struct rfkill *sony_wwan_rfkill; 1109 return -ENOMEM;
1141 1110
1142 sony_wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN); 1111 err = rfkill_register(rfk);
1143 if (!sony_wwan_rfkill) 1112 if (err) {
1144 return -1; 1113 rfkill_destroy(rfk);
1145 sony_wwan_rfkill->name = "sony-wwan"; 1114 return err;
1146 sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set;
1147 sony_wwan_rfkill->get_state = sony_nc_rfkill_get;
1148 sony_wwan_rfkill->data = (void *)SONY_WWAN;
1149 err = rfkill_register(sony_wwan_rfkill);
1150 if (err)
1151 rfkill_free(sony_wwan_rfkill);
1152 else {
1153 sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
1154 sony_nc_rfkill_set(sony_wwan_rfkill->data,
1155 RFKILL_STATE_UNBLOCKED);
1156 } 1115 }
1116 sony_rfkill_devices[nc_type] = rfk;
1117 sony_nc_rfkill_set((void *)nc_type, false);
1157 return err; 1118 return err;
1158} 1119}
1159 1120
1160static int sony_nc_setup_wimax_rfkill(struct acpi_device *device) 1121static void sony_nc_rfkill_update()
1161{ 1122{
1162 int err = 0; 1123 enum sony_nc_rfkill i;
1163 struct rfkill *sony_wimax_rfkill; 1124 int result;
1125 bool hwblock;
1164 1126
1165 sony_wimax_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WIMAX); 1127 sony_call_snc_handle(0x124, 0x200, &result);
1166 if (!sony_wimax_rfkill) 1128 hwblock = !(result & 0x1);
1167 return -1;
1168 sony_wimax_rfkill->name = "sony-wimax";
1169 sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set;
1170 sony_wimax_rfkill->get_state = sony_nc_rfkill_get;
1171 sony_wimax_rfkill->data = (void *)SONY_WIMAX;
1172 err = rfkill_register(sony_wimax_rfkill);
1173 if (err)
1174 rfkill_free(sony_wimax_rfkill);
1175 else {
1176 sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
1177 sony_nc_rfkill_set(sony_wimax_rfkill->data,
1178 RFKILL_STATE_UNBLOCKED);
1179 }
1180 return err;
1181}
1182 1129
1183static void sony_nc_rfkill_update() 1130 for (i = 0; i < N_SONY_RFKILL; i++) {
1184{ 1131 int argument = sony_rfkill_address[i];
1185 int i;
1186 enum rfkill_state state;
1187 1132
1188 for (i = 0; i < SONY_RFKILL_MAX; i++) { 1133 if (!sony_rfkill_devices[i])
1189 if (sony_rfkill_devices[i]) { 1134 continue;
1190 sony_rfkill_devices[i]-> 1135
1191 get_state(sony_rfkill_devices[i]->data, 1136 if (hwblock) {
1192 &state); 1137 if (rfkill_set_hw_state(sony_rfkill_devices[i], true))
1193 rfkill_force_state(sony_rfkill_devices[i], state); 1138 sony_nc_rfkill_set(sony_rfkill_devices[i],
1139 true);
1140 continue;
1194 } 1141 }
1142
1143 sony_call_snc_handle(0x124, argument, &result);
1144 rfkill_set_states(sony_rfkill_devices[i],
1145 !(result & 0xf), false);
1195 } 1146 }
1196} 1147}
1197 1148
@@ -1210,13 +1161,13 @@ static int sony_nc_rfkill_setup(struct acpi_device *device)
1210 } 1161 }
1211 1162
1212 if (result & 0x1) 1163 if (result & 0x1)
1213 sony_nc_setup_wifi_rfkill(device); 1164 sony_nc_setup_rfkill(device, SONY_WIFI);
1214 if (result & 0x2) 1165 if (result & 0x2)
1215 sony_nc_setup_bluetooth_rfkill(device); 1166 sony_nc_setup_rfkill(device, SONY_BLUETOOTH);
1216 if (result & 0x1c) 1167 if (result & 0x1c)
1217 sony_nc_setup_wwan_rfkill(device); 1168 sony_nc_setup_rfkill(device, SONY_WWAN);
1218 if (result & 0x20) 1169 if (result & 0x20)
1219 sony_nc_setup_wimax_rfkill(device); 1170 sony_nc_setup_rfkill(device, SONY_WIMAX);
1220 1171
1221 return 0; 1172 return 0;
1222} 1173}
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 912be65b6261..cfcafa4e9473 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -166,13 +166,6 @@ enum {
166 166
167#define TPACPI_MAX_ACPI_ARGS 3 167#define TPACPI_MAX_ACPI_ARGS 3
168 168
169/* rfkill switches */
170enum {
171 TPACPI_RFK_BLUETOOTH_SW_ID = 0,
172 TPACPI_RFK_WWAN_SW_ID,
173 TPACPI_RFK_UWB_SW_ID,
174};
175
176/* printk headers */ 169/* printk headers */
177#define TPACPI_LOG TPACPI_FILE ": " 170#define TPACPI_LOG TPACPI_FILE ": "
178#define TPACPI_EMERG KERN_EMERG TPACPI_LOG 171#define TPACPI_EMERG KERN_EMERG TPACPI_LOG
@@ -1005,67 +998,237 @@ static int __init tpacpi_check_std_acpi_brightness_support(void)
1005 return 0; 998 return 0;
1006} 999}
1007 1000
1008static int __init tpacpi_new_rfkill(const unsigned int id, 1001static void printk_deprecated_attribute(const char * const what,
1009 struct rfkill **rfk, 1002 const char * const details)
1003{
1004 tpacpi_log_usertask("deprecated sysfs attribute");
1005 printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
1006 "will be removed. %s\n",
1007 what, details);
1008}
1009
1010/*************************************************************************
1011 * rfkill and radio control support helpers
1012 */
1013
1014/*
1015 * ThinkPad-ACPI firmware handling model:
1016 *
1017 * WLSW (master wireless switch) is event-driven, and is common to all
1018 * firmware-controlled radios. It cannot be controlled, just monitored,
1019 * as expected. It overrides all radio state in firmware
1020 *
1021 * The kernel, a masked-off hotkey, and WLSW can change the radio state
1022 * (TODO: verify how WLSW interacts with the returned radio state).
1023 *
1024 * The only time there are shadow radio state changes, is when
1025 * masked-off hotkeys are used.
1026 */
1027
1028/*
1029 * Internal driver API for radio state:
1030 *
1031 * int: < 0 = error, otherwise enum tpacpi_rfkill_state
1032 * bool: true means radio blocked (off)
1033 */
1034enum tpacpi_rfkill_state {
1035 TPACPI_RFK_RADIO_OFF = 0,
1036 TPACPI_RFK_RADIO_ON
1037};
1038
1039/* rfkill switches */
1040enum tpacpi_rfk_id {
1041 TPACPI_RFK_BLUETOOTH_SW_ID = 0,
1042 TPACPI_RFK_WWAN_SW_ID,
1043 TPACPI_RFK_UWB_SW_ID,
1044 TPACPI_RFK_SW_MAX
1045};
1046
1047static const char *tpacpi_rfkill_names[] = {
1048 [TPACPI_RFK_BLUETOOTH_SW_ID] = "bluetooth",
1049 [TPACPI_RFK_WWAN_SW_ID] = "wwan",
1050 [TPACPI_RFK_UWB_SW_ID] = "uwb",
1051 [TPACPI_RFK_SW_MAX] = NULL
1052};
1053
1054/* ThinkPad-ACPI rfkill subdriver */
1055struct tpacpi_rfk {
1056 struct rfkill *rfkill;
1057 enum tpacpi_rfk_id id;
1058 const struct tpacpi_rfk_ops *ops;
1059};
1060
1061struct tpacpi_rfk_ops {
1062 /* firmware interface */
1063 int (*get_status)(void);
1064 int (*set_status)(const enum tpacpi_rfkill_state);
1065};
1066
1067static struct tpacpi_rfk *tpacpi_rfkill_switches[TPACPI_RFK_SW_MAX];
1068
1069/* Query FW and update rfkill sw state for a given rfkill switch */
1070static int tpacpi_rfk_update_swstate(const struct tpacpi_rfk *tp_rfk)
1071{
1072 int status;
1073
1074 if (!tp_rfk)
1075 return -ENODEV;
1076
1077 status = (tp_rfk->ops->get_status)();
1078 if (status < 0)
1079 return status;
1080
1081 rfkill_set_sw_state(tp_rfk->rfkill,
1082 (status == TPACPI_RFK_RADIO_OFF));
1083
1084 return status;
1085}
1086
1087/* Query FW and update rfkill sw state for all rfkill switches */
1088static void tpacpi_rfk_update_swstate_all(void)
1089{
1090 unsigned int i;
1091
1092 for (i = 0; i < TPACPI_RFK_SW_MAX; i++)
1093 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[i]);
1094}
1095
1096/*
1097 * Sync the HW-blocking state of all rfkill switches,
1098 * do notice it causes the rfkill core to schedule uevents
1099 */
1100static void tpacpi_rfk_update_hwblock_state(bool blocked)
1101{
1102 unsigned int i;
1103 struct tpacpi_rfk *tp_rfk;
1104
1105 for (i = 0; i < TPACPI_RFK_SW_MAX; i++) {
1106 tp_rfk = tpacpi_rfkill_switches[i];
1107 if (tp_rfk) {
1108 if (rfkill_set_hw_state(tp_rfk->rfkill,
1109 blocked)) {
1110 /* ignore -- we track sw block */
1111 }
1112 }
1113 }
1114}
1115
1116/* Call to get the WLSW state from the firmware */
1117static int hotkey_get_wlsw(void);
1118
1119/* Call to query WLSW state and update all rfkill switches */
1120static bool tpacpi_rfk_check_hwblock_state(void)
1121{
1122 int res = hotkey_get_wlsw();
1123 int hw_blocked;
1124
1125 /* When unknown or unsupported, we have to assume it is unblocked */
1126 if (res < 0)
1127 return false;
1128
1129 hw_blocked = (res == TPACPI_RFK_RADIO_OFF);
1130 tpacpi_rfk_update_hwblock_state(hw_blocked);
1131
1132 return hw_blocked;
1133}
1134
1135static int tpacpi_rfk_hook_set_block(void *data, bool blocked)
1136{
1137 struct tpacpi_rfk *tp_rfk = data;
1138 int res;
1139
1140 dbg_printk(TPACPI_DBG_RFKILL,
1141 "request to change radio state to %s\n",
1142 blocked ? "blocked" : "unblocked");
1143
1144 /* try to set radio state */
1145 res = (tp_rfk->ops->set_status)(blocked ?
1146 TPACPI_RFK_RADIO_OFF : TPACPI_RFK_RADIO_ON);
1147
1148 /* and update the rfkill core with whatever the FW really did */
1149 tpacpi_rfk_update_swstate(tp_rfk);
1150
1151 return (res < 0) ? res : 0;
1152}
1153
1154static const struct rfkill_ops tpacpi_rfk_rfkill_ops = {
1155 .set_block = tpacpi_rfk_hook_set_block,
1156};
1157
1158static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
1159 const struct tpacpi_rfk_ops *tp_rfkops,
1010 const enum rfkill_type rfktype, 1160 const enum rfkill_type rfktype,
1011 const char *name, 1161 const char *name,
1012 const bool set_default, 1162 const bool set_default)
1013 int (*toggle_radio)(void *, enum rfkill_state),
1014 int (*get_state)(void *, enum rfkill_state *))
1015{ 1163{
1164 struct tpacpi_rfk *atp_rfk;
1016 int res; 1165 int res;
1017 enum rfkill_state initial_state = RFKILL_STATE_SOFT_BLOCKED; 1166 bool initial_sw_state = false;
1167 int initial_sw_status;
1018 1168
1019 res = get_state(NULL, &initial_state); 1169 BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]);
1020 if (res < 0) { 1170
1171 initial_sw_status = (tp_rfkops->get_status)();
1172 if (initial_sw_status < 0) {
1021 printk(TPACPI_ERR 1173 printk(TPACPI_ERR
1022 "failed to read initial state for %s, error %d; " 1174 "failed to read initial state for %s, error %d; "
1023 "will turn radio off\n", name, res); 1175 "will turn radio off\n", name, initial_sw_status);
1024 } else if (set_default) { 1176 } else {
1025 /* try to set the initial state as the default for the rfkill 1177 initial_sw_state = (initial_sw_status == TPACPI_RFK_RADIO_OFF);
1026 * type, since we ask the firmware to preserve it across S5 in 1178 if (set_default) {
1027 * NVRAM */ 1179 /* try to set the initial state as the default for the
1028 if (rfkill_set_default(rfktype, 1180 * rfkill type, since we ask the firmware to preserve
1029 (initial_state == RFKILL_STATE_UNBLOCKED) ? 1181 * it across S5 in NVRAM */
1030 RFKILL_STATE_UNBLOCKED : 1182 rfkill_set_global_sw_state(rfktype, initial_sw_state);
1031 RFKILL_STATE_SOFT_BLOCKED) == -EPERM) 1183 }
1032 vdbg_printk(TPACPI_DBG_RFKILL, 1184 }
1033 "Default state for %s cannot be changed\n", 1185
1034 name); 1186 atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL);
1035 } 1187 if (atp_rfk)
1036 1188 atp_rfk->rfkill = rfkill_alloc(name,
1037 *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype); 1189 &tpacpi_pdev->dev,
1038 if (!*rfk) { 1190 rfktype,
1191 &tpacpi_rfk_rfkill_ops,
1192 atp_rfk);
1193 if (!atp_rfk || !atp_rfk->rfkill) {
1039 printk(TPACPI_ERR 1194 printk(TPACPI_ERR
1040 "failed to allocate memory for rfkill class\n"); 1195 "failed to allocate memory for rfkill class\n");
1196 kfree(atp_rfk);
1041 return -ENOMEM; 1197 return -ENOMEM;
1042 } 1198 }
1043 1199
1044 (*rfk)->name = name; 1200 atp_rfk->id = id;
1045 (*rfk)->get_state = get_state; 1201 atp_rfk->ops = tp_rfkops;
1046 (*rfk)->toggle_radio = toggle_radio; 1202
1047 (*rfk)->state = initial_state; 1203 rfkill_set_states(atp_rfk->rfkill, initial_sw_state,
1204 tpacpi_rfk_check_hwblock_state());
1048 1205
1049 res = rfkill_register(*rfk); 1206 res = rfkill_register(atp_rfk->rfkill);
1050 if (res < 0) { 1207 if (res < 0) {
1051 printk(TPACPI_ERR 1208 printk(TPACPI_ERR
1052 "failed to register %s rfkill switch: %d\n", 1209 "failed to register %s rfkill switch: %d\n",
1053 name, res); 1210 name, res);
1054 rfkill_free(*rfk); 1211 rfkill_destroy(atp_rfk->rfkill);
1055 *rfk = NULL; 1212 kfree(atp_rfk);
1056 return res; 1213 return res;
1057 } 1214 }
1058 1215
1216 tpacpi_rfkill_switches[id] = atp_rfk;
1059 return 0; 1217 return 0;
1060} 1218}
1061 1219
1062static void printk_deprecated_attribute(const char * const what, 1220static void tpacpi_destroy_rfkill(const enum tpacpi_rfk_id id)
1063 const char * const details)
1064{ 1221{
1065 tpacpi_log_usertask("deprecated sysfs attribute"); 1222 struct tpacpi_rfk *tp_rfk;
1066 printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and " 1223
1067 "will be removed. %s\n", 1224 BUG_ON(id >= TPACPI_RFK_SW_MAX);
1068 what, details); 1225
1226 tp_rfk = tpacpi_rfkill_switches[id];
1227 if (tp_rfk) {
1228 rfkill_unregister(tp_rfk->rfkill);
1229 tpacpi_rfkill_switches[id] = NULL;
1230 kfree(tp_rfk);
1231 }
1069} 1232}
1070 1233
1071static void printk_deprecated_rfkill_attribute(const char * const what) 1234static void printk_deprecated_rfkill_attribute(const char * const what)
@@ -1074,6 +1237,112 @@ static void printk_deprecated_rfkill_attribute(const char * const what)
1074 "Please switch to generic rfkill before year 2010"); 1237 "Please switch to generic rfkill before year 2010");
1075} 1238}
1076 1239
1240/* sysfs <radio> enable ------------------------------------------------ */
1241static ssize_t tpacpi_rfk_sysfs_enable_show(const enum tpacpi_rfk_id id,
1242 struct device_attribute *attr,
1243 char *buf)
1244{
1245 int status;
1246
1247 printk_deprecated_rfkill_attribute(attr->attr.name);
1248
1249 /* This is in the ABI... */
1250 if (tpacpi_rfk_check_hwblock_state()) {
1251 status = TPACPI_RFK_RADIO_OFF;
1252 } else {
1253 status = tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
1254 if (status < 0)
1255 return status;
1256 }
1257
1258 return snprintf(buf, PAGE_SIZE, "%d\n",
1259 (status == TPACPI_RFK_RADIO_ON) ? 1 : 0);
1260}
1261
1262static ssize_t tpacpi_rfk_sysfs_enable_store(const enum tpacpi_rfk_id id,
1263 struct device_attribute *attr,
1264 const char *buf, size_t count)
1265{
1266 unsigned long t;
1267 int res;
1268
1269 printk_deprecated_rfkill_attribute(attr->attr.name);
1270
1271 if (parse_strtoul(buf, 1, &t))
1272 return -EINVAL;
1273
1274 tpacpi_disclose_usertask(attr->attr.name, "set to %ld\n", t);
1275
1276 /* This is in the ABI... */
1277 if (tpacpi_rfk_check_hwblock_state() && !!t)
1278 return -EPERM;
1279
1280 res = tpacpi_rfkill_switches[id]->ops->set_status((!!t) ?
1281 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF);
1282 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
1283
1284 return (res < 0) ? res : count;
1285}
1286
1287/* procfs -------------------------------------------------------------- */
1288static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, char *p)
1289{
1290 int len = 0;
1291
1292 if (id >= TPACPI_RFK_SW_MAX)
1293 len += sprintf(p + len, "status:\t\tnot supported\n");
1294 else {
1295 int status;
1296
1297 /* This is in the ABI... */
1298 if (tpacpi_rfk_check_hwblock_state()) {
1299 status = TPACPI_RFK_RADIO_OFF;
1300 } else {
1301 status = tpacpi_rfk_update_swstate(
1302 tpacpi_rfkill_switches[id]);
1303 if (status < 0)
1304 return status;
1305 }
1306
1307 len += sprintf(p + len, "status:\t\t%s\n",
1308 (status == TPACPI_RFK_RADIO_ON) ?
1309 "enabled" : "disabled");
1310 len += sprintf(p + len, "commands:\tenable, disable\n");
1311 }
1312
1313 return len;
1314}
1315
1316static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf)
1317{
1318 char *cmd;
1319 int status = -1;
1320 int res = 0;
1321
1322 if (id >= TPACPI_RFK_SW_MAX)
1323 return -ENODEV;
1324
1325 while ((cmd = next_cmd(&buf))) {
1326 if (strlencmp(cmd, "enable") == 0)
1327 status = TPACPI_RFK_RADIO_ON;
1328 else if (strlencmp(cmd, "disable") == 0)
1329 status = TPACPI_RFK_RADIO_OFF;
1330 else
1331 return -EINVAL;
1332 }
1333
1334 if (status != -1) {
1335 tpacpi_disclose_usertask("procfs", "attempt to %s %s\n",
1336 (status == TPACPI_RFK_RADIO_ON) ?
1337 "enable" : "disable",
1338 tpacpi_rfkill_names[id]);
1339 res = (tpacpi_rfkill_switches[id]->ops->set_status)(status);
1340 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
1341 }
1342
1343 return res;
1344}
1345
1077/************************************************************************* 1346/*************************************************************************
1078 * thinkpad-acpi driver attributes 1347 * thinkpad-acpi driver attributes
1079 */ 1348 */
@@ -1127,8 +1396,6 @@ static DRIVER_ATTR(version, S_IRUGO,
1127 1396
1128#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 1397#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1129 1398
1130static void tpacpi_send_radiosw_update(void);
1131
1132/* wlsw_emulstate ------------------------------------------------------ */ 1399/* wlsw_emulstate ------------------------------------------------------ */
1133static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv, 1400static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv,
1134 char *buf) 1401 char *buf)
@@ -1144,11 +1411,10 @@ static ssize_t tpacpi_driver_wlsw_emulstate_store(struct device_driver *drv,
1144 if (parse_strtoul(buf, 1, &t)) 1411 if (parse_strtoul(buf, 1, &t))
1145 return -EINVAL; 1412 return -EINVAL;
1146 1413
1147 if (tpacpi_wlsw_emulstate != t) { 1414 if (tpacpi_wlsw_emulstate != !!t) {
1148 tpacpi_wlsw_emulstate = !!t;
1149 tpacpi_send_radiosw_update();
1150 } else
1151 tpacpi_wlsw_emulstate = !!t; 1415 tpacpi_wlsw_emulstate = !!t;
1416 tpacpi_rfk_update_hwblock_state(!t); /* negative logic */
1417 }
1152 1418
1153 return count; 1419 return count;
1154} 1420}
@@ -1463,17 +1729,23 @@ static struct attribute_set *hotkey_dev_attributes;
1463/* HKEY.MHKG() return bits */ 1729/* HKEY.MHKG() return bits */
1464#define TP_HOTKEY_TABLET_MASK (1 << 3) 1730#define TP_HOTKEY_TABLET_MASK (1 << 3)
1465 1731
1466static int hotkey_get_wlsw(int *status) 1732static int hotkey_get_wlsw(void)
1467{ 1733{
1734 int status;
1735
1736 if (!tp_features.hotkey_wlsw)
1737 return -ENODEV;
1738
1468#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 1739#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1469 if (dbg_wlswemul) { 1740 if (dbg_wlswemul)
1470 *status = !!tpacpi_wlsw_emulstate; 1741 return (tpacpi_wlsw_emulstate) ?
1471 return 0; 1742 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
1472 }
1473#endif 1743#endif
1474 if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) 1744
1745 if (!acpi_evalf(hkey_handle, &status, "WLSW", "d"))
1475 return -EIO; 1746 return -EIO;
1476 return 0; 1747
1748 return (status) ? TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
1477} 1749}
1478 1750
1479static int hotkey_get_tablet_mode(int *status) 1751static int hotkey_get_tablet_mode(int *status)
@@ -2107,12 +2379,16 @@ static ssize_t hotkey_radio_sw_show(struct device *dev,
2107 struct device_attribute *attr, 2379 struct device_attribute *attr,
2108 char *buf) 2380 char *buf)
2109{ 2381{
2110 int res, s; 2382 int res;
2111 res = hotkey_get_wlsw(&s); 2383 res = hotkey_get_wlsw();
2112 if (res < 0) 2384 if (res < 0)
2113 return res; 2385 return res;
2114 2386
2115 return snprintf(buf, PAGE_SIZE, "%d\n", !!s); 2387 /* Opportunistic update */
2388 tpacpi_rfk_update_hwblock_state((res == TPACPI_RFK_RADIO_OFF));
2389
2390 return snprintf(buf, PAGE_SIZE, "%d\n",
2391 (res == TPACPI_RFK_RADIO_OFF) ? 0 : 1);
2116} 2392}
2117 2393
2118static struct device_attribute dev_attr_hotkey_radio_sw = 2394static struct device_attribute dev_attr_hotkey_radio_sw =
@@ -2223,30 +2499,52 @@ static struct attribute *hotkey_mask_attributes[] __initdata = {
2223 &dev_attr_hotkey_wakeup_hotunplug_complete.attr, 2499 &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
2224}; 2500};
2225 2501
2226static void bluetooth_update_rfk(void); 2502/*
2227static void wan_update_rfk(void); 2503 * Sync both the hw and sw blocking state of all switches
2228static void uwb_update_rfk(void); 2504 */
2229static void tpacpi_send_radiosw_update(void) 2505static void tpacpi_send_radiosw_update(void)
2230{ 2506{
2231 int wlsw; 2507 int wlsw;
2232 2508
2233 /* Sync these BEFORE sending any rfkill events */ 2509 /*
2234 if (tp_features.bluetooth) 2510 * We must sync all rfkill controllers *before* issuing any
2235 bluetooth_update_rfk(); 2511 * rfkill input events, or we will race the rfkill core input
2236 if (tp_features.wan) 2512 * handler.
2237 wan_update_rfk(); 2513 *
2238 if (tp_features.uwb) 2514 * tpacpi_inputdev_send_mutex works as a syncronization point
2239 uwb_update_rfk(); 2515 * for the above.
2516 *
2517 * We optimize to avoid numerous calls to hotkey_get_wlsw.
2518 */
2240 2519
2241 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { 2520 wlsw = hotkey_get_wlsw();
2521
2522 /* Sync hw blocking state first if it is hw-blocked */
2523 if (wlsw == TPACPI_RFK_RADIO_OFF)
2524 tpacpi_rfk_update_hwblock_state(true);
2525
2526 /* Sync sw blocking state */
2527 tpacpi_rfk_update_swstate_all();
2528
2529 /* Sync hw blocking state last if it is hw-unblocked */
2530 if (wlsw == TPACPI_RFK_RADIO_ON)
2531 tpacpi_rfk_update_hwblock_state(false);
2532
2533 /* Issue rfkill input event for WLSW switch */
2534 if (!(wlsw < 0)) {
2242 mutex_lock(&tpacpi_inputdev_send_mutex); 2535 mutex_lock(&tpacpi_inputdev_send_mutex);
2243 2536
2244 input_report_switch(tpacpi_inputdev, 2537 input_report_switch(tpacpi_inputdev,
2245 SW_RFKILL_ALL, !!wlsw); 2538 SW_RFKILL_ALL, (wlsw > 0));
2246 input_sync(tpacpi_inputdev); 2539 input_sync(tpacpi_inputdev);
2247 2540
2248 mutex_unlock(&tpacpi_inputdev_send_mutex); 2541 mutex_unlock(&tpacpi_inputdev_send_mutex);
2249 } 2542 }
2543
2544 /*
2545 * this can be unconditional, as we will poll state again
2546 * if userspace uses the notify to read data
2547 */
2250 hotkey_radio_sw_notify_change(); 2548 hotkey_radio_sw_notify_change();
2251} 2549}
2252 2550
@@ -3056,8 +3354,6 @@ enum {
3056 3354
3057#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw" 3355#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
3058 3356
3059static struct rfkill *tpacpi_bluetooth_rfkill;
3060
3061static void bluetooth_suspend(pm_message_t state) 3357static void bluetooth_suspend(pm_message_t state)
3062{ 3358{
3063 /* Try to make sure radio will resume powered off */ 3359 /* Try to make sure radio will resume powered off */
@@ -3067,83 +3363,47 @@ static void bluetooth_suspend(pm_message_t state)
3067 "bluetooth power down on resume request failed\n"); 3363 "bluetooth power down on resume request failed\n");
3068} 3364}
3069 3365
3070static int bluetooth_get_radiosw(void) 3366static int bluetooth_get_status(void)
3071{ 3367{
3072 int status; 3368 int status;
3073 3369
3074 if (!tp_features.bluetooth)
3075 return -ENODEV;
3076
3077 /* WLSW overrides bluetooth in firmware/hardware, reflect that */
3078 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
3079 return RFKILL_STATE_HARD_BLOCKED;
3080
3081#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3370#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3082 if (dbg_bluetoothemul) 3371 if (dbg_bluetoothemul)
3083 return (tpacpi_bluetooth_emulstate) ? 3372 return (tpacpi_bluetooth_emulstate) ?
3084 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3373 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3085#endif 3374#endif
3086 3375
3087 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) 3376 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
3088 return -EIO; 3377 return -EIO;
3089 3378
3090 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ? 3379 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ?
3091 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3380 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3092} 3381}
3093 3382
3094static void bluetooth_update_rfk(void) 3383static int bluetooth_set_status(enum tpacpi_rfkill_state state)
3095{ 3384{
3096 int status; 3385 int status;
3097 3386
3098 if (!tpacpi_bluetooth_rfkill)
3099 return;
3100
3101 status = bluetooth_get_radiosw();
3102 if (status < 0)
3103 return;
3104 rfkill_force_state(tpacpi_bluetooth_rfkill, status);
3105
3106 vdbg_printk(TPACPI_DBG_RFKILL, 3387 vdbg_printk(TPACPI_DBG_RFKILL,
3107 "forced rfkill state to %d\n", 3388 "will attempt to %s bluetooth\n",
3108 status); 3389 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3109}
3110
3111static int bluetooth_set_radiosw(int radio_on, int update_rfk)
3112{
3113 int status;
3114
3115 if (!tp_features.bluetooth)
3116 return -ENODEV;
3117
3118 /* WLSW overrides bluetooth in firmware/hardware, but there is no
3119 * reason to risk weird behaviour. */
3120 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
3121 && radio_on)
3122 return -EPERM;
3123
3124 vdbg_printk(TPACPI_DBG_RFKILL,
3125 "will %s bluetooth\n", radio_on ? "enable" : "disable");
3126 3390
3127#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3391#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3128 if (dbg_bluetoothemul) { 3392 if (dbg_bluetoothemul) {
3129 tpacpi_bluetooth_emulstate = !!radio_on; 3393 tpacpi_bluetooth_emulstate = (state == TPACPI_RFK_RADIO_ON);
3130 if (update_rfk)
3131 bluetooth_update_rfk();
3132 return 0; 3394 return 0;
3133 } 3395 }
3134#endif 3396#endif
3135 3397
3136 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ 3398 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
3137 if (radio_on) 3399 if (state == TPACPI_RFK_RADIO_ON)
3138 status = TP_ACPI_BLUETOOTH_RADIOSSW; 3400 status = TP_ACPI_BLUETOOTH_RADIOSSW;
3139 else 3401 else
3140 status = 0; 3402 status = 0;
3403
3141 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) 3404 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
3142 return -EIO; 3405 return -EIO;
3143 3406
3144 if (update_rfk)
3145 bluetooth_update_rfk();
3146
3147 return 0; 3407 return 0;
3148} 3408}
3149 3409
@@ -3152,35 +3412,16 @@ static ssize_t bluetooth_enable_show(struct device *dev,
3152 struct device_attribute *attr, 3412 struct device_attribute *attr,
3153 char *buf) 3413 char *buf)
3154{ 3414{
3155 int status; 3415 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_BLUETOOTH_SW_ID,
3156 3416 attr, buf);
3157 printk_deprecated_rfkill_attribute("bluetooth_enable");
3158
3159 status = bluetooth_get_radiosw();
3160 if (status < 0)
3161 return status;
3162
3163 return snprintf(buf, PAGE_SIZE, "%d\n",
3164 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0);
3165} 3417}
3166 3418
3167static ssize_t bluetooth_enable_store(struct device *dev, 3419static ssize_t bluetooth_enable_store(struct device *dev,
3168 struct device_attribute *attr, 3420 struct device_attribute *attr,
3169 const char *buf, size_t count) 3421 const char *buf, size_t count)
3170{ 3422{
3171 unsigned long t; 3423 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_BLUETOOTH_SW_ID,
3172 int res; 3424 attr, buf, count);
3173
3174 printk_deprecated_rfkill_attribute("bluetooth_enable");
3175
3176 if (parse_strtoul(buf, 1, &t))
3177 return -EINVAL;
3178
3179 tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t);
3180
3181 res = bluetooth_set_radiosw(t, 1);
3182
3183 return (res) ? res : count;
3184} 3425}
3185 3426
3186static struct device_attribute dev_attr_bluetooth_enable = 3427static struct device_attribute dev_attr_bluetooth_enable =
@@ -3198,23 +3439,10 @@ static const struct attribute_group bluetooth_attr_group = {
3198 .attrs = bluetooth_attributes, 3439 .attrs = bluetooth_attributes,
3199}; 3440};
3200 3441
3201static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state) 3442static const struct tpacpi_rfk_ops bluetooth_tprfk_ops = {
3202{ 3443 .get_status = bluetooth_get_status,
3203 int bts = bluetooth_get_radiosw(); 3444 .set_status = bluetooth_set_status,
3204 3445};
3205 if (bts < 0)
3206 return bts;
3207
3208 *state = bts;
3209 return 0;
3210}
3211
3212static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
3213{
3214 dbg_printk(TPACPI_DBG_RFKILL,
3215 "request to change radio state to %d\n", state);
3216 return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3217}
3218 3446
3219static void bluetooth_shutdown(void) 3447static void bluetooth_shutdown(void)
3220{ 3448{
@@ -3230,13 +3458,12 @@ static void bluetooth_shutdown(void)
3230 3458
3231static void bluetooth_exit(void) 3459static void bluetooth_exit(void)
3232{ 3460{
3233 bluetooth_shutdown();
3234
3235 if (tpacpi_bluetooth_rfkill)
3236 rfkill_unregister(tpacpi_bluetooth_rfkill);
3237
3238 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 3461 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
3239 &bluetooth_attr_group); 3462 &bluetooth_attr_group);
3463
3464 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
3465
3466 bluetooth_shutdown();
3240} 3467}
3241 3468
3242static int __init bluetooth_init(struct ibm_init_struct *iibm) 3469static int __init bluetooth_init(struct ibm_init_struct *iibm)
@@ -3277,20 +3504,18 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
3277 if (!tp_features.bluetooth) 3504 if (!tp_features.bluetooth)
3278 return 1; 3505 return 1;
3279 3506
3280 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3281 &bluetooth_attr_group);
3282 if (res)
3283 return res;
3284
3285 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID, 3507 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
3286 &tpacpi_bluetooth_rfkill, 3508 &bluetooth_tprfk_ops,
3287 RFKILL_TYPE_BLUETOOTH, 3509 RFKILL_TYPE_BLUETOOTH,
3288 TPACPI_RFK_BLUETOOTH_SW_NAME, 3510 TPACPI_RFK_BLUETOOTH_SW_NAME,
3289 true, 3511 true);
3290 tpacpi_bluetooth_rfk_set, 3512 if (res)
3291 tpacpi_bluetooth_rfk_get); 3513 return res;
3514
3515 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3516 &bluetooth_attr_group);
3292 if (res) { 3517 if (res) {
3293 bluetooth_exit(); 3518 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
3294 return res; 3519 return res;
3295 } 3520 }
3296 3521
@@ -3300,46 +3525,12 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
3300/* procfs -------------------------------------------------------------- */ 3525/* procfs -------------------------------------------------------------- */
3301static int bluetooth_read(char *p) 3526static int bluetooth_read(char *p)
3302{ 3527{
3303 int len = 0; 3528 return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, p);
3304 int status = bluetooth_get_radiosw();
3305
3306 if (!tp_features.bluetooth)
3307 len += sprintf(p + len, "status:\t\tnot supported\n");
3308 else {
3309 len += sprintf(p + len, "status:\t\t%s\n",
3310 (status == RFKILL_STATE_UNBLOCKED) ?
3311 "enabled" : "disabled");
3312 len += sprintf(p + len, "commands:\tenable, disable\n");
3313 }
3314
3315 return len;
3316} 3529}
3317 3530
3318static int bluetooth_write(char *buf) 3531static int bluetooth_write(char *buf)
3319{ 3532{
3320 char *cmd; 3533 return tpacpi_rfk_procfs_write(TPACPI_RFK_BLUETOOTH_SW_ID, buf);
3321 int state = -1;
3322
3323 if (!tp_features.bluetooth)
3324 return -ENODEV;
3325
3326 while ((cmd = next_cmd(&buf))) {
3327 if (strlencmp(cmd, "enable") == 0) {
3328 state = 1;
3329 } else if (strlencmp(cmd, "disable") == 0) {
3330 state = 0;
3331 } else
3332 return -EINVAL;
3333 }
3334
3335 if (state != -1) {
3336 tpacpi_disclose_usertask("procfs bluetooth",
3337 "attempt to %s\n",
3338 state ? "enable" : "disable");
3339 bluetooth_set_radiosw(state, 1);
3340 }
3341
3342 return 0;
3343} 3534}
3344 3535
3345static struct ibm_struct bluetooth_driver_data = { 3536static struct ibm_struct bluetooth_driver_data = {
@@ -3365,8 +3556,6 @@ enum {
3365 3556
3366#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" 3557#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
3367 3558
3368static struct rfkill *tpacpi_wan_rfkill;
3369
3370static void wan_suspend(pm_message_t state) 3559static void wan_suspend(pm_message_t state)
3371{ 3560{
3372 /* Try to make sure radio will resume powered off */ 3561 /* Try to make sure radio will resume powered off */
@@ -3376,83 +3565,47 @@ static void wan_suspend(pm_message_t state)
3376 "WWAN power down on resume request failed\n"); 3565 "WWAN power down on resume request failed\n");
3377} 3566}
3378 3567
3379static int wan_get_radiosw(void) 3568static int wan_get_status(void)
3380{ 3569{
3381 int status; 3570 int status;
3382 3571
3383 if (!tp_features.wan)
3384 return -ENODEV;
3385
3386 /* WLSW overrides WWAN in firmware/hardware, reflect that */
3387 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
3388 return RFKILL_STATE_HARD_BLOCKED;
3389
3390#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3572#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3391 if (dbg_wwanemul) 3573 if (dbg_wwanemul)
3392 return (tpacpi_wwan_emulstate) ? 3574 return (tpacpi_wwan_emulstate) ?
3393 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3575 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3394#endif 3576#endif
3395 3577
3396 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) 3578 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
3397 return -EIO; 3579 return -EIO;
3398 3580
3399 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ? 3581 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ?
3400 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3582 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3401}
3402
3403static void wan_update_rfk(void)
3404{
3405 int status;
3406
3407 if (!tpacpi_wan_rfkill)
3408 return;
3409
3410 status = wan_get_radiosw();
3411 if (status < 0)
3412 return;
3413 rfkill_force_state(tpacpi_wan_rfkill, status);
3414
3415 vdbg_printk(TPACPI_DBG_RFKILL,
3416 "forced rfkill state to %d\n",
3417 status);
3418} 3583}
3419 3584
3420static int wan_set_radiosw(int radio_on, int update_rfk) 3585static int wan_set_status(enum tpacpi_rfkill_state state)
3421{ 3586{
3422 int status; 3587 int status;
3423 3588
3424 if (!tp_features.wan)
3425 return -ENODEV;
3426
3427 /* WLSW overrides bluetooth in firmware/hardware, but there is no
3428 * reason to risk weird behaviour. */
3429 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
3430 && radio_on)
3431 return -EPERM;
3432
3433 vdbg_printk(TPACPI_DBG_RFKILL, 3589 vdbg_printk(TPACPI_DBG_RFKILL,
3434 "will %s WWAN\n", radio_on ? "enable" : "disable"); 3590 "will attempt to %s wwan\n",
3591 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3435 3592
3436#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3593#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3437 if (dbg_wwanemul) { 3594 if (dbg_wwanemul) {
3438 tpacpi_wwan_emulstate = !!radio_on; 3595 tpacpi_wwan_emulstate = (state == TPACPI_RFK_RADIO_ON);
3439 if (update_rfk)
3440 wan_update_rfk();
3441 return 0; 3596 return 0;
3442 } 3597 }
3443#endif 3598#endif
3444 3599
3445 /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */ 3600 /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */
3446 if (radio_on) 3601 if (state == TPACPI_RFK_RADIO_ON)
3447 status = TP_ACPI_WANCARD_RADIOSSW; 3602 status = TP_ACPI_WANCARD_RADIOSSW;
3448 else 3603 else
3449 status = 0; 3604 status = 0;
3605
3450 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) 3606 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
3451 return -EIO; 3607 return -EIO;
3452 3608
3453 if (update_rfk)
3454 wan_update_rfk();
3455
3456 return 0; 3609 return 0;
3457} 3610}
3458 3611
@@ -3461,35 +3614,16 @@ static ssize_t wan_enable_show(struct device *dev,
3461 struct device_attribute *attr, 3614 struct device_attribute *attr,
3462 char *buf) 3615 char *buf)
3463{ 3616{
3464 int status; 3617 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_WWAN_SW_ID,
3465 3618 attr, buf);
3466 printk_deprecated_rfkill_attribute("wwan_enable");
3467
3468 status = wan_get_radiosw();
3469 if (status < 0)
3470 return status;
3471
3472 return snprintf(buf, PAGE_SIZE, "%d\n",
3473 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0);
3474} 3619}
3475 3620
3476static ssize_t wan_enable_store(struct device *dev, 3621static ssize_t wan_enable_store(struct device *dev,
3477 struct device_attribute *attr, 3622 struct device_attribute *attr,
3478 const char *buf, size_t count) 3623 const char *buf, size_t count)
3479{ 3624{
3480 unsigned long t; 3625 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_WWAN_SW_ID,
3481 int res; 3626 attr, buf, count);
3482
3483 printk_deprecated_rfkill_attribute("wwan_enable");
3484
3485 if (parse_strtoul(buf, 1, &t))
3486 return -EINVAL;
3487
3488 tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t);
3489
3490 res = wan_set_radiosw(t, 1);
3491
3492 return (res) ? res : count;
3493} 3627}
3494 3628
3495static struct device_attribute dev_attr_wan_enable = 3629static struct device_attribute dev_attr_wan_enable =
@@ -3507,23 +3641,10 @@ static const struct attribute_group wan_attr_group = {
3507 .attrs = wan_attributes, 3641 .attrs = wan_attributes,
3508}; 3642};
3509 3643
3510static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state) 3644static const struct tpacpi_rfk_ops wan_tprfk_ops = {
3511{ 3645 .get_status = wan_get_status,
3512 int wans = wan_get_radiosw(); 3646 .set_status = wan_set_status,
3513 3647};
3514 if (wans < 0)
3515 return wans;
3516
3517 *state = wans;
3518 return 0;
3519}
3520
3521static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
3522{
3523 dbg_printk(TPACPI_DBG_RFKILL,
3524 "request to change radio state to %d\n", state);
3525 return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3526}
3527 3648
3528static void wan_shutdown(void) 3649static void wan_shutdown(void)
3529{ 3650{
@@ -3539,13 +3660,12 @@ static void wan_shutdown(void)
3539 3660
3540static void wan_exit(void) 3661static void wan_exit(void)
3541{ 3662{
3542 wan_shutdown();
3543
3544 if (tpacpi_wan_rfkill)
3545 rfkill_unregister(tpacpi_wan_rfkill);
3546
3547 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 3663 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
3548 &wan_attr_group); 3664 &wan_attr_group);
3665
3666 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
3667
3668 wan_shutdown();
3549} 3669}
3550 3670
3551static int __init wan_init(struct ibm_init_struct *iibm) 3671static int __init wan_init(struct ibm_init_struct *iibm)
@@ -3584,20 +3704,19 @@ static int __init wan_init(struct ibm_init_struct *iibm)
3584 if (!tp_features.wan) 3704 if (!tp_features.wan)
3585 return 1; 3705 return 1;
3586 3706
3587 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3588 &wan_attr_group);
3589 if (res)
3590 return res;
3591
3592 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID, 3707 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
3593 &tpacpi_wan_rfkill, 3708 &wan_tprfk_ops,
3594 RFKILL_TYPE_WWAN, 3709 RFKILL_TYPE_WWAN,
3595 TPACPI_RFK_WWAN_SW_NAME, 3710 TPACPI_RFK_WWAN_SW_NAME,
3596 true, 3711 true);
3597 tpacpi_wan_rfk_set, 3712 if (res)
3598 tpacpi_wan_rfk_get); 3713 return res;
3714
3715 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3716 &wan_attr_group);
3717
3599 if (res) { 3718 if (res) {
3600 wan_exit(); 3719 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
3601 return res; 3720 return res;
3602 } 3721 }
3603 3722
@@ -3607,48 +3726,12 @@ static int __init wan_init(struct ibm_init_struct *iibm)
3607/* procfs -------------------------------------------------------------- */ 3726/* procfs -------------------------------------------------------------- */
3608static int wan_read(char *p) 3727static int wan_read(char *p)
3609{ 3728{
3610 int len = 0; 3729 return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, p);
3611 int status = wan_get_radiosw();
3612
3613 tpacpi_disclose_usertask("procfs wan", "read");
3614
3615 if (!tp_features.wan)
3616 len += sprintf(p + len, "status:\t\tnot supported\n");
3617 else {
3618 len += sprintf(p + len, "status:\t\t%s\n",
3619 (status == RFKILL_STATE_UNBLOCKED) ?
3620 "enabled" : "disabled");
3621 len += sprintf(p + len, "commands:\tenable, disable\n");
3622 }
3623
3624 return len;
3625} 3730}
3626 3731
3627static int wan_write(char *buf) 3732static int wan_write(char *buf)
3628{ 3733{
3629 char *cmd; 3734 return tpacpi_rfk_procfs_write(TPACPI_RFK_WWAN_SW_ID, buf);
3630 int state = -1;
3631
3632 if (!tp_features.wan)
3633 return -ENODEV;
3634
3635 while ((cmd = next_cmd(&buf))) {
3636 if (strlencmp(cmd, "enable") == 0) {
3637 state = 1;
3638 } else if (strlencmp(cmd, "disable") == 0) {
3639 state = 0;
3640 } else
3641 return -EINVAL;
3642 }
3643
3644 if (state != -1) {
3645 tpacpi_disclose_usertask("procfs wan",
3646 "attempt to %s\n",
3647 state ? "enable" : "disable");
3648 wan_set_radiosw(state, 1);
3649 }
3650
3651 return 0;
3652} 3735}
3653 3736
3654static struct ibm_struct wan_driver_data = { 3737static struct ibm_struct wan_driver_data = {
@@ -3672,108 +3755,59 @@ enum {
3672 3755
3673#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw" 3756#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw"
3674 3757
3675static struct rfkill *tpacpi_uwb_rfkill; 3758static int uwb_get_status(void)
3676
3677static int uwb_get_radiosw(void)
3678{ 3759{
3679 int status; 3760 int status;
3680 3761
3681 if (!tp_features.uwb)
3682 return -ENODEV;
3683
3684 /* WLSW overrides UWB in firmware/hardware, reflect that */
3685 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
3686 return RFKILL_STATE_HARD_BLOCKED;
3687
3688#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3762#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3689 if (dbg_uwbemul) 3763 if (dbg_uwbemul)
3690 return (tpacpi_uwb_emulstate) ? 3764 return (tpacpi_uwb_emulstate) ?
3691 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3765 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3692#endif 3766#endif
3693 3767
3694 if (!acpi_evalf(hkey_handle, &status, "GUWB", "d")) 3768 if (!acpi_evalf(hkey_handle, &status, "GUWB", "d"))
3695 return -EIO; 3769 return -EIO;
3696 3770
3697 return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ? 3771 return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ?
3698 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3772 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3699} 3773}
3700 3774
3701static void uwb_update_rfk(void) 3775static int uwb_set_status(enum tpacpi_rfkill_state state)
3702{ 3776{
3703 int status; 3777 int status;
3704 3778
3705 if (!tpacpi_uwb_rfkill)
3706 return;
3707
3708 status = uwb_get_radiosw();
3709 if (status < 0)
3710 return;
3711 rfkill_force_state(tpacpi_uwb_rfkill, status);
3712
3713 vdbg_printk(TPACPI_DBG_RFKILL, 3779 vdbg_printk(TPACPI_DBG_RFKILL,
3714 "forced rfkill state to %d\n", 3780 "will attempt to %s UWB\n",
3715 status); 3781 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3716}
3717
3718static int uwb_set_radiosw(int radio_on, int update_rfk)
3719{
3720 int status;
3721
3722 if (!tp_features.uwb)
3723 return -ENODEV;
3724
3725 /* WLSW overrides UWB in firmware/hardware, but there is no
3726 * reason to risk weird behaviour. */
3727 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
3728 && radio_on)
3729 return -EPERM;
3730
3731 vdbg_printk(TPACPI_DBG_RFKILL,
3732 "will %s UWB\n", radio_on ? "enable" : "disable");
3733 3782
3734#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3783#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3735 if (dbg_uwbemul) { 3784 if (dbg_uwbemul) {
3736 tpacpi_uwb_emulstate = !!radio_on; 3785 tpacpi_uwb_emulstate = (state == TPACPI_RFK_RADIO_ON);
3737 if (update_rfk)
3738 uwb_update_rfk();
3739 return 0; 3786 return 0;
3740 } 3787 }
3741#endif 3788#endif
3742 3789
3743 status = (radio_on) ? TP_ACPI_UWB_RADIOSSW : 0; 3790 if (state == TPACPI_RFK_RADIO_ON)
3791 status = TP_ACPI_UWB_RADIOSSW;
3792 else
3793 status = 0;
3794
3744 if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status)) 3795 if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status))
3745 return -EIO; 3796 return -EIO;
3746 3797
3747 if (update_rfk)
3748 uwb_update_rfk();
3749
3750 return 0; 3798 return 0;
3751} 3799}
3752 3800
3753/* --------------------------------------------------------------------- */ 3801/* --------------------------------------------------------------------- */
3754 3802
3755static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state) 3803static const struct tpacpi_rfk_ops uwb_tprfk_ops = {
3756{ 3804 .get_status = uwb_get_status,
3757 int uwbs = uwb_get_radiosw(); 3805 .set_status = uwb_set_status,
3758 3806};
3759 if (uwbs < 0)
3760 return uwbs;
3761
3762 *state = uwbs;
3763 return 0;
3764}
3765
3766static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
3767{
3768 dbg_printk(TPACPI_DBG_RFKILL,
3769 "request to change radio state to %d\n", state);
3770 return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3771}
3772 3807
3773static void uwb_exit(void) 3808static void uwb_exit(void)
3774{ 3809{
3775 if (tpacpi_uwb_rfkill) 3810 tpacpi_destroy_rfkill(TPACPI_RFK_UWB_SW_ID);
3776 rfkill_unregister(tpacpi_uwb_rfkill);
3777} 3811}
3778 3812
3779static int __init uwb_init(struct ibm_init_struct *iibm) 3813static int __init uwb_init(struct ibm_init_struct *iibm)
@@ -3813,13 +3847,10 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
3813 return 1; 3847 return 1;
3814 3848
3815 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID, 3849 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
3816 &tpacpi_uwb_rfkill, 3850 &uwb_tprfk_ops,
3817 RFKILL_TYPE_UWB, 3851 RFKILL_TYPE_UWB,
3818 TPACPI_RFK_UWB_SW_NAME, 3852 TPACPI_RFK_UWB_SW_NAME,
3819 false, 3853 false);
3820 tpacpi_uwb_rfk_set,
3821 tpacpi_uwb_rfk_get);
3822
3823 return res; 3854 return res;
3824} 3855}
3825 3856
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 4345089f5171..81d31ea507d1 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -45,7 +45,6 @@
45#include <linux/backlight.h> 45#include <linux/backlight.h>
46#include <linux/platform_device.h> 46#include <linux/platform_device.h>
47#include <linux/rfkill.h> 47#include <linux/rfkill.h>
48#include <linux/input-polldev.h>
49 48
50#include <asm/uaccess.h> 49#include <asm/uaccess.h>
51 50
@@ -250,21 +249,15 @@ static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result)
250 249
251struct toshiba_acpi_dev { 250struct toshiba_acpi_dev {
252 struct platform_device *p_dev; 251 struct platform_device *p_dev;
253 struct rfkill *rfk_dev; 252 struct rfkill *bt_rfk;
254 struct input_polled_dev *poll_dev;
255 253
256 const char *bt_name; 254 const char *bt_name;
257 const char *rfk_name;
258
259 bool last_rfk_state;
260 255
261 struct mutex mutex; 256 struct mutex mutex;
262}; 257};
263 258
264static struct toshiba_acpi_dev toshiba_acpi = { 259static struct toshiba_acpi_dev toshiba_acpi = {
265 .bt_name = "Toshiba Bluetooth", 260 .bt_name = "Toshiba Bluetooth",
266 .rfk_name = "Toshiba RFKill Switch",
267 .last_rfk_state = false,
268}; 261};
269 262
270/* Bluetooth rfkill handlers */ 263/* Bluetooth rfkill handlers */
@@ -283,21 +276,6 @@ static u32 hci_get_bt_present(bool *present)
283 return hci_result; 276 return hci_result;
284} 277}
285 278
286static u32 hci_get_bt_on(bool *on)
287{
288 u32 hci_result;
289 u32 value, value2;
290
291 value = 0;
292 value2 = 0x0001;
293 hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
294 if (hci_result == HCI_SUCCESS)
295 *on = (value & HCI_WIRELESS_BT_POWER) &&
296 (value & HCI_WIRELESS_BT_ATTACH);
297
298 return hci_result;
299}
300
301static u32 hci_get_radio_state(bool *radio_state) 279static u32 hci_get_radio_state(bool *radio_state)
302{ 280{
303 u32 hci_result; 281 u32 hci_result;
@@ -311,70 +289,67 @@ static u32 hci_get_radio_state(bool *radio_state)
311 return hci_result; 289 return hci_result;
312} 290}
313 291
314static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state) 292static int bt_rfkill_set_block(void *data, bool blocked)
315{ 293{
294 struct toshiba_acpi_dev *dev = data;
316 u32 result1, result2; 295 u32 result1, result2;
317 u32 value; 296 u32 value;
297 int err;
318 bool radio_state; 298 bool radio_state;
319 struct toshiba_acpi_dev *dev = data;
320 299
321 value = (state == RFKILL_STATE_UNBLOCKED); 300 value = (blocked == false);
322 301
323 if (hci_get_radio_state(&radio_state) != HCI_SUCCESS) 302 mutex_lock(&dev->mutex);
324 return -EFAULT; 303 if (hci_get_radio_state(&radio_state) != HCI_SUCCESS) {
304 err = -EBUSY;
305 goto out;
306 }
325 307
326 switch (state) { 308 if (!radio_state) {
327 case RFKILL_STATE_UNBLOCKED: 309 err = 0;
328 if (!radio_state) 310 goto out;
329 return -EPERM;
330 break;
331 case RFKILL_STATE_SOFT_BLOCKED:
332 break;
333 default:
334 return -EINVAL;
335 } 311 }
336 312
337 mutex_lock(&dev->mutex);
338 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1); 313 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1);
339 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2); 314 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2);
340 mutex_unlock(&dev->mutex);
341 315
342 if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS) 316 if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS)
343 return -EFAULT; 317 err = -EBUSY;
344 318 else
345 return 0; 319 err = 0;
320 out:
321 mutex_unlock(&dev->mutex);
322 return err;
346} 323}
347 324
348static void bt_poll_rfkill(struct input_polled_dev *poll_dev) 325static void bt_rfkill_poll(struct rfkill *rfkill, void *data)
349{ 326{
350 bool state_changed;
351 bool new_rfk_state; 327 bool new_rfk_state;
352 bool value; 328 bool value;
353 u32 hci_result; 329 u32 hci_result;
354 struct toshiba_acpi_dev *dev = poll_dev->private; 330 struct toshiba_acpi_dev *dev = data;
331
332 mutex_lock(&dev->mutex);
355 333
356 hci_result = hci_get_radio_state(&value); 334 hci_result = hci_get_radio_state(&value);
357 if (hci_result != HCI_SUCCESS) 335 if (hci_result != HCI_SUCCESS) {
358 return; /* Can't do anything useful */ 336 /* Can't do anything useful */
337 mutex_unlock(&dev->mutex);
338 }
359 339
360 new_rfk_state = value; 340 new_rfk_state = value;
361 341
362 mutex_lock(&dev->mutex);
363 state_changed = new_rfk_state != dev->last_rfk_state;
364 dev->last_rfk_state = new_rfk_state;
365 mutex_unlock(&dev->mutex); 342 mutex_unlock(&dev->mutex);
366 343
367 if (unlikely(state_changed)) { 344 if (rfkill_set_hw_state(rfkill, !new_rfk_state))
368 rfkill_force_state(dev->rfk_dev, 345 bt_rfkill_set_block(data, true);
369 new_rfk_state ?
370 RFKILL_STATE_SOFT_BLOCKED :
371 RFKILL_STATE_HARD_BLOCKED);
372 input_report_switch(poll_dev->input, SW_RFKILL_ALL,
373 new_rfk_state);
374 input_sync(poll_dev->input);
375 }
376} 346}
377 347
348static const struct rfkill_ops toshiba_rfk_ops = {
349 .set_block = bt_rfkill_set_block,
350 .poll = bt_rfkill_poll,
351};
352
378static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; 353static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
379static struct backlight_device *toshiba_backlight_device; 354static struct backlight_device *toshiba_backlight_device;
380static int force_fan; 355static int force_fan;
@@ -702,14 +677,11 @@ static struct backlight_ops toshiba_backlight_data = {
702 677
703static void toshiba_acpi_exit(void) 678static void toshiba_acpi_exit(void)
704{ 679{
705 if (toshiba_acpi.poll_dev) { 680 if (toshiba_acpi.bt_rfk) {
706 input_unregister_polled_device(toshiba_acpi.poll_dev); 681 rfkill_unregister(toshiba_acpi.bt_rfk);
707 input_free_polled_device(toshiba_acpi.poll_dev); 682 rfkill_destroy(toshiba_acpi.bt_rfk);
708 } 683 }
709 684
710 if (toshiba_acpi.rfk_dev)
711 rfkill_unregister(toshiba_acpi.rfk_dev);
712
713 if (toshiba_backlight_device) 685 if (toshiba_backlight_device)
714 backlight_device_unregister(toshiba_backlight_device); 686 backlight_device_unregister(toshiba_backlight_device);
715 687
@@ -728,8 +700,6 @@ static int __init toshiba_acpi_init(void)
728 acpi_status status = AE_OK; 700 acpi_status status = AE_OK;
729 u32 hci_result; 701 u32 hci_result;
730 bool bt_present; 702 bool bt_present;
731 bool bt_on;
732 bool radio_on;
733 int ret = 0; 703 int ret = 0;
734 704
735 if (acpi_disabled) 705 if (acpi_disabled)
@@ -793,60 +763,21 @@ static int __init toshiba_acpi_init(void)
793 763
794 /* Register rfkill switch for Bluetooth */ 764 /* Register rfkill switch for Bluetooth */
795 if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) { 765 if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {
796 toshiba_acpi.rfk_dev = rfkill_allocate(&toshiba_acpi.p_dev->dev, 766 toshiba_acpi.bt_rfk = rfkill_alloc(toshiba_acpi.bt_name,
797 RFKILL_TYPE_BLUETOOTH); 767 &toshiba_acpi.p_dev->dev,
798 if (!toshiba_acpi.rfk_dev) { 768 RFKILL_TYPE_BLUETOOTH,
769 &toshiba_rfk_ops,
770 &toshiba_acpi);
771 if (!toshiba_acpi.bt_rfk) {
799 printk(MY_ERR "unable to allocate rfkill device\n"); 772 printk(MY_ERR "unable to allocate rfkill device\n");
800 toshiba_acpi_exit(); 773 toshiba_acpi_exit();
801 return -ENOMEM; 774 return -ENOMEM;
802 } 775 }
803 776
804 toshiba_acpi.rfk_dev->name = toshiba_acpi.bt_name; 777 ret = rfkill_register(toshiba_acpi.bt_rfk);
805 toshiba_acpi.rfk_dev->toggle_radio = bt_rfkill_toggle_radio;
806 toshiba_acpi.rfk_dev->data = &toshiba_acpi;
807
808 if (hci_get_bt_on(&bt_on) == HCI_SUCCESS && bt_on) {
809 toshiba_acpi.rfk_dev->state = RFKILL_STATE_UNBLOCKED;
810 } else if (hci_get_radio_state(&radio_on) == HCI_SUCCESS &&
811 radio_on) {
812 toshiba_acpi.rfk_dev->state = RFKILL_STATE_SOFT_BLOCKED;
813 } else {
814 toshiba_acpi.rfk_dev->state = RFKILL_STATE_HARD_BLOCKED;
815 }
816
817 ret = rfkill_register(toshiba_acpi.rfk_dev);
818 if (ret) { 778 if (ret) {
819 printk(MY_ERR "unable to register rfkill device\n"); 779 printk(MY_ERR "unable to register rfkill device\n");
820 toshiba_acpi_exit(); 780 rfkill_destroy(toshiba_acpi.bt_rfk);
821 return -ENOMEM;
822 }
823
824 /* Register input device for kill switch */
825 toshiba_acpi.poll_dev = input_allocate_polled_device();
826 if (!toshiba_acpi.poll_dev) {
827 printk(MY_ERR
828 "unable to allocate kill-switch input device\n");
829 toshiba_acpi_exit();
830 return -ENOMEM;
831 }
832 toshiba_acpi.poll_dev->private = &toshiba_acpi;
833 toshiba_acpi.poll_dev->poll = bt_poll_rfkill;
834 toshiba_acpi.poll_dev->poll_interval = 1000; /* msecs */
835
836 toshiba_acpi.poll_dev->input->name = toshiba_acpi.rfk_name;
837 toshiba_acpi.poll_dev->input->id.bustype = BUS_HOST;
838 /* Toshiba USB ID */
839 toshiba_acpi.poll_dev->input->id.vendor = 0x0930;
840 set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit);
841 set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit);
842 input_report_switch(toshiba_acpi.poll_dev->input,
843 SW_RFKILL_ALL, TRUE);
844 input_sync(toshiba_acpi.poll_dev->input);
845
846 ret = input_register_polled_device(toshiba_acpi.poll_dev);
847 if (ret) {
848 printk(MY_ERR
849 "unable to register kill-switch input device\n");
850 toshiba_acpi_exit(); 781 toshiba_acpi_exit();
851 return ret; 782 return ret;
852 } 783 }
diff --git a/include/asm-generic/errno.h b/include/asm-generic/errno.h
index e8852c092fea..28cc03bf19e6 100644
--- a/include/asm-generic/errno.h
+++ b/include/asm-generic/errno.h
@@ -106,4 +106,6 @@
106#define EOWNERDEAD 130 /* Owner died */ 106#define EOWNERDEAD 130 /* Owner died */
107#define ENOTRECOVERABLE 131 /* State not recoverable */ 107#define ENOTRECOVERABLE 131 /* State not recoverable */
108 108
109#define ERFKILL 132 /* Operation not possible due to RF-kill */
110
109#endif 111#endif
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 3f0eaa397ef5..7e09c5c1ed02 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -311,6 +311,7 @@ unifdef-y += ptrace.h
311unifdef-y += qnx4_fs.h 311unifdef-y += qnx4_fs.h
312unifdef-y += quota.h 312unifdef-y += quota.h
313unifdef-y += random.h 313unifdef-y += random.h
314unifdef-y += rfkill.h
314unifdef-y += irqnr.h 315unifdef-y += irqnr.h
315unifdef-y += reboot.h 316unifdef-y += reboot.h
316unifdef-y += reiserfs_fs.h 317unifdef-y += reiserfs_fs.h
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 34de8b21f6d4..a9173d5434d1 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1092,6 +1092,7 @@ enum ieee80211_key_len {
1092 WLAN_KEY_LEN_WEP104 = 13, 1092 WLAN_KEY_LEN_WEP104 = 13,
1093 WLAN_KEY_LEN_CCMP = 16, 1093 WLAN_KEY_LEN_CCMP = 16,
1094 WLAN_KEY_LEN_TKIP = 32, 1094 WLAN_KEY_LEN_TKIP = 32,
1095 WLAN_KEY_LEN_AES_CMAC = 16,
1095}; 1096};
1096 1097
1097/* 1098/*
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index b86fa2ffca0c..81bc252dc8ac 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -198,6 +198,7 @@ static inline int notifier_to_errno(int ret)
198#define NETDEV_CHANGENAME 0x000A 198#define NETDEV_CHANGENAME 0x000A
199#define NETDEV_FEAT_CHANGE 0x000B 199#define NETDEV_FEAT_CHANGE 0x000B
200#define NETDEV_BONDING_FAILOVER 0x000C 200#define NETDEV_BONDING_FAILOVER 0x000C
201#define NETDEV_PRE_UP 0x000D
201 202
202#define SYS_DOWN 0x0001 /* Notify of system down */ 203#define SYS_DOWN 0x0001 /* Notify of system down */
203#define SYS_RESTART SYS_DOWN 204#define SYS_RESTART SYS_DOWN
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index de18ef227e00..ee3eddea8568 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -4,6 +4,7 @@
4/* 4/*
5 * Copyright (C) 2006 - 2007 Ivo van Doorn 5 * Copyright (C) 2006 - 2007 Ivo van Doorn
6 * Copyright (C) 2007 Dmitry Torokhov 6 * Copyright (C) 2007 Dmitry Torokhov
7 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -22,117 +23,341 @@
22 */ 23 */
23 24
24#include <linux/types.h> 25#include <linux/types.h>
25#include <linux/kernel.h> 26
26#include <linux/list.h> 27/* define userspace visible states */
27#include <linux/mutex.h> 28#define RFKILL_STATE_SOFT_BLOCKED 0
28#include <linux/device.h> 29#define RFKILL_STATE_UNBLOCKED 1
29#include <linux/leds.h> 30#define RFKILL_STATE_HARD_BLOCKED 2
30 31
31/** 32/**
32 * enum rfkill_type - type of rfkill switch. 33 * enum rfkill_type - type of rfkill switch.
33 * RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device. 34 *
34 * RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device. 35 * @RFKILL_TYPE_ALL: toggles all switches (userspace only)
35 * RFKILL_TYPE_UWB: switch is on a ultra wideband device. 36 * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
36 * RFKILL_TYPE_WIMAX: switch is on a WiMAX device. 37 * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
37 * RFKILL_TYPE_WWAN: switch is on a wireless WAN device. 38 * @RFKILL_TYPE_UWB: switch is on a ultra wideband device.
39 * @RFKILL_TYPE_WIMAX: switch is on a WiMAX device.
40 * @RFKILL_TYPE_WWAN: switch is on a wireless WAN device.
41 * @NUM_RFKILL_TYPES: number of defined rfkill types
38 */ 42 */
39enum rfkill_type { 43enum rfkill_type {
40 RFKILL_TYPE_WLAN , 44 RFKILL_TYPE_ALL = 0,
45 RFKILL_TYPE_WLAN,
41 RFKILL_TYPE_BLUETOOTH, 46 RFKILL_TYPE_BLUETOOTH,
42 RFKILL_TYPE_UWB, 47 RFKILL_TYPE_UWB,
43 RFKILL_TYPE_WIMAX, 48 RFKILL_TYPE_WIMAX,
44 RFKILL_TYPE_WWAN, 49 RFKILL_TYPE_WWAN,
45 RFKILL_TYPE_MAX, 50 NUM_RFKILL_TYPES,
46}; 51};
47 52
48enum rfkill_state { 53/**
49 RFKILL_STATE_SOFT_BLOCKED = 0, /* Radio output blocked */ 54 * enum rfkill_operation - operation types
50 RFKILL_STATE_UNBLOCKED = 1, /* Radio output allowed */ 55 * @RFKILL_OP_ADD: a device was added
51 RFKILL_STATE_HARD_BLOCKED = 2, /* Output blocked, non-overrideable */ 56 * @RFKILL_OP_DEL: a device was removed
52 RFKILL_STATE_MAX, /* marker for last valid state */ 57 * @RFKILL_OP_CHANGE: a device's state changed -- userspace changes one device
58 * @RFKILL_OP_CHANGE_ALL: userspace changes all devices (of a type, or all)
59 */
60enum rfkill_operation {
61 RFKILL_OP_ADD = 0,
62 RFKILL_OP_DEL,
63 RFKILL_OP_CHANGE,
64 RFKILL_OP_CHANGE_ALL,
53}; 65};
54 66
55/** 67/**
56 * struct rfkill - rfkill control structure. 68 * struct rfkill_event - events for userspace on /dev/rfkill
57 * @name: Name of the switch. 69 * @idx: index of dev rfkill
58 * @type: Radio type which the button controls, the value stored 70 * @type: type of the rfkill struct
59 * here should be a value from enum rfkill_type. 71 * @op: operation code
60 * @state: State of the switch, "UNBLOCKED" means radio can operate. 72 * @hard: hard state (0/1)
61 * @mutex: Guards switch state transitions. It serializes callbacks 73 * @soft: soft state (0/1)
62 * and also protects the state. 74 *
63 * @data: Pointer to the RF button drivers private data which will be 75 * Structure used for userspace communication on /dev/rfkill,
64 * passed along when toggling radio state. 76 * used for events from the kernel and control to the kernel.
65 * @toggle_radio(): Mandatory handler to control state of the radio. 77 */
66 * only RFKILL_STATE_SOFT_BLOCKED and RFKILL_STATE_UNBLOCKED are 78struct rfkill_event {
67 * valid parameters. 79 __u32 idx;
68 * @get_state(): handler to read current radio state from hardware, 80 __u8 type;
69 * may be called from atomic context, should return 0 on success. 81 __u8 op;
70 * Either this handler OR judicious use of rfkill_force_state() is 82 __u8 soft, hard;
71 * MANDATORY for any driver capable of RFKILL_STATE_HARD_BLOCKED. 83} __packed;
72 * @led_trigger: A LED trigger for this button's LED.
73 * @dev: Device structure integrating the switch into device tree.
74 * @node: Used to place switch into list of all switches known to the
75 * the system.
76 *
77 * This structure represents a RF switch located on a network device.
78 */
79struct rfkill {
80 const char *name;
81 enum rfkill_type type;
82
83 /* the mutex serializes callbacks and also protects
84 * the state */
85 struct mutex mutex;
86 enum rfkill_state state;
87 void *data;
88 int (*toggle_radio)(void *data, enum rfkill_state state);
89 int (*get_state)(void *data, enum rfkill_state *state);
90 84
91#ifdef CONFIG_RFKILL_LEDS 85/* ioctl for turning off rfkill-input (if present) */
92 struct led_trigger led_trigger; 86#define RFKILL_IOC_MAGIC 'R'
93#endif 87#define RFKILL_IOC_NOINPUT 1
88#define RFKILL_IOCTL_NOINPUT _IO(RFKILL_IOC_MAGIC, RFKILL_IOC_NOINPUT)
94 89
95 struct device dev; 90/* and that's all userspace gets */
96 struct list_head node; 91#ifdef __KERNEL__
97 enum rfkill_state state_for_resume; 92/* don't allow anyone to use these in the kernel */
93enum rfkill_user_states {
94 RFKILL_USER_STATE_SOFT_BLOCKED = RFKILL_STATE_SOFT_BLOCKED,
95 RFKILL_USER_STATE_UNBLOCKED = RFKILL_STATE_UNBLOCKED,
96 RFKILL_USER_STATE_HARD_BLOCKED = RFKILL_STATE_HARD_BLOCKED,
98}; 97};
99#define to_rfkill(d) container_of(d, struct rfkill, dev) 98#undef RFKILL_STATE_SOFT_BLOCKED
99#undef RFKILL_STATE_UNBLOCKED
100#undef RFKILL_STATE_HARD_BLOCKED
101
102#include <linux/types.h>
103#include <linux/kernel.h>
104#include <linux/list.h>
105#include <linux/mutex.h>
106#include <linux/device.h>
107#include <linux/leds.h>
108
109/* this is opaque */
110struct rfkill;
111
112/**
113 * struct rfkill_ops - rfkill driver methods
114 *
115 * @poll: poll the rfkill block state(s) -- only assign this method
116 * when you need polling. When called, simply call one of the
117 * rfkill_set{,_hw,_sw}_state family of functions. If the hw
118 * is getting unblocked you need to take into account the return
119 * value of those functions to make sure the software block is
120 * properly used.
121 * @query: query the rfkill block state(s) and call exactly one of the
122 * rfkill_set{,_hw,_sw}_state family of functions. Assign this
123 * method if input events can cause hardware state changes to make
124 * the rfkill core query your driver before setting a requested
125 * block.
126 * @set_block: turn the transmitter on (blocked == false) or off
127 * (blocked == true) -- ignore and return 0 when hard blocked.
128 * This callback must be assigned.
129 */
130struct rfkill_ops {
131 void (*poll)(struct rfkill *rfkill, void *data);
132 void (*query)(struct rfkill *rfkill, void *data);
133 int (*set_block)(void *data, bool blocked);
134};
135
136#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
137/**
138 * rfkill_alloc - allocate rfkill structure
139 * @name: name of the struct -- the string is not copied internally
140 * @parent: device that has rf switch on it
141 * @type: type of the switch (RFKILL_TYPE_*)
142 * @ops: rfkill methods
143 * @ops_data: data passed to each method
144 *
145 * This function should be called by the transmitter driver to allocate an
146 * rfkill structure. Returns %NULL on failure.
147 */
148struct rfkill * __must_check rfkill_alloc(const char *name,
149 struct device *parent,
150 const enum rfkill_type type,
151 const struct rfkill_ops *ops,
152 void *ops_data);
100 153
101struct rfkill * __must_check rfkill_allocate(struct device *parent, 154/**
102 enum rfkill_type type); 155 * rfkill_register - Register a rfkill structure.
103void rfkill_free(struct rfkill *rfkill); 156 * @rfkill: rfkill structure to be registered
157 *
158 * This function should be called by the transmitter driver to register
159 * the rfkill structure needs to be registered. Before calling this function
160 * the driver needs to be ready to service method calls from rfkill.
161 */
104int __must_check rfkill_register(struct rfkill *rfkill); 162int __must_check rfkill_register(struct rfkill *rfkill);
163
164/**
165 * rfkill_pause_polling(struct rfkill *rfkill)
166 *
167 * Pause polling -- say transmitter is off for other reasons.
168 * NOTE: not necessary for suspend/resume -- in that case the
169 * core stops polling anyway
170 */
171void rfkill_pause_polling(struct rfkill *rfkill);
172
173/**
174 * rfkill_resume_polling(struct rfkill *rfkill)
175 *
176 * Pause polling -- say transmitter is off for other reasons.
177 * NOTE: not necessary for suspend/resume -- in that case the
178 * core stops polling anyway
179 */
180void rfkill_resume_polling(struct rfkill *rfkill);
181
182
183/**
184 * rfkill_unregister - Unregister a rfkill structure.
185 * @rfkill: rfkill structure to be unregistered
186 *
187 * This function should be called by the network driver during device
188 * teardown to destroy rfkill structure. Until it returns, the driver
189 * needs to be able to service method calls.
190 */
105void rfkill_unregister(struct rfkill *rfkill); 191void rfkill_unregister(struct rfkill *rfkill);
106 192
107int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state); 193/**
108int rfkill_set_default(enum rfkill_type type, enum rfkill_state state); 194 * rfkill_destroy - free rfkill structure
195 * @rfkill: rfkill structure to be destroyed
196 *
197 * Destroys the rfkill structure.
198 */
199void rfkill_destroy(struct rfkill *rfkill);
200
201/**
202 * rfkill_set_hw_state - Set the internal rfkill hardware block state
203 * @rfkill: pointer to the rfkill class to modify.
204 * @state: the current hardware block state to set
205 *
206 * rfkill drivers that get events when the hard-blocked state changes
207 * use this function to notify the rfkill core (and through that also
208 * userspace) of the current state -- they should also use this after
209 * resume if the state could have changed.
210 *
211 * You need not (but may) call this function if poll_state is assigned.
212 *
213 * This function can be called in any context, even from within rfkill
214 * callbacks.
215 *
216 * The function returns the combined block state (true if transmitter
217 * should be blocked) so that drivers need not keep track of the soft
218 * block state -- which they might not be able to.
219 */
220bool __must_check rfkill_set_hw_state(struct rfkill *rfkill, bool blocked);
221
222/**
223 * rfkill_set_sw_state - Set the internal rfkill software block state
224 * @rfkill: pointer to the rfkill class to modify.
225 * @state: the current software block state to set
226 *
227 * rfkill drivers that get events when the soft-blocked state changes
228 * (yes, some platforms directly act on input but allow changing again)
229 * use this function to notify the rfkill core (and through that also
230 * userspace) of the current state -- they should also use this after
231 * resume if the state could have changed.
232 *
233 * This function can be called in any context, even from within rfkill
234 * callbacks.
235 *
236 * The function returns the combined block state (true if transmitter
237 * should be blocked).
238 */
239bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked);
240
241/**
242 * rfkill_set_states - Set the internal rfkill block states
243 * @rfkill: pointer to the rfkill class to modify.
244 * @sw: the current software block state to set
245 * @hw: the current hardware block state to set
246 *
247 * This function can be called in any context, even from within rfkill
248 * callbacks.
249 */
250void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw);
109 251
110/** 252/**
111 * rfkill_state_complement - return complementar state 253 * rfkill_set_global_sw_state - set global sw block default
112 * @state: state to return the complement of 254 * @type: rfkill type to set default for
255 * @blocked: default to set
113 * 256 *
114 * Returns RFKILL_STATE_SOFT_BLOCKED if @state is RFKILL_STATE_UNBLOCKED, 257 * This function sets the global default -- use at boot if your platform has
115 * returns RFKILL_STATE_UNBLOCKED otherwise. 258 * an rfkill switch. If not early enough this call may be ignored.
259 *
260 * XXX: instead of ignoring -- how about just updating all currently
261 * registered drivers?
116 */ 262 */
117static inline enum rfkill_state rfkill_state_complement(enum rfkill_state state) 263void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked);
264
265/**
266 * rfkill_blocked - query rfkill block
267 *
268 * @rfkill: rfkill struct to query
269 */
270bool rfkill_blocked(struct rfkill *rfkill);
271#else /* !RFKILL */
272static inline struct rfkill * __must_check
273rfkill_alloc(const char *name,
274 struct device *parent,
275 const enum rfkill_type type,
276 const struct rfkill_ops *ops,
277 void *ops_data)
278{
279 return ERR_PTR(-ENODEV);
280}
281
282static inline int __must_check rfkill_register(struct rfkill *rfkill)
283{
284 if (rfkill == ERR_PTR(-ENODEV))
285 return 0;
286 return -EINVAL;
287}
288
289static inline void rfkill_pause_polling(struct rfkill *rfkill)
290{
291}
292
293static inline void rfkill_resume_polling(struct rfkill *rfkill)
294{
295}
296
297static inline void rfkill_unregister(struct rfkill *rfkill)
298{
299}
300
301static inline void rfkill_destroy(struct rfkill *rfkill)
302{
303}
304
305static inline bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
306{
307 return blocked;
308}
309
310static inline bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
311{
312 return blocked;
313}
314
315static inline void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
118{ 316{
119 return (state == RFKILL_STATE_UNBLOCKED) ?
120 RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;
121} 317}
122 318
319static inline void rfkill_set_global_sw_state(const enum rfkill_type type,
320 bool blocked)
321{
322}
323
324static inline bool rfkill_blocked(struct rfkill *rfkill)
325{
326 return false;
327}
328#endif /* RFKILL || RFKILL_MODULE */
329
330
331#ifdef CONFIG_RFKILL_LEDS
123/** 332/**
124 * rfkill_get_led_name - Get the LED trigger name for the button's LED. 333 * rfkill_get_led_trigger_name - Get the LED trigger name for the button's LED.
125 * This function might return a NULL pointer if registering of the 334 * This function might return a NULL pointer if registering of the
126 * LED trigger failed. 335 * LED trigger failed. Use this as "default_trigger" for the LED.
127 * Use this as "default_trigger" for the LED.
128 */ 336 */
129static inline char *rfkill_get_led_name(struct rfkill *rfkill) 337const char *rfkill_get_led_trigger_name(struct rfkill *rfkill);
130{ 338
131#ifdef CONFIG_RFKILL_LEDS 339/**
132 return (char *)(rfkill->led_trigger.name); 340 * rfkill_set_led_trigger_name -- set the LED trigger name
341 * @rfkill: rfkill struct
342 * @name: LED trigger name
343 *
344 * This function sets the LED trigger name of the radio LED
345 * trigger that rfkill creates. It is optional, but if called
346 * must be called before rfkill_register() to be effective.
347 */
348void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name);
133#else 349#else
350static inline const char *rfkill_get_led_trigger_name(struct rfkill *rfkill)
351{
134 return NULL; 352 return NULL;
135#endif
136} 353}
137 354
355static inline void
356rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name)
357{
358}
359#endif
360
361#endif /* __KERNEL__ */
362
138#endif /* RFKILL_H */ 363#endif /* RFKILL_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f20da7d63b1e..1a21895b732b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -752,6 +752,19 @@ enum wiphy_params_flags {
752}; 752};
753 753
754/** 754/**
755 * enum tx_power_setting - TX power adjustment
756 *
757 * @TX_POWER_AUTOMATIC: the dbm parameter is ignored
758 * @TX_POWER_LIMITED: limit TX power by the dbm parameter
759 * @TX_POWER_FIXED: fix TX power to the dbm parameter
760 */
761enum tx_power_setting {
762 TX_POWER_AUTOMATIC,
763 TX_POWER_LIMITED,
764 TX_POWER_FIXED,
765};
766
767/**
755 * struct cfg80211_ops - backend description for wireless configuration 768 * struct cfg80211_ops - backend description for wireless configuration
756 * 769 *
757 * This struct is registered by fullmac card drivers and/or wireless stacks 770 * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -837,6 +850,13 @@ enum wiphy_params_flags {
837 * @changed bitfield (see &enum wiphy_params_flags) describes which values 850 * @changed bitfield (see &enum wiphy_params_flags) describes which values
838 * have changed. The actual parameter values are available in 851 * have changed. The actual parameter values are available in
839 * struct wiphy. If returning an error, no value should be changed. 852 * struct wiphy. If returning an error, no value should be changed.
853 *
854 * @set_tx_power: set the transmit power according to the parameters
855 * @get_tx_power: store the current TX power into the dbm variable;
856 * return 0 if successful
857 *
858 * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting
859 * functions to adjust rfkill hw state
840 */ 860 */
841struct cfg80211_ops { 861struct cfg80211_ops {
842 int (*suspend)(struct wiphy *wiphy); 862 int (*suspend)(struct wiphy *wiphy);
@@ -928,6 +948,12 @@ struct cfg80211_ops {
928 int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev); 948 int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev);
929 949
930 int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed); 950 int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed);
951
952 int (*set_tx_power)(struct wiphy *wiphy,
953 enum tx_power_setting type, int dbm);
954 int (*get_tx_power)(struct wiphy *wiphy, int *dbm);
955
956 void (*rfkill_poll)(struct wiphy *wiphy);
931}; 957};
932 958
933/* 959/*
@@ -1451,6 +1477,12 @@ int cfg80211_wext_siwencode(struct net_device *dev,
1451int cfg80211_wext_giwencode(struct net_device *dev, 1477int cfg80211_wext_giwencode(struct net_device *dev,
1452 struct iw_request_info *info, 1478 struct iw_request_info *info,
1453 struct iw_point *erq, char *keybuf); 1479 struct iw_point *erq, char *keybuf);
1480int cfg80211_wext_siwtxpower(struct net_device *dev,
1481 struct iw_request_info *info,
1482 union iwreq_data *data, char *keybuf);
1483int cfg80211_wext_giwtxpower(struct net_device *dev,
1484 struct iw_request_info *info,
1485 union iwreq_data *data, char *keybuf);
1454 1486
1455/* 1487/*
1456 * callbacks for asynchronous cfg80211 methods, notification 1488 * callbacks for asynchronous cfg80211 methods, notification
@@ -1636,4 +1668,23 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
1636 */ 1668 */
1637void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); 1669void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
1638 1670
1671/**
1672 * wiphy_rfkill_set_hw_state - notify cfg80211 about hw block state
1673 * @wiphy: the wiphy
1674 * @blocked: block status
1675 */
1676void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked);
1677
1678/**
1679 * wiphy_rfkill_start_polling - start polling rfkill
1680 * @wiphy: the wiphy
1681 */
1682void wiphy_rfkill_start_polling(struct wiphy *wiphy);
1683
1684/**
1685 * wiphy_rfkill_stop_polling - stop polling rfkill
1686 * @wiphy: the wiphy
1687 */
1688void wiphy_rfkill_stop_polling(struct wiphy *wiphy);
1689
1639#endif /* __NET_CFG80211_H */ 1690#endif /* __NET_CFG80211_H */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index d72346ff3247..17d61d19d912 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -526,8 +526,7 @@ enum ieee80211_conf_flags {
526/** 526/**
527 * enum ieee80211_conf_changed - denotes which configuration changed 527 * enum ieee80211_conf_changed - denotes which configuration changed
528 * 528 *
529 * @IEEE80211_CONF_CHANGE_RADIO_ENABLED: the value of radio_enabled changed 529 * @_IEEE80211_CONF_CHANGE_RADIO_ENABLED: DEPRECATED
530 * @_IEEE80211_CONF_CHANGE_BEACON_INTERVAL: DEPRECATED
531 * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed 530 * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed
532 * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed 531 * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed
533 * @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed 532 * @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed
@@ -537,8 +536,7 @@ enum ieee80211_conf_flags {
537 * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed 536 * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed
538 */ 537 */
539enum ieee80211_conf_changed { 538enum ieee80211_conf_changed {
540 IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0), 539 _IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0),
541 _IEEE80211_CONF_CHANGE_BEACON_INTERVAL = BIT(1),
542 IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2), 540 IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2),
543 IEEE80211_CONF_CHANGE_RADIOTAP = BIT(3), 541 IEEE80211_CONF_CHANGE_RADIOTAP = BIT(3),
544 IEEE80211_CONF_CHANGE_PS = BIT(4), 542 IEEE80211_CONF_CHANGE_PS = BIT(4),
@@ -549,12 +547,12 @@ enum ieee80211_conf_changed {
549}; 547};
550 548
551static inline __deprecated enum ieee80211_conf_changed 549static inline __deprecated enum ieee80211_conf_changed
552__IEEE80211_CONF_CHANGE_BEACON_INTERVAL(void) 550__IEEE80211_CONF_CHANGE_RADIO_ENABLED(void)
553{ 551{
554 return _IEEE80211_CONF_CHANGE_BEACON_INTERVAL; 552 return _IEEE80211_CONF_CHANGE_RADIO_ENABLED;
555} 553}
556#define IEEE80211_CONF_CHANGE_BEACON_INTERVAL \ 554#define IEEE80211_CONF_CHANGE_RADIO_ENABLED \
557 __IEEE80211_CONF_CHANGE_BEACON_INTERVAL() 555 __IEEE80211_CONF_CHANGE_RADIO_ENABLED()
558 556
559/** 557/**
560 * struct ieee80211_conf - configuration of the device 558 * struct ieee80211_conf - configuration of the device
@@ -564,7 +562,7 @@ __IEEE80211_CONF_CHANGE_BEACON_INTERVAL(void)
564 * @flags: configuration flags defined above 562 * @flags: configuration flags defined above
565 * 563 *
566 * @radio_enabled: when zero, driver is required to switch off the radio. 564 * @radio_enabled: when zero, driver is required to switch off the radio.
567 * @beacon_int: beacon interval (TODO make interface config) 565 * @beacon_int: DEPRECATED, DO NOT USE
568 * 566 *
569 * @listen_interval: listen interval in units of beacon interval 567 * @listen_interval: listen interval in units of beacon interval
570 * @max_sleep_period: the maximum number of beacon intervals to sleep for 568 * @max_sleep_period: the maximum number of beacon intervals to sleep for
@@ -589,13 +587,13 @@ __IEEE80211_CONF_CHANGE_BEACON_INTERVAL(void)
589 * number of transmissions not the number of retries 587 * number of transmissions not the number of retries
590 */ 588 */
591struct ieee80211_conf { 589struct ieee80211_conf {
592 int beacon_int; 590 int __deprecated beacon_int;
593 u32 flags; 591 u32 flags;
594 int power_level, dynamic_ps_timeout; 592 int power_level, dynamic_ps_timeout;
595 int max_sleep_period; 593 int max_sleep_period;
596 594
597 u16 listen_interval; 595 u16 listen_interval;
598 bool radio_enabled; 596 bool __deprecated radio_enabled;
599 597
600 u8 long_frame_max_tx_count, short_frame_max_tx_count; 598 u8 long_frame_max_tx_count, short_frame_max_tx_count;
601 599
@@ -1406,6 +1404,10 @@ enum ieee80211_ampdu_mlme_action {
1406 * is the first frame we expect to perform the action on. Notice 1404 * is the first frame we expect to perform the action on. Notice
1407 * that TX/RX_STOP can pass NULL for this parameter. 1405 * that TX/RX_STOP can pass NULL for this parameter.
1408 * Returns a negative error code on failure. 1406 * Returns a negative error code on failure.
1407 *
1408 * @rfkill_poll: Poll rfkill hardware state. If you need this, you also
1409 * need to set wiphy->rfkill_poll to %true before registration,
1410 * and need to call wiphy_rfkill_set_hw_state() in the callback.
1409 */ 1411 */
1410struct ieee80211_ops { 1412struct ieee80211_ops {
1411 int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); 1413 int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -1454,6 +1456,8 @@ struct ieee80211_ops {
1454 int (*ampdu_action)(struct ieee80211_hw *hw, 1456 int (*ampdu_action)(struct ieee80211_hw *hw,
1455 enum ieee80211_ampdu_mlme_action action, 1457 enum ieee80211_ampdu_mlme_action action,
1456 struct ieee80211_sta *sta, u16 tid, u16 *ssn); 1458 struct ieee80211_sta *sta, u16 tid, u16 *ssn);
1459
1460 void (*rfkill_poll)(struct ieee80211_hw *hw);
1457}; 1461};
1458 1462
1459/** 1463/**
diff --git a/include/net/wimax.h b/include/net/wimax.h
index 6b3824edb39e..2af7bf839f23 100644
--- a/include/net/wimax.h
+++ b/include/net/wimax.h
@@ -253,7 +253,6 @@
253struct net_device; 253struct net_device;
254struct genl_info; 254struct genl_info;
255struct wimax_dev; 255struct wimax_dev;
256struct input_dev;
257 256
258/** 257/**
259 * struct wimax_dev - Generic WiMAX device 258 * struct wimax_dev - Generic WiMAX device
@@ -293,8 +292,8 @@ struct input_dev;
293 * See wimax_reset()'s documentation. 292 * See wimax_reset()'s documentation.
294 * 293 *
295 * @name: [fill] A way to identify this device. We need to register a 294 * @name: [fill] A way to identify this device. We need to register a
296 * name with many subsystems (input for RFKILL, workqueue 295 * name with many subsystems (rfkill, workqueue creation, etc).
297 * creation, etc). We can't use the network device name as that 296 * We can't use the network device name as that
298 * might change and in some instances we don't know it yet (until 297 * might change and in some instances we don't know it yet (until
299 * we don't call register_netdev()). So we generate an unique one 298 * we don't call register_netdev()). So we generate an unique one
300 * using the driver name and device bus id, place it here and use 299 * using the driver name and device bus id, place it here and use
@@ -316,9 +315,6 @@ struct input_dev;
316 * 315 *
317 * @rfkill: [private] integration into the RF-Kill infrastructure. 316 * @rfkill: [private] integration into the RF-Kill infrastructure.
318 * 317 *
319 * @rfkill_input: [private] virtual input device to process the
320 * hardware RF Kill switches.
321 *
322 * @rf_sw: [private] State of the software radio switch (OFF/ON) 318 * @rf_sw: [private] State of the software radio switch (OFF/ON)
323 * 319 *
324 * @rf_hw: [private] State of the hardware radio switch (OFF/ON) 320 * @rf_hw: [private] State of the hardware radio switch (OFF/ON)
diff --git a/net/core/dev.c b/net/core/dev.c
index 34b49a6a22fd..1f38401fc028 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1048,7 +1048,7 @@ void dev_load(struct net *net, const char *name)
1048int dev_open(struct net_device *dev) 1048int dev_open(struct net_device *dev)
1049{ 1049{
1050 const struct net_device_ops *ops = dev->netdev_ops; 1050 const struct net_device_ops *ops = dev->netdev_ops;
1051 int ret = 0; 1051 int ret;
1052 1052
1053 ASSERT_RTNL(); 1053 ASSERT_RTNL();
1054 1054
@@ -1065,6 +1065,11 @@ int dev_open(struct net_device *dev)
1065 if (!netif_device_present(dev)) 1065 if (!netif_device_present(dev))
1066 return -ENODEV; 1066 return -ENODEV;
1067 1067
1068 ret = call_netdevice_notifiers(NETDEV_PRE_UP, dev);
1069 ret = notifier_to_errno(ret);
1070 if (ret)
1071 return ret;
1072
1068 /* 1073 /*
1069 * Call device private open method 1074 * Call device private open method
1070 */ 1075 */
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 9cbf545e95a2..ba2643a43c73 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -1,16 +1,19 @@
1config MAC80211 1config MAC80211
2 tristate "Generic IEEE 802.11 Networking Stack (mac80211)" 2 tristate "Generic IEEE 802.11 Networking Stack (mac80211)"
3 depends on CFG80211
3 select CRYPTO 4 select CRYPTO
4 select CRYPTO_ECB 5 select CRYPTO_ECB
5 select CRYPTO_ARC4 6 select CRYPTO_ARC4
6 select CRYPTO_AES 7 select CRYPTO_AES
7 select CRC32 8 select CRC32
8 select WIRELESS_EXT 9 select WIRELESS_EXT
9 select CFG80211
10 ---help--- 10 ---help---
11 This option enables the hardware independent IEEE 802.11 11 This option enables the hardware independent IEEE 802.11
12 networking stack. 12 networking stack.
13 13
14comment "CFG80211 needs to be enabled for MAC80211"
15 depends on CFG80211=n
16
14config MAC80211_DEFAULT_PS 17config MAC80211_DEFAULT_PS
15 bool "enable powersave by default" 18 bool "enable powersave by default"
16 depends on MAC80211 19 depends on MAC80211
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 77e9ff5ec4f3..a9211cc183cb 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -664,18 +664,19 @@ static void sta_apply_parameters(struct ieee80211_local *local,
664 spin_unlock_bh(&sta->lock); 664 spin_unlock_bh(&sta->lock);
665 665
666 /* 666 /*
667 * cfg80211 validates this (1-2007) and allows setting the AID
668 * only when creating a new station entry
669 */
670 if (params->aid)
671 sta->sta.aid = params->aid;
672
673 /*
667 * FIXME: updating the following information is racy when this 674 * FIXME: updating the following information is racy when this
668 * function is called from ieee80211_change_station(). 675 * function is called from ieee80211_change_station().
669 * However, all this information should be static so 676 * However, all this information should be static so
670 * maybe we should just reject attemps to change it. 677 * maybe we should just reject attemps to change it.
671 */ 678 */
672 679
673 if (params->aid) {
674 sta->sta.aid = params->aid;
675 if (sta->sta.aid > IEEE80211_MAX_AID)
676 sta->sta.aid = 0; /* XXX: should this be an error? */
677 }
678
679 if (params->listen_interval >= 0) 680 if (params->listen_interval >= 0)
680 sta->listen_interval = params->listen_interval; 681 sta->listen_interval = params->listen_interval;
681 682
@@ -1255,7 +1256,7 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
1255 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL; 1256 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
1256 1257
1257 ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len); 1258 ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len);
1258 if (ret) 1259 if (ret && ret != -EALREADY)
1259 return ret; 1260 return ret;
1260 1261
1261 if (req->use_mfp) { 1262 if (req->use_mfp) {
@@ -1333,6 +1334,53 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1333 return 0; 1334 return 0;
1334} 1335}
1335 1336
1337static int ieee80211_set_tx_power(struct wiphy *wiphy,
1338 enum tx_power_setting type, int dbm)
1339{
1340 struct ieee80211_local *local = wiphy_priv(wiphy);
1341 struct ieee80211_channel *chan = local->hw.conf.channel;
1342 u32 changes = 0;
1343
1344 switch (type) {
1345 case TX_POWER_AUTOMATIC:
1346 local->user_power_level = -1;
1347 break;
1348 case TX_POWER_LIMITED:
1349 if (dbm < 0)
1350 return -EINVAL;
1351 local->user_power_level = dbm;
1352 break;
1353 case TX_POWER_FIXED:
1354 if (dbm < 0)
1355 return -EINVAL;
1356 /* TODO: move to cfg80211 when it knows the channel */
1357 if (dbm > chan->max_power)
1358 return -EINVAL;
1359 local->user_power_level = dbm;
1360 break;
1361 }
1362
1363 ieee80211_hw_config(local, changes);
1364
1365 return 0;
1366}
1367
1368static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
1369{
1370 struct ieee80211_local *local = wiphy_priv(wiphy);
1371
1372 *dbm = local->hw.conf.power_level;
1373
1374 return 0;
1375}
1376
1377static void ieee80211_rfkill_poll(struct wiphy *wiphy)
1378{
1379 struct ieee80211_local *local = wiphy_priv(wiphy);
1380
1381 drv_rfkill_poll(local);
1382}
1383
1336struct cfg80211_ops mac80211_config_ops = { 1384struct cfg80211_ops mac80211_config_ops = {
1337 .add_virtual_intf = ieee80211_add_iface, 1385 .add_virtual_intf = ieee80211_add_iface,
1338 .del_virtual_intf = ieee80211_del_iface, 1386 .del_virtual_intf = ieee80211_del_iface,
@@ -1372,4 +1420,7 @@ struct cfg80211_ops mac80211_config_ops = {
1372 .join_ibss = ieee80211_join_ibss, 1420 .join_ibss = ieee80211_join_ibss,
1373 .leave_ibss = ieee80211_leave_ibss, 1421 .leave_ibss = ieee80211_leave_ibss,
1374 .set_wiphy_params = ieee80211_set_wiphy_params, 1422 .set_wiphy_params = ieee80211_set_wiphy_params,
1423 .set_tx_power = ieee80211_set_tx_power,
1424 .get_tx_power = ieee80211_get_tx_power,
1425 .rfkill_poll = ieee80211_rfkill_poll,
1375}; 1426};
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 3912b5334b9c..b13446afd48f 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -181,4 +181,11 @@ static inline int drv_ampdu_action(struct ieee80211_local *local,
181 sta, tid, ssn); 181 sta, tid, ssn);
182 return -EOPNOTSUPP; 182 return -EOPNOTSUPP;
183} 183}
184
185
186static inline void drv_rfkill_poll(struct ieee80211_local *local)
187{
188 if (local->ops->rfkill_poll)
189 local->ops->rfkill_poll(&local->hw);
190}
184#endif /* __MAC80211_DRIVER_OPS */ 191#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 8c9f1c722cdb..b7c8a4484298 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -170,7 +170,7 @@ static int ieee80211_open(struct net_device *dev)
170 goto err_del_bss; 170 goto err_del_bss;
171 /* we're brought up, everything changes */ 171 /* we're brought up, everything changes */
172 hw_reconf_flags = ~0; 172 hw_reconf_flags = ~0;
173 ieee80211_led_radio(local, local->hw.conf.radio_enabled); 173 ieee80211_led_radio(local, true);
174 } 174 }
175 175
176 /* 176 /*
@@ -560,7 +560,7 @@ static int ieee80211_stop(struct net_device *dev)
560 560
561 drv_stop(local); 561 drv_stop(local);
562 562
563 ieee80211_led_radio(local, 0); 563 ieee80211_led_radio(local, false);
564 564
565 flush_workqueue(local->hw.workqueue); 565 flush_workqueue(local->hw.workqueue);
566 566
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index e37770ced53c..2683df918073 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -289,16 +289,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
289 drv_bss_info_changed(local, &sdata->vif, 289 drv_bss_info_changed(local, &sdata->vif,
290 &sdata->vif.bss_conf, changed); 290 &sdata->vif.bss_conf, changed);
291 291
292 /* 292 /* DEPRECATED */
293 * DEPRECATED 293 local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int;
294 *
295 * ~changed is just there to not do this at resume time
296 */
297 if (changed & BSS_CHANGED_BEACON_INT && ~changed) {
298 local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int;
299 ieee80211_hw_config(local,
300 _IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
301 }
302} 294}
303 295
304u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) 296u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index d5611d8fd0d6..a360bceeba59 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -44,6 +44,15 @@
44 * When the insertion fails (sta_info_insert()) returns non-zero), the 44 * When the insertion fails (sta_info_insert()) returns non-zero), the
45 * structure will have been freed by sta_info_insert()! 45 * structure will have been freed by sta_info_insert()!
46 * 46 *
47 * sta entries are added by mac80211 when you establish a link with a
48 * peer. This means different things for the different type of interfaces
49 * we support. For a regular station this mean we add the AP sta when we
50 * receive an assocation response from the AP. For IBSS this occurs when
51 * we receive a probe response or a beacon from target IBSS network. For
52 * WDS we add the sta for the peer imediately upon device open. When using
53 * AP mode we add stations for each respective station upon request from
54 * userspace through nl80211.
55 *
47 * Because there are debugfs entries for each station, and adding those 56 * Because there are debugfs entries for each station, and adding those
48 * must be able to sleep, it is also possible to "pin" a station entry, 57 * must be able to sleep, it is also possible to "pin" a station entry,
49 * that means it can be removed from the hash table but not be freed. 58 * that means it can be removed from the hash table but not be freed.
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index a910148b8228..1436f747531a 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1238,7 +1238,6 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1238 bool txpending) 1238 bool txpending)
1239{ 1239{
1240 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1240 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1241 struct sta_info *sta;
1242 struct ieee80211_tx_data tx; 1241 struct ieee80211_tx_data tx;
1243 ieee80211_tx_result res_prepare; 1242 ieee80211_tx_result res_prepare;
1244 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1243 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -1270,7 +1269,6 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1270 return; 1269 return;
1271 } 1270 }
1272 1271
1273 sta = tx.sta;
1274 tx.channel = local->hw.conf.channel; 1272 tx.channel = local->hw.conf.channel;
1275 info->band = tx.channel->band; 1273 info->band = tx.channel->band;
1276 1274
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 949d857debd8..22f63815fb36 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -657,15 +657,15 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
657 657
658 switch (queue) { 658 switch (queue) {
659 case 3: /* AC_BK */ 659 case 3: /* AC_BK */
660 qparam.cw_max = aCWmin; 660 qparam.cw_max = aCWmax;
661 qparam.cw_min = aCWmax; 661 qparam.cw_min = aCWmin;
662 qparam.txop = 0; 662 qparam.txop = 0;
663 qparam.aifs = 7; 663 qparam.aifs = 7;
664 break; 664 break;
665 default: /* never happens but let's not leave undefined */ 665 default: /* never happens but let's not leave undefined */
666 case 2: /* AC_BE */ 666 case 2: /* AC_BE */
667 qparam.cw_max = aCWmin; 667 qparam.cw_max = aCWmax;
668 qparam.cw_min = aCWmax; 668 qparam.cw_min = aCWmin;
669 qparam.txop = 0; 669 qparam.txop = 0;
670 qparam.aifs = 3; 670 qparam.aifs = 3;
671 break; 671 break;
@@ -973,7 +973,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
973 if (local->open_count) { 973 if (local->open_count) {
974 res = drv_start(local); 974 res = drv_start(local);
975 975
976 ieee80211_led_radio(local, hw->conf.radio_enabled); 976 ieee80211_led_radio(local, true);
977 } 977 }
978 978
979 /* add interfaces */ 979 /* add interfaces */
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index a01154e127f0..d2d81b103341 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -306,82 +306,6 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
306 return 0; 306 return 0;
307} 307}
308 308
309static int ieee80211_ioctl_siwtxpower(struct net_device *dev,
310 struct iw_request_info *info,
311 union iwreq_data *data, char *extra)
312{
313 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
314 struct ieee80211_channel* chan = local->hw.conf.channel;
315 bool reconf = false;
316 u32 reconf_flags = 0;
317 int new_power_level;
318
319 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
320 return -EINVAL;
321 if (data->txpower.flags & IW_TXPOW_RANGE)
322 return -EINVAL;
323 if (!chan)
324 return -EINVAL;
325
326 /* only change when not disabling */
327 if (!data->txpower.disabled) {
328 if (data->txpower.fixed) {
329 if (data->txpower.value < 0)
330 return -EINVAL;
331 new_power_level = data->txpower.value;
332 /*
333 * Debatable, but we cannot do a fixed power
334 * level above the regulatory constraint.
335 * Use "iwconfig wlan0 txpower 15dBm" instead.
336 */
337 if (new_power_level > chan->max_power)
338 return -EINVAL;
339 } else {
340 /*
341 * Automatic power level setting, max being the value
342 * passed in from userland.
343 */
344 if (data->txpower.value < 0)
345 new_power_level = -1;
346 else
347 new_power_level = data->txpower.value;
348 }
349
350 reconf = true;
351
352 /*
353 * ieee80211_hw_config() will limit to the channel's
354 * max power and possibly power constraint from AP.
355 */
356 local->user_power_level = new_power_level;
357 }
358
359 if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) {
360 local->hw.conf.radio_enabled = !(data->txpower.disabled);
361 reconf_flags |= IEEE80211_CONF_CHANGE_RADIO_ENABLED;
362 ieee80211_led_radio(local, local->hw.conf.radio_enabled);
363 }
364
365 if (reconf || reconf_flags)
366 ieee80211_hw_config(local, reconf_flags);
367
368 return 0;
369}
370
371static int ieee80211_ioctl_giwtxpower(struct net_device *dev,
372 struct iw_request_info *info,
373 union iwreq_data *data, char *extra)
374{
375 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
376
377 data->txpower.fixed = 1;
378 data->txpower.disabled = !(local->hw.conf.radio_enabled);
379 data->txpower.value = local->hw.conf.power_level;
380 data->txpower.flags = IW_TXPOW_DBM;
381
382 return 0;
383}
384
385static int ieee80211_ioctl_siwpower(struct net_device *dev, 309static int ieee80211_ioctl_siwpower(struct net_device *dev,
386 struct iw_request_info *info, 310 struct iw_request_info *info,
387 struct iw_param *wrq, 311 struct iw_param *wrq,
@@ -658,8 +582,8 @@ static const iw_handler ieee80211_handler[] =
658 (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */ 582 (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */
659 (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */ 583 (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */
660 (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */ 584 (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */
661 (iw_handler) ieee80211_ioctl_siwtxpower, /* SIOCSIWTXPOW */ 585 (iw_handler) cfg80211_wext_siwtxpower, /* SIOCSIWTXPOW */
662 (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */ 586 (iw_handler) cfg80211_wext_giwtxpower, /* SIOCGIWTXPOW */
663 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */ 587 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */
664 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */ 588 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */
665 (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */ 589 (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */
diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig
index 7f807b30cfbb..fd7600d8ab14 100644
--- a/net/rfkill/Kconfig
+++ b/net/rfkill/Kconfig
@@ -10,22 +10,15 @@ menuconfig RFKILL
10 To compile this driver as a module, choose M here: the 10 To compile this driver as a module, choose M here: the
11 module will be called rfkill. 11 module will be called rfkill.
12 12
13config RFKILL_INPUT
14 tristate "Input layer to RF switch connector"
15 depends on RFKILL && INPUT
16 help
17 Say Y here if you want kernel automatically toggle state
18 of RF switches on and off when user presses appropriate
19 button or a key on the keyboard. Without this module you
20 need a some kind of userspace application to control
21 state of the switches.
22
23 To compile this driver as a module, choose M here: the
24 module will be called rfkill-input.
25
26# LED trigger support 13# LED trigger support
27config RFKILL_LEDS 14config RFKILL_LEDS
28 bool 15 bool
29 depends on RFKILL && LEDS_TRIGGERS 16 depends on RFKILL
17 depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS
30 default y 18 default y
31 19
20config RFKILL_INPUT
21 bool "RF switch input support"
22 depends on RFKILL
23 depends on INPUT = y || RFKILL = INPUT
24 default y if !EMBEDDED
diff --git a/net/rfkill/Makefile b/net/rfkill/Makefile
index b38c430be057..662105352691 100644
--- a/net/rfkill/Makefile
+++ b/net/rfkill/Makefile
@@ -2,5 +2,6 @@
2# Makefile for the RF switch subsystem. 2# Makefile for the RF switch subsystem.
3# 3#
4 4
5obj-$(CONFIG_RFKILL) += rfkill.o 5rfkill-y += core.o
6obj-$(CONFIG_RFKILL_INPUT) += rfkill-input.o 6rfkill-$(CONFIG_RFKILL_INPUT) += input.o
7obj-$(CONFIG_RFKILL) += rfkill.o
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
new file mode 100644
index 000000000000..11b7314723df
--- /dev/null
+++ b/net/rfkill/core.c
@@ -0,0 +1,1228 @@
1/*
2 * Copyright (C) 2006 - 2007 Ivo van Doorn
3 * Copyright (C) 2007 Dmitry Torokhov
4 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the
18 * Free Software Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/workqueue.h>
26#include <linux/capability.h>
27#include <linux/list.h>
28#include <linux/mutex.h>
29#include <linux/rfkill.h>
30#include <linux/spinlock.h>
31#include <linux/miscdevice.h>
32#include <linux/wait.h>
33#include <linux/poll.h>
34#include <linux/fs.h>
35
36#include "rfkill.h"
37
38#define POLL_INTERVAL (5 * HZ)
39
40#define RFKILL_BLOCK_HW BIT(0)
41#define RFKILL_BLOCK_SW BIT(1)
42#define RFKILL_BLOCK_SW_PREV BIT(2)
43#define RFKILL_BLOCK_ANY (RFKILL_BLOCK_HW |\
44 RFKILL_BLOCK_SW |\
45 RFKILL_BLOCK_SW_PREV)
46#define RFKILL_BLOCK_SW_SETCALL BIT(31)
47
48struct rfkill {
49 spinlock_t lock;
50
51 const char *name;
52 enum rfkill_type type;
53
54 unsigned long state;
55
56 u32 idx;
57
58 bool registered;
59 bool suspended;
60
61 const struct rfkill_ops *ops;
62 void *data;
63
64#ifdef CONFIG_RFKILL_LEDS
65 struct led_trigger led_trigger;
66 const char *ledtrigname;
67#endif
68
69 struct device dev;
70 struct list_head node;
71
72 struct delayed_work poll_work;
73 struct work_struct uevent_work;
74 struct work_struct sync_work;
75};
76#define to_rfkill(d) container_of(d, struct rfkill, dev)
77
78struct rfkill_int_event {
79 struct list_head list;
80 struct rfkill_event ev;
81};
82
83struct rfkill_data {
84 struct list_head list;
85 struct list_head events;
86 struct mutex mtx;
87 wait_queue_head_t read_wait;
88 bool input_handler;
89};
90
91
92MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
93MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
94MODULE_DESCRIPTION("RF switch support");
95MODULE_LICENSE("GPL");
96
97
98/*
99 * The locking here should be made much smarter, we currently have
100 * a bit of a stupid situation because drivers might want to register
101 * the rfkill struct under their own lock, and take this lock during
102 * rfkill method calls -- which will cause an AB-BA deadlock situation.
103 *
104 * To fix that, we need to rework this code here to be mostly lock-free
105 * and only use the mutex for list manipulations, not to protect the
106 * various other global variables. Then we can avoid holding the mutex
107 * around driver operations, and all is happy.
108 */
109static LIST_HEAD(rfkill_list); /* list of registered rf switches */
110static DEFINE_MUTEX(rfkill_global_mutex);
111static LIST_HEAD(rfkill_fds); /* list of open fds of /dev/rfkill */
112
113static unsigned int rfkill_default_state = 1;
114module_param_named(default_state, rfkill_default_state, uint, 0444);
115MODULE_PARM_DESC(default_state,
116 "Default initial state for all radio types, 0 = radio off");
117
118static struct {
119 bool cur, def;
120} rfkill_global_states[NUM_RFKILL_TYPES];
121
122static unsigned long rfkill_states_default_locked;
123
124static bool rfkill_epo_lock_active;
125
126
127#ifdef CONFIG_RFKILL_LEDS
128static void rfkill_led_trigger_event(struct rfkill *rfkill)
129{
130 struct led_trigger *trigger;
131
132 if (!rfkill->registered)
133 return;
134
135 trigger = &rfkill->led_trigger;
136
137 if (rfkill->state & RFKILL_BLOCK_ANY)
138 led_trigger_event(trigger, LED_OFF);
139 else
140 led_trigger_event(trigger, LED_FULL);
141}
142
143static void rfkill_led_trigger_activate(struct led_classdev *led)
144{
145 struct rfkill *rfkill;
146
147 rfkill = container_of(led->trigger, struct rfkill, led_trigger);
148
149 rfkill_led_trigger_event(rfkill);
150}
151
152const char *rfkill_get_led_trigger_name(struct rfkill *rfkill)
153{
154 return rfkill->led_trigger.name;
155}
156EXPORT_SYMBOL(rfkill_get_led_trigger_name);
157
158void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name)
159{
160 BUG_ON(!rfkill);
161
162 rfkill->ledtrigname = name;
163}
164EXPORT_SYMBOL(rfkill_set_led_trigger_name);
165
166static int rfkill_led_trigger_register(struct rfkill *rfkill)
167{
168 rfkill->led_trigger.name = rfkill->ledtrigname
169 ? : dev_name(&rfkill->dev);
170 rfkill->led_trigger.activate = rfkill_led_trigger_activate;
171 return led_trigger_register(&rfkill->led_trigger);
172}
173
174static void rfkill_led_trigger_unregister(struct rfkill *rfkill)
175{
176 led_trigger_unregister(&rfkill->led_trigger);
177}
178#else
179static void rfkill_led_trigger_event(struct rfkill *rfkill)
180{
181}
182
183static inline int rfkill_led_trigger_register(struct rfkill *rfkill)
184{
185 return 0;
186}
187
188static inline void rfkill_led_trigger_unregister(struct rfkill *rfkill)
189{
190}
191#endif /* CONFIG_RFKILL_LEDS */
192
193static void rfkill_fill_event(struct rfkill_event *ev, struct rfkill *rfkill,
194 enum rfkill_operation op)
195{
196 unsigned long flags;
197
198 ev->idx = rfkill->idx;
199 ev->type = rfkill->type;
200 ev->op = op;
201
202 spin_lock_irqsave(&rfkill->lock, flags);
203 ev->hard = !!(rfkill->state & RFKILL_BLOCK_HW);
204 ev->soft = !!(rfkill->state & (RFKILL_BLOCK_SW |
205 RFKILL_BLOCK_SW_PREV));
206 spin_unlock_irqrestore(&rfkill->lock, flags);
207}
208
209static void rfkill_send_events(struct rfkill *rfkill, enum rfkill_operation op)
210{
211 struct rfkill_data *data;
212 struct rfkill_int_event *ev;
213
214 list_for_each_entry(data, &rfkill_fds, list) {
215 ev = kzalloc(sizeof(*ev), GFP_KERNEL);
216 if (!ev)
217 continue;
218 rfkill_fill_event(&ev->ev, rfkill, op);
219 mutex_lock(&data->mtx);
220 list_add_tail(&ev->list, &data->events);
221 mutex_unlock(&data->mtx);
222 wake_up_interruptible(&data->read_wait);
223 }
224}
225
226static void rfkill_event(struct rfkill *rfkill)
227{
228 if (!rfkill->registered || rfkill->suspended)
229 return;
230
231 kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
232
233 /* also send event to /dev/rfkill */
234 rfkill_send_events(rfkill, RFKILL_OP_CHANGE);
235}
236
237static bool __rfkill_set_hw_state(struct rfkill *rfkill,
238 bool blocked, bool *change)
239{
240 unsigned long flags;
241 bool prev, any;
242
243 BUG_ON(!rfkill);
244
245 spin_lock_irqsave(&rfkill->lock, flags);
246 prev = !!(rfkill->state & RFKILL_BLOCK_HW);
247 if (blocked)
248 rfkill->state |= RFKILL_BLOCK_HW;
249 else
250 rfkill->state &= ~RFKILL_BLOCK_HW;
251 *change = prev != blocked;
252 any = rfkill->state & RFKILL_BLOCK_ANY;
253 spin_unlock_irqrestore(&rfkill->lock, flags);
254
255 rfkill_led_trigger_event(rfkill);
256
257 return any;
258}
259
260/**
261 * rfkill_set_block - wrapper for set_block method
262 *
263 * @rfkill: the rfkill struct to use
264 * @blocked: the new software state
265 *
266 * Calls the set_block method (when applicable) and handles notifications
267 * etc. as well.
268 */
269static void rfkill_set_block(struct rfkill *rfkill, bool blocked)
270{
271 unsigned long flags;
272 int err;
273
274 /*
275 * Some platforms (...!) generate input events which affect the
276 * _hard_ kill state -- whenever something tries to change the
277 * current software state query the hardware state too.
278 */
279 if (rfkill->ops->query)
280 rfkill->ops->query(rfkill, rfkill->data);
281
282 spin_lock_irqsave(&rfkill->lock, flags);
283 if (rfkill->state & RFKILL_BLOCK_SW)
284 rfkill->state |= RFKILL_BLOCK_SW_PREV;
285 else
286 rfkill->state &= ~RFKILL_BLOCK_SW_PREV;
287
288 if (blocked)
289 rfkill->state |= RFKILL_BLOCK_SW;
290 else
291 rfkill->state &= ~RFKILL_BLOCK_SW;
292
293 rfkill->state |= RFKILL_BLOCK_SW_SETCALL;
294 spin_unlock_irqrestore(&rfkill->lock, flags);
295
296 if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP))
297 return;
298
299 err = rfkill->ops->set_block(rfkill->data, blocked);
300
301 spin_lock_irqsave(&rfkill->lock, flags);
302 if (err) {
303 /*
304 * Failed -- reset status to _prev, this may be different
305 * from what set set _PREV to earlier in this function
306 * if rfkill_set_sw_state was invoked.
307 */
308 if (rfkill->state & RFKILL_BLOCK_SW_PREV)
309 rfkill->state |= RFKILL_BLOCK_SW;
310 else
311 rfkill->state &= ~RFKILL_BLOCK_SW;
312 }
313 rfkill->state &= ~RFKILL_BLOCK_SW_SETCALL;
314 rfkill->state &= ~RFKILL_BLOCK_SW_PREV;
315 spin_unlock_irqrestore(&rfkill->lock, flags);
316
317 rfkill_led_trigger_event(rfkill);
318 rfkill_event(rfkill);
319}
320
321#ifdef CONFIG_RFKILL_INPUT
322static atomic_t rfkill_input_disabled = ATOMIC_INIT(0);
323
324/**
325 * __rfkill_switch_all - Toggle state of all switches of given type
326 * @type: type of interfaces to be affected
327 * @state: the new state
328 *
329 * This function sets the state of all switches of given type,
330 * unless a specific switch is claimed by userspace (in which case,
331 * that switch is left alone) or suspended.
332 *
333 * Caller must have acquired rfkill_global_mutex.
334 */
335static void __rfkill_switch_all(const enum rfkill_type type, bool blocked)
336{
337 struct rfkill *rfkill;
338
339 rfkill_global_states[type].cur = blocked;
340 list_for_each_entry(rfkill, &rfkill_list, node) {
341 if (rfkill->type != type)
342 continue;
343
344 rfkill_set_block(rfkill, blocked);
345 }
346}
347
348/**
349 * rfkill_switch_all - Toggle state of all switches of given type
350 * @type: type of interfaces to be affected
351 * @state: the new state
352 *
353 * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state).
354 * Please refer to __rfkill_switch_all() for details.
355 *
356 * Does nothing if the EPO lock is active.
357 */
358void rfkill_switch_all(enum rfkill_type type, bool blocked)
359{
360 if (atomic_read(&rfkill_input_disabled))
361 return;
362
363 mutex_lock(&rfkill_global_mutex);
364
365 if (!rfkill_epo_lock_active)
366 __rfkill_switch_all(type, blocked);
367
368 mutex_unlock(&rfkill_global_mutex);
369}
370
371/**
372 * rfkill_epo - emergency power off all transmitters
373 *
374 * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED,
375 * ignoring everything in its path but rfkill_global_mutex and rfkill->mutex.
376 *
377 * The global state before the EPO is saved and can be restored later
378 * using rfkill_restore_states().
379 */
380void rfkill_epo(void)
381{
382 struct rfkill *rfkill;
383 int i;
384
385 if (atomic_read(&rfkill_input_disabled))
386 return;
387
388 mutex_lock(&rfkill_global_mutex);
389
390 rfkill_epo_lock_active = true;
391 list_for_each_entry(rfkill, &rfkill_list, node)
392 rfkill_set_block(rfkill, true);
393
394 for (i = 0; i < NUM_RFKILL_TYPES; i++) {
395 rfkill_global_states[i].def = rfkill_global_states[i].cur;
396 rfkill_global_states[i].cur = true;
397 }
398
399 mutex_unlock(&rfkill_global_mutex);
400}
401
402/**
403 * rfkill_restore_states - restore global states
404 *
405 * Restore (and sync switches to) the global state from the
406 * states in rfkill_default_states. This can undo the effects of
407 * a call to rfkill_epo().
408 */
409void rfkill_restore_states(void)
410{
411 int i;
412
413 if (atomic_read(&rfkill_input_disabled))
414 return;
415
416 mutex_lock(&rfkill_global_mutex);
417
418 rfkill_epo_lock_active = false;
419 for (i = 0; i < NUM_RFKILL_TYPES; i++)
420 __rfkill_switch_all(i, rfkill_global_states[i].def);
421 mutex_unlock(&rfkill_global_mutex);
422}
423
424/**
425 * rfkill_remove_epo_lock - unlock state changes
426 *
427 * Used by rfkill-input manually unlock state changes, when
428 * the EPO switch is deactivated.
429 */
430void rfkill_remove_epo_lock(void)
431{
432 if (atomic_read(&rfkill_input_disabled))
433 return;
434
435 mutex_lock(&rfkill_global_mutex);
436 rfkill_epo_lock_active = false;
437 mutex_unlock(&rfkill_global_mutex);
438}
439
440/**
441 * rfkill_is_epo_lock_active - returns true EPO is active
442 *
443 * Returns 0 (false) if there is NOT an active EPO contidion,
444 * and 1 (true) if there is an active EPO contition, which
445 * locks all radios in one of the BLOCKED states.
446 *
447 * Can be called in atomic context.
448 */
449bool rfkill_is_epo_lock_active(void)
450{
451 return rfkill_epo_lock_active;
452}
453
454/**
455 * rfkill_get_global_sw_state - returns global state for a type
456 * @type: the type to get the global state of
457 *
458 * Returns the current global state for a given wireless
459 * device type.
460 */
461bool rfkill_get_global_sw_state(const enum rfkill_type type)
462{
463 return rfkill_global_states[type].cur;
464}
465#endif
466
467void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked)
468{
469 BUG_ON(type == RFKILL_TYPE_ALL);
470
471 mutex_lock(&rfkill_global_mutex);
472
473 /* don't allow unblock when epo */
474 if (rfkill_epo_lock_active && !blocked)
475 goto out;
476
477 /* too late */
478 if (rfkill_states_default_locked & BIT(type))
479 goto out;
480
481 rfkill_states_default_locked |= BIT(type);
482
483 rfkill_global_states[type].cur = blocked;
484 rfkill_global_states[type].def = blocked;
485 out:
486 mutex_unlock(&rfkill_global_mutex);
487}
488EXPORT_SYMBOL(rfkill_set_global_sw_state);
489
490
491bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
492{
493 bool ret, change;
494
495 ret = __rfkill_set_hw_state(rfkill, blocked, &change);
496
497 if (!rfkill->registered)
498 return ret;
499
500 if (change)
501 schedule_work(&rfkill->uevent_work);
502
503 return ret;
504}
505EXPORT_SYMBOL(rfkill_set_hw_state);
506
507static void __rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
508{
509 u32 bit = RFKILL_BLOCK_SW;
510
511 /* if in a ops->set_block right now, use other bit */
512 if (rfkill->state & RFKILL_BLOCK_SW_SETCALL)
513 bit = RFKILL_BLOCK_SW_PREV;
514
515 if (blocked)
516 rfkill->state |= bit;
517 else
518 rfkill->state &= ~bit;
519}
520
521bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
522{
523 unsigned long flags;
524 bool prev, hwblock;
525
526 BUG_ON(!rfkill);
527
528 spin_lock_irqsave(&rfkill->lock, flags);
529 prev = !!(rfkill->state & RFKILL_BLOCK_SW);
530 __rfkill_set_sw_state(rfkill, blocked);
531 hwblock = !!(rfkill->state & RFKILL_BLOCK_HW);
532 blocked = blocked || hwblock;
533 spin_unlock_irqrestore(&rfkill->lock, flags);
534
535 if (!rfkill->registered)
536 return blocked;
537
538 if (prev != blocked && !hwblock)
539 schedule_work(&rfkill->uevent_work);
540
541 rfkill_led_trigger_event(rfkill);
542
543 return blocked;
544}
545EXPORT_SYMBOL(rfkill_set_sw_state);
546
547void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
548{
549 unsigned long flags;
550 bool swprev, hwprev;
551
552 BUG_ON(!rfkill);
553
554 spin_lock_irqsave(&rfkill->lock, flags);
555
556 /*
557 * No need to care about prev/setblock ... this is for uevent only
558 * and that will get triggered by rfkill_set_block anyway.
559 */
560 swprev = !!(rfkill->state & RFKILL_BLOCK_SW);
561 hwprev = !!(rfkill->state & RFKILL_BLOCK_HW);
562 __rfkill_set_sw_state(rfkill, sw);
563
564 spin_unlock_irqrestore(&rfkill->lock, flags);
565
566 if (!rfkill->registered)
567 return;
568
569 if (swprev != sw || hwprev != hw)
570 schedule_work(&rfkill->uevent_work);
571
572 rfkill_led_trigger_event(rfkill);
573}
574EXPORT_SYMBOL(rfkill_set_states);
575
576static ssize_t rfkill_name_show(struct device *dev,
577 struct device_attribute *attr,
578 char *buf)
579{
580 struct rfkill *rfkill = to_rfkill(dev);
581
582 return sprintf(buf, "%s\n", rfkill->name);
583}
584
585static const char *rfkill_get_type_str(enum rfkill_type type)
586{
587 switch (type) {
588 case RFKILL_TYPE_WLAN:
589 return "wlan";
590 case RFKILL_TYPE_BLUETOOTH:
591 return "bluetooth";
592 case RFKILL_TYPE_UWB:
593 return "ultrawideband";
594 case RFKILL_TYPE_WIMAX:
595 return "wimax";
596 case RFKILL_TYPE_WWAN:
597 return "wwan";
598 default:
599 BUG();
600 }
601
602 BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_WWAN + 1);
603}
604
605static ssize_t rfkill_type_show(struct device *dev,
606 struct device_attribute *attr,
607 char *buf)
608{
609 struct rfkill *rfkill = to_rfkill(dev);
610
611 return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));
612}
613
614static ssize_t rfkill_idx_show(struct device *dev,
615 struct device_attribute *attr,
616 char *buf)
617{
618 struct rfkill *rfkill = to_rfkill(dev);
619
620 return sprintf(buf, "%d\n", rfkill->idx);
621}
622
623static u8 user_state_from_blocked(unsigned long state)
624{
625 if (state & RFKILL_BLOCK_HW)
626 return RFKILL_USER_STATE_HARD_BLOCKED;
627 if (state & RFKILL_BLOCK_SW)
628 return RFKILL_USER_STATE_SOFT_BLOCKED;
629
630 return RFKILL_USER_STATE_UNBLOCKED;
631}
632
633static ssize_t rfkill_state_show(struct device *dev,
634 struct device_attribute *attr,
635 char *buf)
636{
637 struct rfkill *rfkill = to_rfkill(dev);
638 unsigned long flags;
639 u32 state;
640
641 spin_lock_irqsave(&rfkill->lock, flags);
642 state = rfkill->state;
643 spin_unlock_irqrestore(&rfkill->lock, flags);
644
645 return sprintf(buf, "%d\n", user_state_from_blocked(state));
646}
647
648static ssize_t rfkill_state_store(struct device *dev,
649 struct device_attribute *attr,
650 const char *buf, size_t count)
651{
652 /*
653 * The intention was that userspace can only take control over
654 * a given device when/if rfkill-input doesn't control it due
655 * to user_claim. Since user_claim is currently unsupported,
656 * we never support changing the state from userspace -- this
657 * can be implemented again later.
658 */
659
660 return -EPERM;
661}
662
663static ssize_t rfkill_claim_show(struct device *dev,
664 struct device_attribute *attr,
665 char *buf)
666{
667 return sprintf(buf, "%d\n", 0);
668}
669
670static ssize_t rfkill_claim_store(struct device *dev,
671 struct device_attribute *attr,
672 const char *buf, size_t count)
673{
674 return -EOPNOTSUPP;
675}
676
677static struct device_attribute rfkill_dev_attrs[] = {
678 __ATTR(name, S_IRUGO, rfkill_name_show, NULL),
679 __ATTR(type, S_IRUGO, rfkill_type_show, NULL),
680 __ATTR(index, S_IRUGO, rfkill_idx_show, NULL),
681 __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store),
682 __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),
683 __ATTR_NULL
684};
685
686static void rfkill_release(struct device *dev)
687{
688 struct rfkill *rfkill = to_rfkill(dev);
689
690 kfree(rfkill);
691}
692
693static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
694{
695 struct rfkill *rfkill = to_rfkill(dev);
696 unsigned long flags;
697 u32 state;
698 int error;
699
700 error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name);
701 if (error)
702 return error;
703 error = add_uevent_var(env, "RFKILL_TYPE=%s",
704 rfkill_get_type_str(rfkill->type));
705 if (error)
706 return error;
707 spin_lock_irqsave(&rfkill->lock, flags);
708 state = rfkill->state;
709 spin_unlock_irqrestore(&rfkill->lock, flags);
710 error = add_uevent_var(env, "RFKILL_STATE=%d",
711 user_state_from_blocked(state));
712 return error;
713}
714
715void rfkill_pause_polling(struct rfkill *rfkill)
716{
717 BUG_ON(!rfkill);
718
719 if (!rfkill->ops->poll)
720 return;
721
722 cancel_delayed_work_sync(&rfkill->poll_work);
723}
724EXPORT_SYMBOL(rfkill_pause_polling);
725
726void rfkill_resume_polling(struct rfkill *rfkill)
727{
728 BUG_ON(!rfkill);
729
730 if (!rfkill->ops->poll)
731 return;
732
733 schedule_work(&rfkill->poll_work.work);
734}
735EXPORT_SYMBOL(rfkill_resume_polling);
736
737static int rfkill_suspend(struct device *dev, pm_message_t state)
738{
739 struct rfkill *rfkill = to_rfkill(dev);
740
741 rfkill_pause_polling(rfkill);
742
743 rfkill->suspended = true;
744
745 return 0;
746}
747
748static int rfkill_resume(struct device *dev)
749{
750 struct rfkill *rfkill = to_rfkill(dev);
751 bool cur;
752
753 mutex_lock(&rfkill_global_mutex);
754 cur = rfkill_global_states[rfkill->type].cur;
755 rfkill_set_block(rfkill, cur);
756 mutex_unlock(&rfkill_global_mutex);
757
758 rfkill->suspended = false;
759
760 schedule_work(&rfkill->uevent_work);
761
762 rfkill_resume_polling(rfkill);
763
764 return 0;
765}
766
767static struct class rfkill_class = {
768 .name = "rfkill",
769 .dev_release = rfkill_release,
770 .dev_attrs = rfkill_dev_attrs,
771 .dev_uevent = rfkill_dev_uevent,
772 .suspend = rfkill_suspend,
773 .resume = rfkill_resume,
774};
775
776bool rfkill_blocked(struct rfkill *rfkill)
777{
778 unsigned long flags;
779 u32 state;
780
781 spin_lock_irqsave(&rfkill->lock, flags);
782 state = rfkill->state;
783 spin_unlock_irqrestore(&rfkill->lock, flags);
784
785 return !!(state & RFKILL_BLOCK_ANY);
786}
787EXPORT_SYMBOL(rfkill_blocked);
788
789
790struct rfkill * __must_check rfkill_alloc(const char *name,
791 struct device *parent,
792 const enum rfkill_type type,
793 const struct rfkill_ops *ops,
794 void *ops_data)
795{
796 struct rfkill *rfkill;
797 struct device *dev;
798
799 if (WARN_ON(!ops))
800 return NULL;
801
802 if (WARN_ON(!ops->set_block))
803 return NULL;
804
805 if (WARN_ON(!name))
806 return NULL;
807
808 if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES))
809 return NULL;
810
811 rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);
812 if (!rfkill)
813 return NULL;
814
815 spin_lock_init(&rfkill->lock);
816 INIT_LIST_HEAD(&rfkill->node);
817 rfkill->type = type;
818 rfkill->name = name;
819 rfkill->ops = ops;
820 rfkill->data = ops_data;
821
822 dev = &rfkill->dev;
823 dev->class = &rfkill_class;
824 dev->parent = parent;
825 device_initialize(dev);
826
827 return rfkill;
828}
829EXPORT_SYMBOL(rfkill_alloc);
830
831static void rfkill_poll(struct work_struct *work)
832{
833 struct rfkill *rfkill;
834
835 rfkill = container_of(work, struct rfkill, poll_work.work);
836
837 /*
838 * Poll hardware state -- driver will use one of the
839 * rfkill_set{,_hw,_sw}_state functions and use its
840 * return value to update the current status.
841 */
842 rfkill->ops->poll(rfkill, rfkill->data);
843
844 schedule_delayed_work(&rfkill->poll_work,
845 round_jiffies_relative(POLL_INTERVAL));
846}
847
848static void rfkill_uevent_work(struct work_struct *work)
849{
850 struct rfkill *rfkill;
851
852 rfkill = container_of(work, struct rfkill, uevent_work);
853
854 mutex_lock(&rfkill_global_mutex);
855 rfkill_event(rfkill);
856 mutex_unlock(&rfkill_global_mutex);
857}
858
859static void rfkill_sync_work(struct work_struct *work)
860{
861 struct rfkill *rfkill;
862 bool cur;
863
864 rfkill = container_of(work, struct rfkill, sync_work);
865
866 mutex_lock(&rfkill_global_mutex);
867 cur = rfkill_global_states[rfkill->type].cur;
868 rfkill_set_block(rfkill, cur);
869 mutex_unlock(&rfkill_global_mutex);
870}
871
872int __must_check rfkill_register(struct rfkill *rfkill)
873{
874 static unsigned long rfkill_no;
875 struct device *dev = &rfkill->dev;
876 int error;
877
878 BUG_ON(!rfkill);
879
880 mutex_lock(&rfkill_global_mutex);
881
882 if (rfkill->registered) {
883 error = -EALREADY;
884 goto unlock;
885 }
886
887 rfkill->idx = rfkill_no;
888 dev_set_name(dev, "rfkill%lu", rfkill_no);
889 rfkill_no++;
890
891 if (!(rfkill_states_default_locked & BIT(rfkill->type))) {
892 /* first of its kind */
893 BUILD_BUG_ON(NUM_RFKILL_TYPES >
894 sizeof(rfkill_states_default_locked) * 8);
895 rfkill_states_default_locked |= BIT(rfkill->type);
896 rfkill_global_states[rfkill->type].cur =
897 rfkill_global_states[rfkill->type].def;
898 }
899
900 list_add_tail(&rfkill->node, &rfkill_list);
901
902 error = device_add(dev);
903 if (error)
904 goto remove;
905
906 error = rfkill_led_trigger_register(rfkill);
907 if (error)
908 goto devdel;
909
910 rfkill->registered = true;
911
912 INIT_DELAYED_WORK(&rfkill->poll_work, rfkill_poll);
913 INIT_WORK(&rfkill->uevent_work, rfkill_uevent_work);
914 INIT_WORK(&rfkill->sync_work, rfkill_sync_work);
915
916 if (rfkill->ops->poll)
917 schedule_delayed_work(&rfkill->poll_work,
918 round_jiffies_relative(POLL_INTERVAL));
919 schedule_work(&rfkill->sync_work);
920
921 rfkill_send_events(rfkill, RFKILL_OP_ADD);
922
923 mutex_unlock(&rfkill_global_mutex);
924 return 0;
925
926 devdel:
927 device_del(&rfkill->dev);
928 remove:
929 list_del_init(&rfkill->node);
930 unlock:
931 mutex_unlock(&rfkill_global_mutex);
932 return error;
933}
934EXPORT_SYMBOL(rfkill_register);
935
936void rfkill_unregister(struct rfkill *rfkill)
937{
938 BUG_ON(!rfkill);
939
940 if (rfkill->ops->poll)
941 cancel_delayed_work_sync(&rfkill->poll_work);
942
943 cancel_work_sync(&rfkill->uevent_work);
944 cancel_work_sync(&rfkill->sync_work);
945
946 rfkill->registered = false;
947
948 device_del(&rfkill->dev);
949
950 mutex_lock(&rfkill_global_mutex);
951 rfkill_send_events(rfkill, RFKILL_OP_DEL);
952 list_del_init(&rfkill->node);
953 mutex_unlock(&rfkill_global_mutex);
954
955 rfkill_led_trigger_unregister(rfkill);
956}
957EXPORT_SYMBOL(rfkill_unregister);
958
959void rfkill_destroy(struct rfkill *rfkill)
960{
961 if (rfkill)
962 put_device(&rfkill->dev);
963}
964EXPORT_SYMBOL(rfkill_destroy);
965
966static int rfkill_fop_open(struct inode *inode, struct file *file)
967{
968 struct rfkill_data *data;
969 struct rfkill *rfkill;
970 struct rfkill_int_event *ev, *tmp;
971
972 data = kzalloc(sizeof(*data), GFP_KERNEL);
973 if (!data)
974 return -ENOMEM;
975
976 INIT_LIST_HEAD(&data->events);
977 mutex_init(&data->mtx);
978 init_waitqueue_head(&data->read_wait);
979
980 mutex_lock(&rfkill_global_mutex);
981 mutex_lock(&data->mtx);
982 /*
983 * start getting events from elsewhere but hold mtx to get
984 * startup events added first
985 */
986 list_add(&data->list, &rfkill_fds);
987
988 list_for_each_entry(rfkill, &rfkill_list, node) {
989 ev = kzalloc(sizeof(*ev), GFP_KERNEL);
990 if (!ev)
991 goto free;
992 rfkill_fill_event(&ev->ev, rfkill, RFKILL_OP_ADD);
993 list_add_tail(&ev->list, &data->events);
994 }
995 mutex_unlock(&data->mtx);
996 mutex_unlock(&rfkill_global_mutex);
997
998 file->private_data = data;
999
1000 return nonseekable_open(inode, file);
1001
1002 free:
1003 mutex_unlock(&data->mtx);
1004 mutex_unlock(&rfkill_global_mutex);
1005 mutex_destroy(&data->mtx);
1006 list_for_each_entry_safe(ev, tmp, &data->events, list)
1007 kfree(ev);
1008 kfree(data);
1009 return -ENOMEM;
1010}
1011
1012static unsigned int rfkill_fop_poll(struct file *file, poll_table *wait)
1013{
1014 struct rfkill_data *data = file->private_data;
1015 unsigned int res = POLLOUT | POLLWRNORM;
1016
1017 poll_wait(file, &data->read_wait, wait);
1018
1019 mutex_lock(&data->mtx);
1020 if (!list_empty(&data->events))
1021 res = POLLIN | POLLRDNORM;
1022 mutex_unlock(&data->mtx);
1023
1024 return res;
1025}
1026
1027static bool rfkill_readable(struct rfkill_data *data)
1028{
1029 bool r;
1030
1031 mutex_lock(&data->mtx);
1032 r = !list_empty(&data->events);
1033 mutex_unlock(&data->mtx);
1034
1035 return r;
1036}
1037
1038static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
1039 size_t count, loff_t *pos)
1040{
1041 struct rfkill_data *data = file->private_data;
1042 struct rfkill_int_event *ev;
1043 unsigned long sz;
1044 int ret;
1045
1046 mutex_lock(&data->mtx);
1047
1048 while (list_empty(&data->events)) {
1049 if (file->f_flags & O_NONBLOCK) {
1050 ret = -EAGAIN;
1051 goto out;
1052 }
1053 mutex_unlock(&data->mtx);
1054 ret = wait_event_interruptible(data->read_wait,
1055 rfkill_readable(data));
1056 mutex_lock(&data->mtx);
1057
1058 if (ret)
1059 goto out;
1060 }
1061
1062 ev = list_first_entry(&data->events, struct rfkill_int_event,
1063 list);
1064
1065 sz = min_t(unsigned long, sizeof(ev->ev), count);
1066 ret = sz;
1067 if (copy_to_user(buf, &ev->ev, sz))
1068 ret = -EFAULT;
1069
1070 list_del(&ev->list);
1071 kfree(ev);
1072 out:
1073 mutex_unlock(&data->mtx);
1074 return ret;
1075}
1076
1077static ssize_t rfkill_fop_write(struct file *file, const char __user *buf,
1078 size_t count, loff_t *pos)
1079{
1080 struct rfkill *rfkill;
1081 struct rfkill_event ev;
1082
1083 /* we don't need the 'hard' variable but accept it */
1084 if (count < sizeof(ev) - 1)
1085 return -EINVAL;
1086
1087 if (copy_from_user(&ev, buf, sizeof(ev) - 1))
1088 return -EFAULT;
1089
1090 if (ev.op != RFKILL_OP_CHANGE && ev.op != RFKILL_OP_CHANGE_ALL)
1091 return -EINVAL;
1092
1093 if (ev.type >= NUM_RFKILL_TYPES)
1094 return -EINVAL;
1095
1096 mutex_lock(&rfkill_global_mutex);
1097
1098 if (ev.op == RFKILL_OP_CHANGE_ALL) {
1099 if (ev.type == RFKILL_TYPE_ALL) {
1100 enum rfkill_type i;
1101 for (i = 0; i < NUM_RFKILL_TYPES; i++)
1102 rfkill_global_states[i].cur = ev.soft;
1103 } else {
1104 rfkill_global_states[ev.type].cur = ev.soft;
1105 }
1106 }
1107
1108 list_for_each_entry(rfkill, &rfkill_list, node) {
1109 if (rfkill->idx != ev.idx && ev.op != RFKILL_OP_CHANGE_ALL)
1110 continue;
1111
1112 if (rfkill->type != ev.type && ev.type != RFKILL_TYPE_ALL)
1113 continue;
1114
1115 rfkill_set_block(rfkill, ev.soft);
1116 }
1117 mutex_unlock(&rfkill_global_mutex);
1118
1119 return count;
1120}
1121
1122static int rfkill_fop_release(struct inode *inode, struct file *file)
1123{
1124 struct rfkill_data *data = file->private_data;
1125 struct rfkill_int_event *ev, *tmp;
1126
1127 mutex_lock(&rfkill_global_mutex);
1128 list_del(&data->list);
1129 mutex_unlock(&rfkill_global_mutex);
1130
1131 mutex_destroy(&data->mtx);
1132 list_for_each_entry_safe(ev, tmp, &data->events, list)
1133 kfree(ev);
1134
1135#ifdef CONFIG_RFKILL_INPUT
1136 if (data->input_handler)
1137 atomic_dec(&rfkill_input_disabled);
1138#endif
1139
1140 kfree(data);
1141
1142 return 0;
1143}
1144
1145#ifdef CONFIG_RFKILL_INPUT
1146static long rfkill_fop_ioctl(struct file *file, unsigned int cmd,
1147 unsigned long arg)
1148{
1149 struct rfkill_data *data = file->private_data;
1150
1151 if (_IOC_TYPE(cmd) != RFKILL_IOC_MAGIC)
1152 return -ENOSYS;
1153
1154 if (_IOC_NR(cmd) != RFKILL_IOC_NOINPUT)
1155 return -ENOSYS;
1156
1157 mutex_lock(&data->mtx);
1158
1159 if (!data->input_handler) {
1160 atomic_inc(&rfkill_input_disabled);
1161 data->input_handler = true;
1162 }
1163
1164 mutex_unlock(&data->mtx);
1165
1166 return 0;
1167}
1168#endif
1169
1170static const struct file_operations rfkill_fops = {
1171 .open = rfkill_fop_open,
1172 .read = rfkill_fop_read,
1173 .write = rfkill_fop_write,
1174 .poll = rfkill_fop_poll,
1175 .release = rfkill_fop_release,
1176#ifdef CONFIG_RFKILL_INPUT
1177 .unlocked_ioctl = rfkill_fop_ioctl,
1178 .compat_ioctl = rfkill_fop_ioctl,
1179#endif
1180};
1181
1182static struct miscdevice rfkill_miscdev = {
1183 .name = "rfkill",
1184 .fops = &rfkill_fops,
1185 .minor = MISC_DYNAMIC_MINOR,
1186};
1187
1188static int __init rfkill_init(void)
1189{
1190 int error;
1191 int i;
1192
1193 for (i = 0; i < NUM_RFKILL_TYPES; i++)
1194 rfkill_global_states[i].def = !rfkill_default_state;
1195
1196 error = class_register(&rfkill_class);
1197 if (error)
1198 goto out;
1199
1200 error = misc_register(&rfkill_miscdev);
1201 if (error) {
1202 class_unregister(&rfkill_class);
1203 goto out;
1204 }
1205
1206#ifdef CONFIG_RFKILL_INPUT
1207 error = rfkill_handler_init();
1208 if (error) {
1209 misc_deregister(&rfkill_miscdev);
1210 class_unregister(&rfkill_class);
1211 goto out;
1212 }
1213#endif
1214
1215 out:
1216 return error;
1217}
1218subsys_initcall(rfkill_init);
1219
1220static void __exit rfkill_exit(void)
1221{
1222#ifdef CONFIG_RFKILL_INPUT
1223 rfkill_handler_exit();
1224#endif
1225 misc_deregister(&rfkill_miscdev);
1226 class_unregister(&rfkill_class);
1227}
1228module_exit(rfkill_exit);
diff --git a/net/rfkill/input.c b/net/rfkill/input.c
new file mode 100644
index 000000000000..a7295ad5f9cb
--- /dev/null
+++ b/net/rfkill/input.c
@@ -0,0 +1,342 @@
1/*
2 * Input layer to RF Kill interface connector
3 *
4 * Copyright (c) 2007 Dmitry Torokhov
5 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published
9 * by the Free Software Foundation.
10 *
11 * If you ever run into a situation in which you have a SW_ type rfkill
12 * input device, then you can revive code that was removed in the patch
13 * "rfkill-input: remove unused code".
14 */
15
16#include <linux/input.h>
17#include <linux/slab.h>
18#include <linux/workqueue.h>
19#include <linux/init.h>
20#include <linux/rfkill.h>
21#include <linux/sched.h>
22
23#include "rfkill.h"
24
25enum rfkill_input_master_mode {
26 RFKILL_INPUT_MASTER_UNLOCK = 0,
27 RFKILL_INPUT_MASTER_RESTORE = 1,
28 RFKILL_INPUT_MASTER_UNBLOCKALL = 2,
29 NUM_RFKILL_INPUT_MASTER_MODES
30};
31
32/* Delay (in ms) between consecutive switch ops */
33#define RFKILL_OPS_DELAY 200
34
35static enum rfkill_input_master_mode rfkill_master_switch_mode =
36 RFKILL_INPUT_MASTER_UNBLOCKALL;
37module_param_named(master_switch_mode, rfkill_master_switch_mode, uint, 0);
38MODULE_PARM_DESC(master_switch_mode,
39 "SW_RFKILL_ALL ON should: 0=do nothing (only unlock); 1=restore; 2=unblock all");
40
41static spinlock_t rfkill_op_lock;
42static bool rfkill_op_pending;
43static unsigned long rfkill_sw_pending[BITS_TO_LONGS(NUM_RFKILL_TYPES)];
44static unsigned long rfkill_sw_state[BITS_TO_LONGS(NUM_RFKILL_TYPES)];
45
46enum rfkill_sched_op {
47 RFKILL_GLOBAL_OP_EPO = 0,
48 RFKILL_GLOBAL_OP_RESTORE,
49 RFKILL_GLOBAL_OP_UNLOCK,
50 RFKILL_GLOBAL_OP_UNBLOCK,
51};
52
53static enum rfkill_sched_op rfkill_master_switch_op;
54static enum rfkill_sched_op rfkill_op;
55
56static void __rfkill_handle_global_op(enum rfkill_sched_op op)
57{
58 unsigned int i;
59
60 switch (op) {
61 case RFKILL_GLOBAL_OP_EPO:
62 rfkill_epo();
63 break;
64 case RFKILL_GLOBAL_OP_RESTORE:
65 rfkill_restore_states();
66 break;
67 case RFKILL_GLOBAL_OP_UNLOCK:
68 rfkill_remove_epo_lock();
69 break;
70 case RFKILL_GLOBAL_OP_UNBLOCK:
71 rfkill_remove_epo_lock();
72 for (i = 0; i < NUM_RFKILL_TYPES; i++)
73 rfkill_switch_all(i, false);
74 break;
75 default:
76 /* memory corruption or bug, fail safely */
77 rfkill_epo();
78 WARN(1, "Unknown requested operation %d! "
79 "rfkill Emergency Power Off activated\n",
80 op);
81 }
82}
83
84static void __rfkill_handle_normal_op(const enum rfkill_type type,
85 const bool complement)
86{
87 bool blocked;
88
89 blocked = rfkill_get_global_sw_state(type);
90 if (complement)
91 blocked = !blocked;
92
93 rfkill_switch_all(type, blocked);
94}
95
96static void rfkill_op_handler(struct work_struct *work)
97{
98 unsigned int i;
99 bool c;
100
101 spin_lock_irq(&rfkill_op_lock);
102 do {
103 if (rfkill_op_pending) {
104 enum rfkill_sched_op op = rfkill_op;
105 rfkill_op_pending = false;
106 memset(rfkill_sw_pending, 0,
107 sizeof(rfkill_sw_pending));
108 spin_unlock_irq(&rfkill_op_lock);
109
110 __rfkill_handle_global_op(op);
111
112 spin_lock_irq(&rfkill_op_lock);
113
114 /*
115 * handle global ops first -- during unlocked period
116 * we might have gotten a new global op.
117 */
118 if (rfkill_op_pending)
119 continue;
120 }
121
122 if (rfkill_is_epo_lock_active())
123 continue;
124
125 for (i = 0; i < NUM_RFKILL_TYPES; i++) {
126 if (__test_and_clear_bit(i, rfkill_sw_pending)) {
127 c = __test_and_clear_bit(i, rfkill_sw_state);
128 spin_unlock_irq(&rfkill_op_lock);
129
130 __rfkill_handle_normal_op(i, c);
131
132 spin_lock_irq(&rfkill_op_lock);
133 }
134 }
135 } while (rfkill_op_pending);
136 spin_unlock_irq(&rfkill_op_lock);
137}
138
139static DECLARE_DELAYED_WORK(rfkill_op_work, rfkill_op_handler);
140static unsigned long rfkill_last_scheduled;
141
142static unsigned long rfkill_ratelimit(const unsigned long last)
143{
144 const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY);
145 return (time_after(jiffies, last + delay)) ? 0 : delay;
146}
147
148static void rfkill_schedule_ratelimited(void)
149{
150 if (delayed_work_pending(&rfkill_op_work))
151 return;
152 schedule_delayed_work(&rfkill_op_work,
153 rfkill_ratelimit(rfkill_last_scheduled));
154 rfkill_last_scheduled = jiffies;
155}
156
157static void rfkill_schedule_global_op(enum rfkill_sched_op op)
158{
159 unsigned long flags;
160
161 spin_lock_irqsave(&rfkill_op_lock, flags);
162 rfkill_op = op;
163 rfkill_op_pending = true;
164 if (op == RFKILL_GLOBAL_OP_EPO && !rfkill_is_epo_lock_active()) {
165 /* bypass the limiter for EPO */
166 cancel_delayed_work(&rfkill_op_work);
167 schedule_delayed_work(&rfkill_op_work, 0);
168 rfkill_last_scheduled = jiffies;
169 } else
170 rfkill_schedule_ratelimited();
171 spin_unlock_irqrestore(&rfkill_op_lock, flags);
172}
173
174static void rfkill_schedule_toggle(enum rfkill_type type)
175{
176 unsigned long flags;
177
178 if (rfkill_is_epo_lock_active())
179 return;
180
181 spin_lock_irqsave(&rfkill_op_lock, flags);
182 if (!rfkill_op_pending) {
183 __set_bit(type, rfkill_sw_pending);
184 __change_bit(type, rfkill_sw_state);
185 rfkill_schedule_ratelimited();
186 }
187 spin_unlock_irqrestore(&rfkill_op_lock, flags);
188}
189
190static void rfkill_schedule_evsw_rfkillall(int state)
191{
192 if (state)
193 rfkill_schedule_global_op(rfkill_master_switch_op);
194 else
195 rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO);
196}
197
198static void rfkill_event(struct input_handle *handle, unsigned int type,
199 unsigned int code, int data)
200{
201 if (type == EV_KEY && data == 1) {
202 switch (code) {
203 case KEY_WLAN:
204 rfkill_schedule_toggle(RFKILL_TYPE_WLAN);
205 break;
206 case KEY_BLUETOOTH:
207 rfkill_schedule_toggle(RFKILL_TYPE_BLUETOOTH);
208 break;
209 case KEY_UWB:
210 rfkill_schedule_toggle(RFKILL_TYPE_UWB);
211 break;
212 case KEY_WIMAX:
213 rfkill_schedule_toggle(RFKILL_TYPE_WIMAX);
214 break;
215 }
216 } else if (type == EV_SW && code == SW_RFKILL_ALL)
217 rfkill_schedule_evsw_rfkillall(data);
218}
219
220static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
221 const struct input_device_id *id)
222{
223 struct input_handle *handle;
224 int error;
225
226 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
227 if (!handle)
228 return -ENOMEM;
229
230 handle->dev = dev;
231 handle->handler = handler;
232 handle->name = "rfkill";
233
234 /* causes rfkill_start() to be called */
235 error = input_register_handle(handle);
236 if (error)
237 goto err_free_handle;
238
239 error = input_open_device(handle);
240 if (error)
241 goto err_unregister_handle;
242
243 return 0;
244
245 err_unregister_handle:
246 input_unregister_handle(handle);
247 err_free_handle:
248 kfree(handle);
249 return error;
250}
251
252static void rfkill_start(struct input_handle *handle)
253{
254 /*
255 * Take event_lock to guard against configuration changes, we
256 * should be able to deal with concurrency with rfkill_event()
257 * just fine (which event_lock will also avoid).
258 */
259 spin_lock_irq(&handle->dev->event_lock);
260
261 if (test_bit(EV_SW, handle->dev->evbit) &&
262 test_bit(SW_RFKILL_ALL, handle->dev->swbit))
263 rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL,
264 handle->dev->sw));
265
266 spin_unlock_irq(&handle->dev->event_lock);
267}
268
269static void rfkill_disconnect(struct input_handle *handle)
270{
271 input_close_device(handle);
272 input_unregister_handle(handle);
273 kfree(handle);
274}
275
276static const struct input_device_id rfkill_ids[] = {
277 {
278 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
279 .evbit = { BIT_MASK(EV_KEY) },
280 .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) },
281 },
282 {
283 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
284 .evbit = { BIT_MASK(EV_KEY) },
285 .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) },
286 },
287 {
288 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
289 .evbit = { BIT_MASK(EV_KEY) },
290 .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },
291 },
292 {
293 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
294 .evbit = { BIT_MASK(EV_KEY) },
295 .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
296 },
297 {
298 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,
299 .evbit = { BIT(EV_SW) },
300 .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },
301 },
302 { }
303};
304
305static struct input_handler rfkill_handler = {
306 .name = "rfkill",
307 .event = rfkill_event,
308 .connect = rfkill_connect,
309 .start = rfkill_start,
310 .disconnect = rfkill_disconnect,
311 .id_table = rfkill_ids,
312};
313
314int __init rfkill_handler_init(void)
315{
316 switch (rfkill_master_switch_mode) {
317 case RFKILL_INPUT_MASTER_UNBLOCKALL:
318 rfkill_master_switch_op = RFKILL_GLOBAL_OP_UNBLOCK;
319 break;
320 case RFKILL_INPUT_MASTER_RESTORE:
321 rfkill_master_switch_op = RFKILL_GLOBAL_OP_RESTORE;
322 break;
323 case RFKILL_INPUT_MASTER_UNLOCK:
324 rfkill_master_switch_op = RFKILL_GLOBAL_OP_UNLOCK;
325 break;
326 default:
327 return -EINVAL;
328 }
329
330 spin_lock_init(&rfkill_op_lock);
331
332 /* Avoid delay at first schedule */
333 rfkill_last_scheduled =
334 jiffies - msecs_to_jiffies(RFKILL_OPS_DELAY) - 1;
335 return input_register_handler(&rfkill_handler);
336}
337
338void __exit rfkill_handler_exit(void)
339{
340 input_unregister_handler(&rfkill_handler);
341 cancel_delayed_work_sync(&rfkill_op_work);
342}
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
deleted file mode 100644
index 60a34f3b5f65..000000000000
--- a/net/rfkill/rfkill-input.c
+++ /dev/null
@@ -1,390 +0,0 @@
1/*
2 * Input layer to RF Kill interface connector
3 *
4 * Copyright (c) 2007 Dmitry Torokhov
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/input.h>
15#include <linux/slab.h>
16#include <linux/workqueue.h>
17#include <linux/init.h>
18#include <linux/rfkill.h>
19#include <linux/sched.h>
20
21#include "rfkill-input.h"
22
23MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
24MODULE_DESCRIPTION("Input layer to RF switch connector");
25MODULE_LICENSE("GPL");
26
27enum rfkill_input_master_mode {
28 RFKILL_INPUT_MASTER_DONOTHING = 0,
29 RFKILL_INPUT_MASTER_RESTORE = 1,
30 RFKILL_INPUT_MASTER_UNBLOCKALL = 2,
31 RFKILL_INPUT_MASTER_MAX, /* marker */
32};
33
34/* Delay (in ms) between consecutive switch ops */
35#define RFKILL_OPS_DELAY 200
36
37static enum rfkill_input_master_mode rfkill_master_switch_mode =
38 RFKILL_INPUT_MASTER_UNBLOCKALL;
39module_param_named(master_switch_mode, rfkill_master_switch_mode, uint, 0);
40MODULE_PARM_DESC(master_switch_mode,
41 "SW_RFKILL_ALL ON should: 0=do nothing; 1=restore; 2=unblock all");
42
43enum rfkill_global_sched_op {
44 RFKILL_GLOBAL_OP_EPO = 0,
45 RFKILL_GLOBAL_OP_RESTORE,
46 RFKILL_GLOBAL_OP_UNLOCK,
47 RFKILL_GLOBAL_OP_UNBLOCK,
48};
49
50struct rfkill_task {
51 struct delayed_work dwork;
52
53 /* ensures that task is serialized */
54 struct mutex mutex;
55
56 /* protects everything below */
57 spinlock_t lock;
58
59 /* pending regular switch operations (1=pending) */
60 unsigned long sw_pending[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
61
62 /* should the state be complemented (1=yes) */
63 unsigned long sw_togglestate[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
64
65 bool global_op_pending;
66 enum rfkill_global_sched_op op;
67
68 /* last time it was scheduled */
69 unsigned long last_scheduled;
70};
71
72static void __rfkill_handle_global_op(enum rfkill_global_sched_op op)
73{
74 unsigned int i;
75
76 switch (op) {
77 case RFKILL_GLOBAL_OP_EPO:
78 rfkill_epo();
79 break;
80 case RFKILL_GLOBAL_OP_RESTORE:
81 rfkill_restore_states();
82 break;
83 case RFKILL_GLOBAL_OP_UNLOCK:
84 rfkill_remove_epo_lock();
85 break;
86 case RFKILL_GLOBAL_OP_UNBLOCK:
87 rfkill_remove_epo_lock();
88 for (i = 0; i < RFKILL_TYPE_MAX; i++)
89 rfkill_switch_all(i, RFKILL_STATE_UNBLOCKED);
90 break;
91 default:
92 /* memory corruption or bug, fail safely */
93 rfkill_epo();
94 WARN(1, "Unknown requested operation %d! "
95 "rfkill Emergency Power Off activated\n",
96 op);
97 }
98}
99
100static void __rfkill_handle_normal_op(const enum rfkill_type type,
101 const bool c)
102{
103 enum rfkill_state state;
104
105 state = rfkill_get_global_state(type);
106 if (c)
107 state = rfkill_state_complement(state);
108
109 rfkill_switch_all(type, state);
110}
111
112static void rfkill_task_handler(struct work_struct *work)
113{
114 struct rfkill_task *task = container_of(work,
115 struct rfkill_task, dwork.work);
116 bool doit = true;
117
118 mutex_lock(&task->mutex);
119
120 spin_lock_irq(&task->lock);
121 while (doit) {
122 if (task->global_op_pending) {
123 enum rfkill_global_sched_op op = task->op;
124 task->global_op_pending = false;
125 memset(task->sw_pending, 0, sizeof(task->sw_pending));
126 spin_unlock_irq(&task->lock);
127
128 __rfkill_handle_global_op(op);
129
130 /* make sure we do at least one pass with
131 * !task->global_op_pending */
132 spin_lock_irq(&task->lock);
133 continue;
134 } else if (!rfkill_is_epo_lock_active()) {
135 unsigned int i = 0;
136
137 while (!task->global_op_pending &&
138 i < RFKILL_TYPE_MAX) {
139 if (test_and_clear_bit(i, task->sw_pending)) {
140 bool c;
141 c = test_and_clear_bit(i,
142 task->sw_togglestate);
143 spin_unlock_irq(&task->lock);
144
145 __rfkill_handle_normal_op(i, c);
146
147 spin_lock_irq(&task->lock);
148 }
149 i++;
150 }
151 }
152 doit = task->global_op_pending;
153 }
154 spin_unlock_irq(&task->lock);
155
156 mutex_unlock(&task->mutex);
157}
158
159static struct rfkill_task rfkill_task = {
160 .dwork = __DELAYED_WORK_INITIALIZER(rfkill_task.dwork,
161 rfkill_task_handler),
162 .mutex = __MUTEX_INITIALIZER(rfkill_task.mutex),
163 .lock = __SPIN_LOCK_UNLOCKED(rfkill_task.lock),
164};
165
166static unsigned long rfkill_ratelimit(const unsigned long last)
167{
168 const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY);
169 return (time_after(jiffies, last + delay)) ? 0 : delay;
170}
171
172static void rfkill_schedule_ratelimited(void)
173{
174 if (!delayed_work_pending(&rfkill_task.dwork)) {
175 schedule_delayed_work(&rfkill_task.dwork,
176 rfkill_ratelimit(rfkill_task.last_scheduled));
177 rfkill_task.last_scheduled = jiffies;
178 }
179}
180
181static void rfkill_schedule_global_op(enum rfkill_global_sched_op op)
182{
183 unsigned long flags;
184
185 spin_lock_irqsave(&rfkill_task.lock, flags);
186 rfkill_task.op = op;
187 rfkill_task.global_op_pending = true;
188 if (op == RFKILL_GLOBAL_OP_EPO && !rfkill_is_epo_lock_active()) {
189 /* bypass the limiter for EPO */
190 cancel_delayed_work(&rfkill_task.dwork);
191 schedule_delayed_work(&rfkill_task.dwork, 0);
192 rfkill_task.last_scheduled = jiffies;
193 } else
194 rfkill_schedule_ratelimited();
195 spin_unlock_irqrestore(&rfkill_task.lock, flags);
196}
197
198static void rfkill_schedule_toggle(enum rfkill_type type)
199{
200 unsigned long flags;
201
202 if (rfkill_is_epo_lock_active())
203 return;
204
205 spin_lock_irqsave(&rfkill_task.lock, flags);
206 if (!rfkill_task.global_op_pending) {
207 set_bit(type, rfkill_task.sw_pending);
208 change_bit(type, rfkill_task.sw_togglestate);
209 rfkill_schedule_ratelimited();
210 }
211 spin_unlock_irqrestore(&rfkill_task.lock, flags);
212}
213
214static void rfkill_schedule_evsw_rfkillall(int state)
215{
216 if (state) {
217 switch (rfkill_master_switch_mode) {
218 case RFKILL_INPUT_MASTER_UNBLOCKALL:
219 rfkill_schedule_global_op(RFKILL_GLOBAL_OP_UNBLOCK);
220 break;
221 case RFKILL_INPUT_MASTER_RESTORE:
222 rfkill_schedule_global_op(RFKILL_GLOBAL_OP_RESTORE);
223 break;
224 case RFKILL_INPUT_MASTER_DONOTHING:
225 rfkill_schedule_global_op(RFKILL_GLOBAL_OP_UNLOCK);
226 break;
227 default:
228 /* memory corruption or driver bug! fail safely */
229 rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO);
230 WARN(1, "Unknown rfkill_master_switch_mode (%d), "
231 "driver bug or memory corruption detected!\n",
232 rfkill_master_switch_mode);
233 break;
234 }
235 } else
236 rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO);
237}
238
239static void rfkill_event(struct input_handle *handle, unsigned int type,
240 unsigned int code, int data)
241{
242 if (type == EV_KEY && data == 1) {
243 enum rfkill_type t;
244
245 switch (code) {
246 case KEY_WLAN:
247 t = RFKILL_TYPE_WLAN;
248 break;
249 case KEY_BLUETOOTH:
250 t = RFKILL_TYPE_BLUETOOTH;
251 break;
252 case KEY_UWB:
253 t = RFKILL_TYPE_UWB;
254 break;
255 case KEY_WIMAX:
256 t = RFKILL_TYPE_WIMAX;
257 break;
258 default:
259 return;
260 }
261 rfkill_schedule_toggle(t);
262 return;
263 } else if (type == EV_SW) {
264 switch (code) {
265 case SW_RFKILL_ALL:
266 rfkill_schedule_evsw_rfkillall(data);
267 return;
268 default:
269 return;
270 }
271 }
272}
273
274static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
275 const struct input_device_id *id)
276{
277 struct input_handle *handle;
278 int error;
279
280 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
281 if (!handle)
282 return -ENOMEM;
283
284 handle->dev = dev;
285 handle->handler = handler;
286 handle->name = "rfkill";
287
288 /* causes rfkill_start() to be called */
289 error = input_register_handle(handle);
290 if (error)
291 goto err_free_handle;
292
293 error = input_open_device(handle);
294 if (error)
295 goto err_unregister_handle;
296
297 return 0;
298
299 err_unregister_handle:
300 input_unregister_handle(handle);
301 err_free_handle:
302 kfree(handle);
303 return error;
304}
305
306static void rfkill_start(struct input_handle *handle)
307{
308 /* Take event_lock to guard against configuration changes, we
309 * should be able to deal with concurrency with rfkill_event()
310 * just fine (which event_lock will also avoid). */
311 spin_lock_irq(&handle->dev->event_lock);
312
313 if (test_bit(EV_SW, handle->dev->evbit)) {
314 if (test_bit(SW_RFKILL_ALL, handle->dev->swbit))
315 rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL,
316 handle->dev->sw));
317 /* add resync for further EV_SW events here */
318 }
319
320 spin_unlock_irq(&handle->dev->event_lock);
321}
322
323static void rfkill_disconnect(struct input_handle *handle)
324{
325 input_close_device(handle);
326 input_unregister_handle(handle);
327 kfree(handle);
328}
329
330static const struct input_device_id rfkill_ids[] = {
331 {
332 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
333 .evbit = { BIT_MASK(EV_KEY) },
334 .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) },
335 },
336 {
337 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
338 .evbit = { BIT_MASK(EV_KEY) },
339 .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) },
340 },
341 {
342 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
343 .evbit = { BIT_MASK(EV_KEY) },
344 .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },
345 },
346 {
347 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
348 .evbit = { BIT_MASK(EV_KEY) },
349 .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
350 },
351 {
352 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,
353 .evbit = { BIT(EV_SW) },
354 .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },
355 },
356 { }
357};
358
359static struct input_handler rfkill_handler = {
360 .event = rfkill_event,
361 .connect = rfkill_connect,
362 .disconnect = rfkill_disconnect,
363 .start = rfkill_start,
364 .name = "rfkill",
365 .id_table = rfkill_ids,
366};
367
368static int __init rfkill_handler_init(void)
369{
370 if (rfkill_master_switch_mode >= RFKILL_INPUT_MASTER_MAX)
371 return -EINVAL;
372
373 /*
374 * The penalty to not doing this is a possible RFKILL_OPS_DELAY delay
375 * at the first use. Acceptable, but if we can avoid it, why not?
376 */
377 rfkill_task.last_scheduled =
378 jiffies - msecs_to_jiffies(RFKILL_OPS_DELAY) - 1;
379 return input_register_handler(&rfkill_handler);
380}
381
382static void __exit rfkill_handler_exit(void)
383{
384 input_unregister_handler(&rfkill_handler);
385 cancel_delayed_work_sync(&rfkill_task.dwork);
386 rfkill_remove_epo_lock();
387}
388
389module_init(rfkill_handler_init);
390module_exit(rfkill_handler_exit);
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
deleted file mode 100644
index 4f5a83183c95..000000000000
--- a/net/rfkill/rfkill.c
+++ /dev/null
@@ -1,855 +0,0 @@
1/*
2 * Copyright (C) 2006 - 2007 Ivo van Doorn
3 * Copyright (C) 2007 Dmitry Torokhov
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the
17 * Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/workqueue.h>
25#include <linux/capability.h>
26#include <linux/list.h>
27#include <linux/mutex.h>
28#include <linux/rfkill.h>
29
30/* Get declaration of rfkill_switch_all() to shut up sparse. */
31#include "rfkill-input.h"
32
33
34MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
35MODULE_VERSION("1.0");
36MODULE_DESCRIPTION("RF switch support");
37MODULE_LICENSE("GPL");
38
39static LIST_HEAD(rfkill_list); /* list of registered rf switches */
40static DEFINE_MUTEX(rfkill_global_mutex);
41
42static unsigned int rfkill_default_state = RFKILL_STATE_UNBLOCKED;
43module_param_named(default_state, rfkill_default_state, uint, 0444);
44MODULE_PARM_DESC(default_state,
45 "Default initial state for all radio types, 0 = radio off");
46
47struct rfkill_gsw_state {
48 enum rfkill_state current_state;
49 enum rfkill_state default_state;
50};
51
52static struct rfkill_gsw_state rfkill_global_states[RFKILL_TYPE_MAX];
53static unsigned long rfkill_states_lockdflt[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
54static bool rfkill_epo_lock_active;
55
56
57#ifdef CONFIG_RFKILL_LEDS
58static void rfkill_led_trigger(struct rfkill *rfkill,
59 enum rfkill_state state)
60{
61 struct led_trigger *led = &rfkill->led_trigger;
62
63 if (!led->name)
64 return;
65 if (state != RFKILL_STATE_UNBLOCKED)
66 led_trigger_event(led, LED_OFF);
67 else
68 led_trigger_event(led, LED_FULL);
69}
70
71static void rfkill_led_trigger_activate(struct led_classdev *led)
72{
73 struct rfkill *rfkill = container_of(led->trigger,
74 struct rfkill, led_trigger);
75
76 rfkill_led_trigger(rfkill, rfkill->state);
77}
78#else
79static inline void rfkill_led_trigger(struct rfkill *rfkill,
80 enum rfkill_state state)
81{
82}
83#endif /* CONFIG_RFKILL_LEDS */
84
85static void rfkill_uevent(struct rfkill *rfkill)
86{
87 kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
88}
89
90static void update_rfkill_state(struct rfkill *rfkill)
91{
92 enum rfkill_state newstate, oldstate;
93
94 if (rfkill->get_state) {
95 mutex_lock(&rfkill->mutex);
96 if (!rfkill->get_state(rfkill->data, &newstate)) {
97 oldstate = rfkill->state;
98 rfkill->state = newstate;
99 if (oldstate != newstate)
100 rfkill_uevent(rfkill);
101 }
102 mutex_unlock(&rfkill->mutex);
103 }
104 rfkill_led_trigger(rfkill, rfkill->state);
105}
106
107/**
108 * rfkill_toggle_radio - wrapper for toggle_radio hook
109 * @rfkill: the rfkill struct to use
110 * @force: calls toggle_radio even if cache says it is not needed,
111 * and also makes sure notifications of the state will be
112 * sent even if it didn't change
113 * @state: the new state to call toggle_radio() with
114 *
115 * Calls rfkill->toggle_radio, enforcing the API for toggle_radio
116 * calls and handling all the red tape such as issuing notifications
117 * if the call is successful.
118 *
119 * Suspended devices are not touched at all, and -EAGAIN is returned.
120 *
121 * Note that the @force parameter cannot override a (possibly cached)
122 * state of RFKILL_STATE_HARD_BLOCKED. Any device making use of
123 * RFKILL_STATE_HARD_BLOCKED implements either get_state() or
124 * rfkill_force_state(), so the cache either is bypassed or valid.
125 *
126 * Note that we do call toggle_radio for RFKILL_STATE_SOFT_BLOCKED
127 * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to
128 * give the driver a hint that it should double-BLOCK the transmitter.
129 *
130 * Caller must have acquired rfkill->mutex.
131 */
132static int rfkill_toggle_radio(struct rfkill *rfkill,
133 enum rfkill_state state,
134 int force)
135{
136 int retval = 0;
137 enum rfkill_state oldstate, newstate;
138
139 if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP))
140 return -EBUSY;
141
142 oldstate = rfkill->state;
143
144 if (rfkill->get_state && !force &&
145 !rfkill->get_state(rfkill->data, &newstate)) {
146 rfkill->state = newstate;
147 }
148
149 switch (state) {
150 case RFKILL_STATE_HARD_BLOCKED:
151 /* typically happens when refreshing hardware state,
152 * such as on resume */
153 state = RFKILL_STATE_SOFT_BLOCKED;
154 break;
155 case RFKILL_STATE_UNBLOCKED:
156 /* force can't override this, only rfkill_force_state() can */
157 if (rfkill->state == RFKILL_STATE_HARD_BLOCKED)
158 return -EPERM;
159 break;
160 case RFKILL_STATE_SOFT_BLOCKED:
161 /* nothing to do, we want to give drivers the hint to double
162 * BLOCK even a transmitter that is already in state
163 * RFKILL_STATE_HARD_BLOCKED */
164 break;
165 default:
166 WARN(1, KERN_WARNING
167 "rfkill: illegal state %d passed as parameter "
168 "to rfkill_toggle_radio\n", state);
169 return -EINVAL;
170 }
171
172 if (force || state != rfkill->state) {
173 retval = rfkill->toggle_radio(rfkill->data, state);
174 /* never allow a HARD->SOFT downgrade! */
175 if (!retval && rfkill->state != RFKILL_STATE_HARD_BLOCKED)
176 rfkill->state = state;
177 }
178
179 if (force || rfkill->state != oldstate)
180 rfkill_uevent(rfkill);
181
182 rfkill_led_trigger(rfkill, rfkill->state);
183 return retval;
184}
185
186/**
187 * __rfkill_switch_all - Toggle state of all switches of given type
188 * @type: type of interfaces to be affected
189 * @state: the new state
190 *
191 * This function toggles the state of all switches of given type,
192 * unless a specific switch is claimed by userspace (in which case,
193 * that switch is left alone) or suspended.
194 *
195 * Caller must have acquired rfkill_global_mutex.
196 */
197static void __rfkill_switch_all(const enum rfkill_type type,
198 const enum rfkill_state state)
199{
200 struct rfkill *rfkill;
201
202 if (WARN((state >= RFKILL_STATE_MAX || type >= RFKILL_TYPE_MAX),
203 KERN_WARNING
204 "rfkill: illegal state %d or type %d "
205 "passed as parameter to __rfkill_switch_all\n",
206 state, type))
207 return;
208
209 rfkill_global_states[type].current_state = state;
210 list_for_each_entry(rfkill, &rfkill_list, node) {
211 if (rfkill->type == type) {
212 mutex_lock(&rfkill->mutex);
213 rfkill_toggle_radio(rfkill, state, 0);
214 mutex_unlock(&rfkill->mutex);
215 rfkill_led_trigger(rfkill, rfkill->state);
216 }
217 }
218}
219
220/**
221 * rfkill_switch_all - Toggle state of all switches of given type
222 * @type: type of interfaces to be affected
223 * @state: the new state
224 *
225 * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state).
226 * Please refer to __rfkill_switch_all() for details.
227 *
228 * Does nothing if the EPO lock is active.
229 */
230void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
231{
232 mutex_lock(&rfkill_global_mutex);
233 if (!rfkill_epo_lock_active)
234 __rfkill_switch_all(type, state);
235 mutex_unlock(&rfkill_global_mutex);
236}
237EXPORT_SYMBOL(rfkill_switch_all);
238
239/**
240 * rfkill_epo - emergency power off all transmitters
241 *
242 * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED,
243 * ignoring everything in its path but rfkill_global_mutex and rfkill->mutex.
244 *
245 * The global state before the EPO is saved and can be restored later
246 * using rfkill_restore_states().
247 */
248void rfkill_epo(void)
249{
250 struct rfkill *rfkill;
251 int i;
252
253 mutex_lock(&rfkill_global_mutex);
254
255 rfkill_epo_lock_active = true;
256 list_for_each_entry(rfkill, &rfkill_list, node) {
257 mutex_lock(&rfkill->mutex);
258 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
259 mutex_unlock(&rfkill->mutex);
260 }
261 for (i = 0; i < RFKILL_TYPE_MAX; i++) {
262 rfkill_global_states[i].default_state =
263 rfkill_global_states[i].current_state;
264 rfkill_global_states[i].current_state =
265 RFKILL_STATE_SOFT_BLOCKED;
266 }
267 mutex_unlock(&rfkill_global_mutex);
268 rfkill_led_trigger(rfkill, rfkill->state);
269}
270EXPORT_SYMBOL_GPL(rfkill_epo);
271
272/**
273 * rfkill_restore_states - restore global states
274 *
275 * Restore (and sync switches to) the global state from the
276 * states in rfkill_default_states. This can undo the effects of
277 * a call to rfkill_epo().
278 */
279void rfkill_restore_states(void)
280{
281 int i;
282
283 mutex_lock(&rfkill_global_mutex);
284
285 rfkill_epo_lock_active = false;
286 for (i = 0; i < RFKILL_TYPE_MAX; i++)
287 __rfkill_switch_all(i, rfkill_global_states[i].default_state);
288 mutex_unlock(&rfkill_global_mutex);
289}
290EXPORT_SYMBOL_GPL(rfkill_restore_states);
291
292/**
293 * rfkill_remove_epo_lock - unlock state changes
294 *
295 * Used by rfkill-input manually unlock state changes, when
296 * the EPO switch is deactivated.
297 */
298void rfkill_remove_epo_lock(void)
299{
300 mutex_lock(&rfkill_global_mutex);
301 rfkill_epo_lock_active = false;
302 mutex_unlock(&rfkill_global_mutex);
303}
304EXPORT_SYMBOL_GPL(rfkill_remove_epo_lock);
305
306/**
307 * rfkill_is_epo_lock_active - returns true EPO is active
308 *
309 * Returns 0 (false) if there is NOT an active EPO contidion,
310 * and 1 (true) if there is an active EPO contition, which
311 * locks all radios in one of the BLOCKED states.
312 *
313 * Can be called in atomic context.
314 */
315bool rfkill_is_epo_lock_active(void)
316{
317 return rfkill_epo_lock_active;
318}
319EXPORT_SYMBOL_GPL(rfkill_is_epo_lock_active);
320
321/**
322 * rfkill_get_global_state - returns global state for a type
323 * @type: the type to get the global state of
324 *
325 * Returns the current global state for a given wireless
326 * device type.
327 */
328enum rfkill_state rfkill_get_global_state(const enum rfkill_type type)
329{
330 return rfkill_global_states[type].current_state;
331}
332EXPORT_SYMBOL_GPL(rfkill_get_global_state);
333
334/**
335 * rfkill_force_state - Force the internal rfkill radio state
336 * @rfkill: pointer to the rfkill class to modify.
337 * @state: the current radio state the class should be forced to.
338 *
339 * This function updates the internal state of the radio cached
340 * by the rfkill class. It should be used when the driver gets
341 * a notification by the firmware/hardware of the current *real*
342 * state of the radio rfkill switch.
343 *
344 * Devices which are subject to external changes on their rfkill
345 * state (such as those caused by a hardware rfkill line) MUST
346 * have their driver arrange to call rfkill_force_state() as soon
347 * as possible after such a change.
348 *
349 * This function may not be called from an atomic context.
350 */
351int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
352{
353 enum rfkill_state oldstate;
354
355 BUG_ON(!rfkill);
356 if (WARN((state >= RFKILL_STATE_MAX),
357 KERN_WARNING
358 "rfkill: illegal state %d passed as parameter "
359 "to rfkill_force_state\n", state))
360 return -EINVAL;
361
362 mutex_lock(&rfkill->mutex);
363
364 oldstate = rfkill->state;
365 rfkill->state = state;
366
367 if (state != oldstate)
368 rfkill_uevent(rfkill);
369
370 mutex_unlock(&rfkill->mutex);
371 rfkill_led_trigger(rfkill, rfkill->state);
372
373 return 0;
374}
375EXPORT_SYMBOL(rfkill_force_state);
376
377static ssize_t rfkill_name_show(struct device *dev,
378 struct device_attribute *attr,
379 char *buf)
380{
381 struct rfkill *rfkill = to_rfkill(dev);
382
383 return sprintf(buf, "%s\n", rfkill->name);
384}
385
386static const char *rfkill_get_type_str(enum rfkill_type type)
387{
388 switch (type) {
389 case RFKILL_TYPE_WLAN:
390 return "wlan";
391 case RFKILL_TYPE_BLUETOOTH:
392 return "bluetooth";
393 case RFKILL_TYPE_UWB:
394 return "ultrawideband";
395 case RFKILL_TYPE_WIMAX:
396 return "wimax";
397 case RFKILL_TYPE_WWAN:
398 return "wwan";
399 default:
400 BUG();
401 }
402}
403
404static ssize_t rfkill_type_show(struct device *dev,
405 struct device_attribute *attr,
406 char *buf)
407{
408 struct rfkill *rfkill = to_rfkill(dev);
409
410 return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));
411}
412
413static ssize_t rfkill_state_show(struct device *dev,
414 struct device_attribute *attr,
415 char *buf)
416{
417 struct rfkill *rfkill = to_rfkill(dev);
418
419 update_rfkill_state(rfkill);
420 return sprintf(buf, "%d\n", rfkill->state);
421}
422
423static ssize_t rfkill_state_store(struct device *dev,
424 struct device_attribute *attr,
425 const char *buf, size_t count)
426{
427 struct rfkill *rfkill = to_rfkill(dev);
428 unsigned long state;
429 int error;
430
431 if (!capable(CAP_NET_ADMIN))
432 return -EPERM;
433
434 error = strict_strtoul(buf, 0, &state);
435 if (error)
436 return error;
437
438 /* RFKILL_STATE_HARD_BLOCKED is illegal here... */
439 if (state != RFKILL_STATE_UNBLOCKED &&
440 state != RFKILL_STATE_SOFT_BLOCKED)
441 return -EINVAL;
442
443 error = mutex_lock_killable(&rfkill->mutex);
444 if (error)
445 return error;
446
447 if (!rfkill_epo_lock_active)
448 error = rfkill_toggle_radio(rfkill, state, 0);
449 else
450 error = -EPERM;
451
452 mutex_unlock(&rfkill->mutex);
453
454 return error ? error : count;
455}
456
457static ssize_t rfkill_claim_show(struct device *dev,
458 struct device_attribute *attr,
459 char *buf)
460{
461 return sprintf(buf, "%d\n", 0);
462}
463
464static ssize_t rfkill_claim_store(struct device *dev,
465 struct device_attribute *attr,
466 const char *buf, size_t count)
467{
468 return -EOPNOTSUPP;
469}
470
471static struct device_attribute rfkill_dev_attrs[] = {
472 __ATTR(name, S_IRUGO, rfkill_name_show, NULL),
473 __ATTR(type, S_IRUGO, rfkill_type_show, NULL),
474 __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store),
475 __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),
476 __ATTR_NULL
477};
478
479static void rfkill_release(struct device *dev)
480{
481 struct rfkill *rfkill = to_rfkill(dev);
482
483 kfree(rfkill);
484 module_put(THIS_MODULE);
485}
486
487#ifdef CONFIG_PM
488static int rfkill_suspend(struct device *dev, pm_message_t state)
489{
490 struct rfkill *rfkill = to_rfkill(dev);
491
492 /* mark class device as suspended */
493 if (dev->power.power_state.event != state.event)
494 dev->power.power_state = state;
495
496 /* store state for the resume handler */
497 rfkill->state_for_resume = rfkill->state;
498
499 return 0;
500}
501
502static int rfkill_resume(struct device *dev)
503{
504 struct rfkill *rfkill = to_rfkill(dev);
505 enum rfkill_state newstate;
506
507 if (dev->power.power_state.event != PM_EVENT_ON) {
508 mutex_lock(&rfkill->mutex);
509
510 dev->power.power_state.event = PM_EVENT_ON;
511
512 /*
513 * rfkill->state could have been modified before we got
514 * called, and won't be updated by rfkill_toggle_radio()
515 * in force mode. Sync it FIRST.
516 */
517 if (rfkill->get_state &&
518 !rfkill->get_state(rfkill->data, &newstate))
519 rfkill->state = newstate;
520
521 /*
522 * If we are under EPO, kick transmitter offline,
523 * otherwise restore to pre-suspend state.
524 *
525 * Issue a notification in any case
526 */
527 rfkill_toggle_radio(rfkill,
528 rfkill_epo_lock_active ?
529 RFKILL_STATE_SOFT_BLOCKED :
530 rfkill->state_for_resume,
531 1);
532
533 mutex_unlock(&rfkill->mutex);
534 rfkill_led_trigger(rfkill, rfkill->state);
535 }
536
537 return 0;
538}
539#else
540#define rfkill_suspend NULL
541#define rfkill_resume NULL
542#endif
543
544static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
545{
546 struct rfkill *rfkill = to_rfkill(dev);
547 int error;
548
549 error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name);
550 if (error)
551 return error;
552 error = add_uevent_var(env, "RFKILL_TYPE=%s",
553 rfkill_get_type_str(rfkill->type));
554 if (error)
555 return error;
556 error = add_uevent_var(env, "RFKILL_STATE=%d", rfkill->state);
557 return error;
558}
559
560static struct class rfkill_class = {
561 .name = "rfkill",
562 .dev_release = rfkill_release,
563 .dev_attrs = rfkill_dev_attrs,
564 .suspend = rfkill_suspend,
565 .resume = rfkill_resume,
566 .dev_uevent = rfkill_dev_uevent,
567};
568
569static int rfkill_check_duplicity(const struct rfkill *rfkill)
570{
571 struct rfkill *p;
572 unsigned long seen[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
573
574 memset(seen, 0, sizeof(seen));
575
576 list_for_each_entry(p, &rfkill_list, node) {
577 if (WARN((p == rfkill), KERN_WARNING
578 "rfkill: illegal attempt to register "
579 "an already registered rfkill struct\n"))
580 return -EEXIST;
581 set_bit(p->type, seen);
582 }
583
584 /* 0: first switch of its kind */
585 return (test_bit(rfkill->type, seen)) ? 1 : 0;
586}
587
588static int rfkill_add_switch(struct rfkill *rfkill)
589{
590 int error;
591
592 mutex_lock(&rfkill_global_mutex);
593
594 error = rfkill_check_duplicity(rfkill);
595 if (error < 0)
596 goto unlock_out;
597
598 if (!error) {
599 /* lock default after first use */
600 set_bit(rfkill->type, rfkill_states_lockdflt);
601 rfkill_global_states[rfkill->type].current_state =
602 rfkill_global_states[rfkill->type].default_state;
603 }
604
605 rfkill_toggle_radio(rfkill,
606 rfkill_global_states[rfkill->type].current_state,
607 0);
608
609 list_add_tail(&rfkill->node, &rfkill_list);
610
611 error = 0;
612unlock_out:
613 mutex_unlock(&rfkill_global_mutex);
614
615 return error;
616}
617
618static void rfkill_remove_switch(struct rfkill *rfkill)
619{
620 mutex_lock(&rfkill_global_mutex);
621 list_del_init(&rfkill->node);
622 mutex_unlock(&rfkill_global_mutex);
623
624 mutex_lock(&rfkill->mutex);
625 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
626 mutex_unlock(&rfkill->mutex);
627}
628
629/**
630 * rfkill_allocate - allocate memory for rfkill structure.
631 * @parent: device that has rf switch on it
632 * @type: type of the switch (RFKILL_TYPE_*)
633 *
634 * This function should be called by the network driver when it needs
635 * rfkill structure. Once the structure is allocated the driver should
636 * finish its initialization by setting the name, private data, enable_radio
637 * and disable_radio methods and then register it with rfkill_register().
638 *
639 * NOTE: If registration fails the structure shoudl be freed by calling
640 * rfkill_free() otherwise rfkill_unregister() should be used.
641 */
642struct rfkill * __must_check rfkill_allocate(struct device *parent,
643 enum rfkill_type type)
644{
645 struct rfkill *rfkill;
646 struct device *dev;
647
648 if (WARN((type >= RFKILL_TYPE_MAX),
649 KERN_WARNING
650 "rfkill: illegal type %d passed as parameter "
651 "to rfkill_allocate\n", type))
652 return NULL;
653
654 rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);
655 if (!rfkill)
656 return NULL;
657
658 mutex_init(&rfkill->mutex);
659 INIT_LIST_HEAD(&rfkill->node);
660 rfkill->type = type;
661
662 dev = &rfkill->dev;
663 dev->class = &rfkill_class;
664 dev->parent = parent;
665 device_initialize(dev);
666
667 __module_get(THIS_MODULE);
668
669 return rfkill;
670}
671EXPORT_SYMBOL(rfkill_allocate);
672
673/**
674 * rfkill_free - Mark rfkill structure for deletion
675 * @rfkill: rfkill structure to be destroyed
676 *
677 * Decrements reference count of the rfkill structure so it is destroyed.
678 * Note that rfkill_free() should _not_ be called after rfkill_unregister().
679 */
680void rfkill_free(struct rfkill *rfkill)
681{
682 if (rfkill)
683 put_device(&rfkill->dev);
684}
685EXPORT_SYMBOL(rfkill_free);
686
687static void rfkill_led_trigger_register(struct rfkill *rfkill)
688{
689#ifdef CONFIG_RFKILL_LEDS
690 int error;
691
692 if (!rfkill->led_trigger.name)
693 rfkill->led_trigger.name = dev_name(&rfkill->dev);
694 if (!rfkill->led_trigger.activate)
695 rfkill->led_trigger.activate = rfkill_led_trigger_activate;
696 error = led_trigger_register(&rfkill->led_trigger);
697 if (error)
698 rfkill->led_trigger.name = NULL;
699#endif /* CONFIG_RFKILL_LEDS */
700}
701
702static void rfkill_led_trigger_unregister(struct rfkill *rfkill)
703{
704#ifdef CONFIG_RFKILL_LEDS
705 if (rfkill->led_trigger.name) {
706 led_trigger_unregister(&rfkill->led_trigger);
707 rfkill->led_trigger.name = NULL;
708 }
709#endif
710}
711
712/**
713 * rfkill_register - Register a rfkill structure.
714 * @rfkill: rfkill structure to be registered
715 *
716 * This function should be called by the network driver when the rfkill
717 * structure needs to be registered. Immediately from registration the
718 * switch driver should be able to service calls to toggle_radio.
719 */
720int __must_check rfkill_register(struct rfkill *rfkill)
721{
722 static atomic_t rfkill_no = ATOMIC_INIT(0);
723 struct device *dev = &rfkill->dev;
724 int error;
725
726 if (WARN((!rfkill || !rfkill->toggle_radio ||
727 rfkill->type >= RFKILL_TYPE_MAX ||
728 rfkill->state >= RFKILL_STATE_MAX),
729 KERN_WARNING
730 "rfkill: attempt to register a "
731 "badly initialized rfkill struct\n"))
732 return -EINVAL;
733
734 dev_set_name(dev, "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);
735
736 rfkill_led_trigger_register(rfkill);
737
738 error = rfkill_add_switch(rfkill);
739 if (error) {
740 rfkill_led_trigger_unregister(rfkill);
741 return error;
742 }
743
744 error = device_add(dev);
745 if (error) {
746 rfkill_remove_switch(rfkill);
747 rfkill_led_trigger_unregister(rfkill);
748 return error;
749 }
750
751 return 0;
752}
753EXPORT_SYMBOL(rfkill_register);
754
755/**
756 * rfkill_unregister - Unregister a rfkill structure.
757 * @rfkill: rfkill structure to be unregistered
758 *
759 * This function should be called by the network driver during device
760 * teardown to destroy rfkill structure. Note that rfkill_free() should
761 * _not_ be called after rfkill_unregister().
762 */
763void rfkill_unregister(struct rfkill *rfkill)
764{
765 BUG_ON(!rfkill);
766 device_del(&rfkill->dev);
767 rfkill_remove_switch(rfkill);
768 rfkill_led_trigger_unregister(rfkill);
769 put_device(&rfkill->dev);
770}
771EXPORT_SYMBOL(rfkill_unregister);
772
773/**
774 * rfkill_set_default - set initial value for a switch type
775 * @type - the type of switch to set the default state of
776 * @state - the new default state for that group of switches
777 *
778 * Sets the initial state rfkill should use for a given type.
779 * The following initial states are allowed: RFKILL_STATE_SOFT_BLOCKED
780 * and RFKILL_STATE_UNBLOCKED.
781 *
782 * This function is meant to be used by platform drivers for platforms
783 * that can save switch state across power down/reboot.
784 *
785 * The default state for each switch type can be changed exactly once.
786 * After a switch of that type is registered, the default state cannot
787 * be changed anymore. This guards against multiple drivers it the
788 * same platform trying to set the initial switch default state, which
789 * is not allowed.
790 *
791 * Returns -EPERM if the state has already been set once or is in use,
792 * so drivers likely want to either ignore or at most printk(KERN_NOTICE)
793 * if this function returns -EPERM.
794 *
795 * Returns 0 if the new default state was set, or an error if it
796 * could not be set.
797 */
798int rfkill_set_default(enum rfkill_type type, enum rfkill_state state)
799{
800 int error;
801
802 if (WARN((type >= RFKILL_TYPE_MAX ||
803 (state != RFKILL_STATE_SOFT_BLOCKED &&
804 state != RFKILL_STATE_UNBLOCKED)),
805 KERN_WARNING
806 "rfkill: illegal state %d or type %d passed as "
807 "parameter to rfkill_set_default\n", state, type))
808 return -EINVAL;
809
810 mutex_lock(&rfkill_global_mutex);
811
812 if (!test_and_set_bit(type, rfkill_states_lockdflt)) {
813 rfkill_global_states[type].default_state = state;
814 rfkill_global_states[type].current_state = state;
815 error = 0;
816 } else
817 error = -EPERM;
818
819 mutex_unlock(&rfkill_global_mutex);
820 return error;
821}
822EXPORT_SYMBOL_GPL(rfkill_set_default);
823
824/*
825 * Rfkill module initialization/deinitialization.
826 */
827static int __init rfkill_init(void)
828{
829 int error;
830 int i;
831
832 /* RFKILL_STATE_HARD_BLOCKED is illegal here... */
833 if (rfkill_default_state != RFKILL_STATE_SOFT_BLOCKED &&
834 rfkill_default_state != RFKILL_STATE_UNBLOCKED)
835 return -EINVAL;
836
837 for (i = 0; i < RFKILL_TYPE_MAX; i++)
838 rfkill_global_states[i].default_state = rfkill_default_state;
839
840 error = class_register(&rfkill_class);
841 if (error) {
842 printk(KERN_ERR "rfkill: unable to register rfkill class\n");
843 return error;
844 }
845
846 return 0;
847}
848
849static void __exit rfkill_exit(void)
850{
851 class_unregister(&rfkill_class);
852}
853
854subsys_initcall(rfkill_init);
855module_exit(rfkill_exit);
diff --git a/net/rfkill/rfkill-input.h b/net/rfkill/rfkill.h
index fe8df6b5b935..d1117cb6e4de 100644
--- a/net/rfkill/rfkill-input.h
+++ b/net/rfkill/rfkill.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (C) 2007 Ivo van Doorn 2 * Copyright (C) 2007 Ivo van Doorn
3 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
3 */ 4 */
4 5
5/* 6/*
@@ -11,11 +12,16 @@
11#ifndef __RFKILL_INPUT_H 12#ifndef __RFKILL_INPUT_H
12#define __RFKILL_INPUT_H 13#define __RFKILL_INPUT_H
13 14
14void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state); 15/* core code */
16void rfkill_switch_all(const enum rfkill_type type, bool blocked);
15void rfkill_epo(void); 17void rfkill_epo(void);
16void rfkill_restore_states(void); 18void rfkill_restore_states(void);
17void rfkill_remove_epo_lock(void); 19void rfkill_remove_epo_lock(void);
18bool rfkill_is_epo_lock_active(void); 20bool rfkill_is_epo_lock_active(void);
19enum rfkill_state rfkill_get_global_state(const enum rfkill_type type); 21bool rfkill_get_global_sw_state(const enum rfkill_type type);
22
23/* input handler */
24int rfkill_handler_init(void);
25void rfkill_handler_exit(void);
20 26
21#endif /* __RFKILL_INPUT_H */ 27#endif /* __RFKILL_INPUT_H */
diff --git a/net/wimax/Kconfig b/net/wimax/Kconfig
index 1b46747a5f5a..e4d97ab476d5 100644
--- a/net/wimax/Kconfig
+++ b/net/wimax/Kconfig
@@ -1,23 +1,10 @@
1# 1#
2# WiMAX LAN device configuration 2# WiMAX LAN device configuration
3# 3#
4# Note the ugly 'depends on' on WIMAX: that disallows RFKILL to be a
5# module if WIMAX is to be linked in. The WiMAX code is done in such a
6# way that it doesn't require and explicit dependency on RFKILL in
7# case an embedded system wants to rip it out.
8#
9# As well, enablement of the RFKILL code means we need the INPUT layer
10# support to inject events coming from hw rfkill switches. That
11# dependency could be killed if input.h provided appropriate means to
12# work when input is disabled.
13
14comment "WiMAX Wireless Broadband support requires CONFIG_INPUT enabled"
15 depends on INPUT = n && RFKILL != n
16 4
17menuconfig WIMAX 5menuconfig WIMAX
18 tristate "WiMAX Wireless Broadband support" 6 tristate "WiMAX Wireless Broadband support"
19 depends on (y && RFKILL != m) || m 7 depends on RFKILL || !RFKILL
20 depends on (INPUT && RFKILL != n) || RFKILL = n
21 help 8 help
22 9
23 Select to configure support for devices that provide 10 Select to configure support for devices that provide
diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c
index a3616e2ccb8a..bb102e4aa3e9 100644
--- a/net/wimax/op-rfkill.c
+++ b/net/wimax/op-rfkill.c
@@ -29,8 +29,8 @@
29 * A non-polled generic rfkill device is embedded into the WiMAX 29 * A non-polled generic rfkill device is embedded into the WiMAX
30 * subsystem's representation of a device. 30 * subsystem's representation of a device.
31 * 31 *
32 * FIXME: Need polled support? use a timer or add the implementation 32 * FIXME: Need polled support? Let drivers provide a poll routine
33 * to the stack. 33 * and hand it to rfkill ops then?
34 * 34 *
35 * All device drivers have to do is after wimax_dev_init(), call 35 * All device drivers have to do is after wimax_dev_init(), call
36 * wimax_report_rfkill_hw() and wimax_report_rfkill_sw() to update 36 * wimax_report_rfkill_hw() and wimax_report_rfkill_sw() to update
@@ -43,7 +43,7 @@
43 * wimax_rfkill() Kernel calling wimax_rfkill() 43 * wimax_rfkill() Kernel calling wimax_rfkill()
44 * __wimax_rf_toggle_radio() 44 * __wimax_rf_toggle_radio()
45 * 45 *
46 * wimax_rfkill_toggle_radio() RF-Kill subsytem calling 46 * wimax_rfkill_set_radio_block() RF-Kill subsytem calling
47 * __wimax_rf_toggle_radio() 47 * __wimax_rf_toggle_radio()
48 * 48 *
49 * __wimax_rf_toggle_radio() 49 * __wimax_rf_toggle_radio()
@@ -65,15 +65,11 @@
65#include <linux/wimax.h> 65#include <linux/wimax.h>
66#include <linux/security.h> 66#include <linux/security.h>
67#include <linux/rfkill.h> 67#include <linux/rfkill.h>
68#include <linux/input.h>
69#include "wimax-internal.h" 68#include "wimax-internal.h"
70 69
71#define D_SUBMODULE op_rfkill 70#define D_SUBMODULE op_rfkill
72#include "debug-levels.h" 71#include "debug-levels.h"
73 72
74#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
75
76
77/** 73/**
78 * wimax_report_rfkill_hw - Reports changes in the hardware RF switch 74 * wimax_report_rfkill_hw - Reports changes in the hardware RF switch
79 * 75 *
@@ -99,7 +95,6 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
99 int result; 95 int result;
100 struct device *dev = wimax_dev_to_dev(wimax_dev); 96 struct device *dev = wimax_dev_to_dev(wimax_dev);
101 enum wimax_st wimax_state; 97 enum wimax_st wimax_state;
102 enum rfkill_state rfkill_state;
103 98
104 d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); 99 d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state);
105 BUG_ON(state == WIMAX_RF_QUERY); 100 BUG_ON(state == WIMAX_RF_QUERY);
@@ -112,16 +107,15 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
112 107
113 if (state != wimax_dev->rf_hw) { 108 if (state != wimax_dev->rf_hw) {
114 wimax_dev->rf_hw = state; 109 wimax_dev->rf_hw = state;
115 rfkill_state = state == WIMAX_RF_ON ?
116 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
117 if (wimax_dev->rf_hw == WIMAX_RF_ON 110 if (wimax_dev->rf_hw == WIMAX_RF_ON
118 && wimax_dev->rf_sw == WIMAX_RF_ON) 111 && wimax_dev->rf_sw == WIMAX_RF_ON)
119 wimax_state = WIMAX_ST_READY; 112 wimax_state = WIMAX_ST_READY;
120 else 113 else
121 wimax_state = WIMAX_ST_RADIO_OFF; 114 wimax_state = WIMAX_ST_RADIO_OFF;
115
116 rfkill_set_hw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF);
117
122 __wimax_state_change(wimax_dev, wimax_state); 118 __wimax_state_change(wimax_dev, wimax_state);
123 input_report_key(wimax_dev->rfkill_input, KEY_WIMAX,
124 rfkill_state);
125 } 119 }
126error_not_ready: 120error_not_ready:
127 mutex_unlock(&wimax_dev->mutex); 121 mutex_unlock(&wimax_dev->mutex);
@@ -174,6 +168,7 @@ void wimax_report_rfkill_sw(struct wimax_dev *wimax_dev,
174 else 168 else
175 wimax_state = WIMAX_ST_RADIO_OFF; 169 wimax_state = WIMAX_ST_RADIO_OFF;
176 __wimax_state_change(wimax_dev, wimax_state); 170 __wimax_state_change(wimax_dev, wimax_state);
171 rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF);
177 } 172 }
178error_not_ready: 173error_not_ready:
179 mutex_unlock(&wimax_dev->mutex); 174 mutex_unlock(&wimax_dev->mutex);
@@ -249,36 +244,31 @@ out_no_change:
249 * 244 *
250 * NOTE: This call will block until the operation is completed. 245 * NOTE: This call will block until the operation is completed.
251 */ 246 */
252static 247static int wimax_rfkill_set_radio_block(void *data, bool blocked)
253int wimax_rfkill_toggle_radio(void *data, enum rfkill_state state)
254{ 248{
255 int result; 249 int result;
256 struct wimax_dev *wimax_dev = data; 250 struct wimax_dev *wimax_dev = data;
257 struct device *dev = wimax_dev_to_dev(wimax_dev); 251 struct device *dev = wimax_dev_to_dev(wimax_dev);
258 enum wimax_rf_state rf_state; 252 enum wimax_rf_state rf_state;
259 253
260 d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); 254 d_fnstart(3, dev, "(wimax_dev %p blocked %u)\n", wimax_dev, blocked);
261 switch (state) { 255 rf_state = WIMAX_RF_ON;
262 case RFKILL_STATE_SOFT_BLOCKED: 256 if (blocked)
263 rf_state = WIMAX_RF_OFF; 257 rf_state = WIMAX_RF_OFF;
264 break;
265 case RFKILL_STATE_UNBLOCKED:
266 rf_state = WIMAX_RF_ON;
267 break;
268 default:
269 BUG();
270 }
271 mutex_lock(&wimax_dev->mutex); 258 mutex_lock(&wimax_dev->mutex);
272 if (wimax_dev->state <= __WIMAX_ST_QUIESCING) 259 if (wimax_dev->state <= __WIMAX_ST_QUIESCING)
273 result = 0; /* just pretend it didn't happen */ 260 result = 0;
274 else 261 else
275 result = __wimax_rf_toggle_radio(wimax_dev, rf_state); 262 result = __wimax_rf_toggle_radio(wimax_dev, rf_state);
276 mutex_unlock(&wimax_dev->mutex); 263 mutex_unlock(&wimax_dev->mutex);
277 d_fnend(3, dev, "(wimax_dev %p state %u) = %d\n", 264 d_fnend(3, dev, "(wimax_dev %p blocked %u) = %d\n",
278 wimax_dev, state, result); 265 wimax_dev, blocked, result);
279 return result; 266 return result;
280} 267}
281 268
269static const struct rfkill_ops wimax_rfkill_ops = {
270 .set_block = wimax_rfkill_set_radio_block,
271};
282 272
283/** 273/**
284 * wimax_rfkill - Set the software RF switch state for a WiMAX device 274 * wimax_rfkill - Set the software RF switch state for a WiMAX device
@@ -322,6 +312,7 @@ int wimax_rfkill(struct wimax_dev *wimax_dev, enum wimax_rf_state state)
322 result = __wimax_rf_toggle_radio(wimax_dev, state); 312 result = __wimax_rf_toggle_radio(wimax_dev, state);
323 if (result < 0) 313 if (result < 0)
324 goto error; 314 goto error;
315 rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF);
325 break; 316 break;
326 case WIMAX_RF_QUERY: 317 case WIMAX_RF_QUERY:
327 break; 318 break;
@@ -349,40 +340,20 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev)
349{ 340{
350 int result; 341 int result;
351 struct rfkill *rfkill; 342 struct rfkill *rfkill;
352 struct input_dev *input_dev;
353 struct device *dev = wimax_dev_to_dev(wimax_dev); 343 struct device *dev = wimax_dev_to_dev(wimax_dev);
354 344
355 d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev); 345 d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev);
356 /* Initialize RF Kill */ 346 /* Initialize RF Kill */
357 result = -ENOMEM; 347 result = -ENOMEM;
358 rfkill = rfkill_allocate(dev, RFKILL_TYPE_WIMAX); 348 rfkill = rfkill_alloc(wimax_dev->name, dev, RFKILL_TYPE_WIMAX,
349 &wimax_rfkill_ops, wimax_dev);
359 if (rfkill == NULL) 350 if (rfkill == NULL)
360 goto error_rfkill_allocate; 351 goto error_rfkill_allocate;
352
353 d_printf(1, dev, "rfkill %p\n", rfkill);
354
361 wimax_dev->rfkill = rfkill; 355 wimax_dev->rfkill = rfkill;
362 356
363 rfkill->name = wimax_dev->name;
364 rfkill->state = RFKILL_STATE_UNBLOCKED;
365 rfkill->data = wimax_dev;
366 rfkill->toggle_radio = wimax_rfkill_toggle_radio;
367
368 /* Initialize the input device for the hw key */
369 input_dev = input_allocate_device();
370 if (input_dev == NULL)
371 goto error_input_allocate;
372 wimax_dev->rfkill_input = input_dev;
373 d_printf(1, dev, "rfkill %p input %p\n", rfkill, input_dev);
374
375 input_dev->name = wimax_dev->name;
376 /* FIXME: get a real device bus ID and stuff? do we care? */
377 input_dev->id.bustype = BUS_HOST;
378 input_dev->id.vendor = 0xffff;
379 input_dev->evbit[0] = BIT(EV_KEY);
380 set_bit(KEY_WIMAX, input_dev->keybit);
381
382 /* Register both */
383 result = input_register_device(wimax_dev->rfkill_input);
384 if (result < 0)
385 goto error_input_register;
386 result = rfkill_register(wimax_dev->rfkill); 357 result = rfkill_register(wimax_dev->rfkill);
387 if (result < 0) 358 if (result < 0)
388 goto error_rfkill_register; 359 goto error_rfkill_register;
@@ -394,17 +365,8 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev)
394 d_fnend(3, dev, "(wimax_dev %p) = 0\n", wimax_dev); 365 d_fnend(3, dev, "(wimax_dev %p) = 0\n", wimax_dev);
395 return 0; 366 return 0;
396 367
397 /* if rfkill_register() suceeds, can't use rfkill_free() any
398 * more, only rfkill_unregister() [it owns the refcount]; with
399 * the input device we have the same issue--hence the if. */
400error_rfkill_register: 368error_rfkill_register:
401 input_unregister_device(wimax_dev->rfkill_input); 369 rfkill_destroy(wimax_dev->rfkill);
402 wimax_dev->rfkill_input = NULL;
403error_input_register:
404 if (wimax_dev->rfkill_input)
405 input_free_device(wimax_dev->rfkill_input);
406error_input_allocate:
407 rfkill_free(wimax_dev->rfkill);
408error_rfkill_allocate: 370error_rfkill_allocate:
409 d_fnend(3, dev, "(wimax_dev %p) = %d\n", wimax_dev, result); 371 d_fnend(3, dev, "(wimax_dev %p) = %d\n", wimax_dev, result);
410 return result; 372 return result;
@@ -423,45 +385,12 @@ void wimax_rfkill_rm(struct wimax_dev *wimax_dev)
423{ 385{
424 struct device *dev = wimax_dev_to_dev(wimax_dev); 386 struct device *dev = wimax_dev_to_dev(wimax_dev);
425 d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev); 387 d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev);
426 rfkill_unregister(wimax_dev->rfkill); /* frees */ 388 rfkill_unregister(wimax_dev->rfkill);
427 input_unregister_device(wimax_dev->rfkill_input); 389 rfkill_destroy(wimax_dev->rfkill);
428 d_fnend(3, dev, "(wimax_dev %p)\n", wimax_dev); 390 d_fnend(3, dev, "(wimax_dev %p)\n", wimax_dev);
429} 391}
430 392
431 393
432#else /* #ifdef CONFIG_RFKILL */
433
434void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
435 enum wimax_rf_state state)
436{
437}
438EXPORT_SYMBOL_GPL(wimax_report_rfkill_hw);
439
440void wimax_report_rfkill_sw(struct wimax_dev *wimax_dev,
441 enum wimax_rf_state state)
442{
443}
444EXPORT_SYMBOL_GPL(wimax_report_rfkill_sw);
445
446int wimax_rfkill(struct wimax_dev *wimax_dev,
447 enum wimax_rf_state state)
448{
449 return WIMAX_RF_ON << 1 | WIMAX_RF_ON;
450}
451EXPORT_SYMBOL_GPL(wimax_rfkill);
452
453int wimax_rfkill_add(struct wimax_dev *wimax_dev)
454{
455 return 0;
456}
457
458void wimax_rfkill_rm(struct wimax_dev *wimax_dev)
459{
460}
461
462#endif /* #ifdef CONFIG_RFKILL */
463
464
465/* 394/*
466 * Exporting to user space over generic netlink 395 * Exporting to user space over generic netlink
467 * 396 *
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 45005497c634..4428dd5e911d 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -1,5 +1,6 @@
1config CFG80211 1config CFG80211
2 tristate "Improved wireless configuration API" 2 tristate "Improved wireless configuration API"
3 depends on RFKILL || !RFKILL
3 4
4config CFG80211_REG_DEBUG 5config CFG80211_REG_DEBUG
5 bool "cfg80211 regulatory debugging" 6 bool "cfg80211 regulatory debugging"
diff --git a/net/wireless/core.c b/net/wireless/core.c
index a5dbea1da476..3b74b88e10a3 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -12,6 +12,7 @@
12#include <linux/debugfs.h> 12#include <linux/debugfs.h>
13#include <linux/notifier.h> 13#include <linux/notifier.h>
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/rtnetlink.h>
15#include <net/genetlink.h> 16#include <net/genetlink.h>
16#include <net/cfg80211.h> 17#include <net/cfg80211.h>
17#include "nl80211.h" 18#include "nl80211.h"
@@ -227,6 +228,41 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
227 return 0; 228 return 0;
228} 229}
229 230
231static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
232{
233 struct cfg80211_registered_device *drv = data;
234
235 drv->ops->rfkill_poll(&drv->wiphy);
236}
237
238static int cfg80211_rfkill_set_block(void *data, bool blocked)
239{
240 struct cfg80211_registered_device *drv = data;
241 struct wireless_dev *wdev;
242
243 if (!blocked)
244 return 0;
245
246 rtnl_lock();
247 mutex_lock(&drv->devlist_mtx);
248
249 list_for_each_entry(wdev, &drv->netdev_list, list)
250 dev_close(wdev->netdev);
251
252 mutex_unlock(&drv->devlist_mtx);
253 rtnl_unlock();
254
255 return 0;
256}
257
258static void cfg80211_rfkill_sync_work(struct work_struct *work)
259{
260 struct cfg80211_registered_device *drv;
261
262 drv = container_of(work, struct cfg80211_registered_device, rfkill_sync);
263 cfg80211_rfkill_set_block(drv, rfkill_blocked(drv->rfkill));
264}
265
230/* exported functions */ 266/* exported functions */
231 267
232struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) 268struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
@@ -274,6 +310,18 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
274 drv->wiphy.dev.class = &ieee80211_class; 310 drv->wiphy.dev.class = &ieee80211_class;
275 drv->wiphy.dev.platform_data = drv; 311 drv->wiphy.dev.platform_data = drv;
276 312
313 drv->rfkill_ops.set_block = cfg80211_rfkill_set_block;
314 drv->rfkill = rfkill_alloc(dev_name(&drv->wiphy.dev),
315 &drv->wiphy.dev, RFKILL_TYPE_WLAN,
316 &drv->rfkill_ops, drv);
317
318 if (!drv->rfkill) {
319 kfree(drv);
320 return NULL;
321 }
322
323 INIT_WORK(&drv->rfkill_sync, cfg80211_rfkill_sync_work);
324
277 /* 325 /*
278 * Initialize wiphy parameters to IEEE 802.11 MIB default values. 326 * Initialize wiphy parameters to IEEE 802.11 MIB default values.
279 * Fragmentation and RTS threshold are disabled by default with the 327 * Fragmentation and RTS threshold are disabled by default with the
@@ -356,6 +404,10 @@ int wiphy_register(struct wiphy *wiphy)
356 if (res) 404 if (res)
357 goto out_unlock; 405 goto out_unlock;
358 406
407 res = rfkill_register(drv->rfkill);
408 if (res)
409 goto out_rm_dev;
410
359 list_add(&drv->list, &cfg80211_drv_list); 411 list_add(&drv->list, &cfg80211_drv_list);
360 412
361 /* add to debugfs */ 413 /* add to debugfs */
@@ -379,16 +431,41 @@ int wiphy_register(struct wiphy *wiphy)
379 cfg80211_debugfs_drv_add(drv); 431 cfg80211_debugfs_drv_add(drv);
380 432
381 res = 0; 433 res = 0;
382out_unlock: 434 goto out_unlock;
435
436 out_rm_dev:
437 device_del(&drv->wiphy.dev);
438 out_unlock:
383 mutex_unlock(&cfg80211_mutex); 439 mutex_unlock(&cfg80211_mutex);
384 return res; 440 return res;
385} 441}
386EXPORT_SYMBOL(wiphy_register); 442EXPORT_SYMBOL(wiphy_register);
387 443
444void wiphy_rfkill_start_polling(struct wiphy *wiphy)
445{
446 struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
447
448 if (!drv->ops->rfkill_poll)
449 return;
450 drv->rfkill_ops.poll = cfg80211_rfkill_poll;
451 rfkill_resume_polling(drv->rfkill);
452}
453EXPORT_SYMBOL(wiphy_rfkill_start_polling);
454
455void wiphy_rfkill_stop_polling(struct wiphy *wiphy)
456{
457 struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
458
459 rfkill_pause_polling(drv->rfkill);
460}
461EXPORT_SYMBOL(wiphy_rfkill_stop_polling);
462
388void wiphy_unregister(struct wiphy *wiphy) 463void wiphy_unregister(struct wiphy *wiphy)
389{ 464{
390 struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy); 465 struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
391 466
467 rfkill_unregister(drv->rfkill);
468
392 /* protect the device list */ 469 /* protect the device list */
393 mutex_lock(&cfg80211_mutex); 470 mutex_lock(&cfg80211_mutex);
394 471
@@ -425,6 +502,7 @@ EXPORT_SYMBOL(wiphy_unregister);
425void cfg80211_dev_free(struct cfg80211_registered_device *drv) 502void cfg80211_dev_free(struct cfg80211_registered_device *drv)
426{ 503{
427 struct cfg80211_internal_bss *scan, *tmp; 504 struct cfg80211_internal_bss *scan, *tmp;
505 rfkill_destroy(drv->rfkill);
428 mutex_destroy(&drv->mtx); 506 mutex_destroy(&drv->mtx);
429 mutex_destroy(&drv->devlist_mtx); 507 mutex_destroy(&drv->devlist_mtx);
430 list_for_each_entry_safe(scan, tmp, &drv->bss_list, list) 508 list_for_each_entry_safe(scan, tmp, &drv->bss_list, list)
@@ -438,6 +516,15 @@ void wiphy_free(struct wiphy *wiphy)
438} 516}
439EXPORT_SYMBOL(wiphy_free); 517EXPORT_SYMBOL(wiphy_free);
440 518
519void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked)
520{
521 struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
522
523 if (rfkill_set_hw_state(drv->rfkill, blocked))
524 schedule_work(&drv->rfkill_sync);
525}
526EXPORT_SYMBOL(wiphy_rfkill_set_hw_state);
527
441static int cfg80211_netdev_notifier_call(struct notifier_block * nb, 528static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
442 unsigned long state, 529 unsigned long state,
443 void *ndev) 530 void *ndev)
@@ -446,7 +533,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
446 struct cfg80211_registered_device *rdev; 533 struct cfg80211_registered_device *rdev;
447 534
448 if (!dev->ieee80211_ptr) 535 if (!dev->ieee80211_ptr)
449 return 0; 536 return NOTIFY_DONE;
450 537
451 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy); 538 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
452 539
@@ -492,9 +579,13 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
492 } 579 }
493 mutex_unlock(&rdev->devlist_mtx); 580 mutex_unlock(&rdev->devlist_mtx);
494 break; 581 break;
582 case NETDEV_PRE_UP:
583 if (rfkill_blocked(rdev->rfkill))
584 return notifier_from_errno(-ERFKILL);
585 break;
495 } 586 }
496 587
497 return 0; 588 return NOTIFY_DONE;
498} 589}
499 590
500static struct notifier_block cfg80211_netdev_notifier = { 591static struct notifier_block cfg80211_netdev_notifier = {
diff --git a/net/wireless/core.h b/net/wireless/core.h
index ab512bcd8153..bfa340c7abb5 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -11,6 +11,8 @@
11#include <linux/kref.h> 11#include <linux/kref.h>
12#include <linux/rbtree.h> 12#include <linux/rbtree.h>
13#include <linux/debugfs.h> 13#include <linux/debugfs.h>
14#include <linux/rfkill.h>
15#include <linux/workqueue.h>
14#include <net/genetlink.h> 16#include <net/genetlink.h>
15#include <net/cfg80211.h> 17#include <net/cfg80211.h>
16#include "reg.h" 18#include "reg.h"
@@ -24,6 +26,11 @@ struct cfg80211_registered_device {
24 * any call is in progress */ 26 * any call is in progress */
25 struct mutex mtx; 27 struct mutex mtx;
26 28
29 /* rfkill support */
30 struct rfkill_ops rfkill_ops;
31 struct rfkill *rfkill;
32 struct work_struct rfkill_sync;
33
27 /* ISO / IEC 3166 alpha2 for which this device is receiving 34 /* ISO / IEC 3166 alpha2 for which this device is receiving
28 * country IEs on, this can help disregard country IEs from APs 35 * country IEs on, this can help disregard country IEs from APs
29 * on the same alpha2 quickly. The alpha2 may differ from 36 * on the same alpha2 quickly. The alpha2 may differ from
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4b4d3c8a1aed..24168560ebae 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1687,6 +1687,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1687 if (err) 1687 if (err)
1688 goto out_rtnl; 1688 goto out_rtnl;
1689 1689
1690 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1691 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
1692 err = -EINVAL;
1693 goto out;
1694 }
1695
1690 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan); 1696 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
1691 if (err) 1697 if (err)
1692 goto out; 1698 goto out;
@@ -1738,7 +1744,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1738 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); 1744 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1739 params.listen_interval = 1745 params.listen_interval =
1740 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 1746 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1747
1741 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); 1748 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
1749 if (!params.aid || params.aid > IEEE80211_MAX_AID)
1750 return -EINVAL;
1751
1742 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) 1752 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1743 params.ht_capa = 1753 params.ht_capa =
1744 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 1754 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
@@ -3559,11 +3569,43 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
3559 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); 3569 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
3560} 3570}
3561 3571
3572static int nl80211_add_scan_req(struct sk_buff *msg,
3573 struct cfg80211_registered_device *rdev)
3574{
3575 struct cfg80211_scan_request *req = rdev->scan_req;
3576 struct nlattr *nest;
3577 int i;
3578
3579 if (WARN_ON(!req))
3580 return 0;
3581
3582 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
3583 if (!nest)
3584 goto nla_put_failure;
3585 for (i = 0; i < req->n_ssids; i++)
3586 NLA_PUT(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid);
3587 nla_nest_end(msg, nest);
3588
3589 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
3590 if (!nest)
3591 goto nla_put_failure;
3592 for (i = 0; i < req->n_channels; i++)
3593 NLA_PUT_U32(msg, i, req->channels[i]->center_freq);
3594 nla_nest_end(msg, nest);
3595
3596 if (req->ie)
3597 NLA_PUT(msg, NL80211_ATTR_IE, req->ie_len, req->ie);
3598
3599 return 0;
3600 nla_put_failure:
3601 return -ENOBUFS;
3602}
3603
3562static int nl80211_send_scan_donemsg(struct sk_buff *msg, 3604static int nl80211_send_scan_donemsg(struct sk_buff *msg,
3563 struct cfg80211_registered_device *rdev, 3605 struct cfg80211_registered_device *rdev,
3564 struct net_device *netdev, 3606 struct net_device *netdev,
3565 u32 pid, u32 seq, int flags, 3607 u32 pid, u32 seq, int flags,
3566 u32 cmd) 3608 u32 cmd)
3567{ 3609{
3568 void *hdr; 3610 void *hdr;
3569 3611
@@ -3574,7 +3616,8 @@ static int nl80211_send_scan_donemsg(struct sk_buff *msg,
3574 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); 3616 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3575 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); 3617 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3576 3618
3577 /* XXX: we should probably bounce back the request? */ 3619 /* ignore errors and send incomplete event anyway */
3620 nl80211_add_scan_req(msg, rdev);
3578 3621
3579 return genlmsg_end(msg, hdr); 3622 return genlmsg_end(msg, hdr);
3580 3623
@@ -3828,7 +3871,7 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
3828 struct sk_buff *msg; 3871 struct sk_buff *msg;
3829 void *hdr; 3872 void *hdr;
3830 3873
3831 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3874 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
3832 if (!msg) 3875 if (!msg)
3833 return; 3876 return;
3834 3877
@@ -3852,7 +3895,7 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
3852 return; 3895 return;
3853 } 3896 }
3854 3897
3855 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL); 3898 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
3856 return; 3899 return;
3857 3900
3858 nla_put_failure: 3901 nla_put_failure:
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index f87ac1df2df5..ea4c299fbe3b 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2171,7 +2171,13 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2171 * the country IE rd with what CRDA believes that country should have 2171 * the country IE rd with what CRDA believes that country should have
2172 */ 2172 */
2173 2173
2174 BUG_ON(!country_ie_regdomain); 2174 /*
2175 * Userspace could have sent two replies with only
2176 * one kernel request. By the second reply we would have
2177 * already processed and consumed the country_ie_regdomain.
2178 */
2179 if (!country_ie_regdomain)
2180 return -EALREADY;
2175 BUG_ON(rd == country_ie_regdomain); 2181 BUG_ON(rd == country_ie_regdomain);
2176 2182
2177 /* 2183 /*
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index df59440290e5..e95b638b919f 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -29,13 +29,14 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
29 goto out; 29 goto out;
30 30
31 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); 31 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
32 wiphy_to_dev(request->wiphy)->scan_req = NULL;
33 32
34 if (aborted) 33 if (aborted)
35 nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev); 34 nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev);
36 else 35 else
37 nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev); 36 nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev);
38 37
38 wiphy_to_dev(request->wiphy)->scan_req = NULL;
39
39#ifdef CONFIG_WIRELESS_EXT 40#ifdef CONFIG_WIRELESS_EXT
40 if (!aborted) { 41 if (!aborted) {
41 memset(&wrqu, 0, sizeof(wrqu)); 42 memset(&wrqu, 0, sizeof(wrqu));
diff --git a/net/wireless/util.c b/net/wireless/util.c
index d072bff463aa..25550692dda6 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -157,26 +157,25 @@ int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
157 params->cipher != WLAN_CIPHER_SUITE_WEP104) 157 params->cipher != WLAN_CIPHER_SUITE_WEP104)
158 return -EINVAL; 158 return -EINVAL;
159 159
160 /* TODO: add definitions for the lengths to linux/ieee80211.h */
161 switch (params->cipher) { 160 switch (params->cipher) {
162 case WLAN_CIPHER_SUITE_WEP40: 161 case WLAN_CIPHER_SUITE_WEP40:
163 if (params->key_len != 5) 162 if (params->key_len != WLAN_KEY_LEN_WEP40)
164 return -EINVAL; 163 return -EINVAL;
165 break; 164 break;
166 case WLAN_CIPHER_SUITE_TKIP: 165 case WLAN_CIPHER_SUITE_TKIP:
167 if (params->key_len != 32) 166 if (params->key_len != WLAN_KEY_LEN_TKIP)
168 return -EINVAL; 167 return -EINVAL;
169 break; 168 break;
170 case WLAN_CIPHER_SUITE_CCMP: 169 case WLAN_CIPHER_SUITE_CCMP:
171 if (params->key_len != 16) 170 if (params->key_len != WLAN_KEY_LEN_CCMP)
172 return -EINVAL; 171 return -EINVAL;
173 break; 172 break;
174 case WLAN_CIPHER_SUITE_WEP104: 173 case WLAN_CIPHER_SUITE_WEP104:
175 if (params->key_len != 13) 174 if (params->key_len != WLAN_KEY_LEN_WEP104)
176 return -EINVAL; 175 return -EINVAL;
177 break; 176 break;
178 case WLAN_CIPHER_SUITE_AES_CMAC: 177 case WLAN_CIPHER_SUITE_AES_CMAC:
179 if (params->key_len != 16) 178 if (params->key_len != WLAN_KEY_LEN_AES_CMAC)
180 return -EINVAL; 179 return -EINVAL;
181 break; 180 break;
182 default: 181 default:
@@ -259,7 +258,7 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
259} 258}
260EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); 259EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
261 260
262int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) 261static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
263{ 262{
264 int ae = meshhdr->flags & MESH_FLAGS_AE; 263 int ae = meshhdr->flags & MESH_FLAGS_AE;
265 /* 7.1.3.5a.2 */ 264 /* 7.1.3.5a.2 */
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 711e00a0c9b5..d030c5315672 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -744,3 +744,86 @@ int cfg80211_wext_giwencode(struct net_device *dev,
744 return err; 744 return err;
745} 745}
746EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode); 746EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
747
748int cfg80211_wext_siwtxpower(struct net_device *dev,
749 struct iw_request_info *info,
750 union iwreq_data *data, char *extra)
751{
752 struct wireless_dev *wdev = dev->ieee80211_ptr;
753 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
754 enum tx_power_setting type;
755 int dbm = 0;
756
757 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
758 return -EINVAL;
759 if (data->txpower.flags & IW_TXPOW_RANGE)
760 return -EINVAL;
761
762 if (!rdev->ops->set_tx_power)
763 return -EOPNOTSUPP;
764
765 /* only change when not disabling */
766 if (!data->txpower.disabled) {
767 rfkill_set_sw_state(rdev->rfkill, false);
768
769 if (data->txpower.fixed) {
770 /*
771 * wext doesn't support negative values, see
772 * below where it's for automatic
773 */
774 if (data->txpower.value < 0)
775 return -EINVAL;
776 dbm = data->txpower.value;
777 type = TX_POWER_FIXED;
778 /* TODO: do regulatory check! */
779 } else {
780 /*
781 * Automatic power level setting, max being the value
782 * passed in from userland.
783 */
784 if (data->txpower.value < 0) {
785 type = TX_POWER_AUTOMATIC;
786 } else {
787 dbm = data->txpower.value;
788 type = TX_POWER_LIMITED;
789 }
790 }
791 } else {
792 rfkill_set_sw_state(rdev->rfkill, true);
793 schedule_work(&rdev->rfkill_sync);
794 return 0;
795 }
796
797 return rdev->ops->set_tx_power(wdev->wiphy, type, dbm);;
798}
799EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower);
800
801int cfg80211_wext_giwtxpower(struct net_device *dev,
802 struct iw_request_info *info,
803 union iwreq_data *data, char *extra)
804{
805 struct wireless_dev *wdev = dev->ieee80211_ptr;
806 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
807 int err, val;
808
809 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
810 return -EINVAL;
811 if (data->txpower.flags & IW_TXPOW_RANGE)
812 return -EINVAL;
813
814 if (!rdev->ops->get_tx_power)
815 return -EOPNOTSUPP;
816
817 err = rdev->ops->get_tx_power(wdev->wiphy, &val);
818 if (err)
819 return err;
820
821 /* well... oh well */
822 data->txpower.fixed = 1;
823 data->txpower.disabled = rfkill_blocked(rdev->rfkill);
824 data->txpower.value = val;
825 data->txpower.flags = IW_TXPOW_DBM;
826
827 return 0;
828}
829EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower);