From 8fc0fee09245fe740d81aded36f4af6db1054015 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 24 May 2009 16:57:19 +0200 Subject: cfg80211: use key size constants Instead of hardcoding the key length for validation, use the constants Zhu Yi recently added and add one for AES_CMAC too. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 34de8b21f6d..a9173d5434d 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1092,6 +1092,7 @@ enum ieee80211_key_len { WLAN_KEY_LEN_WEP104 = 13, WLAN_KEY_LEN_CCMP = 16, WLAN_KEY_LEN_TKIP = 32, + WLAN_KEY_LEN_AES_CMAC = 16, }; /* -- cgit v1.2.3 From 3b8bcfd5d31ea0fec58681d035544ace707d2536 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 30 May 2009 01:39:53 +0200 Subject: net: introduce pre-up netdev notifier NETDEV_UP is called after the device is set UP, but sometimes it is useful to be able to veto the device UP. Introduce a new NETDEV_PRE_UP notifier that can be used for exactly this. The first use case will be cfg80211 denying interfaces to be set UP if the device is known to be rfkill'ed. Signed-off-by: Johannes Berg Acked-by: David S. Miller Signed-off-by: John W. Linville --- include/linux/notifier.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/notifier.h b/include/linux/notifier.h index b86fa2ffca0..81bc252dc8a 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -198,6 +198,7 @@ static inline int notifier_to_errno(int ret) #define NETDEV_CHANGENAME 0x000A #define NETDEV_FEAT_CHANGE 0x000B #define NETDEV_BONDING_FAILOVER 0x000C +#define NETDEV_PRE_UP 0x000D #define SYS_DOWN 0x0001 /* Notify of system down */ #define SYS_RESTART SYS_DOWN -- cgit v1.2.3 From 19d337dff95cbf76edd3ad95c0cee2732c3e1ec5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 2 Jun 2009 13:01:37 +0200 Subject: rfkill: rewrite This patch completely rewrites the rfkill core to address the following deficiencies: * all rfkill drivers need to implement polling where necessary rather than having one central implementation * updating the rfkill state cannot be done from arbitrary contexts, forcing drivers to use schedule_work and requiring lots of code * rfkill drivers need to keep track of soft/hard blocked internally -- the core should do this * the rfkill API has many unexpected quirks, for example being asymmetric wrt. alloc/free and register/unregister * rfkill can call back into a driver from within a function the driver called -- this is prone to deadlocks and generally should be avoided * rfkill-input pointlessly is a separate module * drivers need to #ifdef rfkill functions (unless they want to depend on or select RFKILL) -- rfkill should provide inlines that do nothing if it isn't compiled in * the rfkill structure is not opaque -- drivers need to initialise it correctly (lots of sanity checking code required) -- instead force drivers to pass the right variables to rfkill_alloc() * the documentation is hard to read because it always assumes the reader is completely clueless and contains way TOO MANY CAPS * the rfkill code needlessly uses a lot of locks and atomic operations in locked sections * fix LED trigger to actually change the LED when the radio state changes -- this wasn't done before Tested-by: Alan Jenkins Signed-off-by: Henrique de Moraes Holschuh [thinkpad] Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/Kbuild | 1 + include/linux/rfkill.h | 325 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 252 insertions(+), 74 deletions(-) (limited to 'include/linux') diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 3f0eaa397ef..7e09c5c1ed0 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -311,6 +311,7 @@ unifdef-y += ptrace.h unifdef-y += qnx4_fs.h unifdef-y += quota.h unifdef-y += random.h +unifdef-y += rfkill.h unifdef-y += irqnr.h unifdef-y += reboot.h unifdef-y += reiserfs_fs.h diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index de18ef227e0..090852c8de7 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -4,6 +4,7 @@ /* * Copyright (C) 2006 - 2007 Ivo van Doorn * Copyright (C) 2007 Dmitry Torokhov + * Copyright 2009 Johannes Berg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +22,24 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* define userspace visible states */ +#define RFKILL_STATE_SOFT_BLOCKED 0 +#define RFKILL_STATE_UNBLOCKED 1 +#define RFKILL_STATE_HARD_BLOCKED 2 + +/* and that's all userspace gets */ +#ifdef __KERNEL__ +/* don't allow anyone to use these in the kernel */ +enum rfkill_user_states { + RFKILL_USER_STATE_SOFT_BLOCKED = RFKILL_STATE_SOFT_BLOCKED, + RFKILL_USER_STATE_UNBLOCKED = RFKILL_STATE_UNBLOCKED, + RFKILL_USER_STATE_HARD_BLOCKED = RFKILL_STATE_HARD_BLOCKED, +}; +#undef RFKILL_STATE_SOFT_BLOCKED +#undef RFKILL_STATE_UNBLOCKED +#undef RFKILL_STATE_HARD_BLOCKED + #include #include #include @@ -30,109 +49,267 @@ /** * enum rfkill_type - type of rfkill switch. - * RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device. - * RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device. - * RFKILL_TYPE_UWB: switch is on a ultra wideband device. - * RFKILL_TYPE_WIMAX: switch is on a WiMAX device. - * RFKILL_TYPE_WWAN: switch is on a wireless WAN device. + * + * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device. + * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device. + * @RFKILL_TYPE_UWB: switch is on a ultra wideband device. + * @RFKILL_TYPE_WIMAX: switch is on a WiMAX device. + * @RFKILL_TYPE_WWAN: switch is on a wireless WAN device. + * @NUM_RFKILL_TYPES: number of defined rfkill types */ enum rfkill_type { - RFKILL_TYPE_WLAN , + RFKILL_TYPE_WLAN, RFKILL_TYPE_BLUETOOTH, RFKILL_TYPE_UWB, RFKILL_TYPE_WIMAX, RFKILL_TYPE_WWAN, - RFKILL_TYPE_MAX, + NUM_RFKILL_TYPES, }; -enum rfkill_state { - RFKILL_STATE_SOFT_BLOCKED = 0, /* Radio output blocked */ - RFKILL_STATE_UNBLOCKED = 1, /* Radio output allowed */ - RFKILL_STATE_HARD_BLOCKED = 2, /* Output blocked, non-overrideable */ - RFKILL_STATE_MAX, /* marker for last valid state */ +/* this is opaque */ +struct rfkill; + +/** + * struct rfkill_ops - rfkill driver methods + * + * @poll: poll the rfkill block state(s) -- only assign this method + * when you need polling. When called, simply call one of the + * rfkill_set{,_hw,_sw}_state family of functions. If the hw + * is getting unblocked you need to take into account the return + * value of those functions to make sure the software block is + * properly used. + * @query: query the rfkill block state(s) and call exactly one of the + * rfkill_set{,_hw,_sw}_state family of functions. Assign this + * method if input events can cause hardware state changes to make + * the rfkill core query your driver before setting a requested + * block. + * @set_block: turn the transmitter on (blocked == false) or off + * (blocked == true) -- this is called only while the transmitter + * is not hard-blocked, but note that the core's view of whether + * the transmitter is hard-blocked might differ from your driver's + * view due to race conditions, so it is possible that it is still + * called at the same time as you are calling rfkill_set_hw_state(). + * This callback must be assigned. + */ +struct rfkill_ops { + void (*poll)(struct rfkill *rfkill, void *data); + void (*query)(struct rfkill *rfkill, void *data); + int (*set_block)(void *data, bool blocked); }; +#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) /** - * struct rfkill - rfkill control structure. - * @name: Name of the switch. - * @type: Radio type which the button controls, the value stored - * here should be a value from enum rfkill_type. - * @state: State of the switch, "UNBLOCKED" means radio can operate. - * @mutex: Guards switch state transitions. It serializes callbacks - * and also protects the state. - * @data: Pointer to the RF button drivers private data which will be - * passed along when toggling radio state. - * @toggle_radio(): Mandatory handler to control state of the radio. - * only RFKILL_STATE_SOFT_BLOCKED and RFKILL_STATE_UNBLOCKED are - * valid parameters. - * @get_state(): handler to read current radio state from hardware, - * may be called from atomic context, should return 0 on success. - * Either this handler OR judicious use of rfkill_force_state() is - * MANDATORY for any driver capable of RFKILL_STATE_HARD_BLOCKED. - * @led_trigger: A LED trigger for this button's LED. - * @dev: Device structure integrating the switch into device tree. - * @node: Used to place switch into list of all switches known to the - * the system. - * - * This structure represents a RF switch located on a network device. + * rfkill_alloc - allocate rfkill structure + * @name: name of the struct -- the string is not copied internally + * @parent: device that has rf switch on it + * @type: type of the switch (RFKILL_TYPE_*) + * @ops: rfkill methods + * @ops_data: data passed to each method + * + * This function should be called by the transmitter driver to allocate an + * rfkill structure. Returns %NULL on failure. */ -struct rfkill { - const char *name; - enum rfkill_type type; - - /* the mutex serializes callbacks and also protects - * the state */ - struct mutex mutex; - enum rfkill_state state; - void *data; - int (*toggle_radio)(void *data, enum rfkill_state state); - int (*get_state)(void *data, enum rfkill_state *state); +struct rfkill * __must_check rfkill_alloc(const char *name, + struct device *parent, + const enum rfkill_type type, + const struct rfkill_ops *ops, + void *ops_data); -#ifdef CONFIG_RFKILL_LEDS - struct led_trigger led_trigger; -#endif +/** + * rfkill_register - Register a rfkill structure. + * @rfkill: rfkill structure to be registered + * + * This function should be called by the transmitter driver to register + * the rfkill structure needs to be registered. Before calling this function + * the driver needs to be ready to service method calls from rfkill. + */ +int __must_check rfkill_register(struct rfkill *rfkill); - struct device dev; - struct list_head node; - enum rfkill_state state_for_resume; -}; -#define to_rfkill(d) container_of(d, struct rfkill, dev) +/** + * rfkill_pause_polling(struct rfkill *rfkill) + * + * Pause polling -- say transmitter is off for other reasons. + * NOTE: not necessary for suspend/resume -- in that case the + * core stops polling anyway + */ +void rfkill_pause_polling(struct rfkill *rfkill); -struct rfkill * __must_check rfkill_allocate(struct device *parent, - enum rfkill_type type); -void rfkill_free(struct rfkill *rfkill); -int __must_check rfkill_register(struct rfkill *rfkill); +/** + * rfkill_resume_polling(struct rfkill *rfkill) + * + * Pause polling -- say transmitter is off for other reasons. + * NOTE: not necessary for suspend/resume -- in that case the + * core stops polling anyway + */ +void rfkill_resume_polling(struct rfkill *rfkill); + + +/** + * rfkill_unregister - Unregister a rfkill structure. + * @rfkill: rfkill structure to be unregistered + * + * This function should be called by the network driver during device + * teardown to destroy rfkill structure. Until it returns, the driver + * needs to be able to service method calls. + */ void rfkill_unregister(struct rfkill *rfkill); -int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state); -int rfkill_set_default(enum rfkill_type type, enum rfkill_state state); +/** + * rfkill_destroy - free rfkill structure + * @rfkill: rfkill structure to be destroyed + * + * Destroys the rfkill structure. + */ +void rfkill_destroy(struct rfkill *rfkill); + +/** + * rfkill_set_hw_state - Set the internal rfkill hardware block state + * @rfkill: pointer to the rfkill class to modify. + * @state: the current hardware block state to set + * + * rfkill drivers that get events when the hard-blocked state changes + * use this function to notify the rfkill core (and through that also + * userspace) of the current state -- they should also use this after + * resume if the state could have changed. + * + * You need not (but may) call this function if poll_state is assigned. + * + * This function can be called in any context, even from within rfkill + * callbacks. + * + * The function returns the combined block state (true if transmitter + * should be blocked) so that drivers need not keep track of the soft + * block state -- which they might not be able to. + */ +bool __must_check rfkill_set_hw_state(struct rfkill *rfkill, bool blocked); + +/** + * rfkill_set_sw_state - Set the internal rfkill software block state + * @rfkill: pointer to the rfkill class to modify. + * @state: the current software block state to set + * + * rfkill drivers that get events when the soft-blocked state changes + * (yes, some platforms directly act on input but allow changing again) + * use this function to notify the rfkill core (and through that also + * userspace) of the current state -- they should also use this after + * resume if the state could have changed. + * + * This function can be called in any context, even from within rfkill + * callbacks. + * + * The function returns the combined block state (true if transmitter + * should be blocked). + */ +bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked); + +/** + * rfkill_set_states - Set the internal rfkill block states + * @rfkill: pointer to the rfkill class to modify. + * @sw: the current software block state to set + * @hw: the current hardware block state to set + * + * This function can be called in any context, even from within rfkill + * callbacks. + */ +void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw); /** - * rfkill_state_complement - return complementar state - * @state: state to return the complement of + * rfkill_set_global_sw_state - set global sw block default + * @type: rfkill type to set default for + * @blocked: default to set * - * Returns RFKILL_STATE_SOFT_BLOCKED if @state is RFKILL_STATE_UNBLOCKED, - * returns RFKILL_STATE_UNBLOCKED otherwise. + * This function sets the global default -- use at boot if your platform has + * an rfkill switch. If not early enough this call may be ignored. + * + * XXX: instead of ignoring -- how about just updating all currently + * registered drivers? */ -static inline enum rfkill_state rfkill_state_complement(enum rfkill_state state) +void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked); +#else /* !RFKILL */ +static inline struct rfkill * __must_check +rfkill_alloc(const char *name, + struct device *parent, + const enum rfkill_type type, + const struct rfkill_ops *ops, + void *ops_data) +{ + return ERR_PTR(-ENODEV); +} + +static inline int __must_check rfkill_register(struct rfkill *rfkill) +{ + if (rfkill == ERR_PTR(-ENODEV)) + return 0; + return -EINVAL; +} + +static inline void rfkill_pause_polling(struct rfkill *rfkill) +{ +} + +static inline void rfkill_resume_polling(struct rfkill *rfkill) +{ +} + +static inline void rfkill_unregister(struct rfkill *rfkill) +{ +} + +static inline void rfkill_destroy(struct rfkill *rfkill) +{ +} + +static inline bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) +{ + return blocked; +} + +static inline bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) +{ + return blocked; +} + +static inline void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) +{ +} + +static inline void rfkill_set_global_sw_state(const enum rfkill_type type, + bool blocked) { - return (state == RFKILL_STATE_UNBLOCKED) ? - RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED; } +#endif /* RFKILL || RFKILL_MODULE */ + +#ifdef CONFIG_RFKILL_LEDS /** - * rfkill_get_led_name - Get the LED trigger name for the button's LED. + * rfkill_get_led_trigger_name - Get the LED trigger name for the button's LED. * This function might return a NULL pointer if registering of the - * LED trigger failed. - * Use this as "default_trigger" for the LED. + * LED trigger failed. Use this as "default_trigger" for the LED. */ -static inline char *rfkill_get_led_name(struct rfkill *rfkill) -{ -#ifdef CONFIG_RFKILL_LEDS - return (char *)(rfkill->led_trigger.name); +const char *rfkill_get_led_trigger_name(struct rfkill *rfkill); + +/** + * rfkill_set_led_trigger_name -- set the LED trigger name + * @rfkill: rfkill struct + * @name: LED trigger name + * + * This function sets the LED trigger name of the radio LED + * trigger that rfkill creates. It is optional, but if called + * must be called before rfkill_register() to be effective. + */ +void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name); #else +static inline const char *rfkill_get_led_trigger_name(struct rfkill *rfkill) +{ return NULL; -#endif } +static inline void +rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name) +{ +} +#endif + +#endif /* __KERNEL__ */ + #endif /* RFKILL_H */ -- cgit v1.2.3 From c64fb01627e24725d1f9d535e4426475a4415753 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 2 Jun 2009 13:01:38 +0200 Subject: rfkill: create useful userspace interface The new code added by this patch will make rfkill create a misc character device /dev/rfkill that userspace can use to control rfkill soft blocks and get status of devices as well as events when the status changes. Using it is very simple -- when you open it you can read a number of times to get the initial state, and every further read blocks (you can poll) on getting the next event from the kernel. The same structure you read is also used when writing to it to change the soft block of a given device, all devices of a given type, or all devices. This also makes CONFIG_RFKILL_INPUT selectable again in order to be able to test without it present since its functionality can now be replaced by userspace entirely and distros and users may not want the input part of rfkill interfering with their userspace code. We will also write a userspace daemon to handle all that and consequently add the input code to the feature removal schedule. In order to have rfkilld support both kernels with and without CONFIG_RFKILL_INPUT (or new kernels after its eventual removal) we also add an ioctl (that only exists if rfkill-input is present) to disable rfkill-input. It is not very efficient, but at least gives the correct behaviour in all cases. Signed-off-by: Johannes Berg Acked-by: Marcel Holtmann Signed-off-by: John W. Linville --- include/linux/rfkill.h | 84 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 24 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index 090852c8de7..7c116f6631b 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -22,34 +22,17 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include /* define userspace visible states */ #define RFKILL_STATE_SOFT_BLOCKED 0 #define RFKILL_STATE_UNBLOCKED 1 #define RFKILL_STATE_HARD_BLOCKED 2 -/* and that's all userspace gets */ -#ifdef __KERNEL__ -/* don't allow anyone to use these in the kernel */ -enum rfkill_user_states { - RFKILL_USER_STATE_SOFT_BLOCKED = RFKILL_STATE_SOFT_BLOCKED, - RFKILL_USER_STATE_UNBLOCKED = RFKILL_STATE_UNBLOCKED, - RFKILL_USER_STATE_HARD_BLOCKED = RFKILL_STATE_HARD_BLOCKED, -}; -#undef RFKILL_STATE_SOFT_BLOCKED -#undef RFKILL_STATE_UNBLOCKED -#undef RFKILL_STATE_HARD_BLOCKED - -#include -#include -#include -#include -#include -#include - /** * enum rfkill_type - type of rfkill switch. * + * @RFKILL_TYPE_ALL: toggles all switches (userspace only) * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device. * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device. * @RFKILL_TYPE_UWB: switch is on a ultra wideband device. @@ -58,6 +41,7 @@ enum rfkill_user_states { * @NUM_RFKILL_TYPES: number of defined rfkill types */ enum rfkill_type { + RFKILL_TYPE_ALL = 0, RFKILL_TYPE_WLAN, RFKILL_TYPE_BLUETOOTH, RFKILL_TYPE_UWB, @@ -66,6 +50,62 @@ enum rfkill_type { NUM_RFKILL_TYPES, }; +/** + * enum rfkill_operation - operation types + * @RFKILL_OP_ADD: a device was added + * @RFKILL_OP_DEL: a device was removed + * @RFKILL_OP_CHANGE: a device's state changed -- userspace changes one device + * @RFKILL_OP_CHANGE_ALL: userspace changes all devices (of a type, or all) + */ +enum rfkill_operation { + RFKILL_OP_ADD = 0, + RFKILL_OP_DEL, + RFKILL_OP_CHANGE, + RFKILL_OP_CHANGE_ALL, +}; + +/** + * struct rfkill_event - events for userspace on /dev/rfkill + * @idx: index of dev rfkill + * @type: type of the rfkill struct + * @op: operation code + * @hard: hard state (0/1) + * @soft: soft state (0/1) + * + * Structure used for userspace communication on /dev/rfkill, + * used for events from the kernel and control to the kernel. + */ +struct rfkill_event { + __u32 idx; + __u8 type; + __u8 op; + __u8 soft, hard; +} __packed; + +/* ioctl for turning off rfkill-input (if present) */ +#define RFKILL_IOC_MAGIC 'R' +#define RFKILL_IOC_NOINPUT 1 +#define RFKILL_IOCTL_NOINPUT _IO(RFKILL_IOC_MAGIC, RFKILL_IOC_NOINPUT) + +/* and that's all userspace gets */ +#ifdef __KERNEL__ +/* don't allow anyone to use these in the kernel */ +enum rfkill_user_states { + RFKILL_USER_STATE_SOFT_BLOCKED = RFKILL_STATE_SOFT_BLOCKED, + RFKILL_USER_STATE_UNBLOCKED = RFKILL_STATE_UNBLOCKED, + RFKILL_USER_STATE_HARD_BLOCKED = RFKILL_STATE_HARD_BLOCKED, +}; +#undef RFKILL_STATE_SOFT_BLOCKED +#undef RFKILL_STATE_UNBLOCKED +#undef RFKILL_STATE_HARD_BLOCKED + +#include +#include +#include +#include +#include +#include + /* this is opaque */ struct rfkill; @@ -84,11 +124,7 @@ struct rfkill; * the rfkill core query your driver before setting a requested * block. * @set_block: turn the transmitter on (blocked == false) or off - * (blocked == true) -- this is called only while the transmitter - * is not hard-blocked, but note that the core's view of whether - * the transmitter is hard-blocked might differ from your driver's - * view due to race conditions, so it is possible that it is still - * called at the same time as you are calling rfkill_set_hw_state(). + * (blocked == true) -- ignore and return 0 when hard blocked. * This callback must be assigned. */ struct rfkill_ops { -- cgit v1.2.3 From 6081162e2ed78dfcf149b076b047078ab1445cc2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 2 Jun 2009 13:01:40 +0200 Subject: rfkill: add function to query state Sometimes it is necessary to know how the state is, and it is easier to query rfkill than keep track of it somewhere else, so add a function for that. This could later be expanded to return hard/soft block, but so far that isn't necessary. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/rfkill.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include/linux') diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index 7c116f6631b..ee3eddea856 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -261,6 +261,13 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw); * registered drivers? */ void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked); + +/** + * rfkill_blocked - query rfkill block + * + * @rfkill: rfkill struct to query + */ +bool rfkill_blocked(struct rfkill *rfkill); #else /* !RFKILL */ static inline struct rfkill * __must_check rfkill_alloc(const char *name, @@ -313,6 +320,11 @@ static inline void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked) { } + +static inline bool rfkill_blocked(struct rfkill *rfkill) +{ + return false; +} #endif /* RFKILL || RFKILL_MODULE */ -- cgit v1.2.3