aboutsummaryrefslogtreecommitdiffstats
path: root/net/rfkill/rfkill.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rfkill/rfkill.c')
-rw-r--r--net/rfkill/rfkill.c304
1 files changed, 266 insertions, 38 deletions
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 4e10a95de83..ce0e23148cd 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -39,8 +39,56 @@ MODULE_LICENSE("GPL");
39static LIST_HEAD(rfkill_list); /* list of registered rf switches */ 39static LIST_HEAD(rfkill_list); /* list of registered rf switches */
40static DEFINE_MUTEX(rfkill_mutex); 40static DEFINE_MUTEX(rfkill_mutex);
41 41
42static unsigned int rfkill_default_state = RFKILL_STATE_UNBLOCKED;
43module_param_named(default_state, rfkill_default_state, uint, 0444);
44MODULE_PARM_DESC(default_state,
45 "Default initial state for all radio types, 0 = radio off");
46
42static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX]; 47static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX];
43 48
49static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list);
50
51
52/**
53 * register_rfkill_notifier - Add notifier to rfkill notifier chain
54 * @nb: pointer to the new entry to add to the chain
55 *
56 * See blocking_notifier_chain_register() for return value and further
57 * observations.
58 *
59 * Adds a notifier to the rfkill notifier chain. The chain will be
60 * called with a pointer to the relevant rfkill structure as a parameter,
61 * refer to include/linux/rfkill.h for the possible events.
62 *
63 * Notifiers added to this chain are to always return NOTIFY_DONE. This
64 * chain is a blocking notifier chain: notifiers can sleep.
65 *
66 * Calls to this chain may have been done through a workqueue. One must
67 * assume unordered asynchronous behaviour, there is no way to know if
68 * actions related to the event that generated the notification have been
69 * carried out already.
70 */
71int register_rfkill_notifier(struct notifier_block *nb)
72{
73 return blocking_notifier_chain_register(&rfkill_notifier_list, nb);
74}
75EXPORT_SYMBOL_GPL(register_rfkill_notifier);
76
77/**
78 * unregister_rfkill_notifier - remove notifier from rfkill notifier chain
79 * @nb: pointer to the entry to remove from the chain
80 *
81 * See blocking_notifier_chain_unregister() for return value and further
82 * observations.
83 *
84 * Removes a notifier from the rfkill notifier chain.
85 */
86int unregister_rfkill_notifier(struct notifier_block *nb)
87{
88 return blocking_notifier_chain_unregister(&rfkill_notifier_list, nb);
89}
90EXPORT_SYMBOL_GPL(unregister_rfkill_notifier);
91
44 92
45static void rfkill_led_trigger(struct rfkill *rfkill, 93static void rfkill_led_trigger(struct rfkill *rfkill,
46 enum rfkill_state state) 94 enum rfkill_state state)
@@ -50,24 +98,99 @@ static void rfkill_led_trigger(struct rfkill *rfkill,
50 98
51 if (!led->name) 99 if (!led->name)
52 return; 100 return;
53 if (state == RFKILL_STATE_OFF) 101 if (state != RFKILL_STATE_UNBLOCKED)
54 led_trigger_event(led, LED_OFF); 102 led_trigger_event(led, LED_OFF);
55 else 103 else
56 led_trigger_event(led, LED_FULL); 104 led_trigger_event(led, LED_FULL);
57#endif /* CONFIG_RFKILL_LEDS */ 105#endif /* CONFIG_RFKILL_LEDS */
58} 106}
59 107
108static void notify_rfkill_state_change(struct rfkill *rfkill)
109{
110 blocking_notifier_call_chain(&rfkill_notifier_list,
111 RFKILL_STATE_CHANGED,
112 rfkill);
113}
114
115static void update_rfkill_state(struct rfkill *rfkill)
116{
117 enum rfkill_state newstate, oldstate;
118
119 if (rfkill->get_state) {
120 mutex_lock(&rfkill->mutex);
121 if (!rfkill->get_state(rfkill->data, &newstate)) {
122 oldstate = rfkill->state;
123 rfkill->state = newstate;
124 if (oldstate != newstate)
125 notify_rfkill_state_change(rfkill);
126 }
127 mutex_unlock(&rfkill->mutex);
128 }
129}
130
131/**
132 * rfkill_toggle_radio - wrapper for toggle_radio hook
133 * calls toggle_radio taking into account a lot of "small"
134 * details.
135 * @rfkill: the rfkill struct to use
136 * @force: calls toggle_radio even if cache says it is not needed,
137 * and also makes sure notifications of the state will be
138 * sent even if it didn't change
139 * @state: the new state to call toggle_radio() with
140 *
141 * This wrappen protects and enforces the API for toggle_radio
142 * calls. Note that @force cannot override a (possibly cached)
143 * state of RFKILL_STATE_HARD_BLOCKED. Any device making use of
144 * RFKILL_STATE_HARD_BLOCKED implements either get_state() or
145 * rfkill_force_state(), so the cache either is bypassed or valid.
146 *
147 * Note that we do call toggle_radio for RFKILL_STATE_SOFT_BLOCKED
148 * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to
149 * give the driver a hint that it should double-BLOCK the transmitter.
150 *
151 * Caller must have aquired rfkill_mutex.
152 */
60static int rfkill_toggle_radio(struct rfkill *rfkill, 153static int rfkill_toggle_radio(struct rfkill *rfkill,
61 enum rfkill_state state) 154 enum rfkill_state state,
155 int force)
62{ 156{
63 int retval = 0; 157 int retval = 0;
158 enum rfkill_state oldstate, newstate;
159
160 oldstate = rfkill->state;
64 161
65 if (state != rfkill->state) { 162 if (rfkill->get_state && !force &&
163 !rfkill->get_state(rfkill->data, &newstate))
164 rfkill->state = newstate;
165
166 switch (state) {
167 case RFKILL_STATE_HARD_BLOCKED:
168 /* typically happens when refreshing hardware state,
169 * such as on resume */
170 state = RFKILL_STATE_SOFT_BLOCKED;
171 break;
172 case RFKILL_STATE_UNBLOCKED:
173 /* force can't override this, only rfkill_force_state() can */
174 if (rfkill->state == RFKILL_STATE_HARD_BLOCKED)
175 return -EPERM;
176 break;
177 case RFKILL_STATE_SOFT_BLOCKED:
178 /* nothing to do, we want to give drivers the hint to double
179 * BLOCK even a transmitter that is already in state
180 * RFKILL_STATE_HARD_BLOCKED */
181 break;
182 }
183
184 if (force || state != rfkill->state) {
66 retval = rfkill->toggle_radio(rfkill->data, state); 185 retval = rfkill->toggle_radio(rfkill->data, state);
67 if (!retval) { 186 /* never allow a HARD->SOFT downgrade! */
187 if (!retval && rfkill->state != RFKILL_STATE_HARD_BLOCKED)
68 rfkill->state = state; 188 rfkill->state = state;
69 rfkill_led_trigger(rfkill, state); 189 }
70 } 190
191 if (force || rfkill->state != oldstate) {
192 rfkill_led_trigger(rfkill, rfkill->state);
193 notify_rfkill_state_change(rfkill);
71 } 194 }
72 195
73 return retval; 196 return retval;
@@ -82,7 +205,6 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
82 * a specific switch is claimed by userspace in which case it is 205 * a specific switch is claimed by userspace in which case it is
83 * left alone. 206 * left alone.
84 */ 207 */
85
86void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) 208void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
87{ 209{
88 struct rfkill *rfkill; 210 struct rfkill *rfkill;
@@ -93,13 +215,66 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
93 215
94 list_for_each_entry(rfkill, &rfkill_list, node) { 216 list_for_each_entry(rfkill, &rfkill_list, node) {
95 if ((!rfkill->user_claim) && (rfkill->type == type)) 217 if ((!rfkill->user_claim) && (rfkill->type == type))
96 rfkill_toggle_radio(rfkill, state); 218 rfkill_toggle_radio(rfkill, state, 0);
97 } 219 }
98 220
99 mutex_unlock(&rfkill_mutex); 221 mutex_unlock(&rfkill_mutex);
100} 222}
101EXPORT_SYMBOL(rfkill_switch_all); 223EXPORT_SYMBOL(rfkill_switch_all);
102 224
225/**
226 * rfkill_epo - emergency power off all transmitters
227 *
228 * This kicks all rfkill devices to RFKILL_STATE_SOFT_BLOCKED, ignoring
229 * everything in its path but rfkill_mutex.
230 */
231void rfkill_epo(void)
232{
233 struct rfkill *rfkill;
234
235 mutex_lock(&rfkill_mutex);
236 list_for_each_entry(rfkill, &rfkill_list, node) {
237 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
238 }
239 mutex_unlock(&rfkill_mutex);
240}
241EXPORT_SYMBOL_GPL(rfkill_epo);
242
243/**
244 * rfkill_force_state - Force the internal rfkill radio state
245 * @rfkill: pointer to the rfkill class to modify.
246 * @state: the current radio state the class should be forced to.
247 *
248 * This function updates the internal state of the radio cached
249 * by the rfkill class. It should be used when the driver gets
250 * a notification by the firmware/hardware of the current *real*
251 * state of the radio rfkill switch.
252 *
253 * It may not be called from an atomic context.
254 */
255int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
256{
257 enum rfkill_state oldstate;
258
259 if (state != RFKILL_STATE_SOFT_BLOCKED &&
260 state != RFKILL_STATE_UNBLOCKED &&
261 state != RFKILL_STATE_HARD_BLOCKED)
262 return -EINVAL;
263
264 mutex_lock(&rfkill->mutex);
265
266 oldstate = rfkill->state;
267 rfkill->state = state;
268
269 if (state != oldstate)
270 notify_rfkill_state_change(rfkill);
271
272 mutex_unlock(&rfkill->mutex);
273
274 return 0;
275}
276EXPORT_SYMBOL(rfkill_force_state);
277
103static ssize_t rfkill_name_show(struct device *dev, 278static ssize_t rfkill_name_show(struct device *dev,
104 struct device_attribute *attr, 279 struct device_attribute *attr,
105 char *buf) 280 char *buf)
@@ -109,31 +284,31 @@ static ssize_t rfkill_name_show(struct device *dev,
109 return sprintf(buf, "%s\n", rfkill->name); 284 return sprintf(buf, "%s\n", rfkill->name);
110} 285}
111 286
112static ssize_t rfkill_type_show(struct device *dev, 287static const char *rfkill_get_type_str(enum rfkill_type type)
113 struct device_attribute *attr,
114 char *buf)
115{ 288{
116 struct rfkill *rfkill = to_rfkill(dev); 289 switch (type) {
117 const char *type;
118
119 switch (rfkill->type) {
120 case RFKILL_TYPE_WLAN: 290 case RFKILL_TYPE_WLAN:
121 type = "wlan"; 291 return "wlan";
122 break;
123 case RFKILL_TYPE_BLUETOOTH: 292 case RFKILL_TYPE_BLUETOOTH:
124 type = "bluetooth"; 293 return "bluetooth";
125 break;
126 case RFKILL_TYPE_UWB: 294 case RFKILL_TYPE_UWB:
127 type = "ultrawideband"; 295 return "ultrawideband";
128 break;
129 case RFKILL_TYPE_WIMAX: 296 case RFKILL_TYPE_WIMAX:
130 type = "wimax"; 297 return "wimax";
131 break; 298 case RFKILL_TYPE_WWAN:
299 return "wwan";
132 default: 300 default:
133 BUG(); 301 BUG();
134 } 302 }
303}
304
305static ssize_t rfkill_type_show(struct device *dev,
306 struct device_attribute *attr,
307 char *buf)
308{
309 struct rfkill *rfkill = to_rfkill(dev);
135 310
136 return sprintf(buf, "%s\n", type); 311 return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));
137} 312}
138 313
139static ssize_t rfkill_state_show(struct device *dev, 314static ssize_t rfkill_state_show(struct device *dev,
@@ -142,6 +317,7 @@ static ssize_t rfkill_state_show(struct device *dev,
142{ 317{
143 struct rfkill *rfkill = to_rfkill(dev); 318 struct rfkill *rfkill = to_rfkill(dev);
144 319
320 update_rfkill_state(rfkill);
145 return sprintf(buf, "%d\n", rfkill->state); 321 return sprintf(buf, "%d\n", rfkill->state);
146} 322}
147 323
@@ -156,10 +332,14 @@ static ssize_t rfkill_state_store(struct device *dev,
156 if (!capable(CAP_NET_ADMIN)) 332 if (!capable(CAP_NET_ADMIN))
157 return -EPERM; 333 return -EPERM;
158 334
335 /* RFKILL_STATE_HARD_BLOCKED is illegal here... */
336 if (state != RFKILL_STATE_UNBLOCKED &&
337 state != RFKILL_STATE_SOFT_BLOCKED)
338 return -EINVAL;
339
159 if (mutex_lock_interruptible(&rfkill->mutex)) 340 if (mutex_lock_interruptible(&rfkill->mutex))
160 return -ERESTARTSYS; 341 return -ERESTARTSYS;
161 error = rfkill_toggle_radio(rfkill, 342 error = rfkill_toggle_radio(rfkill, state, 0);
162 state ? RFKILL_STATE_ON : RFKILL_STATE_OFF);
163 mutex_unlock(&rfkill->mutex); 343 mutex_unlock(&rfkill->mutex);
164 344
165 return error ? error : count; 345 return error ? error : count;
@@ -200,7 +380,8 @@ static ssize_t rfkill_claim_store(struct device *dev,
200 if (rfkill->user_claim != claim) { 380 if (rfkill->user_claim != claim) {
201 if (!claim) 381 if (!claim)
202 rfkill_toggle_radio(rfkill, 382 rfkill_toggle_radio(rfkill,
203 rfkill_states[rfkill->type]); 383 rfkill_states[rfkill->type],
384 0);
204 rfkill->user_claim = claim; 385 rfkill->user_claim = claim;
205 } 386 }
206 387
@@ -233,12 +414,12 @@ static int rfkill_suspend(struct device *dev, pm_message_t state)
233 414
234 if (dev->power.power_state.event != state.event) { 415 if (dev->power.power_state.event != state.event) {
235 if (state.event & PM_EVENT_SLEEP) { 416 if (state.event & PM_EVENT_SLEEP) {
236 mutex_lock(&rfkill->mutex); 417 /* Stop transmitter, keep state, no notifies */
237 418 update_rfkill_state(rfkill);
238 if (rfkill->state == RFKILL_STATE_ON)
239 rfkill->toggle_radio(rfkill->data,
240 RFKILL_STATE_OFF);
241 419
420 mutex_lock(&rfkill->mutex);
421 rfkill->toggle_radio(rfkill->data,
422 RFKILL_STATE_SOFT_BLOCKED);
242 mutex_unlock(&rfkill->mutex); 423 mutex_unlock(&rfkill->mutex);
243 } 424 }
244 425
@@ -255,8 +436,8 @@ static int rfkill_resume(struct device *dev)
255 if (dev->power.power_state.event != PM_EVENT_ON) { 436 if (dev->power.power_state.event != PM_EVENT_ON) {
256 mutex_lock(&rfkill->mutex); 437 mutex_lock(&rfkill->mutex);
257 438
258 if (rfkill->state == RFKILL_STATE_ON) 439 /* restore radio state AND notify everybody */
259 rfkill->toggle_radio(rfkill->data, RFKILL_STATE_ON); 440 rfkill_toggle_radio(rfkill, rfkill->state, 1);
260 441
261 mutex_unlock(&rfkill->mutex); 442 mutex_unlock(&rfkill->mutex);
262 } 443 }
@@ -269,12 +450,51 @@ static int rfkill_resume(struct device *dev)
269#define rfkill_resume NULL 450#define rfkill_resume NULL
270#endif 451#endif
271 452
453static int rfkill_blocking_uevent_notifier(struct notifier_block *nb,
454 unsigned long eventid,
455 void *data)
456{
457 struct rfkill *rfkill = (struct rfkill *)data;
458
459 switch (eventid) {
460 case RFKILL_STATE_CHANGED:
461 kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
462 break;
463 default:
464 break;
465 }
466
467 return NOTIFY_DONE;
468}
469
470static struct notifier_block rfkill_blocking_uevent_nb = {
471 .notifier_call = rfkill_blocking_uevent_notifier,
472 .priority = 0,
473};
474
475static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
476{
477 struct rfkill *rfkill = to_rfkill(dev);
478 int error;
479
480 error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name);
481 if (error)
482 return error;
483 error = add_uevent_var(env, "RFKILL_TYPE=%s",
484 rfkill_get_type_str(rfkill->type));
485 if (error)
486 return error;
487 error = add_uevent_var(env, "RFKILL_STATE=%d", rfkill->state);
488 return error;
489}
490
272static struct class rfkill_class = { 491static struct class rfkill_class = {
273 .name = "rfkill", 492 .name = "rfkill",
274 .dev_release = rfkill_release, 493 .dev_release = rfkill_release,
275 .dev_attrs = rfkill_dev_attrs, 494 .dev_attrs = rfkill_dev_attrs,
276 .suspend = rfkill_suspend, 495 .suspend = rfkill_suspend,
277 .resume = rfkill_resume, 496 .resume = rfkill_resume,
497 .dev_uevent = rfkill_dev_uevent,
278}; 498};
279 499
280static int rfkill_add_switch(struct rfkill *rfkill) 500static int rfkill_add_switch(struct rfkill *rfkill)
@@ -283,7 +503,7 @@ static int rfkill_add_switch(struct rfkill *rfkill)
283 503
284 mutex_lock(&rfkill_mutex); 504 mutex_lock(&rfkill_mutex);
285 505
286 error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]); 506 error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type], 0);
287 if (!error) 507 if (!error)
288 list_add_tail(&rfkill->node, &rfkill_list); 508 list_add_tail(&rfkill->node, &rfkill_list);
289 509
@@ -296,7 +516,7 @@ static void rfkill_remove_switch(struct rfkill *rfkill)
296{ 516{
297 mutex_lock(&rfkill_mutex); 517 mutex_lock(&rfkill_mutex);
298 list_del_init(&rfkill->node); 518 list_del_init(&rfkill->node);
299 rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF); 519 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
300 mutex_unlock(&rfkill_mutex); 520 mutex_unlock(&rfkill_mutex);
301} 521}
302 522
@@ -412,7 +632,7 @@ int rfkill_register(struct rfkill *rfkill)
412EXPORT_SYMBOL(rfkill_register); 632EXPORT_SYMBOL(rfkill_register);
413 633
414/** 634/**
415 * rfkill_unregister - Uegister a rfkill structure. 635 * rfkill_unregister - Unregister a rfkill structure.
416 * @rfkill: rfkill structure to be unregistered 636 * @rfkill: rfkill structure to be unregistered
417 * 637 *
418 * This function should be called by the network driver during device 638 * This function should be called by the network driver during device
@@ -436,8 +656,13 @@ static int __init rfkill_init(void)
436 int error; 656 int error;
437 int i; 657 int i;
438 658
659 /* RFKILL_STATE_HARD_BLOCKED is illegal here... */
660 if (rfkill_default_state != RFKILL_STATE_SOFT_BLOCKED &&
661 rfkill_default_state != RFKILL_STATE_UNBLOCKED)
662 return -EINVAL;
663
439 for (i = 0; i < ARRAY_SIZE(rfkill_states); i++) 664 for (i = 0; i < ARRAY_SIZE(rfkill_states); i++)
440 rfkill_states[i] = RFKILL_STATE_ON; 665 rfkill_states[i] = rfkill_default_state;
441 666
442 error = class_register(&rfkill_class); 667 error = class_register(&rfkill_class);
443 if (error) { 668 if (error) {
@@ -445,11 +670,14 @@ static int __init rfkill_init(void)
445 return error; 670 return error;
446 } 671 }
447 672
673 register_rfkill_notifier(&rfkill_blocking_uevent_nb);
674
448 return 0; 675 return 0;
449} 676}
450 677
451static void __exit rfkill_exit(void) 678static void __exit rfkill_exit(void)
452{ 679{
680 unregister_rfkill_notifier(&rfkill_blocking_uevent_nb);
453 class_unregister(&rfkill_class); 681 class_unregister(&rfkill_class);
454} 682}
455 683