mac80211: Add radio led trigger
Some devices have a seperate LED which indicates if the radio is enabled or not. This adds a LED trigger to mac80211 where drivers can hook into when they are interested in radio status changes. v2: Check hw.conf.radio_enabled when calling start(). Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									df26e7ea04
								
							
						
					
					
						commit
						cdcb006fbe
					
				| @ -1143,6 +1143,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw); | ||||
| extern char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw); | ||||
| extern char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw); | ||||
| extern char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw); | ||||
| extern char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw); | ||||
| #endif | ||||
| /**
 | ||||
|  * ieee80211_get_tx_led_name - get name of TX LED | ||||
| @ -1182,6 +1183,16 @@ static inline char *ieee80211_get_rx_led_name(struct ieee80211_hw *hw) | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ieee80211_get_assoc_led_name - get name of association LED | ||||
|  * | ||||
|  * mac80211 creates a association LED trigger for each wireless hardware | ||||
|  * that can be used to drive LEDs if your driver registers a LED device. | ||||
|  * This function returns the name (or %NULL if not configured for LEDs) | ||||
|  * of the trigger so you can automatically link the LED device. | ||||
|  * | ||||
|  * @hw: the hardware to get the LED trigger name for | ||||
|  */ | ||||
| static inline char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw) | ||||
| { | ||||
| #ifdef CONFIG_MAC80211_LEDS | ||||
| @ -1191,6 +1202,24 @@ static inline char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw) | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ieee80211_get_radio_led_name - get name of radio LED | ||||
|  * | ||||
|  * mac80211 creates a radio change LED trigger for each wireless hardware | ||||
|  * that can be used to drive LEDs if your driver registers a LED device. | ||||
|  * This function returns the name (or %NULL if not configured for LEDs) | ||||
|  * of the trigger so you can automatically link the LED device. | ||||
|  * | ||||
|  * @hw: the hardware to get the LED trigger name for | ||||
|  */ | ||||
| static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw) | ||||
| { | ||||
| #ifdef CONFIG_MAC80211_LEDS | ||||
| 	return __ieee80211_get_radio_led_name(hw); | ||||
| #else | ||||
| 	return NULL; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /* Register a new hardware PHYMODE capability to the stack. */ | ||||
| int ieee80211_register_hwmode(struct ieee80211_hw *hw, | ||||
|  | ||||
| @ -219,6 +219,7 @@ static int ieee80211_open(struct net_device *dev) | ||||
| 		if (res) | ||||
| 			return res; | ||||
| 		ieee80211_hw_config(local); | ||||
| 		ieee80211_led_radio(local, local->hw.conf.radio_enabled); | ||||
| 	} | ||||
| 
 | ||||
| 	switch (sdata->type) { | ||||
| @ -392,6 +393,8 @@ static int ieee80211_stop(struct net_device *dev) | ||||
| 		if (local->ops->stop) | ||||
| 			local->ops->stop(local_to_hw(local)); | ||||
| 
 | ||||
| 		ieee80211_led_radio(local, 0); | ||||
| 
 | ||||
| 		tasklet_disable(&local->tx_pending_tasklet); | ||||
| 		tasklet_disable(&local->tasklet); | ||||
| 	} | ||||
|  | ||||
| @ -500,8 +500,9 @@ struct ieee80211_local { | ||||
| 
 | ||||
| #ifdef CONFIG_MAC80211_LEDS | ||||
| 	int tx_led_counter, rx_led_counter; | ||||
| 	struct led_trigger *tx_led, *rx_led, *assoc_led; | ||||
| 	char tx_led_name[32], rx_led_name[32], assoc_led_name[32]; | ||||
| 	struct led_trigger *tx_led, *rx_led, *assoc_led, *radio_led; | ||||
| 	char tx_led_name[32], rx_led_name[32], | ||||
| 	     assoc_led_name[32], radio_led_name[32]; | ||||
| #endif | ||||
| 
 | ||||
| 	u32 channel_use; | ||||
|  | ||||
| @ -21,6 +21,7 @@ | ||||
| 
 | ||||
| #include <net/mac80211.h> | ||||
| #include "ieee80211_i.h" | ||||
| #include "ieee80211_led.h" | ||||
| #include "ieee80211_rate.h" | ||||
| #include "wpa.h" | ||||
| #include "aes_ccm.h" | ||||
| @ -652,6 +653,7 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev, | ||||
| 	if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { | ||||
| 		local->hw.conf.radio_enabled = !(data->txpower.disabled); | ||||
| 		need_reconfig = 1; | ||||
| 		ieee80211_led_radio(local, local->hw.conf.radio_enabled); | ||||
| 	} | ||||
| 
 | ||||
| 	if (need_reconfig) { | ||||
|  | ||||
| @ -43,6 +43,16 @@ void ieee80211_led_assoc(struct ieee80211_local *local, bool associated) | ||||
| 		led_trigger_event(local->assoc_led, LED_OFF); | ||||
| } | ||||
| 
 | ||||
| void ieee80211_led_radio(struct ieee80211_local *local, bool enabled) | ||||
| { | ||||
| 	if (unlikely(!local->radio_led)) | ||||
| 		return; | ||||
| 	if (enabled) | ||||
| 		led_trigger_event(local->radio_led, LED_FULL); | ||||
| 	else | ||||
| 		led_trigger_event(local->radio_led, LED_OFF); | ||||
| } | ||||
| 
 | ||||
| void ieee80211_led_init(struct ieee80211_local *local) | ||||
| { | ||||
| 	local->rx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); | ||||
| @ -77,10 +87,25 @@ void ieee80211_led_init(struct ieee80211_local *local) | ||||
| 			local->assoc_led = NULL; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	local->radio_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); | ||||
| 	if (local->radio_led) { | ||||
| 		snprintf(local->radio_led_name, sizeof(local->radio_led_name), | ||||
| 			 "%sradio", wiphy_name(local->hw.wiphy)); | ||||
| 		local->radio_led->name = local->radio_led_name; | ||||
| 		if (led_trigger_register(local->radio_led)) { | ||||
| 			kfree(local->radio_led); | ||||
| 			local->radio_led = NULL; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void ieee80211_led_exit(struct ieee80211_local *local) | ||||
| { | ||||
| 	if (local->radio_led) { | ||||
| 		led_trigger_unregister(local->radio_led); | ||||
| 		kfree(local->radio_led); | ||||
| 	} | ||||
| 	if (local->assoc_led) { | ||||
| 		led_trigger_unregister(local->assoc_led); | ||||
| 		kfree(local->assoc_led); | ||||
| @ -95,6 +120,16 @@ void ieee80211_led_exit(struct ieee80211_local *local) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw) | ||||
| { | ||||
| 	struct ieee80211_local *local = hw_to_local(hw); | ||||
| 
 | ||||
| 	if (local->radio_led) | ||||
| 		return local->radio_led_name; | ||||
| 	return NULL; | ||||
| } | ||||
| EXPORT_SYMBOL(__ieee80211_get_radio_led_name); | ||||
| 
 | ||||
| char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw) | ||||
| { | ||||
| 	struct ieee80211_local *local = hw_to_local(hw); | ||||
|  | ||||
| @ -16,6 +16,8 @@ extern void ieee80211_led_rx(struct ieee80211_local *local); | ||||
| extern void ieee80211_led_tx(struct ieee80211_local *local, int q); | ||||
| extern void ieee80211_led_assoc(struct ieee80211_local *local, | ||||
| 				bool associated); | ||||
| extern void ieee80211_led_radio(struct ieee80211_local *local, | ||||
| 				bool enabled); | ||||
| extern void ieee80211_led_init(struct ieee80211_local *local); | ||||
| extern void ieee80211_led_exit(struct ieee80211_local *local); | ||||
| #else | ||||
| @ -29,6 +31,10 @@ static inline void ieee80211_led_assoc(struct ieee80211_local *local, | ||||
| 				       bool associated) | ||||
| { | ||||
| } | ||||
| static inline void ieee80211_led_radio(struct ieee80211_local *local, | ||||
| 				       bool enabled) | ||||
| { | ||||
| } | ||||
| static inline void ieee80211_led_init(struct ieee80211_local *local) | ||||
| { | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user