Word count: 1409, reading time approximately 8 minutes
Linux Wireless RFKill Subsystem
About RFKill
The rfkill subsystem provides a generic interface for 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.
The rfkill subsystem has a concept of “hard” and “soft” block, which differ little in their meaning (block == transmitters off) but rather in whether they can be changed or not:
• hard block read-only radio block that cannot be overridden by software • soft block writable radio block (need not be readable) that is set by the system software. The rfkill subsystem has two parameters,
<span>rfkill.default_state</span>
and<span>rfkill.master_switch_mode</span>
, which are documented in admin-guide/kernel-parameters.rst.
The rfkill subsystem provides a generic interface for disabling any radio transmitter in the system. When a transmitter is blocked, it should 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. The rfkill subsystem has a concept of “hard” and “soft” block, which differ little in their meaning (block == transmitters off) but rather in whether they can be changed or not:
-
• Hard block is a read-only radio block that cannot be overridden by software. -
• Soft block is a writable radio block (need not be readable) that is set by the system software.
The rfkill subsystem has two parameters, <span>rfkill.default_state</span>
and <span>rfkill.master_switch_mode</span>
, which are documented in <span>admin-guide/kernel-parameters.rst</span>
.
Main Implementation
<span>rfkill</span>
subsystem consists of three main components:
-
• rfkill core ( <span>net/rfkill/core.c</span>
) -
• Deprecated rfkill-input module ( <span>net/rfkill/input.c</span>
an input layer handler being replaced by user space policy code) -
• rfkill drivers (various wireless subsystems and custom drivers)
<span>rfkill</span>
core provides the API for registering rfkill for kernel drivers, methods to enable and disable it, and informs the system about the possible hardware disable states on the device.
<span>rfkill</span>
core code also informs user space of state changes and provides methods for user space to query the current state. See the “down” section below for details.
When a device is hard blocked (obtained by calling <span>rfkill_set_hw_state()</span>
or from <span>query_hw_block</span>
), <span>set_block()</span>
will be called for additional software blocking, but drivers can ignore this method call since they can synchronize the software state using the return value of the <span>rfkill_set_hw_state()</span><code><span> function instead of tracking calls to </span><code><span>set_block()</span><code><span>. In fact, unless hardware actually tracks soft and hard blocking separately, drivers should use the return value of </span><code><span>rfkill_set_hw_state()</span><code><span>.</span>
Down
How does RFKill control various wireless devices?
In various wireless device drivers, such as Bluetooth, Wi-Fi, etc., the rfkill interface is implemented to control the enabling and disabling of the devices.
For example, in the Bluetooth subsystem <span>net/bluetooth/hci_core.c</span>
, in the wireless subsystem <span>net/wireless/core.c</span>
, in the NFC subsystem <span>net/nfc/core.c</span>
, or in custom implementations,
it is sufficient to register the rfkill device using <span>rfkill_alloc</span>
and <span>rfkill_register</span>
, and then essentially implement the <span>rfkill_ops</span>
operation set’s <span>.set_block</span>
interface, where specific power management operations can be performed to power down the device. When <span>rfkill_set_block</span>
is called, it invokes this interface of the specific device to control the enabling and disabling of the device.
Up
The recommended user space interface is <span>/dev/rfkill</span>
, which is a miscellaneous character device allowing user space to get and set the status of <span>rfkill</span>
devices and device groups. It also notifies user space of device addition and removal. This API is a simple read/write API defined in <span>linux/rfkill.h</span>
, containing an <span>ioctl</span>
to close the deprecated input handler in the kernel during the transition period.
In addition to this <span>ioctl</span>
, communication with the kernel is also done by reading and writing instances of <span>struct rfkill_event</span>
. In this structure, soft and hard blocks are properly separated (unlike <span>sysfs</span>
, see below), allowing user space to obtain a consistent snapshot of all <span>rfkill</span>
devices in the system. Additionally, all <span>rfkill</span>
drivers (or all drivers of a specified type) can be switched to a state, which will also update the default state of hot-plug devices.
Applications opening <span>/dev/rfkill</span>
can read the current status of all devices. They can poll the descriptor for hot-plug or status change events, or listen for <span>uevents</span>
emitted by the rfkill core framework to get changes.
Furthermore, each <span>rfkill</span>
device is registered in <span>sysfs</span>
and can emit <span>uevents</span>
events.
<span>rfkill</span>
devices emit <span>uevents</span>
(action as <span>"change"</span>
) that set the following environment variables:
RFKILL_NAME
RFKILL_STATE
RFKILL_TYPE
The contents of these variables correspond to the <span>"name"</span>
, <span>"state"</span>
, and <span>"type"</span>
sysfs files explained above.
For more details, see <span>Documentation/ABI/stable/sysfs-class-rfkill</span>
.
Basic Usage
Linux provides the rfkill command line tool to manage the state of radio frequency devices.
Common commands are as follows:
# List all RF devices and their status
rfkill list
# Disable a specific device (e.g., Bluetooth):
rfkill block bluetooth
# Enable a specific device (e.g., Wi-Fi):
rfkill unblock wifi
# Disable or enable all devices:
rfkill block all
rfkill unblock all
Main Application Scenarios
-
1. Physical wireless switch on laptops: When the user presses the wireless switch on the laptop, hardware triggers a hard block, and the RFKill core disables all wireless devices. -
2. Airplane mode: User space tools (like NetworkManager) disable all RF devices via the RFKill interface to simulate airplane mode. -
3. Power-saving mode: Disable wireless devices to save power when the system is in sleep or low battery state.
References
-
• https://www.kernel.org/doc/html/latest/driver-api/rfkill.html -
• Documentation path: <span>Documentation/driver-api/rfkill.rst</span>
Welcome to follow:
For more, please click the lower left corner Read the original text!