···437437 driver but this caused driver conflicts.438438Who: Jean Delvare <khali@linux-fr.org>439439 Krzysztof Helt <krzysztof.h1@wp.pl>440440+441441+---------------------------442442+443443+What: CONFIG_RFKILL_INPUT444444+When: 2.6.33445445+Why: Should be implemented in userspace, policy daemon.446446+Who: Johannes Berg <johannes@sipsolutions.net>
+99-534
Documentation/rfkill.txt
···11-rfkill - RF switch subsystem support22-====================================11+rfkill - RF kill switch support22+===============================3344-1 Introduction55-2 Implementation details66-3 Kernel driver guidelines77-3.1 wireless device drivers88-3.2 platform/switch drivers99-3.3 input device drivers1010-4 Kernel API1111-5 Userspace support44+1. Introduction55+2. Implementation details66+3. Kernel driver guidelines77+4. Kernel API88+5. Userspace support12913101414-1. Introduction:1111+1. Introduction15121616-The rfkill switch subsystem exists to add a generic interface to circuitry that1717-can enable or disable the signal output of a wireless *transmitter* of any1818-type. By far, the most common use is to disable radio-frequency transmitters.1313+The rfkill subsystem provides a generic interface to disabling any radio1414+transmitter in the system. When a transmitter is blocked, it shall not1515+radiate any power.19162020-Note that disabling the signal output means that the the transmitter is to be2121-made to not emit any energy when "blocked". rfkill is not about blocking data2222-transmissions, it is about blocking energy emission.1717+The subsystem also provides the ability to react on button presses and1818+disable all transmitters of a certain type (or all). This is intended for1919+situations where transmitters need to be turned off, for example on2020+aircraft.23212424-The rfkill subsystem offers support for keys and switches often found on2525-laptops to enable wireless devices like WiFi and Bluetooth, so that these keys2626-and switches actually perform an action in all wireless devices of a given type2727-attached to the system.28222929-The buttons to enable and disable the wireless transmitters are important in3030-situations where the user is for example using his laptop on a location where3131-radio-frequency transmitters _must_ be disabled (e.g. airplanes).32233333-Because of this requirement, userspace support for the keys should not be made3434-mandatory. Because userspace might want to perform some additional smarter3535-tasks when the key is pressed, rfkill provides userspace the possibility to3636-take over the task to handle the key events.3737-3838-===============================================================================3939-2: Implementation details2424+2. Implementation details40254126The rfkill subsystem is composed of various components: the rfkill class, the4227rfkill-input module (an input layer handler), and some specific input layer4328events.44294545-The rfkill class provides kernel drivers with an interface that allows them to4646-know when they should enable or disable a wireless network device transmitter.4747-This is enabled by the CONFIG_RFKILL Kconfig option.3030+The rfkill class is provided for kernel drivers to register their radio3131+transmitter with the kernel, provide methods for turning it on and off and,3232+optionally, letting the system know about hardware-disabled states that may3333+be implemented on the device. This code is enabled with the CONFIG_RFKILL3434+Kconfig option, which drivers can "select".48354949-The rfkill class support makes sure userspace will be notified of all state5050-changes on rfkill devices through uevents. It provides a notification chain5151-for interested parties in the kernel to also get notified of rfkill state5252-changes in other drivers. It creates several sysfs entries which can be used5353-by userspace. See section "Userspace support".5454-5555-The rfkill-input module provides the kernel with the ability to implement a5656-basic response when the user presses a key or button (or toggles a switch)5757-related to rfkill functionality. It is an in-kernel implementation of default5858-policy of reacting to rfkill-related input events and neither mandatory nor5959-required for wireless drivers to operate. It is enabled by the6060-CONFIG_RFKILL_INPUT Kconfig option.6161-6262-rfkill-input is a rfkill-related events input layer handler. This handler will6363-listen to all rfkill key events and will change the rfkill state of the6464-wireless devices accordingly. With this option enabled userspace could either6565-do nothing or simply perform monitoring tasks.6666-6767-The rfkill-input module also provides EPO (emergency power-off) functionality6868-for all wireless transmitters. This function cannot be overridden, and it is6969-always active. rfkill EPO is related to *_RFKILL_ALL input layer events.7070-7171-7272-Important terms for the rfkill subsystem:7373-7474-In order to avoid confusion, we avoid the term "switch" in rfkill when it is7575-referring to an electronic control circuit that enables or disables a7676-transmitter. We reserve it for the physical device a human manipulates7777-(which is an input device, by the way):7878-7979-rfkill switch:8080-8181- A physical device a human manipulates. Its state can be perceived by8282- the kernel either directly (through a GPIO pin, ACPI GPE) or by its8383- effect on a rfkill line of a wireless device.8484-8585-rfkill controller:8686-8787- A hardware circuit that controls the state of a rfkill line, which a8888- kernel driver can interact with *to modify* that state (i.e. it has8989- either write-only or read/write access).9090-9191-rfkill line:9292-9393- An input channel (hardware or software) of a wireless device, which9494- causes a wireless transmitter to stop emitting energy (BLOCK) when it9595- is active. Point of view is extremely important here: rfkill lines are9696- always seen from the PoV of a wireless device (and its driver).9797-9898-soft rfkill line/software rfkill line:9999-100100- A rfkill line the wireless device driver can directly change the state101101- of. Related to rfkill_state RFKILL_STATE_SOFT_BLOCKED.102102-103103-hard rfkill line/hardware rfkill line:104104-105105- A rfkill line that works fully in hardware or firmware, and that cannot106106- be overridden by the kernel driver. The hardware device or the107107- firmware just exports its status to the driver, but it is read-only.108108- Related to rfkill_state RFKILL_STATE_HARD_BLOCKED.109109-110110-The enum rfkill_state describes the rfkill state of a transmitter:111111-112112-When a rfkill line or rfkill controller is in the RFKILL_STATE_UNBLOCKED state,113113-the wireless transmitter (radio TX circuit for example) is *enabled*. When the114114-it is in the RFKILL_STATE_SOFT_BLOCKED or RFKILL_STATE_HARD_BLOCKED, the115115-wireless transmitter is to be *blocked* from operating.116116-117117-RFKILL_STATE_SOFT_BLOCKED indicates that a call to toggle_radio() can change118118-that state. RFKILL_STATE_HARD_BLOCKED indicates that a call to toggle_radio()119119-will not be able to change the state and will return with a suitable error if120120-attempts are made to set the state to RFKILL_STATE_UNBLOCKED.121121-122122-RFKILL_STATE_HARD_BLOCKED is used by drivers to signal that the device is123123-locked in the BLOCKED state by a hardwire rfkill line (typically an input pin124124-that, when active, forces the transmitter to be disabled) which the driver125125-CANNOT override.126126-127127-Full rfkill functionality requires two different subsystems to cooperate: the128128-input layer and the rfkill class. The input layer issues *commands* to the129129-entire system requesting that devices registered to the rfkill class change130130-state. The way this interaction happens is not complex, but it is not obvious131131-either:132132-133133-Kernel Input layer:134134-135135- * Generates KEY_WWAN, KEY_WLAN, KEY_BLUETOOTH, SW_RFKILL_ALL, and136136- other such events when the user presses certain keys, buttons, or137137- toggles certain physical switches.138138-139139- THE INPUT LAYER IS NEVER USED TO PROPAGATE STATUS, NOTIFICATIONS OR THE140140- KIND OF STUFF AN ON-SCREEN-DISPLAY APPLICATION WOULD REPORT. It is141141- used to issue *commands* for the system to change behaviour, and these142142- commands may or may not be carried out by some kernel driver or143143- userspace application. It follows that doing user feedback based only144144- on input events is broken, as there is no guarantee that an input event145145- will be acted upon.146146-147147- Most wireless communication device drivers implementing rfkill148148- functionality MUST NOT generate these events, and have no reason to149149- register themselves with the input layer. Doing otherwise is a common150150- misconception. There is an API to propagate rfkill status change151151- information, and it is NOT the input layer.152152-153153-rfkill class:154154-155155- * Calls a hook in a driver to effectively change the wireless156156- transmitter state;157157- * Keeps track of the wireless transmitter state (with help from158158- the driver);159159- * Generates userspace notifications (uevents) and a call to a160160- notification chain (kernel) when there is a wireless transmitter161161- state change;162162- * Connects a wireless communications driver with the common rfkill163163- control system, which, for example, allows actions such as164164- "switch all bluetooth devices offline" to be carried out by165165- userspace or by rfkill-input.166166-167167- THE RFKILL CLASS NEVER ISSUES INPUT EVENTS. THE RFKILL CLASS DOES168168- NOT LISTEN TO INPUT EVENTS. NO DRIVER USING THE RFKILL CLASS SHALL169169- EVER LISTEN TO, OR ACT ON RFKILL INPUT EVENTS. Doing otherwise is170170- a layering violation.171171-172172- Most wireless data communication drivers in the kernel have just to173173- implement the rfkill class API to work properly. Interfacing to the174174- input layer is not often required (and is very often a *bug*) on175175- wireless drivers.176176-177177- Platform drivers often have to attach to the input layer to *issue*178178- (but never to listen to) rfkill events for rfkill switches, and also to179179- the rfkill class to export a control interface for the platform rfkill180180- controllers to the rfkill subsystem. This does NOT mean the rfkill181181- switch is attached to a rfkill class (doing so is almost always wrong).182182- It just means the same kernel module is the driver for different183183- devices (rfkill switches and rfkill controllers).184184-185185-186186-Userspace input handlers (uevents) or kernel input handlers (rfkill-input):187187-188188- * Implements the policy of what should happen when one of the input189189- layer events related to rfkill operation is received.190190- * Uses the sysfs interface (userspace) or private rfkill API calls191191- to tell the devices registered with the rfkill class to change192192- their state (i.e. translates the input layer event into real193193- action).194194-195195- * rfkill-input implements EPO by handling EV_SW SW_RFKILL_ALL 0196196- (power off all transmitters) in a special way: it ignores any197197- overrides and local state cache and forces all transmitters to the198198- RFKILL_STATE_SOFT_BLOCKED state (including those which are already199199- supposed to be BLOCKED).200200- * rfkill EPO will remain active until rfkill-input receives an201201- EV_SW SW_RFKILL_ALL 1 event. While the EPO is active, transmitters202202- are locked in the blocked state (rfkill will refuse to unblock them).203203- * rfkill-input implements different policies that the user can204204- select for handling EV_SW SW_RFKILL_ALL 1. It will unlock rfkill,205205- and either do nothing (leave transmitters blocked, but now unlocked),206206- restore the transmitters to their state before the EPO, or unblock207207- them all.208208-209209-Userspace uevent handler or kernel platform-specific drivers hooked to the210210-rfkill notifier chain:211211-212212- * Taps into the rfkill notifier chain or to KOBJ_CHANGE uevents,213213- in order to know when a device that is registered with the rfkill214214- class changes state;215215- * Issues feedback notifications to the user;216216- * In the rare platforms where this is required, synthesizes an input217217- event to command all *OTHER* rfkill devices to also change their218218- statues when a specific rfkill device changes state.219219-220220-221221-===============================================================================222222-3: Kernel driver guidelines223223-224224-Remember: point-of-view is everything for a driver that connects to the rfkill225225-subsystem. All the details below must be measured/perceived from the point of226226-view of the specific driver being modified.227227-228228-The first thing one needs to know is whether his driver should be talking to229229-the rfkill class or to the input layer. In rare cases (platform drivers), it230230-could happen that you need to do both, as platform drivers often handle a231231-variety of devices in the same driver.232232-233233-Do not mistake input devices for rfkill controllers. The only type of "rfkill234234-switch" device that is to be registered with the rfkill class are those235235-directly controlling the circuits that cause a wireless transmitter to stop236236-working (or the software equivalent of them), i.e. what we call a rfkill237237-controller. Every other kind of "rfkill switch" is just an input device and238238-MUST NOT be registered with the rfkill class.239239-240240-A driver should register a device with the rfkill class when ALL of the241241-following conditions are met (they define a rfkill controller):242242-243243-1. The device is/controls a data communications wireless transmitter;244244-245245-2. The kernel can interact with the hardware/firmware to CHANGE the wireless246246- transmitter state (block/unblock TX operation);247247-248248-3. The transmitter can be made to not emit any energy when "blocked":249249- rfkill is not about blocking data transmissions, it is about blocking250250- energy emission;251251-252252-A driver should register a device with the input subsystem to issue253253-rfkill-related events (KEY_WLAN, KEY_BLUETOOTH, KEY_WWAN, KEY_WIMAX,254254-SW_RFKILL_ALL, etc) when ALL of the folowing conditions are met:255255-256256-1. It is directly related to some physical device the user interacts with, to257257- command the O.S./firmware/hardware to enable/disable a data communications258258- wireless transmitter.259259-260260- Examples of the physical device are: buttons, keys and switches the user261261- will press/touch/slide/switch to enable or disable the wireless262262- communication device.263263-264264-2. It is NOT slaved to another device, i.e. there is no other device that265265- issues rfkill-related input events in preference to this one.266266-267267- Please refer to the corner cases and examples section for more details.268268-269269-When in doubt, do not issue input events. For drivers that should generate270270-input events in some platforms, but not in others (e.g. b43), the best solution271271-is to NEVER generate input events in the first place. That work should be272272-deferred to a platform-specific kernel module (which will know when to generate273273-events through the rfkill notifier chain) or to userspace. This avoids the274274-usual maintenance problems with DMI whitelisting.275275-276276-277277-Corner cases and examples:278278-====================================279279-280280-1. If the device is an input device that, because of hardware or firmware,281281-causes wireless transmitters to be blocked regardless of the kernel's will, it282282-is still just an input device, and NOT to be registered with the rfkill class.283283-284284-2. If the wireless transmitter switch control is read-only, it is an input285285-device and not to be registered with the rfkill class (and maybe not to be made286286-an input layer event source either, see below).287287-288288-3. If there is some other device driver *closer* to the actual hardware the289289-user interacted with (the button/switch/key) to issue an input event, THAT is290290-the device driver that should be issuing input events.291291-292292-E.g:293293- [RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input]294294- (platform driver) (wireless card driver)295295-296296-The user is closer to the RFKILL slide switch plaform driver, so the driver297297-which must issue input events is the platform driver looking at the GPIO298298-hardware, and NEVER the wireless card driver (which is just a slave). It is299299-very likely that there are other leaves than just the WLAN card rf-kill input300300-(e.g. a bluetooth card, etc)...301301-302302-On the other hand, some embedded devices do this:303303-304304- [RFKILL slider switch] -- [WLAN card rf-kill input]305305- (wireless card driver)306306-307307-In this situation, the wireless card driver *could* register itself as an input308308-device and issue rf-kill related input events... but in order to AVOID the need309309-for DMI whitelisting, the wireless card driver does NOT do it. Userspace (HAL)310310-or a platform driver (that exists only on these embedded devices) will do the311311-dirty job of issuing the input events.312312-313313-314314-COMMON MISTAKES in kernel drivers, related to rfkill:315315-====================================316316-317317-1. NEVER confuse input device keys and buttons with input device switches.318318-319319- 1a. Switches are always set or reset. They report the current state320320- (on position or off position).321321-322322- 1b. Keys and buttons are either in the pressed or not-pressed state, and323323- that's it. A "button" that latches down when you press it, and324324- unlatches when you press it again is in fact a switch as far as input325325- devices go.326326-327327-Add the SW_* events you need for switches, do NOT try to emulate a button using328328-KEY_* events just because there is no such SW_* event yet. Do NOT try to use,329329-for example, KEY_BLUETOOTH when you should be using SW_BLUETOOTH instead.330330-331331-2. Input device switches (sources of EV_SW events) DO store their current state332332-(so you *must* initialize it by issuing a gratuitous input layer event on333333-driver start-up and also when resuming from sleep), and that state CAN be334334-queried from userspace through IOCTLs. There is no sysfs interface for this,335335-but that doesn't mean you should break things trying to hook it to the rfkill336336-class to get a sysfs interface :-)337337-338338-3. Do not issue *_RFKILL_ALL events by default, unless you are sure it is the339339-correct event for your switch/button. These events are emergency power-off340340-events when they are trying to turn the transmitters off. An example of an341341-input device which SHOULD generate *_RFKILL_ALL events is the wireless-kill342342-switch in a laptop which is NOT a hotkey, but a real sliding/rocker switch.343343-An example of an input device which SHOULD NOT generate *_RFKILL_ALL events by344344-default, is any sort of hot key that is type-specific (e.g. the one for WLAN).345345-346346-347347-3.1 Guidelines for wireless device drivers348348-------------------------------------------349349-350350-(in this text, rfkill->foo means the foo field of struct rfkill).351351-352352-1. Each independent transmitter in a wireless device (usually there is only one353353-transmitter per device) should have a SINGLE rfkill class attached to it.354354-355355-2. If the device does not have any sort of hardware assistance to allow the356356-driver to rfkill the device, the driver should emulate it by taking all actions357357-required to silence the transmitter.358358-359359-3. If it is impossible to silence the transmitter (i.e. it still emits energy,360360-even if it is just in brief pulses, when there is no data to transmit and there361361-is no hardware support to turn it off) do NOT lie to the users. Do not attach362362-it to a rfkill class. The rfkill subsystem does not deal with data363363-transmission, it deals with energy emission. If the transmitter is emitting364364-energy, it is not blocked in rfkill terms.365365-366366-4. It doesn't matter if the device has multiple rfkill input lines affecting367367-the same transmitter, their combined state is to be exported as a single state368368-per transmitter (see rule 1).369369-370370-This rule exists because users of the rfkill subsystem expect to get (and set,371371-when possible) the overall transmitter rfkill state, not of a particular rfkill372372-line.373373-374374-5. The wireless device driver MUST NOT leave the transmitter enabled during375375-suspend and hibernation unless:376376-377377- 5.1. The transmitter has to be enabled for some sort of functionality378378- like wake-on-wireless-packet or autonomous packed forwarding in a mesh379379- network, and that functionality is enabled for this suspend/hibernation380380- cycle.381381-382382-AND383383-384384- 5.2. The device was not on a user-requested BLOCKED state before385385- the suspend (i.e. the driver must NOT unblock a device, not even386386- to support wake-on-wireless-packet or remain in the mesh).387387-388388-In other words, there is absolutely no allowed scenario where a driver can389389-automatically take action to unblock a rfkill controller (obviously, this deals390390-with scenarios where soft-blocking or both soft and hard blocking is happening.391391-Scenarios where hardware rfkill lines are the only ones blocking the392392-transmitter are outside of this rule, since the wireless device driver does not393393-control its input hardware rfkill lines in the first place).394394-395395-6. During resume, rfkill will try to restore its previous state.396396-397397-7. After a rfkill class is suspended, it will *not* call rfkill->toggle_radio398398-until it is resumed.399399-400400-401401-Example of a WLAN wireless driver connected to the rfkill subsystem:402402---------------------------------------------------------------------403403-404404-A certain WLAN card has one input pin that causes it to block the transmitter405405-and makes the status of that input pin available (only for reading!) to the406406-kernel driver. This is a hard rfkill input line (it cannot be overridden by407407-the kernel driver).408408-409409-The card also has one PCI register that, if manipulated by the driver, causes410410-it to block the transmitter. This is a soft rfkill input line.411411-412412-It has also a thermal protection circuitry that shuts down its transmitter if413413-the card overheats, and makes the status of that protection available (only for414414-reading!) to the kernel driver. This is also a hard rfkill input line.415415-416416-If either one of these rfkill lines are active, the transmitter is blocked by417417-the hardware and forced offline.418418-419419-The driver should allocate and attach to its struct device *ONE* instance of420420-the rfkill class (there is only one transmitter).421421-422422-It can implement the get_state() hook, and return RFKILL_STATE_HARD_BLOCKED if423423-either one of its two hard rfkill input lines are active. If the two hard424424-rfkill lines are inactive, it must return RFKILL_STATE_SOFT_BLOCKED if its soft425425-rfkill input line is active. Only if none of the rfkill input lines are426426-active, will it return RFKILL_STATE_UNBLOCKED.427427-428428-Since the device has a hardware rfkill line, it IS subject to state changes429429-external to rfkill. Therefore, the driver must make sure that it calls430430-rfkill_force_state() to keep the status always up-to-date, and it must do a431431-rfkill_force_state() on resume from sleep.432432-433433-Every time the driver gets a notification from the card that one of its rfkill434434-lines changed state (polling might be needed on badly designed cards that don't435435-generate interrupts for such events), it recomputes the rfkill state as per436436-above, and calls rfkill_force_state() to update it.437437-438438-The driver should implement the toggle_radio() hook, that:439439-440440-1. Returns an error if one of the hardware rfkill lines are active, and the441441-caller asked for RFKILL_STATE_UNBLOCKED.442442-443443-2. Activates the soft rfkill line if the caller asked for state444444-RFKILL_STATE_SOFT_BLOCKED. It should do this even if one of the hard rfkill445445-lines are active, effectively double-blocking the transmitter.446446-447447-3. Deactivates the soft rfkill line if none of the hardware rfkill lines are448448-active and the caller asked for RFKILL_STATE_UNBLOCKED.449449-450450-===============================================================================451451-4: Kernel API3636+The rfkill class code also notifies userspace of state changes, this is3737+achieved via uevents. It also provides some sysfs files for userspace to3838+check the status of radio transmitters. See the "Userspace support" section3939+below.4040+4141+4242+The rfkill-input code implements a basic response to rfkill buttons -- it4343+implements turning on/off all devices of a certain class (or all).4444+4545+When the device is hard-blocked (either by a call to rfkill_set_hw_state()4646+or from query_hw_block) set_block() will be invoked but drivers can well4747+ignore the method call since they can use the return value of the function4848+rfkill_set_hw_state() to sync the software state instead of keeping track4949+of calls to set_block().5050+5151+5252+The entire functionality is spread over more than one subsystem:5353+5454+ * The kernel input layer generates KEY_WWAN, KEY_WLAN etc. and5555+ SW_RFKILL_ALL -- when the user presses a button. Drivers for radio5656+ transmitters generally do not register to the input layer, unless the5757+ device really provides an input device (i.e. a button that has no5858+ effect other than generating a button press event)5959+6060+ * The rfkill-input code hooks up to these events and switches the soft-block6161+ of the various radio transmitters, depending on the button type.6262+6363+ * The rfkill drivers turn off/on their transmitters as requested.6464+6565+ * The rfkill class will generate userspace notifications (uevents) to tell6666+ userspace what the current state is.6767+6868+6969+7070+3. Kernel driver guidelines7171+7272+7373+Drivers for radio transmitters normally implement only the rfkill class.7474+These drivers may not unblock the transmitter based on own decisions, they7575+should act on information provided by the rfkill class only.7676+7777+Platform drivers might implement input devices if the rfkill button is just7878+that, a button. If that button influences the hardware then you need to7979+implement an rfkill class instead. This also applies if the platform provides8080+a way to turn on/off the transmitter(s).8181+8282+During suspend/hibernation, transmitters should only be left enabled when8383+wake-on wlan or similar functionality requires it and the device wasn't8484+blocked before suspend/hibernate. Note that it may be necessary to update8585+the rfkill subsystem's idea of what the current state is at resume time if8686+the state may have changed over suspend.8787+8888+8989+9090+4. Kernel API4529145392To build a driver with rfkill subsystem support, the driver should depend on454454-(or select) the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.9393+(or select) the Kconfig symbol RFKILL.4559445695The hardware the driver talks to may be write-only (where the current state45796of the hardware is unknown), or read-write (where the hardware can be queried45897about its current state).45998460460-The rfkill class will call the get_state hook of a device every time it needs461461-to know the *real* current state of the hardware. This can happen often, but462462-it does not do any polling, so it is not enough on hardware that is subject463463-to state changes outside of the rfkill subsystem.9999+Calling rfkill_set_hw_state() when a state change happens is required from100100+rfkill drivers that control devices that can be hard-blocked unless they also101101+assign the poll_hw_block() callback (then the rfkill core will poll the102102+device). Don't do this unless you cannot get the event in any other way.464103465465-Therefore, calling rfkill_force_state() when a state change happens is466466-mandatory when the device has a hardware rfkill line, or when something else467467-like the firmware could cause its state to be changed without going through the468468-rfkill class.469104470470-Some hardware provides events when its status changes. In these cases, it is471471-best for the driver to not provide a get_state hook, and instead register the472472-rfkill class *already* with the correct status, and keep it updated using473473-rfkill_force_state() when it gets an event from the hardware.474105475475-rfkill_force_state() must be used on the device resume handlers to update the476476-rfkill status, should there be any chance of the device status changing during477477-the sleep.106106+5. Userspace support478107479479-There is no provision for a statically-allocated rfkill struct. You must480480-use rfkill_allocate() to allocate one.481481-482482-You should:483483- - rfkill_allocate()484484- - modify rfkill fields (flags, name)485485- - modify state to the current hardware state (THIS IS THE ONLY TIME486486- YOU CAN ACCESS state DIRECTLY)487487- - rfkill_register()488488-489489-The only way to set a device to the RFKILL_STATE_HARD_BLOCKED state is through490490-a suitable return of get_state() or through rfkill_force_state().491491-492492-When a device is in the RFKILL_STATE_HARD_BLOCKED state, the only way to switch493493-it to a different state is through a suitable return of get_state() or through494494-rfkill_force_state().495495-496496-If toggle_radio() is called to set a device to state RFKILL_STATE_SOFT_BLOCKED497497-when that device is already at the RFKILL_STATE_HARD_BLOCKED state, it should498498-not return an error. Instead, it should try to double-block the transmitter,499499-so that its state will change from RFKILL_STATE_HARD_BLOCKED to500500-RFKILL_STATE_SOFT_BLOCKED should the hardware blocking cease.501501-502502-Please refer to the source for more documentation.503503-504504-===============================================================================505505-5: Userspace support506506-507507-rfkill devices issue uevents (with an action of "change"), with the following508508-environment variables set:509509-510510-RFKILL_NAME511511-RFKILL_STATE512512-RFKILL_TYPE513513-514514-The ABI for these variables is defined by the sysfs attributes. It is best515515-to take a quick look at the source to make sure of the possible values.516516-517517-It is expected that HAL will trap those, and bridge them to DBUS, etc. These518518-events CAN and SHOULD be used to give feedback to the user about the rfkill519519-status of the system.520520-521521-Input devices may issue events that are related to rfkill. These are the522522-various KEY_* events and SW_* events supported by rfkill-input.c.523523-524524-Userspace may not change the state of an rfkill switch in response to an525525-input event, it should refrain from changing states entirely.526526-527527-Userspace cannot assume it is the only source of control for rfkill switches.528528-Their state can change due to firmware actions, direct user actions, and the529529-rfkill-input EPO override for *_RFKILL_ALL.530530-531531-When rfkill-input is not active, userspace must initiate a rfkill status532532-change by writing to the "state" attribute in order for anything to happen.533533-534534-Take particular care to implement EV_SW SW_RFKILL_ALL properly. When that535535-switch is set to OFF, *every* rfkill device *MUST* be immediately put into the536536-RFKILL_STATE_SOFT_BLOCKED state, no questions asked.537537-538538-The following sysfs entries will be created:108108+The following sysfs entries exist for every rfkill device:539109540110 name: Name assigned by driver to this key (interface or driver name).541111 type: Name of the key type ("wlan", "bluetooth", etc).542112 state: Current state of the transmitter543113 0: RFKILL_STATE_SOFT_BLOCKED544544- transmitter is forced off, but one can override it545545- by a write to the state attribute;114114+ transmitter is turned off by software546115 1: RFKILL_STATE_UNBLOCKED547547- transmiter is NOT forced off, and may operate if548548- all other conditions for such operation are met549549- (such as interface is up and configured, etc);116116+ transmitter is (potentially) active550117 2: RFKILL_STATE_HARD_BLOCKED551118 transmitter is forced off by something outside of552552- the driver's control. One cannot set a device to553553- this state through writes to the state attribute;554554- claim: 1: Userspace handles events, 0: Kernel handles events119119+ the driver's control.120120+ claim: 0: Kernel handles events (currently always reads that value)555121556556-Both the "state" and "claim" entries are also writable. For the "state" entry557557-this means that when 1 or 0 is written, the device rfkill state (if not yet in558558-the requested state), will be will be toggled accordingly.122122+rfkill devices also issue uevents (with an action of "change"), with the123123+following environment variables set:559124560560-For the "claim" entry writing 1 to it means that the kernel no longer handles561561-key events even though RFKILL_INPUT input was enabled. When "claim" has been562562-set to 0, userspace should make sure that it listens for the input events or563563-check the sysfs "state" entry regularly to correctly perform the required tasks564564-when the rkfill key is pressed.125125+RFKILL_NAME126126+RFKILL_STATE127127+RFKILL_TYPE565128566566-A note about input devices and EV_SW events:129129+The contents of these variables corresponds to the "name", "state" and130130+"type" sysfs files explained above.567131568568-In order to know the current state of an input device switch (like569569-SW_RFKILL_ALL), you will need to use an IOCTL. That information is not570570-available through sysfs in a generic way at this time, and it is not available571571-through the rfkill class AT ALL.132132+An alternative userspace interface exists as a misc device /dev/rfkill,133133+which allows userspace to obtain and set the state of rfkill devices and134134+sets of devices. It also notifies userspace about device addition and135135+removal. The API is a simple read/write API that is defined in136136+linux/rfkill.h.
+3-3
MAINTAINERS
···47534753F: fs/reiserfs/4754475447554755RFKILL47564756-P: Ivo van Doorn47574757-M: IvDoorn@gmail.com47584758-L: netdev@vger.kernel.org47564756+P: Johannes Berg47574757+M: johannes@sipsolutions.net47584758+L: linux-wireless@vger.kernel.org47594759S: Maintained47604760F Documentation/rfkill.txt47614761F: net/rfkill/
···24812481 return 0;24822482}2483248324842484-static int hso_radio_toggle(void *data, enum rfkill_state state)24842484+static int hso_rfkill_set_block(void *data, bool blocked)24852485{24862486 struct hso_device *hso_dev = data;24872487- int enabled = (state == RFKILL_STATE_UNBLOCKED);24872487+ int enabled = !blocked;24882488 int rv;2489248924902490 mutex_lock(&hso_dev->mutex);···24982498 return rv;24992499}2500250025012501+static const struct rfkill_ops hso_rfkill_ops = {25022502+ .set_block = hso_rfkill_set_block,25032503+};25042504+25012505/* Creates and sets up everything for rfkill */25022506static void hso_create_rfkill(struct hso_device *hso_dev,25032507 struct usb_interface *interface)···25102506 struct device *dev = &hso_net->net->dev;25112507 char *rfkn;2512250825132513- hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev,25142514- RFKILL_TYPE_WWAN);25152515- if (!hso_net->rfkill) {25162516- dev_err(dev, "%s - Out of memory\n", __func__);25172517- return;25182518- }25192509 rfkn = kzalloc(20, GFP_KERNEL);25202520- if (!rfkn) {25212521- rfkill_free(hso_net->rfkill);25222522- hso_net->rfkill = NULL;25102510+ if (!rfkn)25232511 dev_err(dev, "%s - Out of memory\n", __func__);25242524- return;25252525- }25122512+25262513 snprintf(rfkn, 20, "hso-%d",25272514 interface->altsetting->desc.bInterfaceNumber);25282528- hso_net->rfkill->name = rfkn;25292529- hso_net->rfkill->state = RFKILL_STATE_UNBLOCKED;25302530- hso_net->rfkill->data = hso_dev;25312531- hso_net->rfkill->toggle_radio = hso_radio_toggle;25322532- if (rfkill_register(hso_net->rfkill) < 0) {25152515+25162516+ hso_net->rfkill = rfkill_alloc(rfkn,25172517+ &interface_to_usbdev(interface)->dev,25182518+ RFKILL_TYPE_WWAN,25192519+ &hso_rfkill_ops, hso_dev);25202520+ if (!hso_net->rfkill) {25212521+ dev_err(dev, "%s - Out of memory\n", __func__);25332522 kfree(rfkn);25342534- hso_net->rfkill->name = NULL;25352535- rfkill_free(hso_net->rfkill);25232523+ return;25242524+ }25252525+ if (rfkill_register(hso_net->rfkill) < 0) {25262526+ rfkill_destroy(hso_net->rfkill);25272527+ kfree(rfkn);25362528 hso_net->rfkill = NULL;25372529 dev_err(dev, "%s - Failed to register rfkill\n", __func__);25382530 return;···31653165 hso_stop_net_device(network_table[i]);31663166 cancel_work_sync(&network_table[i]->async_put_intf);31673167 cancel_work_sync(&network_table[i]->async_get_intf);31683168- if (rfk)31683168+ if (rfk) {31693169 rfkill_unregister(rfk);31703170+ rfkill_destroy(rfk);31713171+ }31703172 hso_free_net_device(network_table[i]);31713173 }31723174 }
+1-1
drivers/net/wireless/Kconfig
···333333config USB_NET_RNDIS_WLAN334334 tristate "Wireless RNDIS USB support"335335 depends on USB && WLAN_80211 && EXPERIMENTAL336336+ depends on CFG80211336337 select USB_USBNET337338 select USB_NET_CDCETHER338339 select USB_NET_RNDIS_HOST339340 select WIRELESS_EXT340340- select CFG80211341341 ---help---342342 This is a driver for wireless RNDIS devices.343343 These are USB based adapters found in devices such as:
···411411 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {412412 DPRINTF(sc, ATH_DBG_BEACON,413413 "beacon is officially stuck\n");414414+ sc->sc_flags |= SC_OP_TSF_RESET;414415 ath_reset(sc, false);415416 }416417···673672 u32 tsftu, intval, nexttbtt;674673675674 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;675675+676676+ /*677677+ * It looks like mac80211 may end up using beacon interval of zero in678678+ * some cases (at least for mesh point). Avoid getting into an679679+ * infinite loop by using a bit safer value instead..680680+ */681681+ if (intval == 0)682682+ intval = 100;676683677684 /* Pull nexttbtt forward to reflect the current TSF */678685
···3470347034713471 if (!!conf->radio_enabled != phy->radio_on) {34723472 if (conf->radio_enabled) {34733473- b43_software_rfkill(dev, RFKILL_STATE_UNBLOCKED);34733473+ b43_software_rfkill(dev, false);34743474 b43info(dev->wl, "Radio turned on by software\n");34753475 if (!dev->radio_hw_enable) {34763476 b43info(dev->wl, "The hardware RF-kill button "···34783478 "Press the button to turn it on.\n");34793479 }34803480 } else {34813481- b43_software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);34813481+ b43_software_rfkill(dev, true);34823482 b43info(dev->wl, "Radio turned off by software\n");34833483 }34843484 }
+2-2
drivers/net/wireless/b43/phy_a.c
···480480}481481482482static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,483483- enum rfkill_state state)483483+ bool blocked)484484{485485 struct b43_phy *phy = &dev->phy;486486487487- if (state == RFKILL_STATE_UNBLOCKED) {487487+ if (!blocked) {488488 if (phy->radio_on)489489 return;490490 b43_radio_write16(dev, 0x0004, 0x00C0);
···4545}46464747/* The poll callback for the hardware button. */4848-static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)4848+static void b43legacy_rfkill_poll(struct rfkill *rfkill, void *data)4949{5050- struct b43legacy_wldev *dev = poll_dev->private;5050+ struct b43legacy_wldev *dev = data;5151 struct b43legacy_wl *wl = dev->wl;5252 bool enabled;5353- bool report_change = 0;54535554 mutex_lock(&wl->mutex);5655 if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) {···5960 enabled = b43legacy_is_hw_radio_enabled(dev);6061 if (unlikely(enabled != dev->radio_hw_enable)) {6162 dev->radio_hw_enable = enabled;6262- report_change = 1;6363 b43legacyinfo(wl, "Radio hardware status changed to %s\n",6464 enabled ? "ENABLED" : "DISABLED");6565+ enabled = !rfkill_set_hw_state(rfkill, !enabled);6666+ if (enabled != dev->phy.radio_on) {6767+ if (enabled)6868+ b43legacy_radio_turn_on(dev);6969+ else7070+ b43legacy_radio_turn_off(dev, 0);7171+ }6572 }6673 mutex_unlock(&wl->mutex);6767-6868- /* send the radio switch event to the system - note both a key press6969- * and a release are required */7070- if (unlikely(report_change)) {7171- input_report_key(poll_dev->input, KEY_WLAN, 1);7272- input_report_key(poll_dev->input, KEY_WLAN, 0);7373- }7474}75757676/* Called when the RFKILL toggled in software.7777 * This is called without locking. */7878-static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state)7878+static int b43legacy_rfkill_soft_set(void *data, bool blocked)7979{8080 struct b43legacy_wldev *dev = data;8181 struct b43legacy_wl *wl = dev->wl;8282- int err = -EBUSY;8282+ int ret = -EINVAL;83838484 if (!wl->rfkill.registered)8585- return 0;8585+ return -EINVAL;86868787 mutex_lock(&wl->mutex);8888 if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)8989 goto out_unlock;9090- err = 0;9191- switch (state) {9292- case RFKILL_STATE_UNBLOCKED:9393- if (!dev->radio_hw_enable) {9494- /* No luck. We can't toggle the hardware RF-kill9595- * button from software. */9696- err = -EBUSY;9797- goto out_unlock;9898- }9999- if (!dev->phy.radio_on)9090+9191+ if (!dev->radio_hw_enable)9292+ goto out_unlock;9393+9494+ if (!blocked != dev->phy.radio_on) {9595+ if (!blocked)10096 b43legacy_radio_turn_on(dev);101101- break;102102- case RFKILL_STATE_SOFT_BLOCKED:103103- if (dev->phy.radio_on)9797+ else10498 b43legacy_radio_turn_off(dev, 0);105105- break;106106- default:107107- b43legacywarn(wl, "Received unexpected rfkill state %d.\n",108108- state);109109- break;11099 }100100+ ret = 0;111101112102out_unlock:113103 mutex_unlock(&wl->mutex);114114-115115- return err;104104+ return ret;116105}117106118118-char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev)107107+const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev)119108{120109 struct b43legacy_rfkill *rfk = &(dev->wl->rfkill);121110122111 if (!rfk->registered)123112 return NULL;124124- return rfkill_get_led_name(rfk->rfkill);113113+ return rfkill_get_led_trigger_name(rfk->rfkill);125114}115115+116116+static const struct rfkill_ops b43legacy_rfkill_ops = {117117+ .set_block = b43legacy_rfkill_soft_set,118118+ .poll = b43legacy_rfkill_poll,119119+};126120127121void b43legacy_rfkill_init(struct b43legacy_wldev *dev)128122{···125133126134 rfk->registered = 0;127135128128- rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);129129- if (!rfk->rfkill)130130- goto out_error;131136 snprintf(rfk->name, sizeof(rfk->name),132137 "b43legacy-%s", wiphy_name(wl->hw->wiphy));133133- rfk->rfkill->name = rfk->name;134134- rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;135135- rfk->rfkill->data = dev;136136- rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle;137137-138138- rfk->poll_dev = input_allocate_polled_device();139139- if (!rfk->poll_dev) {140140- rfkill_free(rfk->rfkill);141141- goto err_freed_rfk;142142- }143143-144144- rfk->poll_dev->private = dev;145145- rfk->poll_dev->poll = b43legacy_rfkill_poll;146146- rfk->poll_dev->poll_interval = 1000; /* msecs */147147-148148- rfk->poll_dev->input->name = rfk->name;149149- rfk->poll_dev->input->id.bustype = BUS_HOST;150150- rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor;151151- rfk->poll_dev->input->evbit[0] = BIT(EV_KEY);152152- set_bit(KEY_WLAN, rfk->poll_dev->input->keybit);138138+ rfk->rfkill = rfkill_alloc(rfk->name,139139+ dev->dev->dev,140140+ RFKILL_TYPE_WLAN,141141+ &b43legacy_rfkill_ops, dev);142142+ if (!rfk->rfkill)143143+ goto out_error;153144154145 err = rfkill_register(rfk->rfkill);155146 if (err)156156- goto err_free_polldev;157157-158158-#ifdef CONFIG_RFKILL_INPUT_MODULE159159- /* B43legacy RF-kill isn't useful without the rfkill-input subsystem.160160- * Try to load the module. */161161- err = request_module("rfkill-input");162162- if (err)163163- b43legacywarn(wl, "Failed to load the rfkill-input module."164164- "The built-in radio LED will not work.\n");165165-#endif /* CONFIG_RFKILL_INPUT */166166-167167- err = input_register_polled_device(rfk->poll_dev);168168- if (err)169169- goto err_unreg_rfk;147147+ goto err_free;170148171149 rfk->registered = 1;172150173151 return;174174-err_unreg_rfk:175175- rfkill_unregister(rfk->rfkill);176176-err_free_polldev:177177- input_free_polled_device(rfk->poll_dev);178178- rfk->poll_dev = NULL;179179-err_freed_rfk:180180- rfk->rfkill = NULL;181181-out_error:152152+ err_free:153153+ rfkill_destroy(rfk->rfkill);154154+ out_error:182155 rfk->registered = 0;183156 b43legacywarn(wl, "RF-kill button init failed\n");184157}···156199 return;157200 rfk->registered = 0;158201159159- input_unregister_polled_device(rfk->poll_dev);160202 rfkill_unregister(rfk->rfkill);161161- input_free_polled_device(rfk->poll_dev);162162- rfk->poll_dev = NULL;203203+ rfkill_destroy(rfk->rfkill);163204 rfk->rfkill = NULL;164205}165206
+1-5
drivers/net/wireless/b43legacy/rfkill.h
···66#ifdef CONFIG_B43LEGACY_RFKILL7788#include <linux/rfkill.h>99-#include <linux/workqueue.h>1010-#include <linux/input-polldev.h>119121013111412struct b43legacy_rfkill {1513 /* The RFKILL subsystem data structure */1614 struct rfkill *rfkill;1717- /* The poll device for the RFKILL input button */1818- struct input_polled_dev *poll_dev;1915 /* Did initialization succeed? Used for freeing. */2016 bool registered;2117 /* The unique name of this rfkill switch */···2327void b43legacy_rfkill_init(struct b43legacy_wldev *dev);2428void b43legacy_rfkill_exit(struct b43legacy_wldev *dev);25292626-char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev);3030+const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev);273128322933#else /* CONFIG_B43LEGACY_RFKILL */
+2-3
drivers/net/wireless/iwlwifi/Kconfig
···55 select FW_LOADER66 select MAC80211_LEDS if IWLWIFI_LEDS77 select LEDS_CLASS if IWLWIFI_LEDS88- select RFKILL if IWLWIFI_RFKILL98109config IWLWIFI_LEDS1110 bool "Enable LED support in iwlagn and iwl3945 drivers"1211 depends on IWLWIFI13121413config IWLWIFI_RFKILL1515- bool "Enable RF kill support in iwlagn and iwl3945 drivers"1616- depends on IWLWIFI1414+ def_bool y1515+ depends on IWLWIFI && RFKILL17161817config IWLWIFI_SPECTRUM_MEASUREMENT1918 bool "Enable Spectrum Measurement in iwlagn driver"
···188188 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));189189 }190190191191- priv->cfg->ops->smgmt->clear_station_table(priv);191191+ iwl_clear_stations_table(priv);192192193193 priv->start_calib = 0;194194···16171617 goto restart;16181618 }1619161916201620- priv->cfg->ops->smgmt->clear_station_table(priv);16201620+ iwl_clear_stations_table(priv);16211621 ret = priv->cfg->ops->lib->alive_notify(priv);16221622 if (ret) {16231623 IWL_WARN(priv,···1703170317041704 iwl_leds_unregister(priv);1705170517061706- priv->cfg->ops->smgmt->clear_station_table(priv);17061706+ iwl_clear_stations_table(priv);1707170717081708 /* Unblock any waiting calls */17091709 wake_up_interruptible_all(&priv->wait_command_queue);···1887188718881888 /* clear (again), then enable host interrupts */18891889 iwl_write32(priv, CSR_INT, 0xFFFFFFFF);18901890- /* enable dram interrupt */18911891- iwl_reset_ict(priv);18921890 iwl_enable_interrupts(priv);1893189118941892 /* really make sure rfkill handshake bits are cleared */···1901190319021904 for (i = 0; i < MAX_HW_RESTARTS; i++) {1903190519041904- priv->cfg->ops->smgmt->clear_station_table(priv);19061906+ iwl_clear_stations_table(priv);1905190719061908 /* load bootstrap state machine,19071909 * load bootstrap program into processor's memory,···1959196119601962 if (test_bit(STATUS_EXIT_PENDING, &priv->status))19611963 return;19641964+19651965+ /* enable dram interrupt */19661966+ iwl_reset_ict(priv);1962196719631968 mutex_lock(&priv->mutex);19641969 iwl_alive_start(priv);···23492348 return -EOPNOTSUPP;23502349 }23512350 addr = sta ? sta->addr : iwl_bcast_addr;23522352- sta_id = priv->cfg->ops->smgmt->find_station(priv, addr);23512351+ sta_id = iwl_find_station(priv, addr);23532352 if (sta_id == IWL_INVALID_STATION) {23542353 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",23552354 addr);···31223121 iwl_rx_queue_free(priv, &priv->rxq);31233122 iwl_hw_txq_ctx_free(priv);3124312331253125- priv->cfg->ops->smgmt->clear_station_table(priv);31243124+ iwl_clear_stations_table(priv);31263125 iwl_eeprom_free(priv);3127312631283127
+13-1
drivers/net/wireless/iwlwifi/iwl-commands.h
···10671067 * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */10681068 __le16 tid_disable_tx;1069106910701070- __le16 reserved1;10701070+ __le16 rate_n_flags; /* 3945 only */1071107110721072 /* TID for which to add block-ack support.10731073 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */···19121912 */19131913 u8 start_rate_index[LINK_QUAL_AC_NUM];19141914} __attribute__ ((packed));19151915+19161916+#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */19171917+#define LINK_QUAL_AGG_TIME_LIMIT_MAX (65535)19181918+#define LINK_QUAL_AGG_TIME_LIMIT_MIN (0)19191919+19201920+#define LINK_QUAL_AGG_DISABLE_START_DEF (3)19211921+#define LINK_QUAL_AGG_DISABLE_START_MAX (255)19221922+#define LINK_QUAL_AGG_DISABLE_START_MIN (0)19231923+19241924+#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (31)19251925+#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (64)19261926+#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0)1915192719161928/**19171929 * struct iwl_link_qual_agg_params
+4-10
drivers/net/wireless/iwlwifi/iwl-core.c
···13891389 mutex_init(&priv->mutex);1390139013911391 /* Clear the driver's (not device's) station table */13921392- priv->cfg->ops->smgmt->clear_station_table(priv);13921392+ iwl_clear_stations_table(priv);1393139313941394 priv->data_retry_limit = -1;13951395 priv->ieee_channels = NULL;···17041704{17051705 struct iwl_priv *priv = data;17061706 u32 inta, inta_mask;17071707+#ifdef CONFIG_IWLWIFI_DEBUG17071708 u32 inta_fh;17081708-17091709+#endif17091710 if (!priv)17101711 return IRQ_NONE;17111712···2680267926812680 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);2682268126832683- priv->cfg->ops->smgmt->clear_station_table(priv);26822682+ iwl_clear_stations_table(priv);2684268326852684 /* dont commit rxon if rf-kill is on*/26862685 if (!iwl_is_ready_rf(priv))26872686 return -EAGAIN;26882688-26892689- cancel_delayed_work(&priv->scan_check);26902690- if (iwl_scan_cancel_timeout(priv, 100)) {26912691- IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");26922692- IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");26932693- return -EAGAIN;26942694- }2695268726962688 iwlcore_commit_rxon(priv);26972689
+1-11
drivers/net/wireless/iwlwifi/iwl-core.h
···8383#define IWL_SKU_A 0x28484#define IWL_SKU_N 0x885858686-struct iwl_station_mgmt_ops {8787- u8 (*add_station)(struct iwl_priv *priv, const u8 *addr,8888- int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info);8989- int (*remove_station)(struct iwl_priv *priv, const u8 *addr,9090- int is_ap);9191- u8 (*find_station)(struct iwl_priv *priv, const u8 *addr);9292- void (*clear_station_table)(struct iwl_priv *priv);9393-};9494-9586struct iwl_hcmd_ops {9687 int (*rxon_assoc)(struct iwl_priv *priv);9788 int (*commit_rxon)(struct iwl_priv *priv);···174183 const struct iwl_lib_ops *lib;175184 const struct iwl_hcmd_ops *hcmd;176185 const struct iwl_hcmd_utils_ops *utils;177177- const struct iwl_station_mgmt_ops *smgmt;178186};179187180188struct iwl_mod_params {···182192 int disable_hw_scan; /* def: 0 = use h/w scan */183193 int num_of_queues; /* def: HW dependent */184194 int num_of_ampdu_queues;/* def: HW dependent */185185- int disable_11n; /* def: 0 = disable 11n capabilities */195195+ int disable_11n; /* def: 0 = 11n capabilities enabled */186196 int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */187197 int antenna; /* def: 0 = both antennas (use diversity) */188198 int restart_fw; /* def: 1 = restart firmware */
···9595 /* the rest are 0 by default */9696};97979898-/*************** STATION TABLE MANAGEMENT ****9999- * mac80211 should be examined to determine if sta_info is duplicating100100- * the functionality provided here101101- */102102-103103-/**************************************************************/104104-#if 0 /* temporary disable till we add real remove station */105105-/**106106- * iwl3945_remove_station - Remove driver's knowledge of station.107107- *108108- * NOTE: This does not remove station from device's station table.109109- */110110-static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)111111-{112112- int index = IWL_INVALID_STATION;113113- int i;114114- unsigned long flags;115115-116116- spin_lock_irqsave(&priv->sta_lock, flags);117117-118118- if (is_ap)119119- index = IWL_AP_ID;120120- else if (is_broadcast_ether_addr(addr))121121- index = priv->hw_params.bcast_sta_id;122122- else123123- for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)124124- if (priv->stations_39[i].used &&125125- !compare_ether_addr(priv->stations_39[i].sta.sta.addr,126126- addr)) {127127- index = i;128128- break;129129- }130130-131131- if (unlikely(index == IWL_INVALID_STATION))132132- goto out;133133-134134- if (priv->stations_39[index].used) {135135- priv->stations_39[index].used = 0;136136- priv->num_stations--;137137- }138138-139139- BUG_ON(priv->num_stations < 0);140140-141141-out:142142- spin_unlock_irqrestore(&priv->sta_lock, flags);143143- return 0;144144-}145145-#endif146146-147147-/**148148- * iwl3945_clear_stations_table - Clear the driver's station table149149- *150150- * NOTE: This does not clear or otherwise alter the device's station table.151151- */152152-void iwl3945_clear_stations_table(struct iwl_priv *priv)153153-{154154- unsigned long flags;155155-156156- spin_lock_irqsave(&priv->sta_lock, flags);157157-158158- priv->num_stations = 0;159159- memset(priv->stations_39, 0, sizeof(priv->stations_39));160160-161161- spin_unlock_irqrestore(&priv->sta_lock, flags);162162-}163163-164164-/**165165- * iwl3945_add_station - Add station to station tables in driver and device166166- */167167-u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info)168168-{169169- int i;170170- int index = IWL_INVALID_STATION;171171- struct iwl3945_station_entry *station;172172- unsigned long flags_spin;173173- u8 rate;174174-175175- spin_lock_irqsave(&priv->sta_lock, flags_spin);176176- if (is_ap)177177- index = IWL_AP_ID;178178- else if (is_broadcast_ether_addr(addr))179179- index = priv->hw_params.bcast_sta_id;180180- else181181- for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {182182- if (!compare_ether_addr(priv->stations_39[i].sta.sta.addr,183183- addr)) {184184- index = i;185185- break;186186- }187187-188188- if (!priv->stations_39[i].used &&189189- index == IWL_INVALID_STATION)190190- index = i;191191- }192192-193193- /* These two conditions has the same outcome but keep them separate194194- since they have different meaning */195195- if (unlikely(index == IWL_INVALID_STATION)) {196196- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);197197- return index;198198- }199199-200200- if (priv->stations_39[index].used &&201201- !compare_ether_addr(priv->stations_39[index].sta.sta.addr, addr)) {202202- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);203203- return index;204204- }205205-206206- IWL_DEBUG_ASSOC(priv, "Add STA ID %d: %pM\n", index, addr);207207- station = &priv->stations_39[index];208208- station->used = 1;209209- priv->num_stations++;210210-211211- /* Set up the REPLY_ADD_STA command to send to device */212212- memset(&station->sta, 0, sizeof(struct iwl3945_addsta_cmd));213213- memcpy(station->sta.sta.addr, addr, ETH_ALEN);214214- station->sta.mode = 0;215215- station->sta.sta.sta_id = index;216216- station->sta.station_flags = 0;217217-218218- if (priv->band == IEEE80211_BAND_5GHZ)219219- rate = IWL_RATE_6M_PLCP;220220- else221221- rate = IWL_RATE_1M_PLCP;222222-223223- /* Turn on both antennas for the station... */224224- station->sta.rate_n_flags =225225- iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);226226-227227- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);228228-229229- /* Add station to device's station table */230230- iwl_send_add_sta(priv,231231- (struct iwl_addsta_cmd *)&station->sta, flags);232232- return index;233233-234234-}235235-23698/**23799 * iwl3945_get_antenna_flags - Get antenna flags for RXON command238100 * @priv: eeprom and antenna fields are used to determine antenna flags···151289 key_flags &= ~STA_KEY_FLG_INVALID;152290153291 spin_lock_irqsave(&priv->sta_lock, flags);154154- priv->stations_39[sta_id].keyinfo.alg = keyconf->alg;155155- priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen;156156- memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key,292292+ priv->stations[sta_id].keyinfo.alg = keyconf->alg;293293+ priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;294294+ memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,157295 keyconf->keylen);158296159159- memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key,297297+ memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,160298 keyconf->keylen);161299162162- if ((priv->stations_39[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)300300+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)163301 == STA_KEY_FLG_NO_ENC)164164- priv->stations_39[sta_id].sta.key.key_offset =302302+ priv->stations[sta_id].sta.key.key_offset =165303 iwl_get_free_ucode_key_index(priv);166304 /* else, we are overriding an existing key => no need to allocated room167305 * in uCode. */168306169169- WARN(priv->stations_39[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,307307+ WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,170308 "no space for a new key");171309172172- priv->stations_39[sta_id].sta.key.key_flags = key_flags;173173- priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;174174- priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;310310+ priv->stations[sta_id].sta.key.key_flags = key_flags;311311+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;312312+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;175313176314 IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");177315178178- ret = iwl_send_add_sta(priv,179179- (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC);316316+ ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);180317181318 spin_unlock_irqrestore(&priv->sta_lock, flags);182319···201340 unsigned long flags;202341203342 spin_lock_irqsave(&priv->sta_lock, flags);204204- memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));205205- memset(&priv->stations_39[sta_id].sta.key, 0,343343+ memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));344344+ memset(&priv->stations[sta_id].sta.key, 0,206345 sizeof(struct iwl4965_keyinfo));207207- priv->stations_39[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;208208- priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;209209- priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;346346+ priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;347347+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;348348+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;210349 spin_unlock_irqrestore(&priv->sta_lock, flags);211350212351 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");213213- iwl_send_add_sta(priv,214214- (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);352352+ iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0);215353 return 0;216354}217355···438578 int sta_id)439579{440580 struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;441441- struct iwl_hw_key *keyinfo = &priv->stations_39[sta_id].keyinfo;581581+ struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;442582443583 switch (keyinfo->alg) {444584 case ALG_CCMP:···613753 if (ieee80211_is_data_qos(fc)) {614754 qc = ieee80211_get_qos_ctl(hdr);615755 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;616616- seq_number = priv->stations_39[sta_id].tid[tid].seq_number &756756+ seq_number = priv->stations[sta_id].tid[tid].seq_number &617757 IEEE80211_SCTL_SEQ;618758 hdr->seq_ctrl = cpu_to_le16(seq_number) |619759 (hdr->seq_ctrl &···673813 if (!ieee80211_has_morefrags(hdr->frame_control)) {674814 txq->need_update = 1;675815 if (qc)676676- priv->stations_39[sta_id].tid[tid].seq_number = seq_number;816816+ priv->stations[sta_id].tid[tid].seq_number = seq_number;677817 } else {678818 wait_write_ptr = 1;679819 txq->need_update = 0;···1176131611771317 /* If we've added more space for the firmware to place data, tell it.11781318 * Increment device's write pointer in multiples of 8. */11791179- if ((write != (rxq->write & ~0x7))13191319+ if ((rxq->write_actual != (rxq->write & ~0x7))11801320 || (abs(rxq->write - rxq->read) > 7)) {11811321 spin_lock_irqsave(&rxq->lock, flags);11821322 rxq->need_update = 1;···11971337 * Also restock the Rx queue via iwl3945_rx_queue_restock.11981338 * This is called as a scheduled work item (except for during initialization)11991339 */12001200-static void iwl3945_rx_allocate(struct iwl_priv *priv)13401340+static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)12011341{12021342 struct iwl_rx_queue *rxq = &priv->rxq;12031343 struct list_head *element;···12201360 /* Alloc a new receive buffer */12211361 rxb->skb =12221362 alloc_skb(priv->hw_params.rx_buf_size,12231223- GFP_KERNEL);13631363+ priority);12241364 if (!rxb->skb) {12251365 if (net_ratelimit())12261366 IWL_CRIT(priv, ": Can not allocate SKB buffers\n");···12791419 * not restocked the Rx queue with fresh buffers */12801420 rxq->read = rxq->write = 0;12811421 rxq->free_count = 0;14221422+ rxq->write_actual = 0;12821423 spin_unlock_irqrestore(&rxq->lock, flags);12831424}12841425···12881427 struct iwl_priv *priv = data;12891428 unsigned long flags;1290142912911291- iwl3945_rx_allocate(priv);14301430+ iwl3945_rx_allocate(priv, GFP_KERNEL);1292143112931432 spin_lock_irqsave(&priv->lock, flags);12941433 iwl3945_rx_queue_restock(priv);12951434 spin_unlock_irqrestore(&priv->lock, flags);12961435}14361436+14371437+static void iwl3945_rx_replenish_now(struct iwl_priv *priv)14381438+{14391439+ iwl3945_rx_allocate(priv, GFP_ATOMIC);14401440+14411441+ iwl3945_rx_queue_restock(priv);14421442+}14431443+1297144412981445/* Assumes that the skb field of the buffers in 'pool' is kept accurate.12991446 * If an SKB has been detached, the POOL needs to have its SKB set to NULL···14251556 unsigned long flags;14261557 u8 fill_rx = 0;14271558 u32 count = 8;15591559+ int total_empty = 0;1428156014291561 /* uCode's read index (stored in shared DRAM) indicates the last Rx14301562 * buffer that the driver may process (last buffer filled by ucode). */14311563 r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;14321564 i = rxq->read;1433156514341434- if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))15661566+ /* calculate total frames need to be restock after handling RX */15671567+ total_empty = r - priv->rxq.write_actual;15681568+ if (total_empty < 0)15691569+ total_empty += RX_QUEUE_SIZE;15701570+15711571+ if (total_empty > (RX_QUEUE_SIZE / 2))14351572 fill_rx = 1;14361573 /* Rx interrupt, but nothing sent from uCode */14371574 if (i == r)···15141639 count++;15151640 if (count >= 8) {15161641 priv->rxq.read = i;15171517- iwl3945_rx_queue_restock(priv);16421642+ iwl3945_rx_replenish_now(priv);15181643 count = 0;15191644 }15201645 }···1522164715231648 /* Backtrack one entry */15241649 priv->rxq.read = i;15251525- iwl3945_rx_queue_restock(priv);16501650+ if (fill_rx)16511651+ iwl3945_rx_replenish_now(priv);16521652+ else16531653+ iwl3945_rx_queue_restock(priv);15261654}1527165515281656/* call this function to flush any scheduled tasklet */···24672589 goto restart;24682590 }2469259124702470- priv->cfg->ops->smgmt->clear_station_table(priv);25922592+ iwl_clear_stations_table(priv);2471259324722594 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);24732595 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);···25592681 set_bit(STATUS_EXIT_PENDING, &priv->status);2560268225612683 iwl3945_led_unregister(priv);25622562- priv->cfg->ops->smgmt->clear_station_table(priv);26842684+ iwl_clear_stations_table(priv);2563268525642686 /* Unblock any waiting calls */25652687 wake_up_interruptible_all(&priv->wait_command_queue);···2711283327122834 for (i = 0; i < MAX_HW_RESTARTS; i++) {2713283527142714- priv->cfg->ops->smgmt->clear_station_table(priv);28362836+ iwl_clear_stations_table(priv);2715283727162838 /* load bootstrap state machine,27172839 * load bootstrap program into processor's memory,···31253247 case NL80211_IFTYPE_ADHOC:3126324831273249 priv->assoc_id = 1;31283128- priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 0, 0, NULL);32503250+ iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL);31293251 iwl3945_sync_sta(priv, IWL_STA_ID,31303252 (priv->band == IEEE80211_BAND_5GHZ) ?31313253 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,···33163438 /* restore RXON assoc */33173439 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;33183440 iwlcore_commit_rxon(priv);33193319- priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL);34413441+ iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL);33203442 }33213443 iwl3945_send_beacon_cmd(priv);33223444···33473469 static_key = !iwl_is_associated(priv);3348347033493471 if (!static_key) {33503350- sta_id = priv->cfg->ops->smgmt->find_station(priv, addr);34723472+ sta_id = iwl_find_station(priv, addr);33513473 if (sta_id == IWL_INVALID_STATION) {33523474 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",33533475 addr);···39224044 mutex_init(&priv->mutex);3923404539244046 /* Clear the driver's (not device's) station table */39253925- priv->cfg->ops->smgmt->clear_station_table(priv);40474047+ iwl_clear_stations_table(priv);3926404839274049 priv->data_retry_limit = -1;39284050 priv->ieee_channels = NULL;···42854407 iwl3945_hw_txq_ctx_free(priv);4286440842874409 iwl3945_unset_hw_params(priv);42884288- priv->cfg->ops->smgmt->clear_station_table(priv);44104410+ iwl_clear_stations_table(priv);4289441142904412 /*netif_stop_queue(dev); */42914413 flush_workqueue(priv->workqueue);
+1-2
drivers/net/wireless/iwmc3200wifi/Kconfig
···11config IWM22 tristate "Intel Wireless Multicomm 3200 WiFi driver"33 depends on MMC && WLAN_80211 && EXPERIMENTAL44+ depends on CFG8021145 select WIRELESS_EXT55- select CFG8021166 select FW_LOADER77- select RFKILL8798config IWM_DEBUG109 bool "Enable full debugging output in iwmc3200wifi"
···268268269269 iwm->conf.frag_threshold = wiphy->frag_threshold;270270271271- ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,271271+ ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,272272 CFG_FRAG_THRESHOLD,273273 iwm->conf.frag_threshold);274274 if (ret < 0)
+1-1
drivers/net/wireless/iwmc3200wifi/fw.c
···7272 }73737474 if (fw->size < IWM_HDR_LEN) {7575- IWM_ERR(iwm, "FW is too small (%d)\n", fw->size);7575+ IWM_ERR(iwm, "FW is too small (%zu)\n", fw->size);7676 return -EINVAL;7777 }7878
···136136137137 wdev->netdev = ndev;138138139139- ret = iwm_rfkill_init(iwm);140140- if (ret) {141141- dev_err(dev, "Failed to init rfkill\n");142142- goto out_rfkill;143143- }144144-145139 return iwm;146146-147147- out_rfkill:148148- unregister_netdev(ndev);149140150141 out_ndev:151142 free_netdev(ndev);···153162 if (!iwm_to_ndev(iwm))154163 return;155164156156- iwm_rfkill_exit(iwm);157165 unregister_netdev(iwm_to_ndev(iwm));158166 free_netdev(iwm_to_ndev(iwm));159167 iwm_wdev_free(iwm);
-88
drivers/net/wireless/iwmc3200wifi/rfkill.c
···11-/*22- * Intel Wireless Multicomm 3200 WiFi driver33- *44- * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>55- * Samuel Ortiz <samuel.ortiz@intel.com>66- * Zhu Yi <yi.zhu@intel.com>77- *88- * This program is free software; you can redistribute it and/or99- * modify it under the terms of the GNU General Public License version1010- * 2 as published by the Free Software Foundation.1111- *1212- * This program is distributed in the hope that it will be useful,1313- * but WITHOUT ANY WARRANTY; without even the implied warranty of1414- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1515- * GNU General Public License for more details.1616- *1717- * You should have received a copy of the GNU General Public License1818- * along with this program; if not, write to the Free Software1919- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA2020- * 02110-1301, USA.2121- *2222- */2323-2424-#include <linux/rfkill.h>2525-2626-#include "iwm.h"2727-2828-static int iwm_rfkill_soft_toggle(void *data, enum rfkill_state state)2929-{3030- struct iwm_priv *iwm = data;3131-3232- switch (state) {3333- case RFKILL_STATE_UNBLOCKED:3434- if (test_bit(IWM_RADIO_RFKILL_HW, &iwm->radio))3535- return -EBUSY;3636-3737- if (test_and_clear_bit(IWM_RADIO_RFKILL_SW, &iwm->radio) &&3838- (iwm_to_ndev(iwm)->flags & IFF_UP))3939- iwm_up(iwm);4040-4141- break;4242- case RFKILL_STATE_SOFT_BLOCKED:4343- if (!test_and_set_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))4444- iwm_down(iwm);4545-4646- break;4747- default:4848- break;4949- }5050-5151- return 0;5252-}5353-5454-int iwm_rfkill_init(struct iwm_priv *iwm)5555-{5656- int ret;5757-5858- iwm->rfkill = rfkill_allocate(iwm_to_dev(iwm), RFKILL_TYPE_WLAN);5959- if (!iwm->rfkill) {6060- IWM_ERR(iwm, "Unable to allocate rfkill device\n");6161- return -ENOMEM;6262- }6363-6464- iwm->rfkill->name = KBUILD_MODNAME;6565- iwm->rfkill->data = iwm;6666- iwm->rfkill->state = RFKILL_STATE_UNBLOCKED;6767- iwm->rfkill->toggle_radio = iwm_rfkill_soft_toggle;6868-6969- ret = rfkill_register(iwm->rfkill);7070- if (ret) {7171- IWM_ERR(iwm, "Failed to register rfkill device\n");7272- goto fail;7373- }7474-7575- return 0;7676- fail:7777- rfkill_free(iwm->rfkill);7878- return ret;7979-}8080-8181-void iwm_rfkill_exit(struct iwm_priv *iwm)8282-{8383- if (iwm->rfkill)8484- rfkill_unregister(iwm->rfkill);8585-8686- rfkill_free(iwm->rfkill);8787- iwm->rfkill = NULL;8888-}
···3939#include "decl.h"4040#include "defs.h"4141#include "dev.h"4242+#include "cmd.h"4243#include "if_sdio.h"4444+4545+/* The if_sdio_remove() callback function is called when4646+ * user removes this module from kernel space or ejects4747+ * the card from the slot. The driver handles these 2 cases4848+ * differently for SD8688 combo chip.4949+ * If the user is removing the module, the FUNC_SHUTDOWN5050+ * command for SD8688 is sent to the firmware.5151+ * If the card is removed, there is no need to send this command.5252+ *5353+ * The variable 'user_rmmod' is used to distinguish these two5454+ * scenarios. This flag is initialized as FALSE in case the card5555+ * is removed, and will be set to TRUE for module removal when5656+ * module_exit function is called.5757+ */5858+static u8 user_rmmod;43594460static char *lbs_helper_name = NULL;4561module_param_named(helper_name, lbs_helper_name, charp, 0644);···7761 int model;7862 const char *helper;7963 const char *firmware;8080- struct if_sdio_card *card;8164};82658366static struct if_sdio_model if_sdio_models[] = {···8570 .model = IF_SDIO_MODEL_8385,8671 .helper = "sd8385_helper.bin",8772 .firmware = "sd8385.bin",8888- .card = NULL,8973 },9074 {9175 /* 8686 */9276 .model = IF_SDIO_MODEL_8686,9377 .helper = "sd8686_helper.bin",9478 .firmware = "sd8686.bin",9595- .card = NULL,9679 },9780 {9881 /* 8688 */9982 .model = IF_SDIO_MODEL_8688,10083 .helper = "sd8688_helper.bin",10184 .firmware = "sd8688.bin",102102- .card = NULL,10385 },10486};10587···939927 goto free;940928 }941929942942- if_sdio_models[i].card = card;943943-944930 card->helper = if_sdio_models[i].helper;945931 card->firmware = if_sdio_models[i].firmware;946932···10241014 /*10251015 * FUNC_INIT is required for SD8688 WLAN/BT multiple functions10261016 */10271027- priv->fn_init_required =10281028- (card->model == IF_SDIO_MODEL_8688) ? 1 : 0;10171017+ if (card->model == IF_SDIO_MODEL_8688) {10181018+ struct cmd_header cmd;10191019+10201020+ memset(&cmd, 0, sizeof(cmd));10211021+10221022+ lbs_deb_sdio("send function INIT command\n");10231023+ if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),10241024+ lbs_cmd_copyback, (unsigned long) &cmd))10251025+ lbs_pr_alert("CMD_FUNC_INIT cmd failed\n");10261026+ }1029102710301028 ret = lbs_start_card(priv);10311029 if (ret)···10751057{10761058 struct if_sdio_card *card;10771059 struct if_sdio_packet *packet;10781078- int ret;1079106010801061 lbs_deb_enter(LBS_DEB_SDIO);1081106210821063 card = sdio_get_drvdata(func);1083106410841084- lbs_stop_card(card->priv);10651065+ if (user_rmmod && (card->model == IF_SDIO_MODEL_8688)) {10661066+ /*10671067+ * FUNC_SHUTDOWN is required for SD8688 WLAN/BT10681068+ * multiple functions10691069+ */10701070+ struct cmd_header cmd;10711071+10721072+ memset(&cmd, 0, sizeof(cmd));10731073+10741074+ lbs_deb_sdio("send function SHUTDOWN command\n");10751075+ if (__lbs_cmd(card->priv, CMD_FUNC_SHUTDOWN,10761076+ &cmd, sizeof(cmd), lbs_cmd_copyback,10771077+ (unsigned long) &cmd))10781078+ lbs_pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");10791079+ }1085108010861081 card->priv->surpriseremoved = 1;1087108210881083 lbs_deb_sdio("call remove card\n");10841084+ lbs_stop_card(card->priv);10891085 lbs_remove_card(card->priv);1090108610911087 flush_workqueue(card->workqueue);10921088 destroy_workqueue(card->workqueue);1093108910941090 sdio_claim_host(func);10951095-10961096- /* Disable interrupts */10971097- sdio_writeb(func, 0x00, IF_SDIO_H_INT_MASK, &ret);10981098-10991091 sdio_release_irq(func);11001092 sdio_disable_func(func);11011101-11021093 sdio_release_host(func);1103109411041095 while (card->packets) {···1143111611441117 ret = sdio_register_driver(&if_sdio_driver);1145111811191119+ /* Clear the flag in case user removes the card. */11201120+ user_rmmod = 0;11211121+11461122 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);1147112311481124 return ret;···1153112311541124static void __exit if_sdio_exit_module(void)11551125{11561156- int i;11571157- struct if_sdio_card *card;11581158-11591126 lbs_deb_enter(LBS_DEB_SDIO);1160112711611161- for (i = 0; i < ARRAY_SIZE(if_sdio_models); i++) {11621162- card = if_sdio_models[i].card;11631163-11641164- /*11651165- * FUNC_SHUTDOWN is required for SD8688 WLAN/BT11661166- * multiple functions11671167- */11681168- if (card && card->priv)11691169- card->priv->fn_shutdown_required =11701170- (card->model == IF_SDIO_MODEL_8688) ? 1 : 0;11711171- }11281128+ /* Set the flag as user is removing this module. */11291129+ user_rmmod = 1;1172113011731131 sdio_unregister_driver(&if_sdio_driver);11741132
+16-18
drivers/net/wireless/libertas/if_spi.c
···119119 * First we have to put a SPU register name on the bus. Then we can120120 * either read from or write to that register.121121 *122122- * For 16-bit transactions, byte order on the bus is big-endian.123123- * We don't have to worry about that here, though.124124- * The translation takes place in the SPI routines.125122 */126123127124static void spu_transaction_init(struct if_spi_card *card)···144147static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)145148{146149 int err = 0;147147- u16 reg_out = reg | IF_SPI_WRITE_OPERATION_MASK;150150+ u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK);148151149152 /* You must give an even number of bytes to the SPU, even if it150153 * doesn't care about the last one. */···166169167170static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val)168171{169169- return spu_write(card, reg, (u8 *)&val, sizeof(u16));170170-}172172+ u16 buff;171173172172-static inline int spu_write_u32(struct if_spi_card *card, u16 reg, u32 val)173173-{174174- /* The lower 16 bits are written first. */175175- u16 out[2];176176- out[0] = val & 0xffff;177177- out[1] = (val & 0xffff0000) >> 16;178178- return spu_write(card, reg, (u8 *)&out, sizeof(u32));174174+ buff = cpu_to_le16(val);175175+ return spu_write(card, reg, (u8 *)&buff, sizeof(u16));179176}180177181178static inline int spu_reg_is_port_reg(u16 reg)···189198 unsigned int i, delay;190199 int err = 0;191200 u16 zero = 0;192192- u16 reg_out = reg | IF_SPI_READ_OPERATION_MASK;201201+ u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK);193202194203 /* You must take an even number of bytes from the SPU, even if you195204 * don't care about the last one. */···227236/* Read 16 bits from an SPI register */228237static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)229238{230230- return spu_read(card, reg, (u8 *)val, sizeof(u16));239239+ u16 buf;240240+ int ret;241241+242242+ ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf));243243+ if (ret == 0)244244+ *val = le16_to_cpup(&buf);245245+ return ret;231246}232247233248/* Read 32 bits from an SPI register.234249 * The low 16 bits are read first. */235250static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)236251{237237- u16 buf[2];252252+ u32 buf;238253 int err;239239- err = spu_read(card, reg, (u8 *)buf, sizeof(u32));254254+255255+ err = spu_read(card, reg, (u8 *)&buf, sizeof(buf));240256 if (!err)241241- *val = buf[0] | (buf[1] << 16);257257+ *val = le32_to_cpup(&buf);242258 return err;243259}244260
-20
drivers/net/wireless/libertas/main.c
···10021002{10031003 int ret = -1;10041004 s16 curlevel = 0, minlevel = 0, maxlevel = 0;10051005- struct cmd_header cmd;1006100510071006 lbs_deb_enter(LBS_DEB_FW);10081008-10091009- if (priv->fn_init_required) {10101010- memset(&cmd, 0, sizeof(cmd));10111011- if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),10121012- lbs_cmd_copyback, (unsigned long) &cmd))10131013- lbs_pr_alert("CMD_FUNC_INIT command failed\n");10141014- }1015100710161008 /* Read MAC address from firmware */10171009 memset(priv->current_addr, 0xff, ETH_ALEN);···11921200 priv->mesh_open = 0;11931201 priv->infra_open = 0;1194120211951195- priv->fn_init_required = 0;11961196- priv->fn_shutdown_required = 0;11971197-11981203 /* Setup the OS Interface to our functions */11991204 dev->netdev_ops = &lbs_netdev_ops;12001205 dev->watchdog_timeo = 5 * HZ;···13731384 struct net_device *dev;13741385 struct cmd_ctrl_node *cmdnode;13751386 unsigned long flags;13761376- struct cmd_header cmd;1377138713781388 lbs_deb_enter(LBS_DEB_MAIN);1379138913801390 if (!priv)13811391 goto out;13821382-13831383- if (priv->fn_shutdown_required) {13841384- memset(&cmd, 0, sizeof(cmd));13851385- if (__lbs_cmd(priv, CMD_FUNC_SHUTDOWN, &cmd, sizeof(cmd),13861386- lbs_cmd_copyback, (unsigned long) &cmd))13871387- lbs_pr_alert("CMD_FUNC_SHUTDOWN command failed\n");13881388- }13891389-13901392 dev = priv->dev;1391139313921394 netif_stop_queue(dev);
···802802 u8 calibration[2];803803804804 /*805805+ * Beacon interval.806806+ */807807+ u16 beacon_int;808808+809809+ /*805810 * Low level statistics which will have806811 * to be kept up to date while device is running.807812 */
+3
drivers/net/wireless/rt2x00/rt2x00config.c
···108108 erp.basic_rates = bss_conf->basic_rates;109109 erp.beacon_int = bss_conf->beacon_int;110110111111+ /* Update global beacon interval time, this is needed for PS support */112112+ rt2x00dev->beacon_int = bss_conf->beacon_int;113113+111114 rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp);112115}113116
···2121 depends on NEW_LEDS2222 depends on BACKLIGHT_CLASS_DEVICE2323 depends on SERIO_I80422424- depends on RFKILL2424+ depends on RFKILL || RFKILL = n2525 select ACPI_WMI2626 ---help---2727 This is a driver for newer Acer (and Wistron) laptops. It adds···6060 depends on DCDBAS6161 depends on EXPERIMENTAL6262 depends on BACKLIGHT_CLASS_DEVICE6363- depends on RFKILL6363+ depends on RFKILL || RFKILL = n6464 depends on POWER_SUPPLY6565 default n6666 ---help---···117117 tristate "HP WMI extras"118118 depends on ACPI_WMI119119 depends on INPUT120120- depends on RFKILL120120+ depends on RFKILL || RFKILL = n121121 help122122 Say Y here if you want to support WMI-based hotkeys on HP laptops and123123 to read data from WMI such as docking or ambient light sensor state.···196196 tristate "ThinkPad ACPI Laptop Extras"197197 depends on ACPI198198 depends on INPUT199199+ depends on RFKILL || RFKILL = n199200 select BACKLIGHT_LCD_SUPPORT200201 select BACKLIGHT_CLASS_DEVICE201202 select HWMON202203 select NVRAM203204 select NEW_LEDS204205 select LEDS_CLASS205205- select NET206206- select RFKILL207206 ---help---208207 This is a driver for the IBM and Lenovo ThinkPad laptops. It adds209208 support for Fn-Fx key combinations, Bluetooth control, video···337338 depends on ACPI338339 depends on INPUT339340 depends on EXPERIMENTAL341341+ depends on RFKILL || RFKILL = n340342 select BACKLIGHT_CLASS_DEVICE341343 select HWMON342342- select RFKILL343344 ---help---344345 This driver supports the Fn-Fx keys on Eee PC laptops.345346 It also adds the ability to switch camera/wlan on/off.···404405 tristate "Toshiba Laptop Extras"405406 depends on ACPI406407 depends on INPUT408408+ depends on RFKILL || RFKILL = n407409 select INPUT_POLLDEV408408- select NET409409- select RFKILL410410 select BACKLIGHT_CLASS_DEVICE411411 ---help---412412 This driver adds support for access to certain system settings
+22-28
drivers/platform/x86/acer-wmi.c
···958958959959 status = get_u32(&state, ACER_CAP_WIRELESS);960960 if (ACPI_SUCCESS(status))961961- rfkill_force_state(wireless_rfkill, state ?962962- RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED);961961+ rfkill_set_sw_state(wireless_rfkill, !!state);963962964963 if (has_cap(ACER_CAP_BLUETOOTH)) {965964 status = get_u32(&state, ACER_CAP_BLUETOOTH);966965 if (ACPI_SUCCESS(status))967967- rfkill_force_state(bluetooth_rfkill, state ?968968- RFKILL_STATE_UNBLOCKED :969969- RFKILL_STATE_SOFT_BLOCKED);966966+ rfkill_set_sw_state(bluetooth_rfkill, !!state);970967 }971968972969 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));973970}974971975975-static int acer_rfkill_set(void *data, enum rfkill_state state)972972+static int acer_rfkill_set(void *data, bool blocked)976973{977974 acpi_status status;978978- u32 *cap = data;979979- status = set_u32((u32) (state == RFKILL_STATE_UNBLOCKED), *cap);975975+ u32 cap = (unsigned long)data;976976+ status = set_u32(!!blocked, cap);980977 if (ACPI_FAILURE(status))981978 return -ENODEV;982979 return 0;983980}984981985985-static struct rfkill * acer_rfkill_register(struct device *dev,986986-enum rfkill_type type, char *name, u32 cap)982982+static const struct rfkill_ops acer_rfkill_ops = {983983+ .set_block = acer_rfkill_set,984984+};985985+986986+static struct rfkill *acer_rfkill_register(struct device *dev,987987+ enum rfkill_type type,988988+ char *name, u32 cap)987989{988990 int err;989991 u32 state;990990- u32 *data;991992 struct rfkill *rfkill_dev;992993993993- rfkill_dev = rfkill_allocate(dev, type);994994+ rfkill_dev = rfkill_alloc(name, dev, type,995995+ &acer_rfkill_ops,996996+ (void *)(unsigned long)cap);994997 if (!rfkill_dev)995998 return ERR_PTR(-ENOMEM);996996- rfkill_dev->name = name;997999 get_u32(&state, cap);998998- rfkill_dev->state = state ? RFKILL_STATE_UNBLOCKED :999999- RFKILL_STATE_SOFT_BLOCKED;10001000- data = kzalloc(sizeof(u32), GFP_KERNEL);10011001- if (!data) {10021002- rfkill_free(rfkill_dev);10031003- return ERR_PTR(-ENOMEM);10041004- }10051005- *data = cap;10061006- rfkill_dev->data = data;10071007- rfkill_dev->toggle_radio = acer_rfkill_set;10001000+ rfkill_set_sw_state(rfkill_dev, !state);1008100110091002 err = rfkill_register(rfkill_dev);10101003 if (err) {10111011- kfree(rfkill_dev->data);10121012- rfkill_free(rfkill_dev);10041004+ rfkill_destroy(rfkill_dev);10131005 return ERR_PTR(err);10141006 }10151007 return rfkill_dev;···10191027 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",10201028 ACER_CAP_BLUETOOTH);10211029 if (IS_ERR(bluetooth_rfkill)) {10221022- kfree(wireless_rfkill->data);10231030 rfkill_unregister(wireless_rfkill);10311031+ rfkill_destroy(wireless_rfkill);10241032 return PTR_ERR(bluetooth_rfkill);10251033 }10261034 }···10331041static void acer_rfkill_exit(void)10341042{10351043 cancel_delayed_work_sync(&acer_rfkill_work);10361036- kfree(wireless_rfkill->data);10441044+10371045 rfkill_unregister(wireless_rfkill);10461046+ rfkill_destroy(wireless_rfkill);10471047+10381048 if (has_cap(ACER_CAP_BLUETOOTH)) {10391039- kfree(bluetooth_rfkill->data);10401049 rfkill_unregister(bluetooth_rfkill);10501050+ rfkill_destroy(bluetooth_rfkill);10411051 }10421052 return;10431053}
+34-71
drivers/platform/x86/dell-laptop.c
···174174 result[3]: NVRAM format version number175175*/176176177177-static int dell_rfkill_set(int radio, enum rfkill_state state)177177+static int dell_rfkill_set(void *data, bool blocked)178178{179179 struct calling_interface_buffer buffer;180180- int disable = (state == RFKILL_STATE_UNBLOCKED) ? 0 : 1;180180+ int disable = blocked ? 0 : 1;181181+ unsigned long radio = (unsigned long)data;181182182183 memset(&buffer, 0, sizeof(struct calling_interface_buffer));183184 buffer.input[0] = (1 | (radio<<8) | (disable << 16));···187186 return 0;188187}189188190190-static int dell_wifi_set(void *data, enum rfkill_state state)191191-{192192- return dell_rfkill_set(1, state);193193-}194194-195195-static int dell_bluetooth_set(void *data, enum rfkill_state state)196196-{197197- return dell_rfkill_set(2, state);198198-}199199-200200-static int dell_wwan_set(void *data, enum rfkill_state state)201201-{202202- return dell_rfkill_set(3, state);203203-}204204-205205-static int dell_rfkill_get(int bit, enum rfkill_state *state)189189+static void dell_rfkill_query(struct rfkill *rfkill, void *data)206190{207191 struct calling_interface_buffer buffer;208192 int status;209209- int new_state = RFKILL_STATE_HARD_BLOCKED;193193+ int bit = (unsigned long)data + 16;210194211195 memset(&buffer, 0, sizeof(struct calling_interface_buffer));212196 dell_send_request(&buffer, 17, 11);213197 status = buffer.output[1];214198215215- if (status & (1<<16))216216- new_state = RFKILL_STATE_SOFT_BLOCKED;217217-218218- if (status & (1<<bit))219219- *state = new_state;220220- else221221- *state = RFKILL_STATE_UNBLOCKED;222222-223223- return 0;199199+ if (status & BIT(bit))200200+ rfkill_set_hw_state(rfkill, !!(status & BIT(16)));224201}225202226226-static int dell_wifi_get(void *data, enum rfkill_state *state)227227-{228228- return dell_rfkill_get(17, state);229229-}230230-231231-static int dell_bluetooth_get(void *data, enum rfkill_state *state)232232-{233233- return dell_rfkill_get(18, state);234234-}235235-236236-static int dell_wwan_get(void *data, enum rfkill_state *state)237237-{238238- return dell_rfkill_get(19, state);239239-}203203+static const struct rfkill_ops dell_rfkill_ops = {204204+ .set_block = dell_rfkill_set,205205+ .query = dell_rfkill_query,206206+};240207241208static int dell_setup_rfkill(void)242209{···217248 status = buffer.output[1];218249219250 if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {220220- wifi_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WLAN);221221- if (!wifi_rfkill)251251+ wifi_rfkill = rfkill_alloc("dell-wifi", NULL, RFKILL_TYPE_WLAN,252252+ &dell_rfkill_ops, (void *) 1);253253+ if (!wifi_rfkill) {254254+ ret = -ENOMEM;222255 goto err_wifi;223223- wifi_rfkill->name = "dell-wifi";224224- wifi_rfkill->toggle_radio = dell_wifi_set;225225- wifi_rfkill->get_state = dell_wifi_get;256256+ }226257 ret = rfkill_register(wifi_rfkill);227258 if (ret)228259 goto err_wifi;229260 }230261231262 if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) {232232- bluetooth_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_BLUETOOTH);233233- if (!bluetooth_rfkill)263263+ bluetooth_rfkill = rfkill_alloc("dell-bluetooth", NULL,264264+ RFKILL_TYPE_BLUETOOTH,265265+ &dell_rfkill_ops, (void *) 2);266266+ if (!bluetooth_rfkill) {267267+ ret = -ENOMEM;234268 goto err_bluetooth;235235- bluetooth_rfkill->name = "dell-bluetooth";236236- bluetooth_rfkill->toggle_radio = dell_bluetooth_set;237237- bluetooth_rfkill->get_state = dell_bluetooth_get;269269+ }238270 ret = rfkill_register(bluetooth_rfkill);239271 if (ret)240272 goto err_bluetooth;241273 }242274243275 if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) {244244- wwan_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WWAN);245245- if (!wwan_rfkill)276276+ wwan_rfkill = rfkill_alloc("dell-wwan", NULL, RFKILL_TYPE_WWAN,277277+ &dell_rfkill_ops, (void *) 3);278278+ if (!wwan_rfkill) {279279+ ret = -ENOMEM;246280 goto err_wwan;247247- wwan_rfkill->name = "dell-wwan";248248- wwan_rfkill->toggle_radio = dell_wwan_set;249249- wwan_rfkill->get_state = dell_wwan_get;281281+ }250282 ret = rfkill_register(wwan_rfkill);251283 if (ret)252284 goto err_wwan;···255285256286 return 0;257287err_wwan:258258- if (wwan_rfkill)259259- rfkill_free(wwan_rfkill);260260- if (bluetooth_rfkill) {261261- rfkill_unregister(bluetooth_rfkill);262262- bluetooth_rfkill = NULL;263263- }264264-err_bluetooth:288288+ rfkill_destroy(wwan_rfkill);265289 if (bluetooth_rfkill)266266- rfkill_free(bluetooth_rfkill);267267- if (wifi_rfkill) {268268- rfkill_unregister(wifi_rfkill);269269- wifi_rfkill = NULL;270270- }271271-err_wifi:290290+ rfkill_unregister(bluetooth_rfkill);291291+err_bluetooth:292292+ rfkill_destroy(bluetooth_rfkill);272293 if (wifi_rfkill)273273- rfkill_free(wifi_rfkill);294294+ rfkill_unregister(wifi_rfkill);295295+err_wifi:296296+ rfkill_destroy(wifi_rfkill);274297275298 return ret;276299}
···106106#define EOWNERDEAD 130 /* Owner died */107107#define ENOTRECOVERABLE 131 /* State not recoverable */108108109109+#define ERFKILL 132 /* Operation not possible due to RF-kill */110110+109111#endif
···198198#define NETDEV_CHANGENAME 0x000A199199#define NETDEV_FEAT_CHANGE 0x000B200200#define NETDEV_BONDING_FAILOVER 0x000C201201+#define NETDEV_PRE_UP 0x000D201202202203#define SYS_DOWN 0x0001 /* Notify of system down */203204#define SYS_RESTART SYS_DOWN
+314-89
include/linux/rfkill.h
···44/*55 * Copyright (C) 2006 - 2007 Ivo van Doorn66 * Copyright (C) 2007 Dmitry Torokhov77+ * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>78 *89 * This program is free software; you can redistribute it and/or modify910 * it under the terms of the GNU General Public License as published by···2322 */24232524#include <linux/types.h>2525+2626+/* define userspace visible states */2727+#define RFKILL_STATE_SOFT_BLOCKED 02828+#define RFKILL_STATE_UNBLOCKED 12929+#define RFKILL_STATE_HARD_BLOCKED 23030+3131+/**3232+ * enum rfkill_type - type of rfkill switch.3333+ *3434+ * @RFKILL_TYPE_ALL: toggles all switches (userspace only)3535+ * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.3636+ * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.3737+ * @RFKILL_TYPE_UWB: switch is on a ultra wideband device.3838+ * @RFKILL_TYPE_WIMAX: switch is on a WiMAX device.3939+ * @RFKILL_TYPE_WWAN: switch is on a wireless WAN device.4040+ * @NUM_RFKILL_TYPES: number of defined rfkill types4141+ */4242+enum rfkill_type {4343+ RFKILL_TYPE_ALL = 0,4444+ RFKILL_TYPE_WLAN,4545+ RFKILL_TYPE_BLUETOOTH,4646+ RFKILL_TYPE_UWB,4747+ RFKILL_TYPE_WIMAX,4848+ RFKILL_TYPE_WWAN,4949+ NUM_RFKILL_TYPES,5050+};5151+5252+/**5353+ * enum rfkill_operation - operation types5454+ * @RFKILL_OP_ADD: a device was added5555+ * @RFKILL_OP_DEL: a device was removed5656+ * @RFKILL_OP_CHANGE: a device's state changed -- userspace changes one device5757+ * @RFKILL_OP_CHANGE_ALL: userspace changes all devices (of a type, or all)5858+ */5959+enum rfkill_operation {6060+ RFKILL_OP_ADD = 0,6161+ RFKILL_OP_DEL,6262+ RFKILL_OP_CHANGE,6363+ RFKILL_OP_CHANGE_ALL,6464+};6565+6666+/**6767+ * struct rfkill_event - events for userspace on /dev/rfkill6868+ * @idx: index of dev rfkill6969+ * @type: type of the rfkill struct7070+ * @op: operation code7171+ * @hard: hard state (0/1)7272+ * @soft: soft state (0/1)7373+ *7474+ * Structure used for userspace communication on /dev/rfkill,7575+ * used for events from the kernel and control to the kernel.7676+ */7777+struct rfkill_event {7878+ __u32 idx;7979+ __u8 type;8080+ __u8 op;8181+ __u8 soft, hard;8282+} __packed;8383+8484+/* ioctl for turning off rfkill-input (if present) */8585+#define RFKILL_IOC_MAGIC 'R'8686+#define RFKILL_IOC_NOINPUT 18787+#define RFKILL_IOCTL_NOINPUT _IO(RFKILL_IOC_MAGIC, RFKILL_IOC_NOINPUT)8888+8989+/* and that's all userspace gets */9090+#ifdef __KERNEL__9191+/* don't allow anyone to use these in the kernel */9292+enum rfkill_user_states {9393+ RFKILL_USER_STATE_SOFT_BLOCKED = RFKILL_STATE_SOFT_BLOCKED,9494+ RFKILL_USER_STATE_UNBLOCKED = RFKILL_STATE_UNBLOCKED,9595+ RFKILL_USER_STATE_HARD_BLOCKED = RFKILL_STATE_HARD_BLOCKED,9696+};9797+#undef RFKILL_STATE_SOFT_BLOCKED9898+#undef RFKILL_STATE_UNBLOCKED9999+#undef RFKILL_STATE_HARD_BLOCKED100100+101101+#include <linux/types.h>26102#include <linux/kernel.h>27103#include <linux/list.h>28104#include <linux/mutex.h>29105#include <linux/device.h>30106#include <linux/leds.h>311073232-/**3333- * enum rfkill_type - type of rfkill switch.3434- * RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.3535- * RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.3636- * RFKILL_TYPE_UWB: switch is on a ultra wideband device.3737- * RFKILL_TYPE_WIMAX: switch is on a WiMAX device.3838- * RFKILL_TYPE_WWAN: switch is on a wireless WAN device.3939- */4040-enum rfkill_type {4141- RFKILL_TYPE_WLAN ,4242- RFKILL_TYPE_BLUETOOTH,4343- RFKILL_TYPE_UWB,4444- RFKILL_TYPE_WIMAX,4545- RFKILL_TYPE_WWAN,4646- RFKILL_TYPE_MAX,4747-};4848-4949-enum rfkill_state {5050- RFKILL_STATE_SOFT_BLOCKED = 0, /* Radio output blocked */5151- RFKILL_STATE_UNBLOCKED = 1, /* Radio output allowed */5252- RFKILL_STATE_HARD_BLOCKED = 2, /* Output blocked, non-overrideable */5353- RFKILL_STATE_MAX, /* marker for last valid state */5454-};108108+/* this is opaque */109109+struct rfkill;5511056111/**5757- * struct rfkill - rfkill control structure.5858- * @name: Name of the switch.5959- * @type: Radio type which the button controls, the value stored6060- * here should be a value from enum rfkill_type.6161- * @state: State of the switch, "UNBLOCKED" means radio can operate.6262- * @mutex: Guards switch state transitions. It serializes callbacks6363- * and also protects the state.6464- * @data: Pointer to the RF button drivers private data which will be6565- * passed along when toggling radio state.6666- * @toggle_radio(): Mandatory handler to control state of the radio.6767- * only RFKILL_STATE_SOFT_BLOCKED and RFKILL_STATE_UNBLOCKED are6868- * valid parameters.6969- * @get_state(): handler to read current radio state from hardware,7070- * may be called from atomic context, should return 0 on success.7171- * Either this handler OR judicious use of rfkill_force_state() is7272- * MANDATORY for any driver capable of RFKILL_STATE_HARD_BLOCKED.7373- * @led_trigger: A LED trigger for this button's LED.7474- * @dev: Device structure integrating the switch into device tree.7575- * @node: Used to place switch into list of all switches known to the7676- * the system.112112+ * struct rfkill_ops - rfkill driver methods77113 *7878- * This structure represents a RF switch located on a network device.114114+ * @poll: poll the rfkill block state(s) -- only assign this method115115+ * when you need polling. When called, simply call one of the116116+ * rfkill_set{,_hw,_sw}_state family of functions. If the hw117117+ * is getting unblocked you need to take into account the return118118+ * value of those functions to make sure the software block is119119+ * properly used.120120+ * @query: query the rfkill block state(s) and call exactly one of the121121+ * rfkill_set{,_hw,_sw}_state family of functions. Assign this122122+ * method if input events can cause hardware state changes to make123123+ * the rfkill core query your driver before setting a requested124124+ * block.125125+ * @set_block: turn the transmitter on (blocked == false) or off126126+ * (blocked == true) -- ignore and return 0 when hard blocked.127127+ * This callback must be assigned.79128 */8080-struct rfkill {8181- const char *name;8282- enum rfkill_type type;8383-8484- /* the mutex serializes callbacks and also protects8585- * the state */8686- struct mutex mutex;8787- enum rfkill_state state;8888- void *data;8989- int (*toggle_radio)(void *data, enum rfkill_state state);9090- int (*get_state)(void *data, enum rfkill_state *state);9191-9292-#ifdef CONFIG_RFKILL_LEDS9393- struct led_trigger led_trigger;9494-#endif9595-9696- struct device dev;9797- struct list_head node;9898- enum rfkill_state state_for_resume;129129+struct rfkill_ops {130130+ void (*poll)(struct rfkill *rfkill, void *data);131131+ void (*query)(struct rfkill *rfkill, void *data);132132+ int (*set_block)(void *data, bool blocked);99133};100100-#define to_rfkill(d) container_of(d, struct rfkill, dev)101134102102-struct rfkill * __must_check rfkill_allocate(struct device *parent,103103- enum rfkill_type type);104104-void rfkill_free(struct rfkill *rfkill);135135+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)136136+/**137137+ * rfkill_alloc - allocate rfkill structure138138+ * @name: name of the struct -- the string is not copied internally139139+ * @parent: device that has rf switch on it140140+ * @type: type of the switch (RFKILL_TYPE_*)141141+ * @ops: rfkill methods142142+ * @ops_data: data passed to each method143143+ *144144+ * This function should be called by the transmitter driver to allocate an145145+ * rfkill structure. Returns %NULL on failure.146146+ */147147+struct rfkill * __must_check rfkill_alloc(const char *name,148148+ struct device *parent,149149+ const enum rfkill_type type,150150+ const struct rfkill_ops *ops,151151+ void *ops_data);152152+153153+/**154154+ * rfkill_register - Register a rfkill structure.155155+ * @rfkill: rfkill structure to be registered156156+ *157157+ * This function should be called by the transmitter driver to register158158+ * the rfkill structure needs to be registered. Before calling this function159159+ * the driver needs to be ready to service method calls from rfkill.160160+ */105161int __must_check rfkill_register(struct rfkill *rfkill);162162+163163+/**164164+ * rfkill_pause_polling(struct rfkill *rfkill)165165+ *166166+ * Pause polling -- say transmitter is off for other reasons.167167+ * NOTE: not necessary for suspend/resume -- in that case the168168+ * core stops polling anyway169169+ */170170+void rfkill_pause_polling(struct rfkill *rfkill);171171+172172+/**173173+ * rfkill_resume_polling(struct rfkill *rfkill)174174+ *175175+ * Pause polling -- say transmitter is off for other reasons.176176+ * NOTE: not necessary for suspend/resume -- in that case the177177+ * core stops polling anyway178178+ */179179+void rfkill_resume_polling(struct rfkill *rfkill);180180+181181+182182+/**183183+ * rfkill_unregister - Unregister a rfkill structure.184184+ * @rfkill: rfkill structure to be unregistered185185+ *186186+ * This function should be called by the network driver during device187187+ * teardown to destroy rfkill structure. Until it returns, the driver188188+ * needs to be able to service method calls.189189+ */106190void rfkill_unregister(struct rfkill *rfkill);107191108108-int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state);109109-int rfkill_set_default(enum rfkill_type type, enum rfkill_state state);110110-111192/**112112- * rfkill_state_complement - return complementar state113113- * @state: state to return the complement of193193+ * rfkill_destroy - free rfkill structure194194+ * @rfkill: rfkill structure to be destroyed114195 *115115- * Returns RFKILL_STATE_SOFT_BLOCKED if @state is RFKILL_STATE_UNBLOCKED,116116- * returns RFKILL_STATE_UNBLOCKED otherwise.196196+ * Destroys the rfkill structure.117197 */118118-static inline enum rfkill_state rfkill_state_complement(enum rfkill_state state)119119-{120120- return (state == RFKILL_STATE_UNBLOCKED) ?121121- RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;122122-}198198+void rfkill_destroy(struct rfkill *rfkill);123199124200/**125125- * rfkill_get_led_name - Get the LED trigger name for the button's LED.126126- * This function might return a NULL pointer if registering of the127127- * LED trigger failed.128128- * Use this as "default_trigger" for the LED.201201+ * rfkill_set_hw_state - Set the internal rfkill hardware block state202202+ * @rfkill: pointer to the rfkill class to modify.203203+ * @state: the current hardware block state to set204204+ *205205+ * rfkill drivers that get events when the hard-blocked state changes206206+ * use this function to notify the rfkill core (and through that also207207+ * userspace) of the current state -- they should also use this after208208+ * resume if the state could have changed.209209+ *210210+ * You need not (but may) call this function if poll_state is assigned.211211+ *212212+ * This function can be called in any context, even from within rfkill213213+ * callbacks.214214+ *215215+ * The function returns the combined block state (true if transmitter216216+ * should be blocked) so that drivers need not keep track of the soft217217+ * block state -- which they might not be able to.129218 */130130-static inline char *rfkill_get_led_name(struct rfkill *rfkill)219219+bool __must_check rfkill_set_hw_state(struct rfkill *rfkill, bool blocked);220220+221221+/**222222+ * rfkill_set_sw_state - Set the internal rfkill software block state223223+ * @rfkill: pointer to the rfkill class to modify.224224+ * @state: the current software block state to set225225+ *226226+ * rfkill drivers that get events when the soft-blocked state changes227227+ * (yes, some platforms directly act on input but allow changing again)228228+ * use this function to notify the rfkill core (and through that also229229+ * userspace) of the current state -- they should also use this after230230+ * resume if the state could have changed.231231+ *232232+ * This function can be called in any context, even from within rfkill233233+ * callbacks.234234+ *235235+ * The function returns the combined block state (true if transmitter236236+ * should be blocked).237237+ */238238+bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked);239239+240240+/**241241+ * rfkill_set_states - Set the internal rfkill block states242242+ * @rfkill: pointer to the rfkill class to modify.243243+ * @sw: the current software block state to set244244+ * @hw: the current hardware block state to set245245+ *246246+ * This function can be called in any context, even from within rfkill247247+ * callbacks.248248+ */249249+void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw);250250+251251+/**252252+ * rfkill_set_global_sw_state - set global sw block default253253+ * @type: rfkill type to set default for254254+ * @blocked: default to set255255+ *256256+ * This function sets the global default -- use at boot if your platform has257257+ * an rfkill switch. If not early enough this call may be ignored.258258+ *259259+ * XXX: instead of ignoring -- how about just updating all currently260260+ * registered drivers?261261+ */262262+void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked);263263+264264+/**265265+ * rfkill_blocked - query rfkill block266266+ *267267+ * @rfkill: rfkill struct to query268268+ */269269+bool rfkill_blocked(struct rfkill *rfkill);270270+#else /* !RFKILL */271271+static inline struct rfkill * __must_check272272+rfkill_alloc(const char *name,273273+ struct device *parent,274274+ const enum rfkill_type type,275275+ const struct rfkill_ops *ops,276276+ void *ops_data)131277{132132-#ifdef CONFIG_RFKILL_LEDS133133- return (char *)(rfkill->led_trigger.name);134134-#else135135- return NULL;136136-#endif278278+ return ERR_PTR(-ENODEV);137279}280280+281281+static inline int __must_check rfkill_register(struct rfkill *rfkill)282282+{283283+ if (rfkill == ERR_PTR(-ENODEV))284284+ return 0;285285+ return -EINVAL;286286+}287287+288288+static inline void rfkill_pause_polling(struct rfkill *rfkill)289289+{290290+}291291+292292+static inline void rfkill_resume_polling(struct rfkill *rfkill)293293+{294294+}295295+296296+static inline void rfkill_unregister(struct rfkill *rfkill)297297+{298298+}299299+300300+static inline void rfkill_destroy(struct rfkill *rfkill)301301+{302302+}303303+304304+static inline bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)305305+{306306+ return blocked;307307+}308308+309309+static inline bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)310310+{311311+ return blocked;312312+}313313+314314+static inline void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)315315+{316316+}317317+318318+static inline void rfkill_set_global_sw_state(const enum rfkill_type type,319319+ bool blocked)320320+{321321+}322322+323323+static inline bool rfkill_blocked(struct rfkill *rfkill)324324+{325325+ return false;326326+}327327+#endif /* RFKILL || RFKILL_MODULE */328328+329329+330330+#ifdef CONFIG_RFKILL_LEDS331331+/**332332+ * rfkill_get_led_trigger_name - Get the LED trigger name for the button's LED.333333+ * This function might return a NULL pointer if registering of the334334+ * LED trigger failed. Use this as "default_trigger" for the LED.335335+ */336336+const char *rfkill_get_led_trigger_name(struct rfkill *rfkill);337337+338338+/**339339+ * rfkill_set_led_trigger_name -- set the LED trigger name340340+ * @rfkill: rfkill struct341341+ * @name: LED trigger name342342+ *343343+ * This function sets the LED trigger name of the radio LED344344+ * trigger that rfkill creates. It is optional, but if called345345+ * must be called before rfkill_register() to be effective.346346+ */347347+void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name);348348+#else349349+static inline const char *rfkill_get_led_trigger_name(struct rfkill *rfkill)350350+{351351+ return NULL;352352+}353353+354354+static inline void355355+rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name)356356+{357357+}358358+#endif359359+360360+#endif /* __KERNEL__ */138361139362#endif /* RFKILL_H */
+51
include/net/cfg80211.h
···752752};753753754754/**755755+ * enum tx_power_setting - TX power adjustment756756+ *757757+ * @TX_POWER_AUTOMATIC: the dbm parameter is ignored758758+ * @TX_POWER_LIMITED: limit TX power by the dbm parameter759759+ * @TX_POWER_FIXED: fix TX power to the dbm parameter760760+ */761761+enum tx_power_setting {762762+ TX_POWER_AUTOMATIC,763763+ TX_POWER_LIMITED,764764+ TX_POWER_FIXED,765765+};766766+767767+/**755768 * struct cfg80211_ops - backend description for wireless configuration756769 *757770 * This struct is registered by fullmac card drivers and/or wireless stacks···850837 * @changed bitfield (see &enum wiphy_params_flags) describes which values851838 * have changed. The actual parameter values are available in852839 * struct wiphy. If returning an error, no value should be changed.840840+ *841841+ * @set_tx_power: set the transmit power according to the parameters842842+ * @get_tx_power: store the current TX power into the dbm variable;843843+ * return 0 if successful844844+ *845845+ * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting846846+ * functions to adjust rfkill hw state853847 */854848struct cfg80211_ops {855849 int (*suspend)(struct wiphy *wiphy);···948928 int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev);949929950930 int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed);931931+932932+ int (*set_tx_power)(struct wiphy *wiphy,933933+ enum tx_power_setting type, int dbm);934934+ int (*get_tx_power)(struct wiphy *wiphy, int *dbm);935935+936936+ void (*rfkill_poll)(struct wiphy *wiphy);951937};952938953939/*···14771451int cfg80211_wext_giwencode(struct net_device *dev,14781452 struct iw_request_info *info,14791453 struct iw_point *erq, char *keybuf);14541454+int cfg80211_wext_siwtxpower(struct net_device *dev,14551455+ struct iw_request_info *info,14561456+ union iwreq_data *data, char *keybuf);14571457+int cfg80211_wext_giwtxpower(struct net_device *dev,14581458+ struct iw_request_info *info,14591459+ union iwreq_data *data, char *keybuf);1480146014811461/*14821462 * callbacks for asynchronous cfg80211 methods, notification···16671635 * always a scan result for this IBSS. cfg80211 will handle the rest.16681636 */16691637void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);16381638+16391639+/**16401640+ * wiphy_rfkill_set_hw_state - notify cfg80211 about hw block state16411641+ * @wiphy: the wiphy16421642+ * @blocked: block status16431643+ */16441644+void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked);16451645+16461646+/**16471647+ * wiphy_rfkill_start_polling - start polling rfkill16481648+ * @wiphy: the wiphy16491649+ */16501650+void wiphy_rfkill_start_polling(struct wiphy *wiphy);16511651+16521652+/**16531653+ * wiphy_rfkill_stop_polling - stop polling rfkill16541654+ * @wiphy: the wiphy16551655+ */16561656+void wiphy_rfkill_stop_polling(struct wiphy *wiphy);1670165716711658#endif /* __NET_CFG80211_H */
+15-11
include/net/mac80211.h
···526526/**527527 * enum ieee80211_conf_changed - denotes which configuration changed528528 *529529- * @IEEE80211_CONF_CHANGE_RADIO_ENABLED: the value of radio_enabled changed530530- * @_IEEE80211_CONF_CHANGE_BEACON_INTERVAL: DEPRECATED529529+ * @_IEEE80211_CONF_CHANGE_RADIO_ENABLED: DEPRECATED531530 * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed532531 * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed533532 * @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed···536537 * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed537538 */538539enum ieee80211_conf_changed {539539- IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0),540540- _IEEE80211_CONF_CHANGE_BEACON_INTERVAL = BIT(1),540540+ _IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0),541541 IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2),542542 IEEE80211_CONF_CHANGE_RADIOTAP = BIT(3),543543 IEEE80211_CONF_CHANGE_PS = BIT(4),···547549};548550549551static inline __deprecated enum ieee80211_conf_changed550550-__IEEE80211_CONF_CHANGE_BEACON_INTERVAL(void)552552+__IEEE80211_CONF_CHANGE_RADIO_ENABLED(void)551553{552552- return _IEEE80211_CONF_CHANGE_BEACON_INTERVAL;554554+ return _IEEE80211_CONF_CHANGE_RADIO_ENABLED;553555}554554-#define IEEE80211_CONF_CHANGE_BEACON_INTERVAL \555555- __IEEE80211_CONF_CHANGE_BEACON_INTERVAL()556556+#define IEEE80211_CONF_CHANGE_RADIO_ENABLED \557557+ __IEEE80211_CONF_CHANGE_RADIO_ENABLED()556558557559/**558560 * struct ieee80211_conf - configuration of the device···562564 * @flags: configuration flags defined above563565 *564566 * @radio_enabled: when zero, driver is required to switch off the radio.565565- * @beacon_int: beacon interval (TODO make interface config)567567+ * @beacon_int: DEPRECATED, DO NOT USE566568 *567569 * @listen_interval: listen interval in units of beacon interval568570 * @max_sleep_period: the maximum number of beacon intervals to sleep for···587589 * number of transmissions not the number of retries588590 */589591struct ieee80211_conf {590590- int beacon_int;592592+ int __deprecated beacon_int;591593 u32 flags;592594 int power_level, dynamic_ps_timeout;593595 int max_sleep_period;594596595597 u16 listen_interval;596596- bool radio_enabled;598598+ bool __deprecated radio_enabled;597599598600 u8 long_frame_max_tx_count, short_frame_max_tx_count;599601···14041406 * is the first frame we expect to perform the action on. Notice14051407 * that TX/RX_STOP can pass NULL for this parameter.14061408 * Returns a negative error code on failure.14091409+ *14101410+ * @rfkill_poll: Poll rfkill hardware state. If you need this, you also14111411+ * need to set wiphy->rfkill_poll to %true before registration,14121412+ * and need to call wiphy_rfkill_set_hw_state() in the callback.14071413 */14081414struct ieee80211_ops {14091415 int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);···14561454 int (*ampdu_action)(struct ieee80211_hw *hw,14571455 enum ieee80211_ampdu_mlme_action action,14581456 struct ieee80211_sta *sta, u16 tid, u16 *ssn);14571457+14581458+ void (*rfkill_poll)(struct ieee80211_hw *hw);14591459};1460146014611461/**
+2-6
include/net/wimax.h
···253253struct net_device;254254struct genl_info;255255struct wimax_dev;256256-struct input_dev;257256258257/**259258 * struct wimax_dev - Generic WiMAX device···292293 * See wimax_reset()'s documentation.293294 *294295 * @name: [fill] A way to identify this device. We need to register a295295- * name with many subsystems (input for RFKILL, workqueue296296- * creation, etc). We can't use the network device name as that296296+ * name with many subsystems (rfkill, workqueue creation, etc).297297+ * We can't use the network device name as that297298 * might change and in some instances we don't know it yet (until298299 * we don't call register_netdev()). So we generate an unique one299300 * using the driver name and device bus id, place it here and use···314315 * @state: [private] Current state of the WiMAX device.315316 *316317 * @rfkill: [private] integration into the RF-Kill infrastructure.317317- *318318- * @rfkill_input: [private] virtual input device to process the319319- * hardware RF Kill switches.320318 *321319 * @rf_sw: [private] State of the software radio switch (OFF/ON)322320 *
···11config MAC8021122 tristate "Generic IEEE 802.11 Networking Stack (mac80211)"33+ depends on CFG8021134 select CRYPTO45 select CRYPTO_ECB56 select CRYPTO_ARC467 select CRYPTO_AES78 select CRC3289 select WIRELESS_EXT99- select CFG802111010 ---help---1111 This option enables the hardware independent IEEE 802.111212 networking stack.1313+1414+comment "CFG80211 needs to be enabled for MAC80211"1515+ depends on CFG80211=n13161417config MAC80211_DEFAULT_PS1518 bool "enable powersave by default"
+58-7
net/mac80211/cfg.c
···664664 spin_unlock_bh(&sta->lock);665665666666 /*667667+ * cfg80211 validates this (1-2007) and allows setting the AID668668+ * only when creating a new station entry669669+ */670670+ if (params->aid)671671+ sta->sta.aid = params->aid;672672+673673+ /*667674 * FIXME: updating the following information is racy when this668675 * function is called from ieee80211_change_station().669676 * However, all this information should be static so670677 * maybe we should just reject attemps to change it.671678 */672672-673673- if (params->aid) {674674- sta->sta.aid = params->aid;675675- if (sta->sta.aid > IEEE80211_MAX_AID)676676- sta->sta.aid = 0; /* XXX: should this be an error? */677677- }678679679680 if (params->listen_interval >= 0)680681 sta->listen_interval = params->listen_interval;···12561255 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;1257125612581257 ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len);12591259- if (ret)12581258+ if (ret && ret != -EALREADY)12601259 return ret;1261126012621261 if (req->use_mfp) {···13341333 return 0;13351334}1336133513361336+static int ieee80211_set_tx_power(struct wiphy *wiphy,13371337+ enum tx_power_setting type, int dbm)13381338+{13391339+ struct ieee80211_local *local = wiphy_priv(wiphy);13401340+ struct ieee80211_channel *chan = local->hw.conf.channel;13411341+ u32 changes = 0;13421342+13431343+ switch (type) {13441344+ case TX_POWER_AUTOMATIC:13451345+ local->user_power_level = -1;13461346+ break;13471347+ case TX_POWER_LIMITED:13481348+ if (dbm < 0)13491349+ return -EINVAL;13501350+ local->user_power_level = dbm;13511351+ break;13521352+ case TX_POWER_FIXED:13531353+ if (dbm < 0)13541354+ return -EINVAL;13551355+ /* TODO: move to cfg80211 when it knows the channel */13561356+ if (dbm > chan->max_power)13571357+ return -EINVAL;13581358+ local->user_power_level = dbm;13591359+ break;13601360+ }13611361+13621362+ ieee80211_hw_config(local, changes);13631363+13641364+ return 0;13651365+}13661366+13671367+static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)13681368+{13691369+ struct ieee80211_local *local = wiphy_priv(wiphy);13701370+13711371+ *dbm = local->hw.conf.power_level;13721372+13731373+ return 0;13741374+}13751375+13761376+static void ieee80211_rfkill_poll(struct wiphy *wiphy)13771377+{13781378+ struct ieee80211_local *local = wiphy_priv(wiphy);13791379+13801380+ drv_rfkill_poll(local);13811381+}13821382+13371383struct cfg80211_ops mac80211_config_ops = {13381384 .add_virtual_intf = ieee80211_add_iface,13391385 .del_virtual_intf = ieee80211_del_iface,···14201372 .join_ibss = ieee80211_join_ibss,14211373 .leave_ibss = ieee80211_leave_ibss,14221374 .set_wiphy_params = ieee80211_set_wiphy_params,13751375+ .set_tx_power = ieee80211_set_tx_power,13761376+ .get_tx_power = ieee80211_get_tx_power,13771377+ .rfkill_poll = ieee80211_rfkill_poll,14231378};
···289289 drv_bss_info_changed(local, &sdata->vif,290290 &sdata->vif.bss_conf, changed);291291292292- /*293293- * DEPRECATED294294- *295295- * ~changed is just there to not do this at resume time296296- */297297- if (changed & BSS_CHANGED_BEACON_INT && ~changed) {298298- local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int;299299- ieee80211_hw_config(local,300300- _IEEE80211_CONF_CHANGE_BEACON_INTERVAL);301301- }292292+ /* DEPRECATED */293293+ local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int;302294}303295304296u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
+9
net/mac80211/sta_info.c
···4444 * When the insertion fails (sta_info_insert()) returns non-zero), the4545 * structure will have been freed by sta_info_insert()!4646 *4747+ * sta entries are added by mac80211 when you establish a link with a4848+ * peer. This means different things for the different type of interfaces4949+ * we support. For a regular station this mean we add the AP sta when we5050+ * receive an assocation response from the AP. For IBSS this occurs when5151+ * we receive a probe response or a beacon from target IBSS network. For5252+ * WDS we add the sta for the peer imediately upon device open. When using5353+ * AP mode we add stations for each respective station upon request from5454+ * userspace through nl80211.5555+ *4756 * Because there are debugfs entries for each station, and adding those4857 * must be able to sleep, it is also possible to "pin" a station entry,4958 * that means it can be removed from the hash table but not be freed.
···306306 return 0;307307}308308309309-static int ieee80211_ioctl_siwtxpower(struct net_device *dev,310310- struct iw_request_info *info,311311- union iwreq_data *data, char *extra)312312-{313313- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);314314- struct ieee80211_channel* chan = local->hw.conf.channel;315315- bool reconf = false;316316- u32 reconf_flags = 0;317317- int new_power_level;318318-319319- if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)320320- return -EINVAL;321321- if (data->txpower.flags & IW_TXPOW_RANGE)322322- return -EINVAL;323323- if (!chan)324324- return -EINVAL;325325-326326- /* only change when not disabling */327327- if (!data->txpower.disabled) {328328- if (data->txpower.fixed) {329329- if (data->txpower.value < 0)330330- return -EINVAL;331331- new_power_level = data->txpower.value;332332- /*333333- * Debatable, but we cannot do a fixed power334334- * level above the regulatory constraint.335335- * Use "iwconfig wlan0 txpower 15dBm" instead.336336- */337337- if (new_power_level > chan->max_power)338338- return -EINVAL;339339- } else {340340- /*341341- * Automatic power level setting, max being the value342342- * passed in from userland.343343- */344344- if (data->txpower.value < 0)345345- new_power_level = -1;346346- else347347- new_power_level = data->txpower.value;348348- }349349-350350- reconf = true;351351-352352- /*353353- * ieee80211_hw_config() will limit to the channel's354354- * max power and possibly power constraint from AP.355355- */356356- local->user_power_level = new_power_level;357357- }358358-359359- if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) {360360- local->hw.conf.radio_enabled = !(data->txpower.disabled);361361- reconf_flags |= IEEE80211_CONF_CHANGE_RADIO_ENABLED;362362- ieee80211_led_radio(local, local->hw.conf.radio_enabled);363363- }364364-365365- if (reconf || reconf_flags)366366- ieee80211_hw_config(local, reconf_flags);367367-368368- return 0;369369-}370370-371371-static int ieee80211_ioctl_giwtxpower(struct net_device *dev,372372- struct iw_request_info *info,373373- union iwreq_data *data, char *extra)374374-{375375- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);376376-377377- data->txpower.fixed = 1;378378- data->txpower.disabled = !(local->hw.conf.radio_enabled);379379- data->txpower.value = local->hw.conf.power_level;380380- data->txpower.flags = IW_TXPOW_DBM;381381-382382- return 0;383383-}384384-385309static int ieee80211_ioctl_siwpower(struct net_device *dev,386310 struct iw_request_info *info,387311 struct iw_param *wrq,···582658 (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */583659 (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */584660 (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */585585- (iw_handler) ieee80211_ioctl_siwtxpower, /* SIOCSIWTXPOW */586586- (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */661661+ (iw_handler) cfg80211_wext_siwtxpower, /* SIOCSIWTXPOW */662662+ (iw_handler) cfg80211_wext_giwtxpower, /* SIOCGIWTXPOW */587663 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */588664 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */589665 (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */
+7-14
net/rfkill/Kconfig
···1010 To compile this driver as a module, choose M here: the1111 module will be called rfkill.12121313-config RFKILL_INPUT1414- tristate "Input layer to RF switch connector"1515- depends on RFKILL && INPUT1616- help1717- Say Y here if you want kernel automatically toggle state1818- of RF switches on and off when user presses appropriate1919- button or a key on the keyboard. Without this module you2020- need a some kind of userspace application to control2121- state of the switches.2222-2323- To compile this driver as a module, choose M here: the2424- module will be called rfkill-input.2525-2613# LED trigger support2714config RFKILL_LEDS2815 bool2929- depends on RFKILL && LEDS_TRIGGERS1616+ depends on RFKILL1717+ depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS3018 default y31192020+config RFKILL_INPUT2121+ bool "RF switch input support"2222+ depends on RFKILL2323+ depends on INPUT = y || RFKILL = INPUT2424+ default y if !EMBEDDED
+3-2
net/rfkill/Makefile
···22# Makefile for the RF switch subsystem.33#4455-obj-$(CONFIG_RFKILL) += rfkill.o66-obj-$(CONFIG_RFKILL_INPUT) += rfkill-input.o55+rfkill-y += core.o66+rfkill-$(CONFIG_RFKILL_INPUT) += input.o77+obj-$(CONFIG_RFKILL) += rfkill.o
+1228
net/rfkill/core.c
···11+/*22+ * Copyright (C) 2006 - 2007 Ivo van Doorn33+ * Copyright (C) 2007 Dmitry Torokhov44+ * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License as published by88+ * the Free Software Foundation; either version 2 of the License, or99+ * (at your option) any later version.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program; if not, write to the1818+ * Free Software Foundation, Inc.,1919+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.2020+ */2121+2222+#include <linux/kernel.h>2323+#include <linux/module.h>2424+#include <linux/init.h>2525+#include <linux/workqueue.h>2626+#include <linux/capability.h>2727+#include <linux/list.h>2828+#include <linux/mutex.h>2929+#include <linux/rfkill.h>3030+#include <linux/spinlock.h>3131+#include <linux/miscdevice.h>3232+#include <linux/wait.h>3333+#include <linux/poll.h>3434+#include <linux/fs.h>3535+3636+#include "rfkill.h"3737+3838+#define POLL_INTERVAL (5 * HZ)3939+4040+#define RFKILL_BLOCK_HW BIT(0)4141+#define RFKILL_BLOCK_SW BIT(1)4242+#define RFKILL_BLOCK_SW_PREV BIT(2)4343+#define RFKILL_BLOCK_ANY (RFKILL_BLOCK_HW |\4444+ RFKILL_BLOCK_SW |\4545+ RFKILL_BLOCK_SW_PREV)4646+#define RFKILL_BLOCK_SW_SETCALL BIT(31)4747+4848+struct rfkill {4949+ spinlock_t lock;5050+5151+ const char *name;5252+ enum rfkill_type type;5353+5454+ unsigned long state;5555+5656+ u32 idx;5757+5858+ bool registered;5959+ bool suspended;6060+6161+ const struct rfkill_ops *ops;6262+ void *data;6363+6464+#ifdef CONFIG_RFKILL_LEDS6565+ struct led_trigger led_trigger;6666+ const char *ledtrigname;6767+#endif6868+6969+ struct device dev;7070+ struct list_head node;7171+7272+ struct delayed_work poll_work;7373+ struct work_struct uevent_work;7474+ struct work_struct sync_work;7575+};7676+#define to_rfkill(d) container_of(d, struct rfkill, dev)7777+7878+struct rfkill_int_event {7979+ struct list_head list;8080+ struct rfkill_event ev;8181+};8282+8383+struct rfkill_data {8484+ struct list_head list;8585+ struct list_head events;8686+ struct mutex mtx;8787+ wait_queue_head_t read_wait;8888+ bool input_handler;8989+};9090+9191+9292+MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");9393+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");9494+MODULE_DESCRIPTION("RF switch support");9595+MODULE_LICENSE("GPL");9696+9797+9898+/*9999+ * The locking here should be made much smarter, we currently have100100+ * a bit of a stupid situation because drivers might want to register101101+ * the rfkill struct under their own lock, and take this lock during102102+ * rfkill method calls -- which will cause an AB-BA deadlock situation.103103+ *104104+ * To fix that, we need to rework this code here to be mostly lock-free105105+ * and only use the mutex for list manipulations, not to protect the106106+ * various other global variables. Then we can avoid holding the mutex107107+ * around driver operations, and all is happy.108108+ */109109+static LIST_HEAD(rfkill_list); /* list of registered rf switches */110110+static DEFINE_MUTEX(rfkill_global_mutex);111111+static LIST_HEAD(rfkill_fds); /* list of open fds of /dev/rfkill */112112+113113+static unsigned int rfkill_default_state = 1;114114+module_param_named(default_state, rfkill_default_state, uint, 0444);115115+MODULE_PARM_DESC(default_state,116116+ "Default initial state for all radio types, 0 = radio off");117117+118118+static struct {119119+ bool cur, def;120120+} rfkill_global_states[NUM_RFKILL_TYPES];121121+122122+static unsigned long rfkill_states_default_locked;123123+124124+static bool rfkill_epo_lock_active;125125+126126+127127+#ifdef CONFIG_RFKILL_LEDS128128+static void rfkill_led_trigger_event(struct rfkill *rfkill)129129+{130130+ struct led_trigger *trigger;131131+132132+ if (!rfkill->registered)133133+ return;134134+135135+ trigger = &rfkill->led_trigger;136136+137137+ if (rfkill->state & RFKILL_BLOCK_ANY)138138+ led_trigger_event(trigger, LED_OFF);139139+ else140140+ led_trigger_event(trigger, LED_FULL);141141+}142142+143143+static void rfkill_led_trigger_activate(struct led_classdev *led)144144+{145145+ struct rfkill *rfkill;146146+147147+ rfkill = container_of(led->trigger, struct rfkill, led_trigger);148148+149149+ rfkill_led_trigger_event(rfkill);150150+}151151+152152+const char *rfkill_get_led_trigger_name(struct rfkill *rfkill)153153+{154154+ return rfkill->led_trigger.name;155155+}156156+EXPORT_SYMBOL(rfkill_get_led_trigger_name);157157+158158+void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name)159159+{160160+ BUG_ON(!rfkill);161161+162162+ rfkill->ledtrigname = name;163163+}164164+EXPORT_SYMBOL(rfkill_set_led_trigger_name);165165+166166+static int rfkill_led_trigger_register(struct rfkill *rfkill)167167+{168168+ rfkill->led_trigger.name = rfkill->ledtrigname169169+ ? : dev_name(&rfkill->dev);170170+ rfkill->led_trigger.activate = rfkill_led_trigger_activate;171171+ return led_trigger_register(&rfkill->led_trigger);172172+}173173+174174+static void rfkill_led_trigger_unregister(struct rfkill *rfkill)175175+{176176+ led_trigger_unregister(&rfkill->led_trigger);177177+}178178+#else179179+static void rfkill_led_trigger_event(struct rfkill *rfkill)180180+{181181+}182182+183183+static inline int rfkill_led_trigger_register(struct rfkill *rfkill)184184+{185185+ return 0;186186+}187187+188188+static inline void rfkill_led_trigger_unregister(struct rfkill *rfkill)189189+{190190+}191191+#endif /* CONFIG_RFKILL_LEDS */192192+193193+static void rfkill_fill_event(struct rfkill_event *ev, struct rfkill *rfkill,194194+ enum rfkill_operation op)195195+{196196+ unsigned long flags;197197+198198+ ev->idx = rfkill->idx;199199+ ev->type = rfkill->type;200200+ ev->op = op;201201+202202+ spin_lock_irqsave(&rfkill->lock, flags);203203+ ev->hard = !!(rfkill->state & RFKILL_BLOCK_HW);204204+ ev->soft = !!(rfkill->state & (RFKILL_BLOCK_SW |205205+ RFKILL_BLOCK_SW_PREV));206206+ spin_unlock_irqrestore(&rfkill->lock, flags);207207+}208208+209209+static void rfkill_send_events(struct rfkill *rfkill, enum rfkill_operation op)210210+{211211+ struct rfkill_data *data;212212+ struct rfkill_int_event *ev;213213+214214+ list_for_each_entry(data, &rfkill_fds, list) {215215+ ev = kzalloc(sizeof(*ev), GFP_KERNEL);216216+ if (!ev)217217+ continue;218218+ rfkill_fill_event(&ev->ev, rfkill, op);219219+ mutex_lock(&data->mtx);220220+ list_add_tail(&ev->list, &data->events);221221+ mutex_unlock(&data->mtx);222222+ wake_up_interruptible(&data->read_wait);223223+ }224224+}225225+226226+static void rfkill_event(struct rfkill *rfkill)227227+{228228+ if (!rfkill->registered || rfkill->suspended)229229+ return;230230+231231+ kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);232232+233233+ /* also send event to /dev/rfkill */234234+ rfkill_send_events(rfkill, RFKILL_OP_CHANGE);235235+}236236+237237+static bool __rfkill_set_hw_state(struct rfkill *rfkill,238238+ bool blocked, bool *change)239239+{240240+ unsigned long flags;241241+ bool prev, any;242242+243243+ BUG_ON(!rfkill);244244+245245+ spin_lock_irqsave(&rfkill->lock, flags);246246+ prev = !!(rfkill->state & RFKILL_BLOCK_HW);247247+ if (blocked)248248+ rfkill->state |= RFKILL_BLOCK_HW;249249+ else250250+ rfkill->state &= ~RFKILL_BLOCK_HW;251251+ *change = prev != blocked;252252+ any = rfkill->state & RFKILL_BLOCK_ANY;253253+ spin_unlock_irqrestore(&rfkill->lock, flags);254254+255255+ rfkill_led_trigger_event(rfkill);256256+257257+ return any;258258+}259259+260260+/**261261+ * rfkill_set_block - wrapper for set_block method262262+ *263263+ * @rfkill: the rfkill struct to use264264+ * @blocked: the new software state265265+ *266266+ * Calls the set_block method (when applicable) and handles notifications267267+ * etc. as well.268268+ */269269+static void rfkill_set_block(struct rfkill *rfkill, bool blocked)270270+{271271+ unsigned long flags;272272+ int err;273273+274274+ /*275275+ * Some platforms (...!) generate input events which affect the276276+ * _hard_ kill state -- whenever something tries to change the277277+ * current software state query the hardware state too.278278+ */279279+ if (rfkill->ops->query)280280+ rfkill->ops->query(rfkill, rfkill->data);281281+282282+ spin_lock_irqsave(&rfkill->lock, flags);283283+ if (rfkill->state & RFKILL_BLOCK_SW)284284+ rfkill->state |= RFKILL_BLOCK_SW_PREV;285285+ else286286+ rfkill->state &= ~RFKILL_BLOCK_SW_PREV;287287+288288+ if (blocked)289289+ rfkill->state |= RFKILL_BLOCK_SW;290290+ else291291+ rfkill->state &= ~RFKILL_BLOCK_SW;292292+293293+ rfkill->state |= RFKILL_BLOCK_SW_SETCALL;294294+ spin_unlock_irqrestore(&rfkill->lock, flags);295295+296296+ if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP))297297+ return;298298+299299+ err = rfkill->ops->set_block(rfkill->data, blocked);300300+301301+ spin_lock_irqsave(&rfkill->lock, flags);302302+ if (err) {303303+ /*304304+ * Failed -- reset status to _prev, this may be different305305+ * from what set set _PREV to earlier in this function306306+ * if rfkill_set_sw_state was invoked.307307+ */308308+ if (rfkill->state & RFKILL_BLOCK_SW_PREV)309309+ rfkill->state |= RFKILL_BLOCK_SW;310310+ else311311+ rfkill->state &= ~RFKILL_BLOCK_SW;312312+ }313313+ rfkill->state &= ~RFKILL_BLOCK_SW_SETCALL;314314+ rfkill->state &= ~RFKILL_BLOCK_SW_PREV;315315+ spin_unlock_irqrestore(&rfkill->lock, flags);316316+317317+ rfkill_led_trigger_event(rfkill);318318+ rfkill_event(rfkill);319319+}320320+321321+#ifdef CONFIG_RFKILL_INPUT322322+static atomic_t rfkill_input_disabled = ATOMIC_INIT(0);323323+324324+/**325325+ * __rfkill_switch_all - Toggle state of all switches of given type326326+ * @type: type of interfaces to be affected327327+ * @state: the new state328328+ *329329+ * This function sets the state of all switches of given type,330330+ * unless a specific switch is claimed by userspace (in which case,331331+ * that switch is left alone) or suspended.332332+ *333333+ * Caller must have acquired rfkill_global_mutex.334334+ */335335+static void __rfkill_switch_all(const enum rfkill_type type, bool blocked)336336+{337337+ struct rfkill *rfkill;338338+339339+ rfkill_global_states[type].cur = blocked;340340+ list_for_each_entry(rfkill, &rfkill_list, node) {341341+ if (rfkill->type != type)342342+ continue;343343+344344+ rfkill_set_block(rfkill, blocked);345345+ }346346+}347347+348348+/**349349+ * rfkill_switch_all - Toggle state of all switches of given type350350+ * @type: type of interfaces to be affected351351+ * @state: the new state352352+ *353353+ * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state).354354+ * Please refer to __rfkill_switch_all() for details.355355+ *356356+ * Does nothing if the EPO lock is active.357357+ */358358+void rfkill_switch_all(enum rfkill_type type, bool blocked)359359+{360360+ if (atomic_read(&rfkill_input_disabled))361361+ return;362362+363363+ mutex_lock(&rfkill_global_mutex);364364+365365+ if (!rfkill_epo_lock_active)366366+ __rfkill_switch_all(type, blocked);367367+368368+ mutex_unlock(&rfkill_global_mutex);369369+}370370+371371+/**372372+ * rfkill_epo - emergency power off all transmitters373373+ *374374+ * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED,375375+ * ignoring everything in its path but rfkill_global_mutex and rfkill->mutex.376376+ *377377+ * The global state before the EPO is saved and can be restored later378378+ * using rfkill_restore_states().379379+ */380380+void rfkill_epo(void)381381+{382382+ struct rfkill *rfkill;383383+ int i;384384+385385+ if (atomic_read(&rfkill_input_disabled))386386+ return;387387+388388+ mutex_lock(&rfkill_global_mutex);389389+390390+ rfkill_epo_lock_active = true;391391+ list_for_each_entry(rfkill, &rfkill_list, node)392392+ rfkill_set_block(rfkill, true);393393+394394+ for (i = 0; i < NUM_RFKILL_TYPES; i++) {395395+ rfkill_global_states[i].def = rfkill_global_states[i].cur;396396+ rfkill_global_states[i].cur = true;397397+ }398398+399399+ mutex_unlock(&rfkill_global_mutex);400400+}401401+402402+/**403403+ * rfkill_restore_states - restore global states404404+ *405405+ * Restore (and sync switches to) the global state from the406406+ * states in rfkill_default_states. This can undo the effects of407407+ * a call to rfkill_epo().408408+ */409409+void rfkill_restore_states(void)410410+{411411+ int i;412412+413413+ if (atomic_read(&rfkill_input_disabled))414414+ return;415415+416416+ mutex_lock(&rfkill_global_mutex);417417+418418+ rfkill_epo_lock_active = false;419419+ for (i = 0; i < NUM_RFKILL_TYPES; i++)420420+ __rfkill_switch_all(i, rfkill_global_states[i].def);421421+ mutex_unlock(&rfkill_global_mutex);422422+}423423+424424+/**425425+ * rfkill_remove_epo_lock - unlock state changes426426+ *427427+ * Used by rfkill-input manually unlock state changes, when428428+ * the EPO switch is deactivated.429429+ */430430+void rfkill_remove_epo_lock(void)431431+{432432+ if (atomic_read(&rfkill_input_disabled))433433+ return;434434+435435+ mutex_lock(&rfkill_global_mutex);436436+ rfkill_epo_lock_active = false;437437+ mutex_unlock(&rfkill_global_mutex);438438+}439439+440440+/**441441+ * rfkill_is_epo_lock_active - returns true EPO is active442442+ *443443+ * Returns 0 (false) if there is NOT an active EPO contidion,444444+ * and 1 (true) if there is an active EPO contition, which445445+ * locks all radios in one of the BLOCKED states.446446+ *447447+ * Can be called in atomic context.448448+ */449449+bool rfkill_is_epo_lock_active(void)450450+{451451+ return rfkill_epo_lock_active;452452+}453453+454454+/**455455+ * rfkill_get_global_sw_state - returns global state for a type456456+ * @type: the type to get the global state of457457+ *458458+ * Returns the current global state for a given wireless459459+ * device type.460460+ */461461+bool rfkill_get_global_sw_state(const enum rfkill_type type)462462+{463463+ return rfkill_global_states[type].cur;464464+}465465+#endif466466+467467+void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked)468468+{469469+ BUG_ON(type == RFKILL_TYPE_ALL);470470+471471+ mutex_lock(&rfkill_global_mutex);472472+473473+ /* don't allow unblock when epo */474474+ if (rfkill_epo_lock_active && !blocked)475475+ goto out;476476+477477+ /* too late */478478+ if (rfkill_states_default_locked & BIT(type))479479+ goto out;480480+481481+ rfkill_states_default_locked |= BIT(type);482482+483483+ rfkill_global_states[type].cur = blocked;484484+ rfkill_global_states[type].def = blocked;485485+ out:486486+ mutex_unlock(&rfkill_global_mutex);487487+}488488+EXPORT_SYMBOL(rfkill_set_global_sw_state);489489+490490+491491+bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)492492+{493493+ bool ret, change;494494+495495+ ret = __rfkill_set_hw_state(rfkill, blocked, &change);496496+497497+ if (!rfkill->registered)498498+ return ret;499499+500500+ if (change)501501+ schedule_work(&rfkill->uevent_work);502502+503503+ return ret;504504+}505505+EXPORT_SYMBOL(rfkill_set_hw_state);506506+507507+static void __rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)508508+{509509+ u32 bit = RFKILL_BLOCK_SW;510510+511511+ /* if in a ops->set_block right now, use other bit */512512+ if (rfkill->state & RFKILL_BLOCK_SW_SETCALL)513513+ bit = RFKILL_BLOCK_SW_PREV;514514+515515+ if (blocked)516516+ rfkill->state |= bit;517517+ else518518+ rfkill->state &= ~bit;519519+}520520+521521+bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)522522+{523523+ unsigned long flags;524524+ bool prev, hwblock;525525+526526+ BUG_ON(!rfkill);527527+528528+ spin_lock_irqsave(&rfkill->lock, flags);529529+ prev = !!(rfkill->state & RFKILL_BLOCK_SW);530530+ __rfkill_set_sw_state(rfkill, blocked);531531+ hwblock = !!(rfkill->state & RFKILL_BLOCK_HW);532532+ blocked = blocked || hwblock;533533+ spin_unlock_irqrestore(&rfkill->lock, flags);534534+535535+ if (!rfkill->registered)536536+ return blocked;537537+538538+ if (prev != blocked && !hwblock)539539+ schedule_work(&rfkill->uevent_work);540540+541541+ rfkill_led_trigger_event(rfkill);542542+543543+ return blocked;544544+}545545+EXPORT_SYMBOL(rfkill_set_sw_state);546546+547547+void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)548548+{549549+ unsigned long flags;550550+ bool swprev, hwprev;551551+552552+ BUG_ON(!rfkill);553553+554554+ spin_lock_irqsave(&rfkill->lock, flags);555555+556556+ /*557557+ * No need to care about prev/setblock ... this is for uevent only558558+ * and that will get triggered by rfkill_set_block anyway.559559+ */560560+ swprev = !!(rfkill->state & RFKILL_BLOCK_SW);561561+ hwprev = !!(rfkill->state & RFKILL_BLOCK_HW);562562+ __rfkill_set_sw_state(rfkill, sw);563563+564564+ spin_unlock_irqrestore(&rfkill->lock, flags);565565+566566+ if (!rfkill->registered)567567+ return;568568+569569+ if (swprev != sw || hwprev != hw)570570+ schedule_work(&rfkill->uevent_work);571571+572572+ rfkill_led_trigger_event(rfkill);573573+}574574+EXPORT_SYMBOL(rfkill_set_states);575575+576576+static ssize_t rfkill_name_show(struct device *dev,577577+ struct device_attribute *attr,578578+ char *buf)579579+{580580+ struct rfkill *rfkill = to_rfkill(dev);581581+582582+ return sprintf(buf, "%s\n", rfkill->name);583583+}584584+585585+static const char *rfkill_get_type_str(enum rfkill_type type)586586+{587587+ switch (type) {588588+ case RFKILL_TYPE_WLAN:589589+ return "wlan";590590+ case RFKILL_TYPE_BLUETOOTH:591591+ return "bluetooth";592592+ case RFKILL_TYPE_UWB:593593+ return "ultrawideband";594594+ case RFKILL_TYPE_WIMAX:595595+ return "wimax";596596+ case RFKILL_TYPE_WWAN:597597+ return "wwan";598598+ default:599599+ BUG();600600+ }601601+602602+ BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_WWAN + 1);603603+}604604+605605+static ssize_t rfkill_type_show(struct device *dev,606606+ struct device_attribute *attr,607607+ char *buf)608608+{609609+ struct rfkill *rfkill = to_rfkill(dev);610610+611611+ return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));612612+}613613+614614+static ssize_t rfkill_idx_show(struct device *dev,615615+ struct device_attribute *attr,616616+ char *buf)617617+{618618+ struct rfkill *rfkill = to_rfkill(dev);619619+620620+ return sprintf(buf, "%d\n", rfkill->idx);621621+}622622+623623+static u8 user_state_from_blocked(unsigned long state)624624+{625625+ if (state & RFKILL_BLOCK_HW)626626+ return RFKILL_USER_STATE_HARD_BLOCKED;627627+ if (state & RFKILL_BLOCK_SW)628628+ return RFKILL_USER_STATE_SOFT_BLOCKED;629629+630630+ return RFKILL_USER_STATE_UNBLOCKED;631631+}632632+633633+static ssize_t rfkill_state_show(struct device *dev,634634+ struct device_attribute *attr,635635+ char *buf)636636+{637637+ struct rfkill *rfkill = to_rfkill(dev);638638+ unsigned long flags;639639+ u32 state;640640+641641+ spin_lock_irqsave(&rfkill->lock, flags);642642+ state = rfkill->state;643643+ spin_unlock_irqrestore(&rfkill->lock, flags);644644+645645+ return sprintf(buf, "%d\n", user_state_from_blocked(state));646646+}647647+648648+static ssize_t rfkill_state_store(struct device *dev,649649+ struct device_attribute *attr,650650+ const char *buf, size_t count)651651+{652652+ /*653653+ * The intention was that userspace can only take control over654654+ * a given device when/if rfkill-input doesn't control it due655655+ * to user_claim. Since user_claim is currently unsupported,656656+ * we never support changing the state from userspace -- this657657+ * can be implemented again later.658658+ */659659+660660+ return -EPERM;661661+}662662+663663+static ssize_t rfkill_claim_show(struct device *dev,664664+ struct device_attribute *attr,665665+ char *buf)666666+{667667+ return sprintf(buf, "%d\n", 0);668668+}669669+670670+static ssize_t rfkill_claim_store(struct device *dev,671671+ struct device_attribute *attr,672672+ const char *buf, size_t count)673673+{674674+ return -EOPNOTSUPP;675675+}676676+677677+static struct device_attribute rfkill_dev_attrs[] = {678678+ __ATTR(name, S_IRUGO, rfkill_name_show, NULL),679679+ __ATTR(type, S_IRUGO, rfkill_type_show, NULL),680680+ __ATTR(index, S_IRUGO, rfkill_idx_show, NULL),681681+ __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store),682682+ __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),683683+ __ATTR_NULL684684+};685685+686686+static void rfkill_release(struct device *dev)687687+{688688+ struct rfkill *rfkill = to_rfkill(dev);689689+690690+ kfree(rfkill);691691+}692692+693693+static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)694694+{695695+ struct rfkill *rfkill = to_rfkill(dev);696696+ unsigned long flags;697697+ u32 state;698698+ int error;699699+700700+ error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name);701701+ if (error)702702+ return error;703703+ error = add_uevent_var(env, "RFKILL_TYPE=%s",704704+ rfkill_get_type_str(rfkill->type));705705+ if (error)706706+ return error;707707+ spin_lock_irqsave(&rfkill->lock, flags);708708+ state = rfkill->state;709709+ spin_unlock_irqrestore(&rfkill->lock, flags);710710+ error = add_uevent_var(env, "RFKILL_STATE=%d",711711+ user_state_from_blocked(state));712712+ return error;713713+}714714+715715+void rfkill_pause_polling(struct rfkill *rfkill)716716+{717717+ BUG_ON(!rfkill);718718+719719+ if (!rfkill->ops->poll)720720+ return;721721+722722+ cancel_delayed_work_sync(&rfkill->poll_work);723723+}724724+EXPORT_SYMBOL(rfkill_pause_polling);725725+726726+void rfkill_resume_polling(struct rfkill *rfkill)727727+{728728+ BUG_ON(!rfkill);729729+730730+ if (!rfkill->ops->poll)731731+ return;732732+733733+ schedule_work(&rfkill->poll_work.work);734734+}735735+EXPORT_SYMBOL(rfkill_resume_polling);736736+737737+static int rfkill_suspend(struct device *dev, pm_message_t state)738738+{739739+ struct rfkill *rfkill = to_rfkill(dev);740740+741741+ rfkill_pause_polling(rfkill);742742+743743+ rfkill->suspended = true;744744+745745+ return 0;746746+}747747+748748+static int rfkill_resume(struct device *dev)749749+{750750+ struct rfkill *rfkill = to_rfkill(dev);751751+ bool cur;752752+753753+ mutex_lock(&rfkill_global_mutex);754754+ cur = rfkill_global_states[rfkill->type].cur;755755+ rfkill_set_block(rfkill, cur);756756+ mutex_unlock(&rfkill_global_mutex);757757+758758+ rfkill->suspended = false;759759+760760+ schedule_work(&rfkill->uevent_work);761761+762762+ rfkill_resume_polling(rfkill);763763+764764+ return 0;765765+}766766+767767+static struct class rfkill_class = {768768+ .name = "rfkill",769769+ .dev_release = rfkill_release,770770+ .dev_attrs = rfkill_dev_attrs,771771+ .dev_uevent = rfkill_dev_uevent,772772+ .suspend = rfkill_suspend,773773+ .resume = rfkill_resume,774774+};775775+776776+bool rfkill_blocked(struct rfkill *rfkill)777777+{778778+ unsigned long flags;779779+ u32 state;780780+781781+ spin_lock_irqsave(&rfkill->lock, flags);782782+ state = rfkill->state;783783+ spin_unlock_irqrestore(&rfkill->lock, flags);784784+785785+ return !!(state & RFKILL_BLOCK_ANY);786786+}787787+EXPORT_SYMBOL(rfkill_blocked);788788+789789+790790+struct rfkill * __must_check rfkill_alloc(const char *name,791791+ struct device *parent,792792+ const enum rfkill_type type,793793+ const struct rfkill_ops *ops,794794+ void *ops_data)795795+{796796+ struct rfkill *rfkill;797797+ struct device *dev;798798+799799+ if (WARN_ON(!ops))800800+ return NULL;801801+802802+ if (WARN_ON(!ops->set_block))803803+ return NULL;804804+805805+ if (WARN_ON(!name))806806+ return NULL;807807+808808+ if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES))809809+ return NULL;810810+811811+ rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);812812+ if (!rfkill)813813+ return NULL;814814+815815+ spin_lock_init(&rfkill->lock);816816+ INIT_LIST_HEAD(&rfkill->node);817817+ rfkill->type = type;818818+ rfkill->name = name;819819+ rfkill->ops = ops;820820+ rfkill->data = ops_data;821821+822822+ dev = &rfkill->dev;823823+ dev->class = &rfkill_class;824824+ dev->parent = parent;825825+ device_initialize(dev);826826+827827+ return rfkill;828828+}829829+EXPORT_SYMBOL(rfkill_alloc);830830+831831+static void rfkill_poll(struct work_struct *work)832832+{833833+ struct rfkill *rfkill;834834+835835+ rfkill = container_of(work, struct rfkill, poll_work.work);836836+837837+ /*838838+ * Poll hardware state -- driver will use one of the839839+ * rfkill_set{,_hw,_sw}_state functions and use its840840+ * return value to update the current status.841841+ */842842+ rfkill->ops->poll(rfkill, rfkill->data);843843+844844+ schedule_delayed_work(&rfkill->poll_work,845845+ round_jiffies_relative(POLL_INTERVAL));846846+}847847+848848+static void rfkill_uevent_work(struct work_struct *work)849849+{850850+ struct rfkill *rfkill;851851+852852+ rfkill = container_of(work, struct rfkill, uevent_work);853853+854854+ mutex_lock(&rfkill_global_mutex);855855+ rfkill_event(rfkill);856856+ mutex_unlock(&rfkill_global_mutex);857857+}858858+859859+static void rfkill_sync_work(struct work_struct *work)860860+{861861+ struct rfkill *rfkill;862862+ bool cur;863863+864864+ rfkill = container_of(work, struct rfkill, sync_work);865865+866866+ mutex_lock(&rfkill_global_mutex);867867+ cur = rfkill_global_states[rfkill->type].cur;868868+ rfkill_set_block(rfkill, cur);869869+ mutex_unlock(&rfkill_global_mutex);870870+}871871+872872+int __must_check rfkill_register(struct rfkill *rfkill)873873+{874874+ static unsigned long rfkill_no;875875+ struct device *dev = &rfkill->dev;876876+ int error;877877+878878+ BUG_ON(!rfkill);879879+880880+ mutex_lock(&rfkill_global_mutex);881881+882882+ if (rfkill->registered) {883883+ error = -EALREADY;884884+ goto unlock;885885+ }886886+887887+ rfkill->idx = rfkill_no;888888+ dev_set_name(dev, "rfkill%lu", rfkill_no);889889+ rfkill_no++;890890+891891+ if (!(rfkill_states_default_locked & BIT(rfkill->type))) {892892+ /* first of its kind */893893+ BUILD_BUG_ON(NUM_RFKILL_TYPES >894894+ sizeof(rfkill_states_default_locked) * 8);895895+ rfkill_states_default_locked |= BIT(rfkill->type);896896+ rfkill_global_states[rfkill->type].cur =897897+ rfkill_global_states[rfkill->type].def;898898+ }899899+900900+ list_add_tail(&rfkill->node, &rfkill_list);901901+902902+ error = device_add(dev);903903+ if (error)904904+ goto remove;905905+906906+ error = rfkill_led_trigger_register(rfkill);907907+ if (error)908908+ goto devdel;909909+910910+ rfkill->registered = true;911911+912912+ INIT_DELAYED_WORK(&rfkill->poll_work, rfkill_poll);913913+ INIT_WORK(&rfkill->uevent_work, rfkill_uevent_work);914914+ INIT_WORK(&rfkill->sync_work, rfkill_sync_work);915915+916916+ if (rfkill->ops->poll)917917+ schedule_delayed_work(&rfkill->poll_work,918918+ round_jiffies_relative(POLL_INTERVAL));919919+ schedule_work(&rfkill->sync_work);920920+921921+ rfkill_send_events(rfkill, RFKILL_OP_ADD);922922+923923+ mutex_unlock(&rfkill_global_mutex);924924+ return 0;925925+926926+ devdel:927927+ device_del(&rfkill->dev);928928+ remove:929929+ list_del_init(&rfkill->node);930930+ unlock:931931+ mutex_unlock(&rfkill_global_mutex);932932+ return error;933933+}934934+EXPORT_SYMBOL(rfkill_register);935935+936936+void rfkill_unregister(struct rfkill *rfkill)937937+{938938+ BUG_ON(!rfkill);939939+940940+ if (rfkill->ops->poll)941941+ cancel_delayed_work_sync(&rfkill->poll_work);942942+943943+ cancel_work_sync(&rfkill->uevent_work);944944+ cancel_work_sync(&rfkill->sync_work);945945+946946+ rfkill->registered = false;947947+948948+ device_del(&rfkill->dev);949949+950950+ mutex_lock(&rfkill_global_mutex);951951+ rfkill_send_events(rfkill, RFKILL_OP_DEL);952952+ list_del_init(&rfkill->node);953953+ mutex_unlock(&rfkill_global_mutex);954954+955955+ rfkill_led_trigger_unregister(rfkill);956956+}957957+EXPORT_SYMBOL(rfkill_unregister);958958+959959+void rfkill_destroy(struct rfkill *rfkill)960960+{961961+ if (rfkill)962962+ put_device(&rfkill->dev);963963+}964964+EXPORT_SYMBOL(rfkill_destroy);965965+966966+static int rfkill_fop_open(struct inode *inode, struct file *file)967967+{968968+ struct rfkill_data *data;969969+ struct rfkill *rfkill;970970+ struct rfkill_int_event *ev, *tmp;971971+972972+ data = kzalloc(sizeof(*data), GFP_KERNEL);973973+ if (!data)974974+ return -ENOMEM;975975+976976+ INIT_LIST_HEAD(&data->events);977977+ mutex_init(&data->mtx);978978+ init_waitqueue_head(&data->read_wait);979979+980980+ mutex_lock(&rfkill_global_mutex);981981+ mutex_lock(&data->mtx);982982+ /*983983+ * start getting events from elsewhere but hold mtx to get984984+ * startup events added first985985+ */986986+ list_add(&data->list, &rfkill_fds);987987+988988+ list_for_each_entry(rfkill, &rfkill_list, node) {989989+ ev = kzalloc(sizeof(*ev), GFP_KERNEL);990990+ if (!ev)991991+ goto free;992992+ rfkill_fill_event(&ev->ev, rfkill, RFKILL_OP_ADD);993993+ list_add_tail(&ev->list, &data->events);994994+ }995995+ mutex_unlock(&data->mtx);996996+ mutex_unlock(&rfkill_global_mutex);997997+998998+ file->private_data = data;999999+10001000+ return nonseekable_open(inode, file);10011001+10021002+ free:10031003+ mutex_unlock(&data->mtx);10041004+ mutex_unlock(&rfkill_global_mutex);10051005+ mutex_destroy(&data->mtx);10061006+ list_for_each_entry_safe(ev, tmp, &data->events, list)10071007+ kfree(ev);10081008+ kfree(data);10091009+ return -ENOMEM;10101010+}10111011+10121012+static unsigned int rfkill_fop_poll(struct file *file, poll_table *wait)10131013+{10141014+ struct rfkill_data *data = file->private_data;10151015+ unsigned int res = POLLOUT | POLLWRNORM;10161016+10171017+ poll_wait(file, &data->read_wait, wait);10181018+10191019+ mutex_lock(&data->mtx);10201020+ if (!list_empty(&data->events))10211021+ res = POLLIN | POLLRDNORM;10221022+ mutex_unlock(&data->mtx);10231023+10241024+ return res;10251025+}10261026+10271027+static bool rfkill_readable(struct rfkill_data *data)10281028+{10291029+ bool r;10301030+10311031+ mutex_lock(&data->mtx);10321032+ r = !list_empty(&data->events);10331033+ mutex_unlock(&data->mtx);10341034+10351035+ return r;10361036+}10371037+10381038+static ssize_t rfkill_fop_read(struct file *file, char __user *buf,10391039+ size_t count, loff_t *pos)10401040+{10411041+ struct rfkill_data *data = file->private_data;10421042+ struct rfkill_int_event *ev;10431043+ unsigned long sz;10441044+ int ret;10451045+10461046+ mutex_lock(&data->mtx);10471047+10481048+ while (list_empty(&data->events)) {10491049+ if (file->f_flags & O_NONBLOCK) {10501050+ ret = -EAGAIN;10511051+ goto out;10521052+ }10531053+ mutex_unlock(&data->mtx);10541054+ ret = wait_event_interruptible(data->read_wait,10551055+ rfkill_readable(data));10561056+ mutex_lock(&data->mtx);10571057+10581058+ if (ret)10591059+ goto out;10601060+ }10611061+10621062+ ev = list_first_entry(&data->events, struct rfkill_int_event,10631063+ list);10641064+10651065+ sz = min_t(unsigned long, sizeof(ev->ev), count);10661066+ ret = sz;10671067+ if (copy_to_user(buf, &ev->ev, sz))10681068+ ret = -EFAULT;10691069+10701070+ list_del(&ev->list);10711071+ kfree(ev);10721072+ out:10731073+ mutex_unlock(&data->mtx);10741074+ return ret;10751075+}10761076+10771077+static ssize_t rfkill_fop_write(struct file *file, const char __user *buf,10781078+ size_t count, loff_t *pos)10791079+{10801080+ struct rfkill *rfkill;10811081+ struct rfkill_event ev;10821082+10831083+ /* we don't need the 'hard' variable but accept it */10841084+ if (count < sizeof(ev) - 1)10851085+ return -EINVAL;10861086+10871087+ if (copy_from_user(&ev, buf, sizeof(ev) - 1))10881088+ return -EFAULT;10891089+10901090+ if (ev.op != RFKILL_OP_CHANGE && ev.op != RFKILL_OP_CHANGE_ALL)10911091+ return -EINVAL;10921092+10931093+ if (ev.type >= NUM_RFKILL_TYPES)10941094+ return -EINVAL;10951095+10961096+ mutex_lock(&rfkill_global_mutex);10971097+10981098+ if (ev.op == RFKILL_OP_CHANGE_ALL) {10991099+ if (ev.type == RFKILL_TYPE_ALL) {11001100+ enum rfkill_type i;11011101+ for (i = 0; i < NUM_RFKILL_TYPES; i++)11021102+ rfkill_global_states[i].cur = ev.soft;11031103+ } else {11041104+ rfkill_global_states[ev.type].cur = ev.soft;11051105+ }11061106+ }11071107+11081108+ list_for_each_entry(rfkill, &rfkill_list, node) {11091109+ if (rfkill->idx != ev.idx && ev.op != RFKILL_OP_CHANGE_ALL)11101110+ continue;11111111+11121112+ if (rfkill->type != ev.type && ev.type != RFKILL_TYPE_ALL)11131113+ continue;11141114+11151115+ rfkill_set_block(rfkill, ev.soft);11161116+ }11171117+ mutex_unlock(&rfkill_global_mutex);11181118+11191119+ return count;11201120+}11211121+11221122+static int rfkill_fop_release(struct inode *inode, struct file *file)11231123+{11241124+ struct rfkill_data *data = file->private_data;11251125+ struct rfkill_int_event *ev, *tmp;11261126+11271127+ mutex_lock(&rfkill_global_mutex);11281128+ list_del(&data->list);11291129+ mutex_unlock(&rfkill_global_mutex);11301130+11311131+ mutex_destroy(&data->mtx);11321132+ list_for_each_entry_safe(ev, tmp, &data->events, list)11331133+ kfree(ev);11341134+11351135+#ifdef CONFIG_RFKILL_INPUT11361136+ if (data->input_handler)11371137+ atomic_dec(&rfkill_input_disabled);11381138+#endif11391139+11401140+ kfree(data);11411141+11421142+ return 0;11431143+}11441144+11451145+#ifdef CONFIG_RFKILL_INPUT11461146+static long rfkill_fop_ioctl(struct file *file, unsigned int cmd,11471147+ unsigned long arg)11481148+{11491149+ struct rfkill_data *data = file->private_data;11501150+11511151+ if (_IOC_TYPE(cmd) != RFKILL_IOC_MAGIC)11521152+ return -ENOSYS;11531153+11541154+ if (_IOC_NR(cmd) != RFKILL_IOC_NOINPUT)11551155+ return -ENOSYS;11561156+11571157+ mutex_lock(&data->mtx);11581158+11591159+ if (!data->input_handler) {11601160+ atomic_inc(&rfkill_input_disabled);11611161+ data->input_handler = true;11621162+ }11631163+11641164+ mutex_unlock(&data->mtx);11651165+11661166+ return 0;11671167+}11681168+#endif11691169+11701170+static const struct file_operations rfkill_fops = {11711171+ .open = rfkill_fop_open,11721172+ .read = rfkill_fop_read,11731173+ .write = rfkill_fop_write,11741174+ .poll = rfkill_fop_poll,11751175+ .release = rfkill_fop_release,11761176+#ifdef CONFIG_RFKILL_INPUT11771177+ .unlocked_ioctl = rfkill_fop_ioctl,11781178+ .compat_ioctl = rfkill_fop_ioctl,11791179+#endif11801180+};11811181+11821182+static struct miscdevice rfkill_miscdev = {11831183+ .name = "rfkill",11841184+ .fops = &rfkill_fops,11851185+ .minor = MISC_DYNAMIC_MINOR,11861186+};11871187+11881188+static int __init rfkill_init(void)11891189+{11901190+ int error;11911191+ int i;11921192+11931193+ for (i = 0; i < NUM_RFKILL_TYPES; i++)11941194+ rfkill_global_states[i].def = !rfkill_default_state;11951195+11961196+ error = class_register(&rfkill_class);11971197+ if (error)11981198+ goto out;11991199+12001200+ error = misc_register(&rfkill_miscdev);12011201+ if (error) {12021202+ class_unregister(&rfkill_class);12031203+ goto out;12041204+ }12051205+12061206+#ifdef CONFIG_RFKILL_INPUT12071207+ error = rfkill_handler_init();12081208+ if (error) {12091209+ misc_deregister(&rfkill_miscdev);12101210+ class_unregister(&rfkill_class);12111211+ goto out;12121212+ }12131213+#endif12141214+12151215+ out:12161216+ return error;12171217+}12181218+subsys_initcall(rfkill_init);12191219+12201220+static void __exit rfkill_exit(void)12211221+{12221222+#ifdef CONFIG_RFKILL_INPUT12231223+ rfkill_handler_exit();12241224+#endif12251225+ misc_deregister(&rfkill_miscdev);12261226+ class_unregister(&rfkill_class);12271227+}12281228+module_exit(rfkill_exit);
+342
net/rfkill/input.c
···11+/*22+ * Input layer to RF Kill interface connector33+ *44+ * Copyright (c) 2007 Dmitry Torokhov55+ * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>66+ *77+ * This program is free software; you can redistribute it and/or modify it88+ * under the terms of the GNU General Public License version 2 as published99+ * by the Free Software Foundation.1010+ *1111+ * If you ever run into a situation in which you have a SW_ type rfkill1212+ * input device, then you can revive code that was removed in the patch1313+ * "rfkill-input: remove unused code".1414+ */1515+1616+#include <linux/input.h>1717+#include <linux/slab.h>1818+#include <linux/workqueue.h>1919+#include <linux/init.h>2020+#include <linux/rfkill.h>2121+#include <linux/sched.h>2222+2323+#include "rfkill.h"2424+2525+enum rfkill_input_master_mode {2626+ RFKILL_INPUT_MASTER_UNLOCK = 0,2727+ RFKILL_INPUT_MASTER_RESTORE = 1,2828+ RFKILL_INPUT_MASTER_UNBLOCKALL = 2,2929+ NUM_RFKILL_INPUT_MASTER_MODES3030+};3131+3232+/* Delay (in ms) between consecutive switch ops */3333+#define RFKILL_OPS_DELAY 2003434+3535+static enum rfkill_input_master_mode rfkill_master_switch_mode =3636+ RFKILL_INPUT_MASTER_UNBLOCKALL;3737+module_param_named(master_switch_mode, rfkill_master_switch_mode, uint, 0);3838+MODULE_PARM_DESC(master_switch_mode,3939+ "SW_RFKILL_ALL ON should: 0=do nothing (only unlock); 1=restore; 2=unblock all");4040+4141+static spinlock_t rfkill_op_lock;4242+static bool rfkill_op_pending;4343+static unsigned long rfkill_sw_pending[BITS_TO_LONGS(NUM_RFKILL_TYPES)];4444+static unsigned long rfkill_sw_state[BITS_TO_LONGS(NUM_RFKILL_TYPES)];4545+4646+enum rfkill_sched_op {4747+ RFKILL_GLOBAL_OP_EPO = 0,4848+ RFKILL_GLOBAL_OP_RESTORE,4949+ RFKILL_GLOBAL_OP_UNLOCK,5050+ RFKILL_GLOBAL_OP_UNBLOCK,5151+};5252+5353+static enum rfkill_sched_op rfkill_master_switch_op;5454+static enum rfkill_sched_op rfkill_op;5555+5656+static void __rfkill_handle_global_op(enum rfkill_sched_op op)5757+{5858+ unsigned int i;5959+6060+ switch (op) {6161+ case RFKILL_GLOBAL_OP_EPO:6262+ rfkill_epo();6363+ break;6464+ case RFKILL_GLOBAL_OP_RESTORE:6565+ rfkill_restore_states();6666+ break;6767+ case RFKILL_GLOBAL_OP_UNLOCK:6868+ rfkill_remove_epo_lock();6969+ break;7070+ case RFKILL_GLOBAL_OP_UNBLOCK:7171+ rfkill_remove_epo_lock();7272+ for (i = 0; i < NUM_RFKILL_TYPES; i++)7373+ rfkill_switch_all(i, false);7474+ break;7575+ default:7676+ /* memory corruption or bug, fail safely */7777+ rfkill_epo();7878+ WARN(1, "Unknown requested operation %d! "7979+ "rfkill Emergency Power Off activated\n",8080+ op);8181+ }8282+}8383+8484+static void __rfkill_handle_normal_op(const enum rfkill_type type,8585+ const bool complement)8686+{8787+ bool blocked;8888+8989+ blocked = rfkill_get_global_sw_state(type);9090+ if (complement)9191+ blocked = !blocked;9292+9393+ rfkill_switch_all(type, blocked);9494+}9595+9696+static void rfkill_op_handler(struct work_struct *work)9797+{9898+ unsigned int i;9999+ bool c;100100+101101+ spin_lock_irq(&rfkill_op_lock);102102+ do {103103+ if (rfkill_op_pending) {104104+ enum rfkill_sched_op op = rfkill_op;105105+ rfkill_op_pending = false;106106+ memset(rfkill_sw_pending, 0,107107+ sizeof(rfkill_sw_pending));108108+ spin_unlock_irq(&rfkill_op_lock);109109+110110+ __rfkill_handle_global_op(op);111111+112112+ spin_lock_irq(&rfkill_op_lock);113113+114114+ /*115115+ * handle global ops first -- during unlocked period116116+ * we might have gotten a new global op.117117+ */118118+ if (rfkill_op_pending)119119+ continue;120120+ }121121+122122+ if (rfkill_is_epo_lock_active())123123+ continue;124124+125125+ for (i = 0; i < NUM_RFKILL_TYPES; i++) {126126+ if (__test_and_clear_bit(i, rfkill_sw_pending)) {127127+ c = __test_and_clear_bit(i, rfkill_sw_state);128128+ spin_unlock_irq(&rfkill_op_lock);129129+130130+ __rfkill_handle_normal_op(i, c);131131+132132+ spin_lock_irq(&rfkill_op_lock);133133+ }134134+ }135135+ } while (rfkill_op_pending);136136+ spin_unlock_irq(&rfkill_op_lock);137137+}138138+139139+static DECLARE_DELAYED_WORK(rfkill_op_work, rfkill_op_handler);140140+static unsigned long rfkill_last_scheduled;141141+142142+static unsigned long rfkill_ratelimit(const unsigned long last)143143+{144144+ const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY);145145+ return (time_after(jiffies, last + delay)) ? 0 : delay;146146+}147147+148148+static void rfkill_schedule_ratelimited(void)149149+{150150+ if (delayed_work_pending(&rfkill_op_work))151151+ return;152152+ schedule_delayed_work(&rfkill_op_work,153153+ rfkill_ratelimit(rfkill_last_scheduled));154154+ rfkill_last_scheduled = jiffies;155155+}156156+157157+static void rfkill_schedule_global_op(enum rfkill_sched_op op)158158+{159159+ unsigned long flags;160160+161161+ spin_lock_irqsave(&rfkill_op_lock, flags);162162+ rfkill_op = op;163163+ rfkill_op_pending = true;164164+ if (op == RFKILL_GLOBAL_OP_EPO && !rfkill_is_epo_lock_active()) {165165+ /* bypass the limiter for EPO */166166+ cancel_delayed_work(&rfkill_op_work);167167+ schedule_delayed_work(&rfkill_op_work, 0);168168+ rfkill_last_scheduled = jiffies;169169+ } else170170+ rfkill_schedule_ratelimited();171171+ spin_unlock_irqrestore(&rfkill_op_lock, flags);172172+}173173+174174+static void rfkill_schedule_toggle(enum rfkill_type type)175175+{176176+ unsigned long flags;177177+178178+ if (rfkill_is_epo_lock_active())179179+ return;180180+181181+ spin_lock_irqsave(&rfkill_op_lock, flags);182182+ if (!rfkill_op_pending) {183183+ __set_bit(type, rfkill_sw_pending);184184+ __change_bit(type, rfkill_sw_state);185185+ rfkill_schedule_ratelimited();186186+ }187187+ spin_unlock_irqrestore(&rfkill_op_lock, flags);188188+}189189+190190+static void rfkill_schedule_evsw_rfkillall(int state)191191+{192192+ if (state)193193+ rfkill_schedule_global_op(rfkill_master_switch_op);194194+ else195195+ rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO);196196+}197197+198198+static void rfkill_event(struct input_handle *handle, unsigned int type,199199+ unsigned int code, int data)200200+{201201+ if (type == EV_KEY && data == 1) {202202+ switch (code) {203203+ case KEY_WLAN:204204+ rfkill_schedule_toggle(RFKILL_TYPE_WLAN);205205+ break;206206+ case KEY_BLUETOOTH:207207+ rfkill_schedule_toggle(RFKILL_TYPE_BLUETOOTH);208208+ break;209209+ case KEY_UWB:210210+ rfkill_schedule_toggle(RFKILL_TYPE_UWB);211211+ break;212212+ case KEY_WIMAX:213213+ rfkill_schedule_toggle(RFKILL_TYPE_WIMAX);214214+ break;215215+ }216216+ } else if (type == EV_SW && code == SW_RFKILL_ALL)217217+ rfkill_schedule_evsw_rfkillall(data);218218+}219219+220220+static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,221221+ const struct input_device_id *id)222222+{223223+ struct input_handle *handle;224224+ int error;225225+226226+ handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);227227+ if (!handle)228228+ return -ENOMEM;229229+230230+ handle->dev = dev;231231+ handle->handler = handler;232232+ handle->name = "rfkill";233233+234234+ /* causes rfkill_start() to be called */235235+ error = input_register_handle(handle);236236+ if (error)237237+ goto err_free_handle;238238+239239+ error = input_open_device(handle);240240+ if (error)241241+ goto err_unregister_handle;242242+243243+ return 0;244244+245245+ err_unregister_handle:246246+ input_unregister_handle(handle);247247+ err_free_handle:248248+ kfree(handle);249249+ return error;250250+}251251+252252+static void rfkill_start(struct input_handle *handle)253253+{254254+ /*255255+ * Take event_lock to guard against configuration changes, we256256+ * should be able to deal with concurrency with rfkill_event()257257+ * just fine (which event_lock will also avoid).258258+ */259259+ spin_lock_irq(&handle->dev->event_lock);260260+261261+ if (test_bit(EV_SW, handle->dev->evbit) &&262262+ test_bit(SW_RFKILL_ALL, handle->dev->swbit))263263+ rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL,264264+ handle->dev->sw));265265+266266+ spin_unlock_irq(&handle->dev->event_lock);267267+}268268+269269+static void rfkill_disconnect(struct input_handle *handle)270270+{271271+ input_close_device(handle);272272+ input_unregister_handle(handle);273273+ kfree(handle);274274+}275275+276276+static const struct input_device_id rfkill_ids[] = {277277+ {278278+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,279279+ .evbit = { BIT_MASK(EV_KEY) },280280+ .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) },281281+ },282282+ {283283+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,284284+ .evbit = { BIT_MASK(EV_KEY) },285285+ .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) },286286+ },287287+ {288288+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,289289+ .evbit = { BIT_MASK(EV_KEY) },290290+ .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },291291+ },292292+ {293293+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,294294+ .evbit = { BIT_MASK(EV_KEY) },295295+ .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },296296+ },297297+ {298298+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,299299+ .evbit = { BIT(EV_SW) },300300+ .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },301301+ },302302+ { }303303+};304304+305305+static struct input_handler rfkill_handler = {306306+ .name = "rfkill",307307+ .event = rfkill_event,308308+ .connect = rfkill_connect,309309+ .start = rfkill_start,310310+ .disconnect = rfkill_disconnect,311311+ .id_table = rfkill_ids,312312+};313313+314314+int __init rfkill_handler_init(void)315315+{316316+ switch (rfkill_master_switch_mode) {317317+ case RFKILL_INPUT_MASTER_UNBLOCKALL:318318+ rfkill_master_switch_op = RFKILL_GLOBAL_OP_UNBLOCK;319319+ break;320320+ case RFKILL_INPUT_MASTER_RESTORE:321321+ rfkill_master_switch_op = RFKILL_GLOBAL_OP_RESTORE;322322+ break;323323+ case RFKILL_INPUT_MASTER_UNLOCK:324324+ rfkill_master_switch_op = RFKILL_GLOBAL_OP_UNLOCK;325325+ break;326326+ default:327327+ return -EINVAL;328328+ }329329+330330+ spin_lock_init(&rfkill_op_lock);331331+332332+ /* Avoid delay at first schedule */333333+ rfkill_last_scheduled =334334+ jiffies - msecs_to_jiffies(RFKILL_OPS_DELAY) - 1;335335+ return input_register_handler(&rfkill_handler);336336+}337337+338338+void __exit rfkill_handler_exit(void)339339+{340340+ input_unregister_handler(&rfkill_handler);341341+ cancel_delayed_work_sync(&rfkill_op_work);342342+}
-390
net/rfkill/rfkill-input.c
···11-/*22- * Input layer to RF Kill interface connector33- *44- * Copyright (c) 2007 Dmitry Torokhov55- */66-77-/*88- * This program is free software; you can redistribute it and/or modify it99- * under the terms of the GNU General Public License version 2 as published1010- * by the Free Software Foundation.1111- */1212-1313-#include <linux/module.h>1414-#include <linux/input.h>1515-#include <linux/slab.h>1616-#include <linux/workqueue.h>1717-#include <linux/init.h>1818-#include <linux/rfkill.h>1919-#include <linux/sched.h>2020-2121-#include "rfkill-input.h"2222-2323-MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");2424-MODULE_DESCRIPTION("Input layer to RF switch connector");2525-MODULE_LICENSE("GPL");2626-2727-enum rfkill_input_master_mode {2828- RFKILL_INPUT_MASTER_DONOTHING = 0,2929- RFKILL_INPUT_MASTER_RESTORE = 1,3030- RFKILL_INPUT_MASTER_UNBLOCKALL = 2,3131- RFKILL_INPUT_MASTER_MAX, /* marker */3232-};3333-3434-/* Delay (in ms) between consecutive switch ops */3535-#define RFKILL_OPS_DELAY 2003636-3737-static enum rfkill_input_master_mode rfkill_master_switch_mode =3838- RFKILL_INPUT_MASTER_UNBLOCKALL;3939-module_param_named(master_switch_mode, rfkill_master_switch_mode, uint, 0);4040-MODULE_PARM_DESC(master_switch_mode,4141- "SW_RFKILL_ALL ON should: 0=do nothing; 1=restore; 2=unblock all");4242-4343-enum rfkill_global_sched_op {4444- RFKILL_GLOBAL_OP_EPO = 0,4545- RFKILL_GLOBAL_OP_RESTORE,4646- RFKILL_GLOBAL_OP_UNLOCK,4747- RFKILL_GLOBAL_OP_UNBLOCK,4848-};4949-5050-struct rfkill_task {5151- struct delayed_work dwork;5252-5353- /* ensures that task is serialized */5454- struct mutex mutex;5555-5656- /* protects everything below */5757- spinlock_t lock;5858-5959- /* pending regular switch operations (1=pending) */6060- unsigned long sw_pending[BITS_TO_LONGS(RFKILL_TYPE_MAX)];6161-6262- /* should the state be complemented (1=yes) */6363- unsigned long sw_togglestate[BITS_TO_LONGS(RFKILL_TYPE_MAX)];6464-6565- bool global_op_pending;6666- enum rfkill_global_sched_op op;6767-6868- /* last time it was scheduled */6969- unsigned long last_scheduled;7070-};7171-7272-static void __rfkill_handle_global_op(enum rfkill_global_sched_op op)7373-{7474- unsigned int i;7575-7676- switch (op) {7777- case RFKILL_GLOBAL_OP_EPO:7878- rfkill_epo();7979- break;8080- case RFKILL_GLOBAL_OP_RESTORE:8181- rfkill_restore_states();8282- break;8383- case RFKILL_GLOBAL_OP_UNLOCK:8484- rfkill_remove_epo_lock();8585- break;8686- case RFKILL_GLOBAL_OP_UNBLOCK:8787- rfkill_remove_epo_lock();8888- for (i = 0; i < RFKILL_TYPE_MAX; i++)8989- rfkill_switch_all(i, RFKILL_STATE_UNBLOCKED);9090- break;9191- default:9292- /* memory corruption or bug, fail safely */9393- rfkill_epo();9494- WARN(1, "Unknown requested operation %d! "9595- "rfkill Emergency Power Off activated\n",9696- op);9797- }9898-}9999-100100-static void __rfkill_handle_normal_op(const enum rfkill_type type,101101- const bool c)102102-{103103- enum rfkill_state state;104104-105105- state = rfkill_get_global_state(type);106106- if (c)107107- state = rfkill_state_complement(state);108108-109109- rfkill_switch_all(type, state);110110-}111111-112112-static void rfkill_task_handler(struct work_struct *work)113113-{114114- struct rfkill_task *task = container_of(work,115115- struct rfkill_task, dwork.work);116116- bool doit = true;117117-118118- mutex_lock(&task->mutex);119119-120120- spin_lock_irq(&task->lock);121121- while (doit) {122122- if (task->global_op_pending) {123123- enum rfkill_global_sched_op op = task->op;124124- task->global_op_pending = false;125125- memset(task->sw_pending, 0, sizeof(task->sw_pending));126126- spin_unlock_irq(&task->lock);127127-128128- __rfkill_handle_global_op(op);129129-130130- /* make sure we do at least one pass with131131- * !task->global_op_pending */132132- spin_lock_irq(&task->lock);133133- continue;134134- } else if (!rfkill_is_epo_lock_active()) {135135- unsigned int i = 0;136136-137137- while (!task->global_op_pending &&138138- i < RFKILL_TYPE_MAX) {139139- if (test_and_clear_bit(i, task->sw_pending)) {140140- bool c;141141- c = test_and_clear_bit(i,142142- task->sw_togglestate);143143- spin_unlock_irq(&task->lock);144144-145145- __rfkill_handle_normal_op(i, c);146146-147147- spin_lock_irq(&task->lock);148148- }149149- i++;150150- }151151- }152152- doit = task->global_op_pending;153153- }154154- spin_unlock_irq(&task->lock);155155-156156- mutex_unlock(&task->mutex);157157-}158158-159159-static struct rfkill_task rfkill_task = {160160- .dwork = __DELAYED_WORK_INITIALIZER(rfkill_task.dwork,161161- rfkill_task_handler),162162- .mutex = __MUTEX_INITIALIZER(rfkill_task.mutex),163163- .lock = __SPIN_LOCK_UNLOCKED(rfkill_task.lock),164164-};165165-166166-static unsigned long rfkill_ratelimit(const unsigned long last)167167-{168168- const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY);169169- return (time_after(jiffies, last + delay)) ? 0 : delay;170170-}171171-172172-static void rfkill_schedule_ratelimited(void)173173-{174174- if (!delayed_work_pending(&rfkill_task.dwork)) {175175- schedule_delayed_work(&rfkill_task.dwork,176176- rfkill_ratelimit(rfkill_task.last_scheduled));177177- rfkill_task.last_scheduled = jiffies;178178- }179179-}180180-181181-static void rfkill_schedule_global_op(enum rfkill_global_sched_op op)182182-{183183- unsigned long flags;184184-185185- spin_lock_irqsave(&rfkill_task.lock, flags);186186- rfkill_task.op = op;187187- rfkill_task.global_op_pending = true;188188- if (op == RFKILL_GLOBAL_OP_EPO && !rfkill_is_epo_lock_active()) {189189- /* bypass the limiter for EPO */190190- cancel_delayed_work(&rfkill_task.dwork);191191- schedule_delayed_work(&rfkill_task.dwork, 0);192192- rfkill_task.last_scheduled = jiffies;193193- } else194194- rfkill_schedule_ratelimited();195195- spin_unlock_irqrestore(&rfkill_task.lock, flags);196196-}197197-198198-static void rfkill_schedule_toggle(enum rfkill_type type)199199-{200200- unsigned long flags;201201-202202- if (rfkill_is_epo_lock_active())203203- return;204204-205205- spin_lock_irqsave(&rfkill_task.lock, flags);206206- if (!rfkill_task.global_op_pending) {207207- set_bit(type, rfkill_task.sw_pending);208208- change_bit(type, rfkill_task.sw_togglestate);209209- rfkill_schedule_ratelimited();210210- }211211- spin_unlock_irqrestore(&rfkill_task.lock, flags);212212-}213213-214214-static void rfkill_schedule_evsw_rfkillall(int state)215215-{216216- if (state) {217217- switch (rfkill_master_switch_mode) {218218- case RFKILL_INPUT_MASTER_UNBLOCKALL:219219- rfkill_schedule_global_op(RFKILL_GLOBAL_OP_UNBLOCK);220220- break;221221- case RFKILL_INPUT_MASTER_RESTORE:222222- rfkill_schedule_global_op(RFKILL_GLOBAL_OP_RESTORE);223223- break;224224- case RFKILL_INPUT_MASTER_DONOTHING:225225- rfkill_schedule_global_op(RFKILL_GLOBAL_OP_UNLOCK);226226- break;227227- default:228228- /* memory corruption or driver bug! fail safely */229229- rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO);230230- WARN(1, "Unknown rfkill_master_switch_mode (%d), "231231- "driver bug or memory corruption detected!\n",232232- rfkill_master_switch_mode);233233- break;234234- }235235- } else236236- rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO);237237-}238238-239239-static void rfkill_event(struct input_handle *handle, unsigned int type,240240- unsigned int code, int data)241241-{242242- if (type == EV_KEY && data == 1) {243243- enum rfkill_type t;244244-245245- switch (code) {246246- case KEY_WLAN:247247- t = RFKILL_TYPE_WLAN;248248- break;249249- case KEY_BLUETOOTH:250250- t = RFKILL_TYPE_BLUETOOTH;251251- break;252252- case KEY_UWB:253253- t = RFKILL_TYPE_UWB;254254- break;255255- case KEY_WIMAX:256256- t = RFKILL_TYPE_WIMAX;257257- break;258258- default:259259- return;260260- }261261- rfkill_schedule_toggle(t);262262- return;263263- } else if (type == EV_SW) {264264- switch (code) {265265- case SW_RFKILL_ALL:266266- rfkill_schedule_evsw_rfkillall(data);267267- return;268268- default:269269- return;270270- }271271- }272272-}273273-274274-static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,275275- const struct input_device_id *id)276276-{277277- struct input_handle *handle;278278- int error;279279-280280- handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);281281- if (!handle)282282- return -ENOMEM;283283-284284- handle->dev = dev;285285- handle->handler = handler;286286- handle->name = "rfkill";287287-288288- /* causes rfkill_start() to be called */289289- error = input_register_handle(handle);290290- if (error)291291- goto err_free_handle;292292-293293- error = input_open_device(handle);294294- if (error)295295- goto err_unregister_handle;296296-297297- return 0;298298-299299- err_unregister_handle:300300- input_unregister_handle(handle);301301- err_free_handle:302302- kfree(handle);303303- return error;304304-}305305-306306-static void rfkill_start(struct input_handle *handle)307307-{308308- /* Take event_lock to guard against configuration changes, we309309- * should be able to deal with concurrency with rfkill_event()310310- * just fine (which event_lock will also avoid). */311311- spin_lock_irq(&handle->dev->event_lock);312312-313313- if (test_bit(EV_SW, handle->dev->evbit)) {314314- if (test_bit(SW_RFKILL_ALL, handle->dev->swbit))315315- rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL,316316- handle->dev->sw));317317- /* add resync for further EV_SW events here */318318- }319319-320320- spin_unlock_irq(&handle->dev->event_lock);321321-}322322-323323-static void rfkill_disconnect(struct input_handle *handle)324324-{325325- input_close_device(handle);326326- input_unregister_handle(handle);327327- kfree(handle);328328-}329329-330330-static const struct input_device_id rfkill_ids[] = {331331- {332332- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,333333- .evbit = { BIT_MASK(EV_KEY) },334334- .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) },335335- },336336- {337337- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,338338- .evbit = { BIT_MASK(EV_KEY) },339339- .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) },340340- },341341- {342342- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,343343- .evbit = { BIT_MASK(EV_KEY) },344344- .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },345345- },346346- {347347- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,348348- .evbit = { BIT_MASK(EV_KEY) },349349- .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },350350- },351351- {352352- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,353353- .evbit = { BIT(EV_SW) },354354- .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },355355- },356356- { }357357-};358358-359359-static struct input_handler rfkill_handler = {360360- .event = rfkill_event,361361- .connect = rfkill_connect,362362- .disconnect = rfkill_disconnect,363363- .start = rfkill_start,364364- .name = "rfkill",365365- .id_table = rfkill_ids,366366-};367367-368368-static int __init rfkill_handler_init(void)369369-{370370- if (rfkill_master_switch_mode >= RFKILL_INPUT_MASTER_MAX)371371- return -EINVAL;372372-373373- /*374374- * The penalty to not doing this is a possible RFKILL_OPS_DELAY delay375375- * at the first use. Acceptable, but if we can avoid it, why not?376376- */377377- rfkill_task.last_scheduled =378378- jiffies - msecs_to_jiffies(RFKILL_OPS_DELAY) - 1;379379- return input_register_handler(&rfkill_handler);380380-}381381-382382-static void __exit rfkill_handler_exit(void)383383-{384384- input_unregister_handler(&rfkill_handler);385385- cancel_delayed_work_sync(&rfkill_task.dwork);386386- rfkill_remove_epo_lock();387387-}388388-389389-module_init(rfkill_handler_init);390390-module_exit(rfkill_handler_exit);
···11-/*22- * Copyright (C) 2006 - 2007 Ivo van Doorn33- * Copyright (C) 2007 Dmitry Torokhov44- *55- * This program is free software; you can redistribute it and/or modify66- * it under the terms of the GNU General Public License as published by77- * the Free Software Foundation; either version 2 of the License, or88- * (at your option) any later version.99- *1010- * This program is distributed in the hope that it will be useful,1111- * but WITHOUT ANY WARRANTY; without even the implied warranty of1212- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1313- * GNU General Public License for more details.1414- *1515- * You should have received a copy of the GNU General Public License1616- * along with this program; if not, write to the1717- * Free Software Foundation, Inc.,1818- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.1919- */2020-2121-#include <linux/kernel.h>2222-#include <linux/module.h>2323-#include <linux/init.h>2424-#include <linux/workqueue.h>2525-#include <linux/capability.h>2626-#include <linux/list.h>2727-#include <linux/mutex.h>2828-#include <linux/rfkill.h>2929-3030-/* Get declaration of rfkill_switch_all() to shut up sparse. */3131-#include "rfkill-input.h"3232-3333-3434-MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");3535-MODULE_VERSION("1.0");3636-MODULE_DESCRIPTION("RF switch support");3737-MODULE_LICENSE("GPL");3838-3939-static LIST_HEAD(rfkill_list); /* list of registered rf switches */4040-static DEFINE_MUTEX(rfkill_global_mutex);4141-4242-static unsigned int rfkill_default_state = RFKILL_STATE_UNBLOCKED;4343-module_param_named(default_state, rfkill_default_state, uint, 0444);4444-MODULE_PARM_DESC(default_state,4545- "Default initial state for all radio types, 0 = radio off");4646-4747-struct rfkill_gsw_state {4848- enum rfkill_state current_state;4949- enum rfkill_state default_state;5050-};5151-5252-static struct rfkill_gsw_state rfkill_global_states[RFKILL_TYPE_MAX];5353-static unsigned long rfkill_states_lockdflt[BITS_TO_LONGS(RFKILL_TYPE_MAX)];5454-static bool rfkill_epo_lock_active;5555-5656-5757-#ifdef CONFIG_RFKILL_LEDS5858-static void rfkill_led_trigger(struct rfkill *rfkill,5959- enum rfkill_state state)6060-{6161- struct led_trigger *led = &rfkill->led_trigger;6262-6363- if (!led->name)6464- return;6565- if (state != RFKILL_STATE_UNBLOCKED)6666- led_trigger_event(led, LED_OFF);6767- else6868- led_trigger_event(led, LED_FULL);6969-}7070-7171-static void rfkill_led_trigger_activate(struct led_classdev *led)7272-{7373- struct rfkill *rfkill = container_of(led->trigger,7474- struct rfkill, led_trigger);7575-7676- rfkill_led_trigger(rfkill, rfkill->state);7777-}7878-#else7979-static inline void rfkill_led_trigger(struct rfkill *rfkill,8080- enum rfkill_state state)8181-{8282-}8383-#endif /* CONFIG_RFKILL_LEDS */8484-8585-static void rfkill_uevent(struct rfkill *rfkill)8686-{8787- kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);8888-}8989-9090-static void update_rfkill_state(struct rfkill *rfkill)9191-{9292- enum rfkill_state newstate, oldstate;9393-9494- if (rfkill->get_state) {9595- mutex_lock(&rfkill->mutex);9696- if (!rfkill->get_state(rfkill->data, &newstate)) {9797- oldstate = rfkill->state;9898- rfkill->state = newstate;9999- if (oldstate != newstate)100100- rfkill_uevent(rfkill);101101- }102102- mutex_unlock(&rfkill->mutex);103103- }104104- rfkill_led_trigger(rfkill, rfkill->state);105105-}106106-107107-/**108108- * rfkill_toggle_radio - wrapper for toggle_radio hook109109- * @rfkill: the rfkill struct to use110110- * @force: calls toggle_radio even if cache says it is not needed,111111- * and also makes sure notifications of the state will be112112- * sent even if it didn't change113113- * @state: the new state to call toggle_radio() with114114- *115115- * Calls rfkill->toggle_radio, enforcing the API for toggle_radio116116- * calls and handling all the red tape such as issuing notifications117117- * if the call is successful.118118- *119119- * Suspended devices are not touched at all, and -EAGAIN is returned.120120- *121121- * Note that the @force parameter cannot override a (possibly cached)122122- * state of RFKILL_STATE_HARD_BLOCKED. Any device making use of123123- * RFKILL_STATE_HARD_BLOCKED implements either get_state() or124124- * rfkill_force_state(), so the cache either is bypassed or valid.125125- *126126- * Note that we do call toggle_radio for RFKILL_STATE_SOFT_BLOCKED127127- * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to128128- * give the driver a hint that it should double-BLOCK the transmitter.129129- *130130- * Caller must have acquired rfkill->mutex.131131- */132132-static int rfkill_toggle_radio(struct rfkill *rfkill,133133- enum rfkill_state state,134134- int force)135135-{136136- int retval = 0;137137- enum rfkill_state oldstate, newstate;138138-139139- if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP))140140- return -EBUSY;141141-142142- oldstate = rfkill->state;143143-144144- if (rfkill->get_state && !force &&145145- !rfkill->get_state(rfkill->data, &newstate)) {146146- rfkill->state = newstate;147147- }148148-149149- switch (state) {150150- case RFKILL_STATE_HARD_BLOCKED:151151- /* typically happens when refreshing hardware state,152152- * such as on resume */153153- state = RFKILL_STATE_SOFT_BLOCKED;154154- break;155155- case RFKILL_STATE_UNBLOCKED:156156- /* force can't override this, only rfkill_force_state() can */157157- if (rfkill->state == RFKILL_STATE_HARD_BLOCKED)158158- return -EPERM;159159- break;160160- case RFKILL_STATE_SOFT_BLOCKED:161161- /* nothing to do, we want to give drivers the hint to double162162- * BLOCK even a transmitter that is already in state163163- * RFKILL_STATE_HARD_BLOCKED */164164- break;165165- default:166166- WARN(1, KERN_WARNING167167- "rfkill: illegal state %d passed as parameter "168168- "to rfkill_toggle_radio\n", state);169169- return -EINVAL;170170- }171171-172172- if (force || state != rfkill->state) {173173- retval = rfkill->toggle_radio(rfkill->data, state);174174- /* never allow a HARD->SOFT downgrade! */175175- if (!retval && rfkill->state != RFKILL_STATE_HARD_BLOCKED)176176- rfkill->state = state;177177- }178178-179179- if (force || rfkill->state != oldstate)180180- rfkill_uevent(rfkill);181181-182182- rfkill_led_trigger(rfkill, rfkill->state);183183- return retval;184184-}185185-186186-/**187187- * __rfkill_switch_all - Toggle state of all switches of given type188188- * @type: type of interfaces to be affected189189- * @state: the new state190190- *191191- * This function toggles the state of all switches of given type,192192- * unless a specific switch is claimed by userspace (in which case,193193- * that switch is left alone) or suspended.194194- *195195- * Caller must have acquired rfkill_global_mutex.196196- */197197-static void __rfkill_switch_all(const enum rfkill_type type,198198- const enum rfkill_state state)199199-{200200- struct rfkill *rfkill;201201-202202- if (WARN((state >= RFKILL_STATE_MAX || type >= RFKILL_TYPE_MAX),203203- KERN_WARNING204204- "rfkill: illegal state %d or type %d "205205- "passed as parameter to __rfkill_switch_all\n",206206- state, type))207207- return;208208-209209- rfkill_global_states[type].current_state = state;210210- list_for_each_entry(rfkill, &rfkill_list, node) {211211- if (rfkill->type == type) {212212- mutex_lock(&rfkill->mutex);213213- rfkill_toggle_radio(rfkill, state, 0);214214- mutex_unlock(&rfkill->mutex);215215- rfkill_led_trigger(rfkill, rfkill->state);216216- }217217- }218218-}219219-220220-/**221221- * rfkill_switch_all - Toggle state of all switches of given type222222- * @type: type of interfaces to be affected223223- * @state: the new state224224- *225225- * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state).226226- * Please refer to __rfkill_switch_all() for details.227227- *228228- * Does nothing if the EPO lock is active.229229- */230230-void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)231231-{232232- mutex_lock(&rfkill_global_mutex);233233- if (!rfkill_epo_lock_active)234234- __rfkill_switch_all(type, state);235235- mutex_unlock(&rfkill_global_mutex);236236-}237237-EXPORT_SYMBOL(rfkill_switch_all);238238-239239-/**240240- * rfkill_epo - emergency power off all transmitters241241- *242242- * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED,243243- * ignoring everything in its path but rfkill_global_mutex and rfkill->mutex.244244- *245245- * The global state before the EPO is saved and can be restored later246246- * using rfkill_restore_states().247247- */248248-void rfkill_epo(void)249249-{250250- struct rfkill *rfkill;251251- int i;252252-253253- mutex_lock(&rfkill_global_mutex);254254-255255- rfkill_epo_lock_active = true;256256- list_for_each_entry(rfkill, &rfkill_list, node) {257257- mutex_lock(&rfkill->mutex);258258- rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);259259- mutex_unlock(&rfkill->mutex);260260- }261261- for (i = 0; i < RFKILL_TYPE_MAX; i++) {262262- rfkill_global_states[i].default_state =263263- rfkill_global_states[i].current_state;264264- rfkill_global_states[i].current_state =265265- RFKILL_STATE_SOFT_BLOCKED;266266- }267267- mutex_unlock(&rfkill_global_mutex);268268- rfkill_led_trigger(rfkill, rfkill->state);269269-}270270-EXPORT_SYMBOL_GPL(rfkill_epo);271271-272272-/**273273- * rfkill_restore_states - restore global states274274- *275275- * Restore (and sync switches to) the global state from the276276- * states in rfkill_default_states. This can undo the effects of277277- * a call to rfkill_epo().278278- */279279-void rfkill_restore_states(void)280280-{281281- int i;282282-283283- mutex_lock(&rfkill_global_mutex);284284-285285- rfkill_epo_lock_active = false;286286- for (i = 0; i < RFKILL_TYPE_MAX; i++)287287- __rfkill_switch_all(i, rfkill_global_states[i].default_state);288288- mutex_unlock(&rfkill_global_mutex);289289-}290290-EXPORT_SYMBOL_GPL(rfkill_restore_states);291291-292292-/**293293- * rfkill_remove_epo_lock - unlock state changes294294- *295295- * Used by rfkill-input manually unlock state changes, when296296- * the EPO switch is deactivated.297297- */298298-void rfkill_remove_epo_lock(void)299299-{300300- mutex_lock(&rfkill_global_mutex);301301- rfkill_epo_lock_active = false;302302- mutex_unlock(&rfkill_global_mutex);303303-}304304-EXPORT_SYMBOL_GPL(rfkill_remove_epo_lock);305305-306306-/**307307- * rfkill_is_epo_lock_active - returns true EPO is active308308- *309309- * Returns 0 (false) if there is NOT an active EPO contidion,310310- * and 1 (true) if there is an active EPO contition, which311311- * locks all radios in one of the BLOCKED states.312312- *313313- * Can be called in atomic context.314314- */315315-bool rfkill_is_epo_lock_active(void)316316-{317317- return rfkill_epo_lock_active;318318-}319319-EXPORT_SYMBOL_GPL(rfkill_is_epo_lock_active);320320-321321-/**322322- * rfkill_get_global_state - returns global state for a type323323- * @type: the type to get the global state of324324- *325325- * Returns the current global state for a given wireless326326- * device type.327327- */328328-enum rfkill_state rfkill_get_global_state(const enum rfkill_type type)329329-{330330- return rfkill_global_states[type].current_state;331331-}332332-EXPORT_SYMBOL_GPL(rfkill_get_global_state);333333-334334-/**335335- * rfkill_force_state - Force the internal rfkill radio state336336- * @rfkill: pointer to the rfkill class to modify.337337- * @state: the current radio state the class should be forced to.338338- *339339- * This function updates the internal state of the radio cached340340- * by the rfkill class. It should be used when the driver gets341341- * a notification by the firmware/hardware of the current *real*342342- * state of the radio rfkill switch.343343- *344344- * Devices which are subject to external changes on their rfkill345345- * state (such as those caused by a hardware rfkill line) MUST346346- * have their driver arrange to call rfkill_force_state() as soon347347- * as possible after such a change.348348- *349349- * This function may not be called from an atomic context.350350- */351351-int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)352352-{353353- enum rfkill_state oldstate;354354-355355- BUG_ON(!rfkill);356356- if (WARN((state >= RFKILL_STATE_MAX),357357- KERN_WARNING358358- "rfkill: illegal state %d passed as parameter "359359- "to rfkill_force_state\n", state))360360- return -EINVAL;361361-362362- mutex_lock(&rfkill->mutex);363363-364364- oldstate = rfkill->state;365365- rfkill->state = state;366366-367367- if (state != oldstate)368368- rfkill_uevent(rfkill);369369-370370- mutex_unlock(&rfkill->mutex);371371- rfkill_led_trigger(rfkill, rfkill->state);372372-373373- return 0;374374-}375375-EXPORT_SYMBOL(rfkill_force_state);376376-377377-static ssize_t rfkill_name_show(struct device *dev,378378- struct device_attribute *attr,379379- char *buf)380380-{381381- struct rfkill *rfkill = to_rfkill(dev);382382-383383- return sprintf(buf, "%s\n", rfkill->name);384384-}385385-386386-static const char *rfkill_get_type_str(enum rfkill_type type)387387-{388388- switch (type) {389389- case RFKILL_TYPE_WLAN:390390- return "wlan";391391- case RFKILL_TYPE_BLUETOOTH:392392- return "bluetooth";393393- case RFKILL_TYPE_UWB:394394- return "ultrawideband";395395- case RFKILL_TYPE_WIMAX:396396- return "wimax";397397- case RFKILL_TYPE_WWAN:398398- return "wwan";399399- default:400400- BUG();401401- }402402-}403403-404404-static ssize_t rfkill_type_show(struct device *dev,405405- struct device_attribute *attr,406406- char *buf)407407-{408408- struct rfkill *rfkill = to_rfkill(dev);409409-410410- return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));411411-}412412-413413-static ssize_t rfkill_state_show(struct device *dev,414414- struct device_attribute *attr,415415- char *buf)416416-{417417- struct rfkill *rfkill = to_rfkill(dev);418418-419419- update_rfkill_state(rfkill);420420- return sprintf(buf, "%d\n", rfkill->state);421421-}422422-423423-static ssize_t rfkill_state_store(struct device *dev,424424- struct device_attribute *attr,425425- const char *buf, size_t count)426426-{427427- struct rfkill *rfkill = to_rfkill(dev);428428- unsigned long state;429429- int error;430430-431431- if (!capable(CAP_NET_ADMIN))432432- return -EPERM;433433-434434- error = strict_strtoul(buf, 0, &state);435435- if (error)436436- return error;437437-438438- /* RFKILL_STATE_HARD_BLOCKED is illegal here... */439439- if (state != RFKILL_STATE_UNBLOCKED &&440440- state != RFKILL_STATE_SOFT_BLOCKED)441441- return -EINVAL;442442-443443- error = mutex_lock_killable(&rfkill->mutex);444444- if (error)445445- return error;446446-447447- if (!rfkill_epo_lock_active)448448- error = rfkill_toggle_radio(rfkill, state, 0);449449- else450450- error = -EPERM;451451-452452- mutex_unlock(&rfkill->mutex);453453-454454- return error ? error : count;455455-}456456-457457-static ssize_t rfkill_claim_show(struct device *dev,458458- struct device_attribute *attr,459459- char *buf)460460-{461461- return sprintf(buf, "%d\n", 0);462462-}463463-464464-static ssize_t rfkill_claim_store(struct device *dev,465465- struct device_attribute *attr,466466- const char *buf, size_t count)467467-{468468- return -EOPNOTSUPP;469469-}470470-471471-static struct device_attribute rfkill_dev_attrs[] = {472472- __ATTR(name, S_IRUGO, rfkill_name_show, NULL),473473- __ATTR(type, S_IRUGO, rfkill_type_show, NULL),474474- __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store),475475- __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),476476- __ATTR_NULL477477-};478478-479479-static void rfkill_release(struct device *dev)480480-{481481- struct rfkill *rfkill = to_rfkill(dev);482482-483483- kfree(rfkill);484484- module_put(THIS_MODULE);485485-}486486-487487-#ifdef CONFIG_PM488488-static int rfkill_suspend(struct device *dev, pm_message_t state)489489-{490490- struct rfkill *rfkill = to_rfkill(dev);491491-492492- /* mark class device as suspended */493493- if (dev->power.power_state.event != state.event)494494- dev->power.power_state = state;495495-496496- /* store state for the resume handler */497497- rfkill->state_for_resume = rfkill->state;498498-499499- return 0;500500-}501501-502502-static int rfkill_resume(struct device *dev)503503-{504504- struct rfkill *rfkill = to_rfkill(dev);505505- enum rfkill_state newstate;506506-507507- if (dev->power.power_state.event != PM_EVENT_ON) {508508- mutex_lock(&rfkill->mutex);509509-510510- dev->power.power_state.event = PM_EVENT_ON;511511-512512- /*513513- * rfkill->state could have been modified before we got514514- * called, and won't be updated by rfkill_toggle_radio()515515- * in force mode. Sync it FIRST.516516- */517517- if (rfkill->get_state &&518518- !rfkill->get_state(rfkill->data, &newstate))519519- rfkill->state = newstate;520520-521521- /*522522- * If we are under EPO, kick transmitter offline,523523- * otherwise restore to pre-suspend state.524524- *525525- * Issue a notification in any case526526- */527527- rfkill_toggle_radio(rfkill,528528- rfkill_epo_lock_active ?529529- RFKILL_STATE_SOFT_BLOCKED :530530- rfkill->state_for_resume,531531- 1);532532-533533- mutex_unlock(&rfkill->mutex);534534- rfkill_led_trigger(rfkill, rfkill->state);535535- }536536-537537- return 0;538538-}539539-#else540540-#define rfkill_suspend NULL541541-#define rfkill_resume NULL542542-#endif543543-544544-static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)545545-{546546- struct rfkill *rfkill = to_rfkill(dev);547547- int error;548548-549549- error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name);550550- if (error)551551- return error;552552- error = add_uevent_var(env, "RFKILL_TYPE=%s",553553- rfkill_get_type_str(rfkill->type));554554- if (error)555555- return error;556556- error = add_uevent_var(env, "RFKILL_STATE=%d", rfkill->state);557557- return error;558558-}559559-560560-static struct class rfkill_class = {561561- .name = "rfkill",562562- .dev_release = rfkill_release,563563- .dev_attrs = rfkill_dev_attrs,564564- .suspend = rfkill_suspend,565565- .resume = rfkill_resume,566566- .dev_uevent = rfkill_dev_uevent,567567-};568568-569569-static int rfkill_check_duplicity(const struct rfkill *rfkill)570570-{571571- struct rfkill *p;572572- unsigned long seen[BITS_TO_LONGS(RFKILL_TYPE_MAX)];573573-574574- memset(seen, 0, sizeof(seen));575575-576576- list_for_each_entry(p, &rfkill_list, node) {577577- if (WARN((p == rfkill), KERN_WARNING578578- "rfkill: illegal attempt to register "579579- "an already registered rfkill struct\n"))580580- return -EEXIST;581581- set_bit(p->type, seen);582582- }583583-584584- /* 0: first switch of its kind */585585- return (test_bit(rfkill->type, seen)) ? 1 : 0;586586-}587587-588588-static int rfkill_add_switch(struct rfkill *rfkill)589589-{590590- int error;591591-592592- mutex_lock(&rfkill_global_mutex);593593-594594- error = rfkill_check_duplicity(rfkill);595595- if (error < 0)596596- goto unlock_out;597597-598598- if (!error) {599599- /* lock default after first use */600600- set_bit(rfkill->type, rfkill_states_lockdflt);601601- rfkill_global_states[rfkill->type].current_state =602602- rfkill_global_states[rfkill->type].default_state;603603- }604604-605605- rfkill_toggle_radio(rfkill,606606- rfkill_global_states[rfkill->type].current_state,607607- 0);608608-609609- list_add_tail(&rfkill->node, &rfkill_list);610610-611611- error = 0;612612-unlock_out:613613- mutex_unlock(&rfkill_global_mutex);614614-615615- return error;616616-}617617-618618-static void rfkill_remove_switch(struct rfkill *rfkill)619619-{620620- mutex_lock(&rfkill_global_mutex);621621- list_del_init(&rfkill->node);622622- mutex_unlock(&rfkill_global_mutex);623623-624624- mutex_lock(&rfkill->mutex);625625- rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);626626- mutex_unlock(&rfkill->mutex);627627-}628628-629629-/**630630- * rfkill_allocate - allocate memory for rfkill structure.631631- * @parent: device that has rf switch on it632632- * @type: type of the switch (RFKILL_TYPE_*)633633- *634634- * This function should be called by the network driver when it needs635635- * rfkill structure. Once the structure is allocated the driver should636636- * finish its initialization by setting the name, private data, enable_radio637637- * and disable_radio methods and then register it with rfkill_register().638638- *639639- * NOTE: If registration fails the structure shoudl be freed by calling640640- * rfkill_free() otherwise rfkill_unregister() should be used.641641- */642642-struct rfkill * __must_check rfkill_allocate(struct device *parent,643643- enum rfkill_type type)644644-{645645- struct rfkill *rfkill;646646- struct device *dev;647647-648648- if (WARN((type >= RFKILL_TYPE_MAX),649649- KERN_WARNING650650- "rfkill: illegal type %d passed as parameter "651651- "to rfkill_allocate\n", type))652652- return NULL;653653-654654- rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);655655- if (!rfkill)656656- return NULL;657657-658658- mutex_init(&rfkill->mutex);659659- INIT_LIST_HEAD(&rfkill->node);660660- rfkill->type = type;661661-662662- dev = &rfkill->dev;663663- dev->class = &rfkill_class;664664- dev->parent = parent;665665- device_initialize(dev);666666-667667- __module_get(THIS_MODULE);668668-669669- return rfkill;670670-}671671-EXPORT_SYMBOL(rfkill_allocate);672672-673673-/**674674- * rfkill_free - Mark rfkill structure for deletion675675- * @rfkill: rfkill structure to be destroyed676676- *677677- * Decrements reference count of the rfkill structure so it is destroyed.678678- * Note that rfkill_free() should _not_ be called after rfkill_unregister().679679- */680680-void rfkill_free(struct rfkill *rfkill)681681-{682682- if (rfkill)683683- put_device(&rfkill->dev);684684-}685685-EXPORT_SYMBOL(rfkill_free);686686-687687-static void rfkill_led_trigger_register(struct rfkill *rfkill)688688-{689689-#ifdef CONFIG_RFKILL_LEDS690690- int error;691691-692692- if (!rfkill->led_trigger.name)693693- rfkill->led_trigger.name = dev_name(&rfkill->dev);694694- if (!rfkill->led_trigger.activate)695695- rfkill->led_trigger.activate = rfkill_led_trigger_activate;696696- error = led_trigger_register(&rfkill->led_trigger);697697- if (error)698698- rfkill->led_trigger.name = NULL;699699-#endif /* CONFIG_RFKILL_LEDS */700700-}701701-702702-static void rfkill_led_trigger_unregister(struct rfkill *rfkill)703703-{704704-#ifdef CONFIG_RFKILL_LEDS705705- if (rfkill->led_trigger.name) {706706- led_trigger_unregister(&rfkill->led_trigger);707707- rfkill->led_trigger.name = NULL;708708- }709709-#endif710710-}711711-712712-/**713713- * rfkill_register - Register a rfkill structure.714714- * @rfkill: rfkill structure to be registered715715- *716716- * This function should be called by the network driver when the rfkill717717- * structure needs to be registered. Immediately from registration the718718- * switch driver should be able to service calls to toggle_radio.719719- */720720-int __must_check rfkill_register(struct rfkill *rfkill)721721-{722722- static atomic_t rfkill_no = ATOMIC_INIT(0);723723- struct device *dev = &rfkill->dev;724724- int error;725725-726726- if (WARN((!rfkill || !rfkill->toggle_radio ||727727- rfkill->type >= RFKILL_TYPE_MAX ||728728- rfkill->state >= RFKILL_STATE_MAX),729729- KERN_WARNING730730- "rfkill: attempt to register a "731731- "badly initialized rfkill struct\n"))732732- return -EINVAL;733733-734734- dev_set_name(dev, "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);735735-736736- rfkill_led_trigger_register(rfkill);737737-738738- error = rfkill_add_switch(rfkill);739739- if (error) {740740- rfkill_led_trigger_unregister(rfkill);741741- return error;742742- }743743-744744- error = device_add(dev);745745- if (error) {746746- rfkill_remove_switch(rfkill);747747- rfkill_led_trigger_unregister(rfkill);748748- return error;749749- }750750-751751- return 0;752752-}753753-EXPORT_SYMBOL(rfkill_register);754754-755755-/**756756- * rfkill_unregister - Unregister a rfkill structure.757757- * @rfkill: rfkill structure to be unregistered758758- *759759- * This function should be called by the network driver during device760760- * teardown to destroy rfkill structure. Note that rfkill_free() should761761- * _not_ be called after rfkill_unregister().762762- */763763-void rfkill_unregister(struct rfkill *rfkill)764764-{765765- BUG_ON(!rfkill);766766- device_del(&rfkill->dev);767767- rfkill_remove_switch(rfkill);768768- rfkill_led_trigger_unregister(rfkill);769769- put_device(&rfkill->dev);770770-}771771-EXPORT_SYMBOL(rfkill_unregister);772772-773773-/**774774- * rfkill_set_default - set initial value for a switch type775775- * @type - the type of switch to set the default state of776776- * @state - the new default state for that group of switches777777- *778778- * Sets the initial state rfkill should use for a given type.779779- * The following initial states are allowed: RFKILL_STATE_SOFT_BLOCKED780780- * and RFKILL_STATE_UNBLOCKED.781781- *782782- * This function is meant to be used by platform drivers for platforms783783- * that can save switch state across power down/reboot.784784- *785785- * The default state for each switch type can be changed exactly once.786786- * After a switch of that type is registered, the default state cannot787787- * be changed anymore. This guards against multiple drivers it the788788- * same platform trying to set the initial switch default state, which789789- * is not allowed.790790- *791791- * Returns -EPERM if the state has already been set once or is in use,792792- * so drivers likely want to either ignore or at most printk(KERN_NOTICE)793793- * if this function returns -EPERM.794794- *795795- * Returns 0 if the new default state was set, or an error if it796796- * could not be set.797797- */798798-int rfkill_set_default(enum rfkill_type type, enum rfkill_state state)799799-{800800- int error;801801-802802- if (WARN((type >= RFKILL_TYPE_MAX ||803803- (state != RFKILL_STATE_SOFT_BLOCKED &&804804- state != RFKILL_STATE_UNBLOCKED)),805805- KERN_WARNING806806- "rfkill: illegal state %d or type %d passed as "807807- "parameter to rfkill_set_default\n", state, type))808808- return -EINVAL;809809-810810- mutex_lock(&rfkill_global_mutex);811811-812812- if (!test_and_set_bit(type, rfkill_states_lockdflt)) {813813- rfkill_global_states[type].default_state = state;814814- rfkill_global_states[type].current_state = state;815815- error = 0;816816- } else817817- error = -EPERM;818818-819819- mutex_unlock(&rfkill_global_mutex);820820- return error;821821-}822822-EXPORT_SYMBOL_GPL(rfkill_set_default);823823-824824-/*825825- * Rfkill module initialization/deinitialization.826826- */827827-static int __init rfkill_init(void)828828-{829829- int error;830830- int i;831831-832832- /* RFKILL_STATE_HARD_BLOCKED is illegal here... */833833- if (rfkill_default_state != RFKILL_STATE_SOFT_BLOCKED &&834834- rfkill_default_state != RFKILL_STATE_UNBLOCKED)835835- return -EINVAL;836836-837837- for (i = 0; i < RFKILL_TYPE_MAX; i++)838838- rfkill_global_states[i].default_state = rfkill_default_state;839839-840840- error = class_register(&rfkill_class);841841- if (error) {842842- printk(KERN_ERR "rfkill: unable to register rfkill class\n");843843- return error;844844- }845845-846846- return 0;847847-}848848-849849-static void __exit rfkill_exit(void)850850-{851851- class_unregister(&rfkill_class);852852-}853853-854854-subsys_initcall(rfkill_init);855855-module_exit(rfkill_exit);
+1-14
net/wimax/Kconfig
···11#22# WiMAX LAN device configuration33#44-# Note the ugly 'depends on' on WIMAX: that disallows RFKILL to be a55-# module if WIMAX is to be linked in. The WiMAX code is done in such a66-# way that it doesn't require and explicit dependency on RFKILL in77-# case an embedded system wants to rip it out.88-#99-# As well, enablement of the RFKILL code means we need the INPUT layer1010-# support to inject events coming from hw rfkill switches. That1111-# dependency could be killed if input.h provided appropriate means to1212-# work when input is disabled.1313-1414-comment "WiMAX Wireless Broadband support requires CONFIG_INPUT enabled"1515- depends on INPUT = n && RFKILL != n164175menuconfig WIMAX186 tristate "WiMAX Wireless Broadband support"1919- depends on (y && RFKILL != m) || m2020- depends on (INPUT && RFKILL != n) || RFKILL = n77+ depends on RFKILL || !RFKILL218 help2292310 Select to configure support for devices that provide
+26-97
net/wimax/op-rfkill.c
···2929 * A non-polled generic rfkill device is embedded into the WiMAX3030 * subsystem's representation of a device.3131 *3232- * FIXME: Need polled support? use a timer or add the implementation3333- * to the stack.3232+ * FIXME: Need polled support? Let drivers provide a poll routine3333+ * and hand it to rfkill ops then?3434 *3535 * All device drivers have to do is after wimax_dev_init(), call3636 * wimax_report_rfkill_hw() and wimax_report_rfkill_sw() to update···4343 * wimax_rfkill() Kernel calling wimax_rfkill()4444 * __wimax_rf_toggle_radio()4545 *4646- * wimax_rfkill_toggle_radio() RF-Kill subsytem calling4646+ * wimax_rfkill_set_radio_block() RF-Kill subsytem calling4747 * __wimax_rf_toggle_radio()4848 *4949 * __wimax_rf_toggle_radio()···6565#include <linux/wimax.h>6666#include <linux/security.h>6767#include <linux/rfkill.h>6868-#include <linux/input.h>6968#include "wimax-internal.h"70697170#define D_SUBMODULE op_rfkill7271#include "debug-levels.h"7373-7474-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)7575-76727773/**7874 * wimax_report_rfkill_hw - Reports changes in the hardware RF switch···9599 int result;96100 struct device *dev = wimax_dev_to_dev(wimax_dev);97101 enum wimax_st wimax_state;9898- enum rfkill_state rfkill_state;99102100103 d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state);101104 BUG_ON(state == WIMAX_RF_QUERY);···107112108113 if (state != wimax_dev->rf_hw) {109114 wimax_dev->rf_hw = state;110110- rfkill_state = state == WIMAX_RF_ON ?111111- RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;112115 if (wimax_dev->rf_hw == WIMAX_RF_ON113116 && wimax_dev->rf_sw == WIMAX_RF_ON)114117 wimax_state = WIMAX_ST_READY;115118 else116119 wimax_state = WIMAX_ST_RADIO_OFF;120120+121121+ rfkill_set_hw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF);122122+117123 __wimax_state_change(wimax_dev, wimax_state);118118- input_report_key(wimax_dev->rfkill_input, KEY_WIMAX,119119- rfkill_state);120124 }121125error_not_ready:122126 mutex_unlock(&wimax_dev->mutex);···168174 else169175 wimax_state = WIMAX_ST_RADIO_OFF;170176 __wimax_state_change(wimax_dev, wimax_state);177177+ rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF);171178 }172179error_not_ready:173180 mutex_unlock(&wimax_dev->mutex);···244249 *245250 * NOTE: This call will block until the operation is completed.246251 */247247-static248248-int wimax_rfkill_toggle_radio(void *data, enum rfkill_state state)252252+static int wimax_rfkill_set_radio_block(void *data, bool blocked)249253{250254 int result;251255 struct wimax_dev *wimax_dev = data;252256 struct device *dev = wimax_dev_to_dev(wimax_dev);253257 enum wimax_rf_state rf_state;254258255255- d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state);256256- switch (state) {257257- case RFKILL_STATE_SOFT_BLOCKED:259259+ d_fnstart(3, dev, "(wimax_dev %p blocked %u)\n", wimax_dev, blocked);260260+ rf_state = WIMAX_RF_ON;261261+ if (blocked)258262 rf_state = WIMAX_RF_OFF;259259- break;260260- case RFKILL_STATE_UNBLOCKED:261261- rf_state = WIMAX_RF_ON;262262- break;263263- default:264264- BUG();265265- }266263 mutex_lock(&wimax_dev->mutex);267264 if (wimax_dev->state <= __WIMAX_ST_QUIESCING)268268- result = 0; /* just pretend it didn't happen */265265+ result = 0;269266 else270267 result = __wimax_rf_toggle_radio(wimax_dev, rf_state);271268 mutex_unlock(&wimax_dev->mutex);272272- d_fnend(3, dev, "(wimax_dev %p state %u) = %d\n",273273- wimax_dev, state, result);269269+ d_fnend(3, dev, "(wimax_dev %p blocked %u) = %d\n",270270+ wimax_dev, blocked, result);274271 return result;275272}276273274274+static const struct rfkill_ops wimax_rfkill_ops = {275275+ .set_block = wimax_rfkill_set_radio_block,276276+};277277278278/**279279 * wimax_rfkill - Set the software RF switch state for a WiMAX device···312322 result = __wimax_rf_toggle_radio(wimax_dev, state);313323 if (result < 0)314324 goto error;325325+ rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF);315326 break;316327 case WIMAX_RF_QUERY:317328 break;···340349{341350 int result;342351 struct rfkill *rfkill;343343- struct input_dev *input_dev;344352 struct device *dev = wimax_dev_to_dev(wimax_dev);345353346354 d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev);347355 /* Initialize RF Kill */348356 result = -ENOMEM;349349- rfkill = rfkill_allocate(dev, RFKILL_TYPE_WIMAX);357357+ rfkill = rfkill_alloc(wimax_dev->name, dev, RFKILL_TYPE_WIMAX,358358+ &wimax_rfkill_ops, wimax_dev);350359 if (rfkill == NULL)351360 goto error_rfkill_allocate;361361+362362+ d_printf(1, dev, "rfkill %p\n", rfkill);363363+352364 wimax_dev->rfkill = rfkill;353365354354- rfkill->name = wimax_dev->name;355355- rfkill->state = RFKILL_STATE_UNBLOCKED;356356- rfkill->data = wimax_dev;357357- rfkill->toggle_radio = wimax_rfkill_toggle_radio;358358-359359- /* Initialize the input device for the hw key */360360- input_dev = input_allocate_device();361361- if (input_dev == NULL)362362- goto error_input_allocate;363363- wimax_dev->rfkill_input = input_dev;364364- d_printf(1, dev, "rfkill %p input %p\n", rfkill, input_dev);365365-366366- input_dev->name = wimax_dev->name;367367- /* FIXME: get a real device bus ID and stuff? do we care? */368368- input_dev->id.bustype = BUS_HOST;369369- input_dev->id.vendor = 0xffff;370370- input_dev->evbit[0] = BIT(EV_KEY);371371- set_bit(KEY_WIMAX, input_dev->keybit);372372-373373- /* Register both */374374- result = input_register_device(wimax_dev->rfkill_input);375375- if (result < 0)376376- goto error_input_register;377366 result = rfkill_register(wimax_dev->rfkill);378367 if (result < 0)379368 goto error_rfkill_register;···365394 d_fnend(3, dev, "(wimax_dev %p) = 0\n", wimax_dev);366395 return 0;367396368368- /* if rfkill_register() suceeds, can't use rfkill_free() any369369- * more, only rfkill_unregister() [it owns the refcount]; with370370- * the input device we have the same issue--hence the if. */371397error_rfkill_register:372372- input_unregister_device(wimax_dev->rfkill_input);373373- wimax_dev->rfkill_input = NULL;374374-error_input_register:375375- if (wimax_dev->rfkill_input)376376- input_free_device(wimax_dev->rfkill_input);377377-error_input_allocate:378378- rfkill_free(wimax_dev->rfkill);398398+ rfkill_destroy(wimax_dev->rfkill);379399error_rfkill_allocate:380400 d_fnend(3, dev, "(wimax_dev %p) = %d\n", wimax_dev, result);381401 return result;···385423{386424 struct device *dev = wimax_dev_to_dev(wimax_dev);387425 d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev);388388- rfkill_unregister(wimax_dev->rfkill); /* frees */389389- input_unregister_device(wimax_dev->rfkill_input);426426+ rfkill_unregister(wimax_dev->rfkill);427427+ rfkill_destroy(wimax_dev->rfkill);390428 d_fnend(3, dev, "(wimax_dev %p)\n", wimax_dev);391429}392392-393393-394394-#else /* #ifdef CONFIG_RFKILL */395395-396396-void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,397397- enum wimax_rf_state state)398398-{399399-}400400-EXPORT_SYMBOL_GPL(wimax_report_rfkill_hw);401401-402402-void wimax_report_rfkill_sw(struct wimax_dev *wimax_dev,403403- enum wimax_rf_state state)404404-{405405-}406406-EXPORT_SYMBOL_GPL(wimax_report_rfkill_sw);407407-408408-int wimax_rfkill(struct wimax_dev *wimax_dev,409409- enum wimax_rf_state state)410410-{411411- return WIMAX_RF_ON << 1 | WIMAX_RF_ON;412412-}413413-EXPORT_SYMBOL_GPL(wimax_rfkill);414414-415415-int wimax_rfkill_add(struct wimax_dev *wimax_dev)416416-{417417- return 0;418418-}419419-420420-void wimax_rfkill_rm(struct wimax_dev *wimax_dev)421421-{422422-}423423-424424-#endif /* #ifdef CONFIG_RFKILL */425430426431427432/*
···1111#include <linux/kref.h>1212#include <linux/rbtree.h>1313#include <linux/debugfs.h>1414+#include <linux/rfkill.h>1515+#include <linux/workqueue.h>1416#include <net/genetlink.h>1517#include <net/cfg80211.h>1618#include "reg.h"···2523 * to avoid the deregister call to proceed while2624 * any call is in progress */2725 struct mutex mtx;2626+2727+ /* rfkill support */2828+ struct rfkill_ops rfkill_ops;2929+ struct rfkill *rfkill;3030+ struct work_struct rfkill_sync;28312932 /* ISO / IEC 3166 alpha2 for which this device is receiving3033 * country IEs on, this can help disregard country IEs from APs
+50-7
net/wireless/nl80211.c
···16871687 if (err)16881688 goto out_rtnl;1689168916901690+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&16911691+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {16921692+ err = -EINVAL;16931693+ goto out;16941694+ }16951695+16901696 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);16911697 if (err)16921698 goto out;···17441738 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);17451739 params.listen_interval =17461740 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);17411741+17471742 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);17431743+ if (!params.aid || params.aid > IEEE80211_MAX_AID)17441744+ return -EINVAL;17451745+17481746 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])17491747 params.ht_capa =17501748 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);···35693559 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);35703560}3571356135623562+static int nl80211_add_scan_req(struct sk_buff *msg,35633563+ struct cfg80211_registered_device *rdev)35643564+{35653565+ struct cfg80211_scan_request *req = rdev->scan_req;35663566+ struct nlattr *nest;35673567+ int i;35683568+35693569+ if (WARN_ON(!req))35703570+ return 0;35713571+35723572+ nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);35733573+ if (!nest)35743574+ goto nla_put_failure;35753575+ for (i = 0; i < req->n_ssids; i++)35763576+ NLA_PUT(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid);35773577+ nla_nest_end(msg, nest);35783578+35793579+ nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);35803580+ if (!nest)35813581+ goto nla_put_failure;35823582+ for (i = 0; i < req->n_channels; i++)35833583+ NLA_PUT_U32(msg, i, req->channels[i]->center_freq);35843584+ nla_nest_end(msg, nest);35853585+35863586+ if (req->ie)35873587+ NLA_PUT(msg, NL80211_ATTR_IE, req->ie_len, req->ie);35883588+35893589+ return 0;35903590+ nla_put_failure:35913591+ return -ENOBUFS;35923592+}35933593+35723594static int nl80211_send_scan_donemsg(struct sk_buff *msg,35733573- struct cfg80211_registered_device *rdev,35743574- struct net_device *netdev,35753575- u32 pid, u32 seq, int flags,35763576- u32 cmd)35953595+ struct cfg80211_registered_device *rdev,35963596+ struct net_device *netdev,35973597+ u32 pid, u32 seq, int flags,35983598+ u32 cmd)35773599{35783600 void *hdr;35793601···36163574 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);36173575 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);3618357636193619- /* XXX: we should probably bounce back the request? */35773577+ /* ignore errors and send incomplete event anyway */35783578+ nl80211_add_scan_req(msg, rdev);3620357936213580 return genlmsg_end(msg, hdr);36223581···38713828 struct sk_buff *msg;38723829 void *hdr;3873383038743874- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);38313831+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);38753832 if (!msg)38763833 return;38773834···38953852 return;38963853 }3897385438983898- genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL);38553855+ genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);38993856 return;3900385739013858 nla_put_failure:
+7-1
net/wireless/reg.c
···21712171 * the country IE rd with what CRDA believes that country should have21722172 */2173217321742174- BUG_ON(!country_ie_regdomain);21742174+ /*21752175+ * Userspace could have sent two replies with only21762176+ * one kernel request. By the second reply we would have21772177+ * already processed and consumed the country_ie_regdomain.21782178+ */21792179+ if (!country_ie_regdomain)21802180+ return -EALREADY;21752181 BUG_ON(rd == country_ie_regdomain);2176218221772183 /*