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

Commit a9450b70 authored by Ivo van Doorn's avatar Ivo van Doorn Committed by John W. Linville
Browse files

rt2x00: Make use of MAC80211_LED_TRIGGERS



Make use of the led triggers provided by mac80211 to control
the led status. This can be enabled through a per-driver
configuration option which will automatically enable the
generic handler in rt2x00lib.

This has been enabled for rt2500usb and rt73usb for the moment
since the led class will call set_brightness in irq context which
will not work correctly with the usb drivers who need to sleep.

Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent f2a3c7f5
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -38,6 +38,13 @@ config RT2X00_LIB_RFKILL
	select RFKILL
	select INPUT_POLLDEV

config RT2X00_LIB_LEDS
	boolean
	depends on RT2X00_LIB
	select LEDS_CLASS
	select LEDS_TRIGGERS
	select MAC80211_LEDS

config RT2400PCI
	tristate "Ralink rt2400 pci/pcmcia support"
	depends on RT2X00 && PCI
@@ -57,6 +64,13 @@ config RT2400PCI_RFKILL
	  hardware button to control the radio state.
	  This feature depends on the RF switch subsystem rfkill.

config RT2400PCI_LEDS
	bool "RT2400 leds support"
	depends on RT2400PCI
	select RT2X00_LIB_LEDS
	---help---
	  This adds support for led triggers provided my mac80211.

config RT2500PCI
	tristate "Ralink rt2500 pci/pcmcia support"
	depends on RT2X00 && PCI
@@ -76,6 +90,13 @@ config RT2500PCI_RFKILL
	  hardware button to control the radio state.
	  This feature depends on the RF switch subsystem rfkill.

config RT2500PCI_LEDS
	bool "RT2500 leds support"
	depends on RT2500PCI
	select RT2X00_LIB_LEDS
	---help---
	  This adds support for led triggers provided my mac80211.

config RT61PCI
	tristate "Ralink rt61 pci/pcmcia support"
	depends on RT2X00 && PCI
@@ -96,6 +117,13 @@ config RT61PCI_RFKILL
	  hardware button to control the radio state.
	  This feature depends on the RF switch subsystem rfkill.

config RT61PCI_LEDS
	bool "RT61 leds support"
	depends on RT61PCI
	select RT2X00_LIB_LEDS
	---help---
	  This adds support for led triggers provided my mac80211.

config RT2500USB
	tristate "Ralink rt2500 usb support"
	depends on RT2X00 && USB
+4 −0
Original line number Diff line number Diff line
@@ -12,6 +12,10 @@ ifeq ($(CONFIG_RT2X00_LIB_FIRMWARE),y)
	rt2x00lib-objs += rt2x00firmware.o
endif

ifeq ($(CONFIG_RT2X00_LIB_LEDS),y)
	rt2x00lib-objs += rt2x00leds.o
endif

obj-$(CONFIG_RT2X00_LIB)	+= rt2x00lib.o
obj-$(CONFIG_RT2X00_LIB_PCI)	+= rt2x00pci.o
obj-$(CONFIG_RT2X00_LIB_USB)	+= rt2x00usb.o
+48 −40
Original line number Diff line number Diff line
@@ -243,6 +243,30 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
#define rt2400pci_rfkill_poll	NULL
#endif /* CONFIG_RT2400PCI_RFKILL */

#ifdef CONFIG_RT2400PCI_LEDS
static void rt2400pci_led_brightness(struct led_classdev *led_cdev,
				     enum led_brightness brightness)
{
	struct rt2x00_led *led =
	    container_of(led_cdev, struct rt2x00_led, led_dev);
	unsigned int enabled = brightness != LED_OFF;
	unsigned int activity =
	    led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY;
	u32 reg;

	rt2x00pci_register_read(led->rt2x00dev, LEDCSR, &reg);

	if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) {
		rt2x00_set_field32(&reg, LEDCSR_LINK, enabled);
		rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, enabled && activity);
	}

	rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg);
}
#else
#define rt2400pci_led_brightness	NULL
#endif /* CONFIG_RT2400PCI_LEDS */

/*
 * Configuration handlers.
 */
@@ -510,34 +534,6 @@ static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev,
	rt2x00pci_register_write(rt2x00dev, CSR11, reg);
}

/*
 * LED functions.
 */
static void rt2400pci_enable_led(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;

	rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);

	rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, 70);
	rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, 30);
	rt2x00_set_field32(&reg, LEDCSR_LINK,
			   (rt2x00dev->led_mode != LED_MODE_ASUS));
	rt2x00_set_field32(&reg, LEDCSR_ACTIVITY,
			   (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY));
	rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
}

static void rt2400pci_disable_led(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;

	rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);
	rt2x00_set_field32(&reg, LEDCSR_LINK, 0);
	rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, 0);
	rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
}

/*
 * Link tuning
 */
@@ -703,6 +699,11 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev)
			   (rt2x00dev->rx->data_size / 128));
	rt2x00pci_register_write(rt2x00dev, CSR9, reg);

	rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);
	rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, 70);
	rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, 30);
	rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);

	rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000);

	rt2x00pci_register_read(rt2x00dev, ARCSR0, &reg);
@@ -872,11 +873,6 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev)
	 */
	rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON);

	/*
	 * Enable LED
	 */
	rt2400pci_enable_led(rt2x00dev);

	return 0;
}

@@ -884,11 +880,6 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;

	/*
	 * Disable LED
	 */
	rt2400pci_disable_led(rt2x00dev);

	rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);

	/*
@@ -1273,8 +1264,24 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
	/*
	 * Store led mode, for correct led behaviour.
	 */
	rt2x00dev->led_mode =
	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
#ifdef CONFIG_RT2400PCI_LEDS
	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);

	switch (value) {
	case LED_MODE_ASUS:
	case LED_MODE_ALPHA:
	case LED_MODE_DEFAULT:
		rt2x00dev->led_flags = LED_SUPPORT_RADIO;
		break;
	case LED_MODE_TXRX_ACTIVITY:
		rt2x00dev->led_flags =
		    LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY;
		break;
	case LED_MODE_SIGNAL_STRENGTH:
		rt2x00dev->led_flags = LED_SUPPORT_RADIO;
		break;
	}
#endif /* CONFIG_RT2400PCI_LEDS */

	/*
	 * Detect if this device has an hardware controlled radio.
@@ -1594,6 +1601,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
	.link_stats		= rt2400pci_link_stats,
	.reset_tuner		= rt2400pci_reset_tuner,
	.link_tuner		= rt2400pci_link_tuner,
	.led_brightness		= rt2400pci_led_brightness,
	.write_tx_desc		= rt2400pci_write_tx_desc,
	.write_tx_data		= rt2x00pci_write_tx_data,
	.kick_tx_queue		= rt2400pci_kick_tx_queue,
+48 −40
Original line number Diff line number Diff line
@@ -243,6 +243,30 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
#define rt2500pci_rfkill_poll	NULL
#endif /* CONFIG_RT2500PCI_RFKILL */

#ifdef CONFIG_RT2500PCI_LEDS
static void rt2500pci_led_brightness(struct led_classdev *led_cdev,
				     enum led_brightness brightness)
{
	struct rt2x00_led *led =
	    container_of(led_cdev, struct rt2x00_led, led_dev);
	unsigned int enabled = brightness != LED_OFF;
	unsigned int activity =
	    led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY;
	u32 reg;

	rt2x00pci_register_read(led->rt2x00dev, LEDCSR, &reg);

	if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) {
		rt2x00_set_field32(&reg, LEDCSR_LINK, enabled);
		rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, enabled && activity);
	}

	rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg);
}
#else
#define rt2500pci_led_brightness	NULL
#endif /* CONFIG_RT2500PCI_LEDS */

/*
 * Configuration handlers.
 */
@@ -548,34 +572,6 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
		rt2500pci_config_duration(rt2x00dev, libconf);
}

/*
 * LED functions.
 */
static void rt2500pci_enable_led(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;

	rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);

	rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, 70);
	rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, 30);
	rt2x00_set_field32(&reg, LEDCSR_LINK,
			   (rt2x00dev->led_mode != LED_MODE_ASUS));
	rt2x00_set_field32(&reg, LEDCSR_ACTIVITY,
			   (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY));
	rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
}

static void rt2500pci_disable_led(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;

	rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);
	rt2x00_set_field32(&reg, LEDCSR_LINK, 0);
	rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, 0);
	rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
}

/*
 * Link tuning
 */
@@ -795,6 +791,11 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev)
	rt2x00_set_field32(&reg, CSR11_CW_SELECT, 0);
	rt2x00pci_register_write(rt2x00dev, CSR11, reg);

	rt2x00pci_register_read(rt2x00dev, LEDCSR, &reg);
	rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, 70);
	rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, 30);
	rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);

	rt2x00pci_register_write(rt2x00dev, CNT3, 0);

	rt2x00pci_register_read(rt2x00dev, TXCSR8, &reg);
@@ -1026,11 +1027,6 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev)
	 */
	rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON);

	/*
	 * Enable LED
	 */
	rt2500pci_enable_led(rt2x00dev);

	return 0;
}

@@ -1038,11 +1034,6 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;

	/*
	 * Disable LED
	 */
	rt2500pci_disable_led(rt2x00dev);

	rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);

	/*
@@ -1445,8 +1436,24 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
	/*
	 * Store led mode, for correct led behaviour.
	 */
	rt2x00dev->led_mode =
	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
#ifdef CONFIG_RT2500PCI_LEDS
	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);

	switch (value) {
	case LED_MODE_ASUS:
	case LED_MODE_ALPHA:
	case LED_MODE_DEFAULT:
		rt2x00dev->led_flags = LED_SUPPORT_RADIO;
		break;
	case LED_MODE_TXRX_ACTIVITY:
		rt2x00dev->led_flags =
		    LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY;
		break;
	case LED_MODE_SIGNAL_STRENGTH:
		rt2x00dev->led_flags = LED_SUPPORT_RADIO;
		break;
	}
#endif /* CONFIG_RT2500PCI_LEDS */

	/*
	 * Detect if this device has an hardware controlled radio.
@@ -1906,6 +1913,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
	.link_stats		= rt2500pci_link_stats,
	.reset_tuner		= rt2500pci_reset_tuner,
	.link_tuner		= rt2500pci_link_tuner,
	.led_brightness		= rt2500pci_led_brightness,
	.write_tx_desc		= rt2500pci_write_tx_desc,
	.write_tx_data		= rt2x00pci_write_tx_data,
	.kick_tx_queue		= rt2500pci_kick_tx_queue,
+49 −42
Original line number Diff line number Diff line
@@ -282,6 +282,31 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = {
};
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */

#ifdef CONFIG_RT2500USB_LEDS
static void rt2500usb_led_brightness(struct led_classdev *led_cdev,
				     enum led_brightness brightness)
{
	struct rt2x00_led *led =
	    container_of(led_cdev, struct rt2x00_led, led_dev);
	unsigned int enabled = brightness != LED_OFF;
	unsigned int activity =
	    led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY;
	u16 reg;

	rt2500usb_register_read(led->rt2x00dev, MAC_CSR20, &reg);

	if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) {
		rt2x00_set_field16(&reg, MAC_CSR20_LINK, enabled);
		rt2x00_set_field16(&reg, MAC_CSR20_ACTIVITY,
				   enabled && activity);
	}

	rt2500usb_register_write(led->rt2x00dev, MAC_CSR20, reg);
}
#else
#define rt2500usb_led_brightness	NULL
#endif /* CONFIG_RT2500USB_LEDS */

/*
 * Configuration handlers.
 */
@@ -525,36 +550,6 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev,
		rt2500usb_config_duration(rt2x00dev, libconf);
}

/*
 * LED functions.
 */
static void rt2500usb_enable_led(struct rt2x00_dev *rt2x00dev)
{
	u16 reg;

	rt2500usb_register_read(rt2x00dev, MAC_CSR21, &reg);
	rt2x00_set_field16(&reg, MAC_CSR21_ON_PERIOD, 70);
	rt2x00_set_field16(&reg, MAC_CSR21_OFF_PERIOD, 30);
	rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg);

	rt2500usb_register_read(rt2x00dev, MAC_CSR20, &reg);
	rt2x00_set_field16(&reg, MAC_CSR20_LINK,
			   (rt2x00dev->led_mode != LED_MODE_ASUS));
	rt2x00_set_field16(&reg, MAC_CSR20_ACTIVITY,
			   (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY));
	rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg);
}

static void rt2500usb_disable_led(struct rt2x00_dev *rt2x00dev)
{
	u16 reg;

	rt2500usb_register_read(rt2x00dev, MAC_CSR20, &reg);
	rt2x00_set_field16(&reg, MAC_CSR20_LINK, 0);
	rt2x00_set_field16(&reg, MAC_CSR20_ACTIVITY, 0);
	rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg);
}

/*
 * Link tuning
 */
@@ -751,6 +746,11 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
	rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 0);
	rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg);

	rt2500usb_register_read(rt2x00dev, MAC_CSR21, &reg);
	rt2x00_set_field16(&reg, MAC_CSR21_ON_PERIOD, 70);
	rt2x00_set_field16(&reg, MAC_CSR21_OFF_PERIOD, 30);
	rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg);

	rt2500usb_register_read(rt2x00dev, TXRX_CSR5, &reg);
	rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID0, 13);
	rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID0_VALID, 1);
@@ -924,21 +924,11 @@ static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev)
		return -EIO;
	}

	/*
	 * Enable LED
	 */
	rt2500usb_enable_led(rt2x00dev);

	return 0;
}

static void rt2500usb_disable_radio(struct rt2x00_dev *rt2x00dev)
{
	/*
	 * Disable LED
	 */
	rt2500usb_disable_led(rt2x00dev);

	rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x2121);
	rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x2121);

@@ -1370,8 +1360,24 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
	/*
	 * Store led mode, for correct led behaviour.
	 */
	rt2x00dev->led_mode =
	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
#ifdef CONFIG_RT2500USB_LEDS
	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);

	switch (value) {
	case LED_MODE_ASUS:
	case LED_MODE_ALPHA:
	case LED_MODE_DEFAULT:
		rt2x00dev->led_flags = LED_SUPPORT_RADIO;
		break;
	case LED_MODE_TXRX_ACTIVITY:
		rt2x00dev->led_flags =
		    LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY;
		break;
	case LED_MODE_SIGNAL_STRENGTH:
		rt2x00dev->led_flags = LED_SUPPORT_RADIO;
		break;
	}
#endif /* CONFIG_RT2500USB_LEDS */

	/*
	 * Check if the BBP tuning should be disabled.
@@ -1817,6 +1823,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
	.link_stats		= rt2500usb_link_stats,
	.reset_tuner		= rt2500usb_reset_tuner,
	.link_tuner		= rt2500usb_link_tuner,
	.led_brightness		= rt2500usb_led_brightness,
	.write_tx_desc		= rt2500usb_write_tx_desc,
	.write_tx_data		= rt2x00usb_write_tx_data,
	.get_tx_data_len	= rt2500usb_get_tx_data_len,
Loading