Linux Wireless RFKill Subsystem

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. 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. 2. Airplane mode: User space tools (like NetworkManager) disable all RF devices via the RFKill interface to simulate airplane mode.
  3. 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:

Welcome to add WeChat to join the group for communication:

Linux Wireless RFKill Subsystem

For more, please click the lower left corner Read the original text!

Leave a Comment