Commit ce0879e324df007f12cc25227102847b92fcafb7
Committed by
John W. Linville
1 parent
7e9debe978
Exists in
master
and in
7 other branches
rfkill: improve docs
Now that the dust has settled a bit, improve the docs on rfkill and include more information about /dev/rfkill. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Showing 1 changed file with 69 additions and 68 deletions Side-by-side Diff
Documentation/rfkill.txt
... | ... | @@ -3,9 +3,8 @@ |
3 | 3 | |
4 | 4 | 1. Introduction |
5 | 5 | 2. Implementation details |
6 | -3. Kernel driver guidelines | |
7 | -4. Kernel API | |
8 | -5. Userspace support | |
6 | +3. Kernel API | |
7 | +4. Userspace support | |
9 | 8 | |
10 | 9 | |
11 | 10 | 1. Introduction |
12 | 11 | |
13 | 12 | |
14 | 13 | |
15 | 14 | |
16 | 15 | |
17 | 16 | |
18 | 17 | |
19 | 18 | |
20 | 19 | |
21 | 20 | |
22 | 21 | |
23 | 22 | |
24 | 23 | |
25 | 24 | |
26 | 25 | |
... | ... | @@ -19,83 +18,63 @@ |
19 | 18 | situations where transmitters need to be turned off, for example on |
20 | 19 | aircraft. |
21 | 20 | |
21 | +The rfkill subsystem has a concept of "hard" and "soft" block, which | |
22 | +differ little in their meaning (block == transmitters off) but rather in | |
23 | +whether they can be changed or not: | |
24 | + - hard block: read-only radio block that cannot be overriden by software | |
25 | + - soft block: writable radio block (need not be readable) that is set by | |
26 | + the system software. | |
22 | 27 | |
23 | 28 | |
24 | 29 | 2. Implementation details |
25 | 30 | |
26 | -The rfkill subsystem is composed of various components: the rfkill class, the | |
27 | -rfkill-input module (an input layer handler), and some specific input layer | |
28 | -events. | |
31 | +The rfkill subsystem is composed of three main components: | |
32 | + * the rfkill core, | |
33 | + * the deprecated rfkill-input module (an input layer handler, being | |
34 | + replaced by userspace policy code) and | |
35 | + * the rfkill drivers. | |
29 | 36 | |
30 | -The rfkill class is provided for kernel drivers to register their radio | |
31 | -transmitter with the kernel, provide methods for turning it on and off and, | |
32 | -optionally, letting the system know about hardware-disabled states that may | |
33 | -be implemented on the device. This code is enabled with the CONFIG_RFKILL | |
34 | -Kconfig option, which drivers can "select". | |
37 | +The rfkill core provides API for kernel drivers to register their radio | |
38 | +transmitter with the kernel, methods for turning it on and off and, letting | |
39 | +the system know about hardware-disabled states that may be implemented on | |
40 | +the device. | |
35 | 41 | |
36 | -The rfkill class code also notifies userspace of state changes, this is | |
37 | -achieved via uevents. It also provides some sysfs files for userspace to | |
38 | -check the status of radio transmitters. See the "Userspace support" section | |
39 | -below. | |
42 | +The rfkill core code also notifies userspace of state changes, and provides | |
43 | +ways for userspace to query the current states. See the "Userspace support" | |
44 | +section below. | |
40 | 45 | |
41 | - | |
42 | -The rfkill-input code implements a basic response to rfkill buttons -- it | |
43 | -implements turning on/off all devices of a certain class (or all). | |
44 | - | |
45 | 46 | When the device is hard-blocked (either by a call to rfkill_set_hw_state() |
46 | -or from query_hw_block) set_block() will be invoked but drivers can well | |
47 | -ignore the method call since they can use the return value of the function | |
48 | -rfkill_set_hw_state() to sync the software state instead of keeping track | |
49 | -of calls to set_block(). | |
47 | +or from query_hw_block) set_block() will be invoked for additional software | |
48 | +block, but drivers can ignore the method call since they can use the return | |
49 | +value of the function rfkill_set_hw_state() to sync the software state | |
50 | +instead of keeping track of calls to set_block(). In fact, drivers should | |
51 | +use the return value of rfkill_set_hw_state() unless the hardware actually | |
52 | +keeps track of soft and hard block separately. | |
50 | 53 | |
51 | 54 | |
52 | -The entire functionality is spread over more than one subsystem: | |
55 | +3. Kernel API | |
53 | 56 | |
54 | - * The kernel input layer generates KEY_WWAN, KEY_WLAN etc. and | |
55 | - SW_RFKILL_ALL -- when the user presses a button. Drivers for radio | |
56 | - transmitters generally do not register to the input layer, unless the | |
57 | - device really provides an input device (i.e. a button that has no | |
58 | - effect other than generating a button press event) | |
59 | 57 | |
60 | - * The rfkill-input code hooks up to these events and switches the soft-block | |
61 | - of the various radio transmitters, depending on the button type. | |
58 | +Drivers for radio transmitters normally implement an rfkill driver. | |
62 | 59 | |
63 | - * The rfkill drivers turn off/on their transmitters as requested. | |
64 | - | |
65 | - * The rfkill class will generate userspace notifications (uevents) to tell | |
66 | - userspace what the current state is. | |
67 | - | |
68 | - | |
69 | - | |
70 | -3. Kernel driver guidelines | |
71 | - | |
72 | - | |
73 | -Drivers for radio transmitters normally implement only the rfkill class. | |
74 | -These drivers may not unblock the transmitter based on own decisions, they | |
75 | -should act on information provided by the rfkill class only. | |
76 | - | |
77 | 60 | Platform drivers might implement input devices if the rfkill button is just |
78 | 61 | that, a button. If that button influences the hardware then you need to |
79 | -implement an rfkill class instead. This also applies if the platform provides | |
62 | +implement an rfkill driver instead. This also applies if the platform provides | |
80 | 63 | a way to turn on/off the transmitter(s). |
81 | 64 | |
82 | -During suspend/hibernation, transmitters should only be left enabled when | |
83 | -wake-on wlan or similar functionality requires it and the device wasn't | |
84 | -blocked before suspend/hibernate. Note that it may be necessary to update | |
85 | -the rfkill subsystem's idea of what the current state is at resume time if | |
86 | -the state may have changed over suspend. | |
65 | +For some platforms, it is possible that the hardware state changes during | |
66 | +suspend/hibernation, in which case it will be necessary to update the rfkill | |
67 | +core with the current state is at resume time. | |
87 | 68 | |
69 | +To create an rfkill driver, driver's Kconfig needs to have | |
88 | 70 | |
71 | + depends on RFKILL || !RFKILL | |
89 | 72 | |
90 | -4. Kernel API | |
73 | +to ensure the driver cannot be built-in when rfkill is modular. The !RFKILL | |
74 | +case allows the driver to be built when rfkill is not configured, which which | |
75 | +case all rfkill API can still be used but will be provided by static inlines | |
76 | +which compile to almost nothing. | |
91 | 77 | |
92 | -To build a driver with rfkill subsystem support, the driver should depend on | |
93 | -(or select) the Kconfig symbol RFKILL. | |
94 | - | |
95 | -The hardware the driver talks to may be write-only (where the current state | |
96 | -of the hardware is unknown), or read-write (where the hardware can be queried | |
97 | -about its current state). | |
98 | - | |
99 | 78 | Calling rfkill_set_hw_state() when a state change happens is required from |
100 | 79 | rfkill drivers that control devices that can be hard-blocked unless they also |
101 | 80 | assign the poll_hw_block() callback (then the rfkill core will poll the |
102 | 81 | |
103 | 82 | |
... | ... | @@ -105,10 +84,33 @@ |
105 | 84 | |
106 | 85 | 5. Userspace support |
107 | 86 | |
108 | -The following sysfs entries exist for every rfkill device: | |
87 | +The recommended userspace interface to use is /dev/rfkill, which is a misc | |
88 | +character device that allows userspace to obtain and set the state of rfkill | |
89 | +devices and sets of devices. It also notifies userspace about device addition | |
90 | +and removal. The API is a simple read/write API that is defined in | |
91 | +linux/rfkill.h, with one ioctl that allows turning off the deprecated input | |
92 | +handler in the kernel for the transition period. | |
109 | 93 | |
94 | +Except for the one ioctl, communication with the kernel is done via read() | |
95 | +and write() of instances of 'struct rfkill_event'. In this structure, the | |
96 | +soft and hard block are properly separated (unlike sysfs, see below) and | |
97 | +userspace is able to get a consistent snapshot of all rfkill devices in the | |
98 | +system. Also, it is possible to switch all rfkill drivers (or all drivers of | |
99 | +a specified type) into a state which also updates the default state for | |
100 | +hotplugged devices. | |
101 | + | |
102 | +After an application opens /dev/rfkill, it can read the current state of | |
103 | +all devices, and afterwards can poll the descriptor for hotplug or state | |
104 | +change events. | |
105 | + | |
106 | +Applications must ignore operations (the "op" field) they do not handle, | |
107 | +this allows the API to be extended in the future. | |
108 | + | |
109 | +Additionally, each rfkill device is registered in sysfs and there has the | |
110 | +following attributes: | |
111 | + | |
110 | 112 | name: Name assigned by driver to this key (interface or driver name). |
111 | - type: Name of the key type ("wlan", "bluetooth", etc). | |
113 | + type: Driver type string ("wlan", "bluetooth", etc). | |
112 | 114 | state: Current state of the transmitter |
113 | 115 | 0: RFKILL_STATE_SOFT_BLOCKED |
114 | 116 | transmitter is turned off by software |
... | ... | @@ -117,7 +119,12 @@ |
117 | 119 | 2: RFKILL_STATE_HARD_BLOCKED |
118 | 120 | transmitter is forced off by something outside of |
119 | 121 | the driver's control. |
120 | - claim: 0: Kernel handles events (currently always reads that value) | |
122 | + This file is deprecated because it can only properly show | |
123 | + three of the four possible states, soft-and-hard-blocked is | |
124 | + missing. | |
125 | + claim: 0: Kernel handles events | |
126 | + This file is deprecated because there no longer is a way to | |
127 | + claim just control over a single rfkill instance. | |
121 | 128 | |
122 | 129 | rfkill devices also issue uevents (with an action of "change"), with the |
123 | 130 | following environment variables set: |
... | ... | @@ -128,10 +135,4 @@ |
128 | 135 | |
129 | 136 | The contents of these variables corresponds to the "name", "state" and |
130 | 137 | "type" sysfs files explained above. |
131 | - | |
132 | -An alternative userspace interface exists as a misc device /dev/rfkill, | |
133 | -which allows userspace to obtain and set the state of rfkill devices and | |
134 | -sets of devices. It also notifies userspace about device addition and | |
135 | -removal. The API is a simple read/write API that is defined in | |
136 | -linux/rfkill.h. |