mirror of https://gitee.com/openkylin/linux.git
137 lines
5.0 KiB
Plaintext
137 lines
5.0 KiB
Plaintext
rfkill - RF kill switch support
|
|
===============================
|
|
|
|
1. Introduction
|
|
2. Implementation details
|
|
3. Kernel driver guidelines
|
|
4. Kernel API
|
|
5. Userspace support
|
|
|
|
|
|
1. Introduction
|
|
|
|
The rfkill subsystem provides a generic interface to disabling any radio
|
|
transmitter in the system. When a transmitter is blocked, it shall not
|
|
radiate any power.
|
|
|
|
The subsystem also provides the ability to react on button presses and
|
|
disable all transmitters of a certain type (or all). This is intended for
|
|
situations where transmitters need to be turned off, for example on
|
|
aircraft.
|
|
|
|
|
|
|
|
2. Implementation details
|
|
|
|
The rfkill subsystem is composed of various components: the rfkill class, the
|
|
rfkill-input module (an input layer handler), and some specific input layer
|
|
events.
|
|
|
|
The rfkill class is provided for kernel drivers to register their radio
|
|
transmitter with the kernel, provide methods for turning it on and off and,
|
|
optionally, letting the system know about hardware-disabled states that may
|
|
be implemented on the device. This code is enabled with the CONFIG_RFKILL
|
|
Kconfig option, which drivers can "select".
|
|
|
|
The rfkill class code also notifies userspace of state changes, this is
|
|
achieved via uevents. It also provides some sysfs files for userspace to
|
|
check the status of radio transmitters. See the "Userspace support" section
|
|
below.
|
|
|
|
|
|
The rfkill-input code implements a basic response to rfkill buttons -- it
|
|
implements turning on/off all devices of a certain class (or all).
|
|
|
|
When the device is hard-blocked (either by a call to rfkill_set_hw_state()
|
|
or from query_hw_block) set_block() will be invoked but drivers can well
|
|
ignore the method call since they can use the return value of the function
|
|
rfkill_set_hw_state() to sync the software state instead of keeping track
|
|
of calls to set_block().
|
|
|
|
|
|
The entire functionality is spread over more than one subsystem:
|
|
|
|
* The kernel input layer generates KEY_WWAN, KEY_WLAN etc. and
|
|
SW_RFKILL_ALL -- when the user presses a button. Drivers for radio
|
|
transmitters generally do not register to the input layer, unless the
|
|
device really provides an input device (i.e. a button that has no
|
|
effect other than generating a button press event)
|
|
|
|
* The rfkill-input code hooks up to these events and switches the soft-block
|
|
of the various radio transmitters, depending on the button type.
|
|
|
|
* The rfkill drivers turn off/on their transmitters as requested.
|
|
|
|
* The rfkill class will generate userspace notifications (uevents) to tell
|
|
userspace what the current state is.
|
|
|
|
|
|
|
|
3. Kernel driver guidelines
|
|
|
|
|
|
Drivers for radio transmitters normally implement only the rfkill class.
|
|
These drivers may not unblock the transmitter based on own decisions, they
|
|
should act on information provided by the rfkill class only.
|
|
|
|
Platform drivers might implement input devices if the rfkill button is just
|
|
that, a button. If that button influences the hardware then you need to
|
|
implement an rfkill class instead. This also applies if the platform provides
|
|
a way to turn on/off the transmitter(s).
|
|
|
|
During suspend/hibernation, transmitters should only be left enabled when
|
|
wake-on wlan or similar functionality requires it and the device wasn't
|
|
blocked before suspend/hibernate. Note that it may be necessary to update
|
|
the rfkill subsystem's idea of what the current state is at resume time if
|
|
the state may have changed over suspend.
|
|
|
|
|
|
|
|
4. Kernel API
|
|
|
|
To build a driver with rfkill subsystem support, the driver should depend on
|
|
(or select) the Kconfig symbol RFKILL.
|
|
|
|
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).
|
|
|
|
Calling rfkill_set_hw_state() when a state change happens is required from
|
|
rfkill drivers that control devices that can be hard-blocked unless they also
|
|
assign the poll_hw_block() callback (then the rfkill core will poll the
|
|
device). Don't do this unless you cannot get the event in any other way.
|
|
|
|
|
|
|
|
5. Userspace support
|
|
|
|
The following sysfs entries exist for every rfkill device:
|
|
|
|
name: Name assigned by driver to this key (interface or driver name).
|
|
type: Name of the key type ("wlan", "bluetooth", etc).
|
|
state: Current state of the transmitter
|
|
0: RFKILL_STATE_SOFT_BLOCKED
|
|
transmitter is turned off by software
|
|
1: RFKILL_STATE_UNBLOCKED
|
|
transmitter is (potentially) active
|
|
2: RFKILL_STATE_HARD_BLOCKED
|
|
transmitter is forced off by something outside of
|
|
the driver's control.
|
|
claim: 0: Kernel handles events (currently always reads that value)
|
|
|
|
rfkill devices also issue uevents (with an action of "change"), with the
|
|
following environment variables set:
|
|
|
|
RFKILL_NAME
|
|
RFKILL_STATE
|
|
RFKILL_TYPE
|
|
|
|
The contents of these variables corresponds to the "name", "state" and
|
|
"type" sysfs files explained above.
|
|
|
|
An alternative userspace interface exists as a misc device /dev/rfkill,
|
|
which allows userspace to obtain and set the state of rfkill devices and
|
|
sets of devices. It also notifies userspace about device addition and
|
|
removal. The API is a simple read/write API that is defined in
|
|
linux/rfkill.h.
|