Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cdcb006f authored by Ivo van Doorn's avatar Ivo van Doorn Committed by David S. Miller
Browse files

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: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent df26e7ea
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -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,
+3 −0
Original line number Diff line number Diff line
@@ -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);
	}
+3 −2
Original line number Diff line number Diff line
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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) {
+35 −0
Original line number Diff line number Diff line
@@ -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);
Loading