]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - Documentation/rfkill.txt
rfkill: document rw rfkill switches and clarify input subsystem interactions
[karo-tx-linux.git] / Documentation / rfkill.txt
index ec75d6d3478538cd2d92df0203cd5c90f5620bf4..cf230c1ad9efe9ea7dc26dc7fd36113d9d3a0824 100644 (file)
 rfkill - RF switch subsystem support
 ====================================
 
-1 Implementation details
-2 Driver support
-3 Userspace support
+1 Introduction
+2 Implementation details
+3 Kernel driver guidelines
+4 Kernel API
+5 Userspace support
 
-===============================================================================
-1: Implementation details
+
+1. Introduction:
 
 The rfkill switch subsystem exists to add a generic interface to circuitry that
-can enable or disable the RF output of a radio *transmitter* of any type.
+can enable or disable the signal output of a wireless *transmitter* of any
+type.  By far, the most common use is to disable radio-frequency transmitters.
 
-When a rfkill switch is in the RFKILL_STATE_ON, the radio transmitter is
-*enabled*.  When the rfkill switch is in the RFKILL_STATE_OFF, the radio
-transmitter is *disabled*.
+The rfkill switch subsystem offers support for keys and switches often found on
+laptops to enable wireless devices like WiFi and Bluetooth to actually perform
+an action.
 
-The rfkill switch subsystem offers support for keys often found on laptops
-to enable wireless devices like WiFi and Bluetooth.
+The buttons to enable and disable the wireless transmitters are important in
+situations where the user is for example using his laptop on a location where
+radio-frequency transmitters _must_ be disabled (e.g. airplanes).
 
-This is done by providing the user 3 possibilities:
- 1 - The rfkill system handles all events; userspace is not aware of events.
- 2 - The rfkill system handles all events; userspace is informed about the events.
- 3 - The rfkill system does not handle events; userspace handles all events.
+Because of this requirement, userspace support for the keys should not be made
+mandatory.  Because userspace might want to perform some additional smarter
+tasks when the key is pressed, rfkill provides userspace the possibility to
+take over the task to handle the key events.
 
-The buttons to enable and disable the wireless radios are important in
-situations where the user is for example using his laptop on a location where
-wireless radios _must_ be disabled (e.g. airplanes).
-Because of this requirement, userspace support for the keys should not be
-made mandatory. Because userspace might want to perform some additional smarter
-tasks when the key is pressed, rfkill still provides userspace the possibility
-to take over the task to handle the key events.
+===============================================================================
+2: Implementation details
+
+The rfkill class provides kernel drivers with an interface that allows them to
+know when they should enable or disable a wireless network device transmitter.
+
+The rfkill-input module provides the kernel with the ability to implement a
+basic response when the user presses a key or button (or toggles a switch)
+related to rfkill functionality.  It is an in-kernel implementation of default
+policy of reacting to rfkill-related input events and neither mandatory nor
+required for wireless drivers to operate.
+
+The rfkill-input module also provides EPO (emergency power-off) functionality
+for all wireless transmitters.  This function cannot be overriden, and it is
+always active.  rfkill EPO is related to *_RFKILL_ALL input events.
+
+All state changes on rfkill devices are propagated by the rfkill class to a
+notification chain and also to userspace through uevents.
 
 The system inside the kernel has been split into 2 separate sections:
        1 - RFKILL
        2 - RFKILL_INPUT
 
-The first option enables rfkill support and will make sure userspace will
-be notified of any events through the input device. It also creates several
-sysfs entries which can be used by userspace. See section "Userspace support".
+The first option enables rfkill support and will make sure userspace will be
+notified of any events through uevents.  It provides a notification chain for
+interested parties in the kernel to also get notified of rfkill state changes
+in other drivers.  It creates several sysfs entries which can be used by
+userspace.  See section "Userspace support".
+
+The second option provides an rfkill input handler. This handler will listen to
+all rfkill key events and will toggle the radio accordingly.  With this option
+enabled userspace could either do nothing or simply perform monitoring tasks.
+
+When a rfkill switch is in the RFKILL_STATE_ON, the wireless transmitter (radio
+TX circuit for example) is *enabled*.  When the rfkill switch is in the
+RFKILL_STATE_OFF, the wireless transmitter is to be *blocked* from operating.
+
+Full rfkill functionality requires two different subsystems to cooperate: the
+input layer and the rfkill class.  The input layer issues *commands* to the
+entire system requesting that devices registered to the rfkill class change
+state.  The way this interaction happens is not complex, but it is not obvious
+either:
+
+Kernel Input layer:
+
+       * Generates KEY_WWAN, KEY_WLAN, KEY_BLUETOOTH, SW_RFKILL_ALL, and
+         other such events when the user presses certain keys, buttons, or
+         toggles certain physical switches.
+
+       THE INPUT LAYER IS NEVER USED TO PROPAGATE STATUS, NOTIFICATIONS OR THE
+       KIND OF STUFF AN ON-SCREEN-DISPLAY APPLICATION WOULD REPORT.  It is
+       used to issue *commands* for the system to change behaviour, and these
+       commands may or may not be carried out by some kernel driver or
+       userspace application.  It follows that doing user feedback based only
+       on input events is broken, there is no guarantee that an input event
+       will be acted upon.
+
+       Most wireless communication device drivers implementing rfkill
+       functionality MUST NOT generate these events, and have no reason to
+       register themselves with the input layer.  This is a common
+       misconception.  There is an API to propagate rfkill status change
+       information, and it is NOT the input layer.
+
+rfkill class:
+
+       * Calls a hook in a driver to effectively change the wireless
+         transmitter state;
+       * Keeps track of the wireless transmitter state (with help from
+         the driver);
+       * Generates userspace notifications (uevents) and a call to a
+         notification chain (kernel) when there is a wireless transmitter
+         state change;
+       * Connects a wireless communications driver with the common rfkill
+         control system, which, for example, allows actions such as
+         "switch all bluetooth devices offline" to be carried out by
+         userspace or by rfkill-input.
+
+       THE RFKILL CLASS NEVER ISSUES INPUT EVENTS.  THE RFKILL CLASS DOES
+       NOT LISTEN TO INPUT EVENTS.  NO DRIVER USING THE RFKILL CLASS SHALL
+       EVER LISTEN TO, OR ACT ON RFKILL INPUT EVENTS.
+
+       Most wireless data communication drivers in the kernel have just to
+       implement the rfkill class API to work properly.  Interfacing to the
+       input layer is not often required (and is very often a *bug*).
+
+Userspace input handlers (uevents) or kernel input handlers (rfkill-input):
+
+       * Implements the policy of what should happen when one of the input
+         layer events related to rfkill operation is received.
+       * Uses the sysfs interface (userspace) or private rfkill API calls
+         to tell the devices registered with the rfkill class to change
+         their state (i.e. translates the input layer event into real
+         action).
+       * rfkill-input implements EPO by handling EV_SW SW_RFKILL_ALL 0
+         (power off all transmitters) in a special way: it ignores any
+         overrides and local state cache and forces all transmitters to
+         the OFF state (including those which are already supposed to be
+         OFF).  Note that the opposite event (power on all transmitters)
+         is handled normally.
+
+Userspace uevent handler or kernel platform-specific drivers hooked to the
+rfkill notifier chain:
+
+       * Taps into the rfkill notifier chain or to KOBJ_CHANGE uevents,
+         in order to know when a device that is registered with the rfkill
+         class changes state;
+       * Issues feedback notifications to the user;
+       * In the rare platforms where this is required, synthesizes an input
+         event to command all *OTHER* rfkill devices to also change their
+         statues when a specific rfkill device changes state.
+
+
+===============================================================================
+3: Kernel driver guidelines
+
+The first thing one needs to know is whether his driver should be talking to
+the rfkill class or to the input layer.
+
+Do not mistake input devices for rfkill devices.  The only type of "rfkill
+switch" device that is to be registered with the rfkill class are those
+directly controlling the circuits that cause a wireless transmitter to stop
+working (or the software equivalent of them).  Every other kind of "rfkill
+switch" is just an input device and MUST NOT be registered with the rfkill
+class.
+
+A driver should register a device with the rfkill class when ALL of the
+following conditions are met:
+
+1. The device is/controls a data communications wireless transmitter;
+
+2. The kernel can interact with the hardware/firmware to CHANGE the wireless
+   transmitter state (block/unblock TX operation);
+
+A driver should register a device with the input subsystem to issue
+rfkill-related events (KEY_WLAN, KEY_BLUETOOTH, KEY_WWAN, KEY_WIMAX,
+SW_RFKILL_ALL, etc) when ALL of the folowing conditions are met:
+
+1. It is directly related to some physical device the user interacts with, to
+   command the O.S./firmware/hardware to enable/disable a data communications
+   wireless transmitter.
+
+   Examples of the physical device are: buttons, keys and switches the user
+   will press/touch/slide/switch to enable or disable the wireless
+   communication device.
+
+2. It is NOT slaved to another device, i.e. there is no other device that
+   issues rfkill-related input events in preference to this one.
+
+   Typically, the ACPI "radio kill" switch of a laptop is the master input
+   device to issue rfkill events, and, e.g., the WLAN card is just a slave
+   device that gets disabled by its hardware radio-kill input pin.
 
-The second option provides an rfkill input handler. This handler will
-listen to all rfkill key events and will toggle the radio accordingly.
-With this option enabled userspace could either do nothing or simply
-perform monitoring tasks.
+When in doubt, do not issue input events.  For drivers that should generate
+input events in some platforms, but not in others (e.g. b43), the best solution
+is to NEVER generate input events in the first place.  That work should be
+deferred to a platform-specific kernel module (which will know when to generate
+events through the rfkill notifier chain) or to userspace.  This avoids the
+usual maintenance problems with DMI whitelisting.
 
+
+Corner cases and examples:
 ====================================
-2: Driver support
 
-To build a driver with rfkill subsystem support, the driver should
-depend on the Kconfig symbol RFKILL; it should _not_ depend on
-RKFILL_INPUT.
+1. If the device is an input device that, because of hardware or firmware,
+causes wireless transmitters to be blocked regardless of the kernel's will, it
+is still just an input device, and NOT to be registered with the rfkill class.
 
-Unless key events trigger an interrupt to which the driver listens, polling
-will be required to determine the key state changes. For this the input
-layer providers the input-polldev handler.
+2. If the wireless transmitter switch control is read-only, it is an input
+device and not to be registered with the rfkill class (and maybe not to be made
+an input layer event source either, see below).
 
-A driver should implement a few steps to correctly make use of the
-rfkill subsystem. First for non-polling drivers:
+3. If there is some other device driver *closer* to the actual hardware the
+user interacted with (the button/switch/key) to issue an input event, THAT is
+the device driver that should be issuing input events.
 
-       - rfkill_allocate()
-       - input_allocate_device()
-       - rfkill_register()
-       - input_register_device()
+E.g:
+  [RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input]
+                           (platform driver)    (wireless card driver)
+
+The user is closer to the RFKILL slide switch plaform driver, so the driver
+which must issue input events is the platform driver looking at the GPIO
+hardware, and NEVER the wireless card driver (which is just a slave).  It is
+very likely that there are other leaves than just the WLAN card rf-kill input
+(e.g. a bluetooth card, etc)...
+
+On the other hand, some embedded devices do this:
+
+  [RFKILL slider switch] -- [WLAN card rf-kill input]
+                             (wireless card driver)
+
+In this situation, the wireless card driver *could* register itself as an input
+device and issue rf-kill related input events... but in order to AVOID the need
+for DMI whitelisting, the wireless card driver does NOT do it.  Userspace (HAL)
+or a platform driver (that exists only on these embedded devices) will do the
+dirty job of issuing the input events.
+
+
+COMMON MISTAKES in kernel drivers, related to rfkill:
+====================================
+
+1. NEVER confuse input device keys and buttons with input device switches.
+
+  1a. Switches are always set or reset.  They report the current state
+      (on position or off position).
+
+  1b. Keys and buttons are either in the pressed or not-pressed state, and
+      that's it.  A "button" that latches down when you press it, and
+      unlatches when you press it again is in fact a switch as far as input
+      devices go.
+
+Add the SW_* events you need for switches, do NOT try to emulate a button using
+KEY_* events just because there is no such SW_* event yet.  Do NOT try to use,
+for example, KEY_BLUETOOTH when you should be using SW_BLUETOOTH instead.
+
+2. Input device switches (sources of EV_SW events) DO store their current
+state, and that state CAN be queried from userspace through IOCTLs.  There is
+no sysfs interface for this, but that doesn't mean you should break things
+trying to hook it to the rfkill class to get a sysfs interface :-)
+
+3. Do not issue *_RFKILL_ALL events, unless you are sure it is the correct
+event for your switch/button.  These events are emergency power-off events when
+they are trying to turn the transmitters off.  An example of an input device
+which SHOULD generate *_RFKILL_ALL events is the wireless-kill switch in a
+laptop which is NOT a hotkey, but a real switch that kills radios in hardware,
+even if the O.S. has gone to lunch.  An example of an input device which SHOULD
+NOT generate *_RFKILL_ALL events is any sort of hot key that does nothing by
+itself, as well as any hot key that is type-specific (e.g. the one for WLAN).
+
+
+===============================================================================
+4: Kernel API
+
+To build a driver with rfkill subsystem support, the driver should depend on
+the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.
+
+The hardware the driver talks to may be write-only (where the current state
+of the hardware is unknown), or read-write (where the hardware can be queried
+about its current state).
+
+The rfkill class will call the get_state hook of a device every time it needs
+to know the *real* current state of the hardware.  This can happen often.
+
+Some hardware provides events when its status changes.  In these cases, it is
+best for the driver to not provide a get_state hook, and instead register the
+rfkill class *already* with the correct status, and keep it updated using
+rfkill_force_state() when it gets an event from the hardware.
 
-For polling drivers:
+There is no provision for a statically-allocated rfkill struct.  You must
+use rfkill_allocate() to allocate one.
 
+You should:
        - rfkill_allocate()
-       - input_allocate_polled_device()
+       - modify rfkill fields (flags, name)
+       - modify state to the current hardware state (THIS IS THE ONLY TIME
+         YOU CAN ACCESS state DIRECTLY)
        - rfkill_register()
-       - input_register_polled_device()
 
-When a key event has been detected, the correct event should be
-sent over the input device which has been registered by the driver.
+Please refer to the source for more documentation.
 
-====================================
-3: Userspace support
+===============================================================================
+5: Userspace support
+
+rfkill devices issue uevents (with an action of "change"), with the following
+environment variables set:
+
+RFKILL_NAME
+RFKILL_STATE
+RFKILL_TYPE
 
-For each key an input device will be created which will send out the correct
-key event when the rfkill key has been pressed.
+The ABI for these variables is defined by the sysfs attributes.  It is best
+to take a quick look at the source to make sure of the possible values.
+
+It is expected that HAL will trap those, and bridge them to DBUS, etc.  These
+events CAN and SHOULD be used to give feedback to the user about the rfkill
+status of the system.
+
+Input devices may issue events that are related to rfkill.  These are the
+various KEY_* events and SW_* events supported by rfkill-input.c.
+
+******IMPORTANT******
+When rfkill-input is ACTIVE, userspace is NOT TO CHANGE THE STATE OF AN RFKILL
+SWITCH IN RESPONSE TO AN INPUT EVENT also handled by rfkill-input, unless it
+has set to true the user_claim attribute for that particular switch.  This rule
+is *absolute*; do NOT violate it.
+******IMPORTANT******
+
+Userspace must not assume it is the only source of control for rfkill switches.
+Their state CAN and WILL change on its own, due to firmware actions, direct
+user actions, and the rfkill-input EPO override for *_RFKILL_ALL.
+
+When rfkill-input is not active, userspace must initiate an rfkill status
+change by writing to the "state" attribute in order for anything to happen.
+
+Take particular care to implement EV_SW SW_RFKILL_ALL properly.  When that
+switch is set to OFF, *every* rfkill device *MUST* be immediately put into the
+OFF state, no questions asked.
 
 The following sysfs entries will be created:
 
@@ -87,10 +332,18 @@ The following sysfs entries will be created:
        claim: 1: Userspace handles events, 0: Kernel handles events
 
 Both the "state" and "claim" entries are also writable. For the "state" entry
-this means that when 1 or 0 is written all radios, not yet in the requested
-state, will be will be toggled accordingly.
+this means that when 1 or 0 is written, the device rfkill state (if not yet in
+the requested state), will be will be toggled accordingly.
+
 For the "claim" entry writing 1 to it means that the kernel no longer handles
 key events even though RFKILL_INPUT input was enabled. When "claim" has been
 set to 0, userspace should make sure that it listens for the input events or
-check the sysfs "state" entry regularly to correctly perform the required
-tasks when the rkfill key is pressed.
+check the sysfs "state" entry regularly to correctly perform the required tasks
+when the rkfill key is pressed.
+
+A note about input devices and EV_SW events:
+
+In order to know the current state of an input device switch (like
+SW_RFKILL_ALL), you will need to use an IOCTL.  That information is not
+available through sysfs in a generic way at this time, and it is not available
+through the rfkill class AT ALL.