All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ath5k: added cfg80211 based rfkill support
@ 2009-06-07 11:40 Tobias Doerffel
  2009-06-07 12:28 ` Johannes Berg
  2009-06-07 15:07 ` [ath5k-devel] " Bob Copeland
  0 siblings, 2 replies; 10+ messages in thread
From: Tobias Doerffel @ 2009-06-07 11:40 UTC (permalink / raw)
  To: ath5k-devel, linux-wireless; +Cc: Tobias Doerffel

This patch introduces initial rfkill support for the ath5k driver
based on rfkill support in the cfg80211 framework.
All rfkill related code is separated into newly created rfkill.c.

Changes to existing code are minimal:

* added a new data structure ath5k_rfkill to the ath5k_softc structure
* new function ath5k_eeprom_read_rfkill() for retrieving RFKILL related
  parameters from EEPROM
* inserted calls to HW rfkill init/deinit routines
* ath5k_intr() has been extended to handle AR5K_INT_GPIO interrupts
---
 drivers/net/wireless/ath/ath5k/Kconfig  |    9 +++
 drivers/net/wireless/ath/ath5k/Makefile |    1 +
 drivers/net/wireless/ath/ath5k/ath5k.h  |   10 +++
 drivers/net/wireless/ath/ath5k/base.c   |   10 +++
 drivers/net/wireless/ath/ath5k/base.h   |   14 ++++
 drivers/net/wireless/ath/ath5k/eeprom.c |   16 ++++
 drivers/net/wireless/ath/ath5k/reset.c  |   17 -----
 drivers/net/wireless/ath/ath5k/rfkill.c |  120 +++++++++++++++++++++++++++++++
 8 files changed, 180 insertions(+), 17 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath5k/rfkill.c

diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index 509b6f9..5f18954 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -39,3 +39,12 @@ config ATH5K_DEBUG
 
 	  modprobe ath5k debug=0x00000400
 
+config ATH5K_RFKILL
+	bool "Atheros 5xxx rfkill support"
+	depends on RFKILL
+	depends on ATH5K
+	default y
+	---help---
+	  Include support for enabling/disabling WiFi via rfkill switch
+	  with Atheros 5xxx cards
+
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
index 84a74c5..f1e281c 100644
--- a/drivers/net/wireless/ath/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -12,4 +12,5 @@ ath5k-y				+= attach.o
 ath5k-y				+= base.o
 ath5k-y				+= led.o
 ath5k-$(CONFIG_ATH5K_DEBUG)	+= debug.o
+ath5k-$(CONFIG_ATH5K_RFKILL)	+= rfkill.o
 obj-$(CONFIG_ATH5K)		+= ath5k.o
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 8137182..125e896 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1190,6 +1190,7 @@ extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_l
 extern int ath5k_eeprom_init(struct ath5k_hw *ah);
 extern void ath5k_eeprom_detach(struct ath5k_hw *ah);
 extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
+extern void ath5k_eeprom_read_rfkill(struct ath5k_hw *ah, u16 *gpio, u8 *polarity);
 extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
 
 /* Protocol Control Unit Functions */
@@ -1256,6 +1257,15 @@ extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
 extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
 extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level);
 
+/* rfkill Functions */
+#ifdef CONFIG_ATH5K_RFKILL
+extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
+extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
+#else
+static inline void ath5k_rfkill_hw_start(struct ath5k_hw *ah) {}
+static inline void ath5k_rfkill_hw_stop(struct ath5k_hw *ah) {}
+#endif
+
 /* Misc functions */
 int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
 extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 85a00db..f55675c 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2360,6 +2360,8 @@ ath5k_init(struct ath5k_softc *sc)
 	if (ret)
 		goto done;
 
+	ath5k_rfkill_hw_start(ah);
+
 	/*
 	 * Reset the key cache since some parts do not reset the
 	 * contents on initial power up or resume from suspend.
@@ -2468,6 +2470,8 @@ ath5k_stop_hw(struct ath5k_softc *sc)
 	tasklet_kill(&sc->restq);
 	tasklet_kill(&sc->beacontq);
 
+	ath5k_rfkill_hw_stop(sc->ah);
+
 	return ret;
 }
 
@@ -2526,6 +2530,12 @@ ath5k_intr(int irq, void *dev_id)
 				 */
 				ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
 			}
+#ifdef CONFIG_ATH5K_RFKILL
+			if (status & AR5K_INT_GPIO)
+			{
+				tasklet_schedule(&sc->rf_kill.toggleq);
+			}
+#endif
 		}
 	} while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
 
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 852b2c1..5e1f904 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -46,6 +46,7 @@
 #include <linux/wireless.h>
 #include <linux/if_ether.h>
 #include <linux/leds.h>
+#include <linux/rfkill.h>
 
 #include "ath5k.h"
 #include "debug.h"
@@ -91,6 +92,15 @@ struct ath5k_led
 	struct led_classdev led_dev;		/* led classdev */
 };
 
+/* Rfkill */
+struct ath5k_rfkill {
+	/* GPIO PIN for rfkill */
+	u16 gpio;
+	/* polarity of rfkill GPIO PIN */
+	u8 polarity;
+	/* RFKILL toggle tasklet */
+	struct tasklet_struct toggleq;
+};
 
 #if CHAN_DEBUG
 #define ATH_CHAN_MAX	(26+26+26+200+200)
@@ -167,6 +177,10 @@ struct ath5k_softc {
 	struct tasklet_struct	txtq;		/* tx intr tasklet */
 	struct ath5k_led	tx_led;		/* tx led */
 
+#ifdef CONFIG_ATH5K_RFKILL
+	struct ath5k_rfkill	rf_kill;
+#endif
+
 	spinlock_t		block;		/* protects beacon */
 	struct tasklet_struct	beacontq;	/* beacon intr tasklet */
 	struct ath5k_buf	*bbuf;		/* beacon buffer */
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index c56b494..ff00502 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -1800,3 +1800,19 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
 
 	return 0;
 }
+
+
+/*
+ * Read RFKILL GPIO configuration from eeprom
+ */
+void ath5k_eeprom_read_rfkill(struct ath5k_hw *ah, u16 *gpio, u8 *polarity)
+{
+	u16 data;
+
+	ath5k_hw_eeprom_read(ah, AR5K_EEPROM_RFKILL_GPIO_SEL, &data);
+	*gpio = AR5K_REG_MS(data, AR5K_EEPROM_RFKILL_GPIO_SEL);
+
+	ath5k_hw_eeprom_read(ah, AR5K_EEPROM_RFKILL_POLARITY, &data);
+	*polarity = AR5K_REG_MS(data, AR5K_EEPROM_RFKILL_POLARITY);
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index bd1940e..8077f0a 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1305,23 +1305,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 	if (ah->ah_version != AR5K_AR5210)
 		ath5k_hw_set_imr(ah, ah->ah_imr);
 
-	/*
-	 * Setup RFKill interrupt if rfkill flag is set on eeprom.
-	 * TODO: Use gpio pin and polarity infos from eeprom
-	 * TODO: Handle this in ath5k_intr because it'll result
-	 * 	 a nasty interrupt storm.
-	 */
-#if 0
-	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
-		ath5k_hw_set_gpio_input(ah, 0);
-		ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
-		if (ah->ah_gpio[0] == 0)
-			ath5k_hw_set_gpio_intr(ah, 0, 1);
-		else
-			ath5k_hw_set_gpio_intr(ah, 0, 0);
-	}
-#endif
-
 	/* Enable 32KHz clock function for AR5212+ chips
 	 * Set clocks to 32KHz operation and use an
 	 * external 32KHz crystal when sleeping if one
diff --git a/drivers/net/wireless/ath/ath5k/rfkill.c b/drivers/net/wireless/ath/ath5k/rfkill.c
new file mode 100644
index 0000000..b57ab27
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/rfkill.c
@@ -0,0 +1,120 @@
+/*
+ * RFKILL support for ath5k
+ *
+ * Copyright (c) 2009 Tobias Doerffel <tobias.doerffel@gmail.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "base.h"
+
+
+static inline void ath5k_rfkill_disable(struct ath5k_softc *sc)
+{
+	ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n",
+		sc->rf_kill.gpio, sc->rf_kill.polarity);
+	ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
+	ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, !sc->rf_kill.polarity);
+}
+
+
+static inline void ath5k_rfkill_enable(struct ath5k_softc *sc)
+{
+	ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n",
+		sc->rf_kill.gpio, sc->rf_kill.polarity);
+	ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
+	ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, sc->rf_kill.polarity);
+}
+
+static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, bool enable)
+{
+	struct ath5k_hw *ah = sc->ah;
+	ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio);
+	ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio);
+	ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ?
+					!!ah->ah_gpio[0] : !ah->ah_gpio[0]);
+}
+
+static bool
+ath5k_is_rfkill_set(struct ath5k_softc *sc)
+{
+	/* configuring GPIO for input for some reason disables rfkill */
+	/*ath5k_hw_set_gpio_input(sc->ah, sc->rf_kill.gpio);*/
+	return ath5k_hw_get_gpio(sc->ah, sc->rf_kill.gpio) ==
+							sc->rf_kill.polarity;
+}
+
+static void
+ath5k_tasklet_rfkill_toggle(unsigned long data)
+{
+	struct ath5k_softc *sc = (void *)data;
+	bool blocked;
+
+	blocked = ath5k_is_rfkill_set(sc);
+	wiphy_rfkill_set_hw_state(sc->hw->wiphy, blocked);
+}
+
+
+void
+ath5k_rfkill_hw_start(struct ath5k_hw *ah)
+{
+	struct ath5k_softc *sc = ah->ah_sc;
+
+	/* read rfkill GPIO configuration from EEPROM */
+	ath5k_eeprom_read_rfkill(ah, &sc->rf_kill.gpio, &sc->rf_kill.polarity);
+
+	tasklet_init(&sc->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle,
+		(unsigned long)sc);
+
+	ath5k_rfkill_disable(sc);
+
+	/* enable interrupt for rfkill switch */
+	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
+		ath5k_rfkill_set_intr(sc, true);
+	}
+}
+
+
+void
+ath5k_rfkill_hw_stop(struct ath5k_hw *ah)
+{
+	struct ath5k_softc *sc = ah->ah_sc;
+
+	/* disable interrupt for rfkill switch */
+	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
+		ath5k_rfkill_set_intr(sc, false);
+	}
+
+	tasklet_kill(&sc->rf_kill.toggleq);
+
+	/* enable RFKILL when stopping HW so Wifi LED is turned off */
+	ath5k_rfkill_enable(sc);
+}
+
-- 
1.6.3.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] ath5k: added cfg80211 based rfkill support
  2009-06-07 11:40 [PATCH] ath5k: added cfg80211 based rfkill support Tobias Doerffel
@ 2009-06-07 12:28 ` Johannes Berg
  2009-06-07 15:07 ` [ath5k-devel] " Bob Copeland
  1 sibling, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2009-06-07 12:28 UTC (permalink / raw)
  To: Tobias Doerffel; +Cc: ath5k-devel, linux-wireless

[-- Attachment #1: Type: text/plain, Size: 374 bytes --]

On Sun, 2009-06-07 at 13:40 +0200, Tobias Doerffel wrote:

> +config ATH5K_RFKILL
> +	bool "Atheros 5xxx rfkill support"
> +	depends on RFKILL
> +	depends on ATH5K
> +	default y
> +	---help---
> +	  Include support for enabling/disabling WiFi via rfkill switch
> +	  with Atheros 5xxx cards

This shouldn't be necessary. All APIs are always present.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [ath5k-devel] [PATCH] ath5k: added cfg80211 based rfkill support
  2009-06-07 11:40 [PATCH] ath5k: added cfg80211 based rfkill support Tobias Doerffel
  2009-06-07 12:28 ` Johannes Berg
@ 2009-06-07 15:07 ` Bob Copeland
  2009-06-09 15:33   ` Tobias Doerffel
  1 sibling, 1 reply; 10+ messages in thread
From: Bob Copeland @ 2009-06-07 15:07 UTC (permalink / raw)
  To: Tobias Doerffel; +Cc: ath5k-devel, linux-wireless

On Sun, Jun 07, 2009 at 01:40:33PM +0200, Tobias Doerffel wrote:
> +/*
> + * Read RFKILL GPIO configuration from eeprom
> + */
> +void ath5k_eeprom_read_rfkill(struct ath5k_hw *ah, u16 *gpio, u8 *polarity)
> +{
> +	u16 data;
> +
> +	ath5k_hw_eeprom_read(ah, AR5K_EEPROM_RFKILL_GPIO_SEL, &data);
> +	*gpio = AR5K_REG_MS(data, AR5K_EEPROM_RFKILL_GPIO_SEL);
> +
> +	ath5k_hw_eeprom_read(ah, AR5K_EEPROM_RFKILL_POLARITY, &data);
> +	*polarity = AR5K_REG_MS(data, AR5K_EEPROM_RFKILL_POLARITY);
> +}

ath5k_eeprom_init_header already reads these values and stuffs them
in the ath5k_eeprom_info struct - you can just use them from there.
Otherwise, mod Johanne's comment, looks great!  Thanks for handling
this.

-- 
Bob Copeland %% www.bobcopeland.com


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] ath5k: added cfg80211 based rfkill support
  2009-06-07 15:07 ` [ath5k-devel] " Bob Copeland
@ 2009-06-09 15:33   ` Tobias Doerffel
  2009-06-09 18:26     ` Bob Copeland
  0 siblings, 1 reply; 10+ messages in thread
From: Tobias Doerffel @ 2009-06-09 15:33 UTC (permalink / raw)
  To: ath5k-devel, linux-wireless; +Cc: Tobias Doerffel

This patch introduces initial rfkill support for the ath5k driver
based on rfkill support in the cfg80211 framework.
All rfkill related code is separated into newly created rfkill.c.

Changes to existing code are minimal:

* added a new data structure ath5k_rfkill to the ath5k_softc structure
* inserted calls to HW rfkill init/deinit routines
* ath5k_intr() has been extended to handle AR5K_INT_GPIO interrupts
---
 drivers/net/wireless/ath/ath5k/Kconfig  |    8 ++
 drivers/net/wireless/ath/ath5k/Makefile |    1 +
 drivers/net/wireless/ath/ath5k/ath5k.h  |    9 +++
 drivers/net/wireless/ath/ath5k/base.c   |   10 +++
 drivers/net/wireless/ath/ath5k/base.h   |   14 ++++
 drivers/net/wireless/ath/ath5k/reset.c  |   17 -----
 drivers/net/wireless/ath/ath5k/rfkill.c |  121 +++++++++++++++++++++++++++++++
 7 files changed, 163 insertions(+), 17 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath5k/rfkill.c

diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index 509b6f9..4863f4b 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -39,3 +39,11 @@ config ATH5K_DEBUG
 
 	  modprobe ath5k debug=0x00000400
 
+config ATH5K_RFKILL
+	bool "Atheros 5xxx rfkill support"
+	depends on ATH5K
+	default y
+	---help---
+	  Include support for enabling/disabling WiFi via rfkill switch
+	  with Atheros 5xxx cards
+
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
index 84a74c5..f1e281c 100644
--- a/drivers/net/wireless/ath/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -12,4 +12,5 @@ ath5k-y				+= attach.o
 ath5k-y				+= base.o
 ath5k-y				+= led.o
 ath5k-$(CONFIG_ATH5K_DEBUG)	+= debug.o
+ath5k-$(CONFIG_ATH5K_RFKILL)	+= rfkill.o
 obj-$(CONFIG_ATH5K)		+= ath5k.o
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 8137182..4c84e30 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1256,6 +1256,15 @@ extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
 extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
 extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level);
 
+/* rfkill Functions */
+#ifdef CONFIG_ATH5K_RFKILL
+extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
+extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
+#else
+static inline void ath5k_rfkill_hw_start(struct ath5k_hw *ah) {}
+static inline void ath5k_rfkill_hw_stop(struct ath5k_hw *ah) {}
+#endif
+
 /* Misc functions */
 int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
 extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 85a00db..f55675c 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2360,6 +2360,8 @@ ath5k_init(struct ath5k_softc *sc)
 	if (ret)
 		goto done;
 
+	ath5k_rfkill_hw_start(ah);
+
 	/*
 	 * Reset the key cache since some parts do not reset the
 	 * contents on initial power up or resume from suspend.
@@ -2468,6 +2470,8 @@ ath5k_stop_hw(struct ath5k_softc *sc)
 	tasklet_kill(&sc->restq);
 	tasklet_kill(&sc->beacontq);
 
+	ath5k_rfkill_hw_stop(sc->ah);
+
 	return ret;
 }
 
@@ -2526,6 +2530,12 @@ ath5k_intr(int irq, void *dev_id)
 				 */
 				ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
 			}
+#ifdef CONFIG_ATH5K_RFKILL
+			if (status & AR5K_INT_GPIO)
+			{
+				tasklet_schedule(&sc->rf_kill.toggleq);
+			}
+#endif
 		}
 	} while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
 
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 852b2c1..7a0ecdd 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -46,6 +46,7 @@
 #include <linux/wireless.h>
 #include <linux/if_ether.h>
 #include <linux/leds.h>
+#include <linux/rfkill.h>
 
 #include "ath5k.h"
 #include "debug.h"
@@ -91,6 +92,15 @@ struct ath5k_led
 	struct led_classdev led_dev;		/* led classdev */
 };
 
+/* Rfkill */
+struct ath5k_rfkill {
+	/* GPIO PIN for rfkill */
+	u16 gpio;
+	/* polarity of rfkill GPIO PIN */
+	bool polarity;
+	/* RFKILL toggle tasklet */
+	struct tasklet_struct toggleq;
+};
 
 #if CHAN_DEBUG
 #define ATH_CHAN_MAX	(26+26+26+200+200)
@@ -167,6 +177,10 @@ struct ath5k_softc {
 	struct tasklet_struct	txtq;		/* tx intr tasklet */
 	struct ath5k_led	tx_led;		/* tx led */
 
+#ifdef CONFIG_ATH5K_RFKILL
+	struct ath5k_rfkill	rf_kill;
+#endif
+
 	spinlock_t		block;		/* protects beacon */
 	struct tasklet_struct	beacontq;	/* beacon intr tasklet */
 	struct ath5k_buf	*bbuf;		/* beacon buffer */
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index bd1940e..8077f0a 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1305,23 +1305,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 	if (ah->ah_version != AR5K_AR5210)
 		ath5k_hw_set_imr(ah, ah->ah_imr);
 
-	/*
-	 * Setup RFKill interrupt if rfkill flag is set on eeprom.
-	 * TODO: Use gpio pin and polarity infos from eeprom
-	 * TODO: Handle this in ath5k_intr because it'll result
-	 * 	 a nasty interrupt storm.
-	 */
-#if 0
-	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
-		ath5k_hw_set_gpio_input(ah, 0);
-		ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
-		if (ah->ah_gpio[0] == 0)
-			ath5k_hw_set_gpio_intr(ah, 0, 1);
-		else
-			ath5k_hw_set_gpio_intr(ah, 0, 0);
-	}
-#endif
-
 	/* Enable 32KHz clock function for AR5212+ chips
 	 * Set clocks to 32KHz operation and use an
 	 * external 32KHz crystal when sleeping if one
diff --git a/drivers/net/wireless/ath/ath5k/rfkill.c b/drivers/net/wireless/ath/ath5k/rfkill.c
new file mode 100644
index 0000000..492ada9
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/rfkill.c
@@ -0,0 +1,121 @@
+/*
+ * RFKILL support for ath5k
+ *
+ * Copyright (c) 2009 Tobias Doerffel <tobias.doerffel@gmail.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "base.h"
+
+
+static inline void ath5k_rfkill_disable(struct ath5k_softc *sc)
+{
+	ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n",
+		sc->rf_kill.gpio, sc->rf_kill.polarity);
+	ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
+	ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, !sc->rf_kill.polarity);
+}
+
+
+static inline void ath5k_rfkill_enable(struct ath5k_softc *sc)
+{
+	ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n",
+		sc->rf_kill.gpio, sc->rf_kill.polarity);
+	ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
+	ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, sc->rf_kill.polarity);
+}
+
+static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, bool enable)
+{
+	struct ath5k_hw *ah = sc->ah;
+	ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio);
+	ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio);
+	ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ?
+					!!ah->ah_gpio[0] : !ah->ah_gpio[0]);
+}
+
+static bool
+ath5k_is_rfkill_set(struct ath5k_softc *sc)
+{
+	/* configuring GPIO for input for some reason disables rfkill */
+	/*ath5k_hw_set_gpio_input(sc->ah, sc->rf_kill.gpio);*/
+	return ath5k_hw_get_gpio(sc->ah, sc->rf_kill.gpio) ==
+							sc->rf_kill.polarity;
+}
+
+static void
+ath5k_tasklet_rfkill_toggle(unsigned long data)
+{
+	struct ath5k_softc *sc = (void *)data;
+	bool blocked;
+
+	blocked = ath5k_is_rfkill_set(sc);
+	wiphy_rfkill_set_hw_state(sc->hw->wiphy, blocked);
+}
+
+
+void
+ath5k_rfkill_hw_start(struct ath5k_hw *ah)
+{
+	struct ath5k_softc *sc = ah->ah_sc;
+
+	/* read rfkill GPIO configuration from EEPROM header */
+	sc->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin;
+	sc->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol;
+
+	tasklet_init(&sc->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle,
+		(unsigned long)sc);
+
+	ath5k_rfkill_disable(sc);
+
+	/* enable interrupt for rfkill switch */
+	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
+		ath5k_rfkill_set_intr(sc, true);
+	}
+}
+
+
+void
+ath5k_rfkill_hw_stop(struct ath5k_hw *ah)
+{
+	struct ath5k_softc *sc = ah->ah_sc;
+
+	/* disable interrupt for rfkill switch */
+	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
+		ath5k_rfkill_set_intr(sc, false);
+	}
+
+	tasklet_kill(&sc->rf_kill.toggleq);
+
+	/* enable RFKILL when stopping HW so Wifi LED is turned off */
+	ath5k_rfkill_enable(sc);
+}
+
-- 
1.6.3.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] ath5k: added cfg80211 based rfkill support
  2009-06-09 15:33   ` Tobias Doerffel
@ 2009-06-09 18:26     ` Bob Copeland
  2009-06-09 19:00       ` John W. Linville
  2009-06-09 21:31       ` [PATCH] ath5k: added cfg80211 based rfkill support Tobias Doerffel
  0 siblings, 2 replies; 10+ messages in thread
From: Bob Copeland @ 2009-06-09 18:26 UTC (permalink / raw)
  To: Tobias Doerffel; +Cc: ath5k-devel, linux-wireless

On Tue, Jun 9, 2009 at 11:33 AM, Tobias
Doerffel<tobias.doerffel@gmail.com> wrote:

> +config ATH5K_RFKILL
> +       bool "Atheros 5xxx rfkill support"
> +       depends on ATH5K
> +       default y
> +       ---help---
> +         Include support for enabling/disabling WiFi via rfkill switch
> +         with Atheros 5xxx cards
> +

We can still drop this.

> +       /* enable interrupt for rfkill switch */
> +       if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
> +               ath5k_rfkill_set_intr(sc, true);
> +       }

Coding style...

> +       if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
> +               ath5k_rfkill_set_intr(sc, false);
> +       }

Ditto..

> +       /* enable RFKILL when stopping HW so Wifi LED is turned off */
> +       ath5k_rfkill_enable(sc);

Odd, but ok :)

This looks really close and the remaining changes are pretty small.  If
you want, I can take care of the above and resubmit it with your s-o-b
so you don't have to go through another respin.

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ath5k: added cfg80211 based rfkill support
  2009-06-09 18:26     ` Bob Copeland
@ 2009-06-09 19:00       ` John W. Linville
  2009-06-09 19:19         ` Bob Copeland
  2009-06-10  3:43         ` [PATCH] ath5k: minor rfkill cleanup Bob Copeland
  2009-06-09 21:31       ` [PATCH] ath5k: added cfg80211 based rfkill support Tobias Doerffel
  1 sibling, 2 replies; 10+ messages in thread
From: John W. Linville @ 2009-06-09 19:00 UTC (permalink / raw)
  To: Bob Copeland; +Cc: Tobias Doerffel, ath5k-devel, linux-wireless

On Tue, Jun 09, 2009 at 02:26:12PM -0400, Bob Copeland wrote:
> On Tue, Jun 9, 2009 at 11:33 AM, Tobias
> Doerffel<tobias.doerffel@gmail.com> wrote:
> 
> > +config ATH5K_RFKILL
> > +       bool "Atheros 5xxx rfkill support"
> > +       depends on ATH5K
> > +       default y
> > +       ---help---
> > +         Include support for enabling/disabling WiFi via rfkill switch
> > +         with Atheros 5xxx cards
> > +
> 
> We can still drop this.
> 
> > +       /* enable interrupt for rfkill switch */
> > +       if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
> > +               ath5k_rfkill_set_intr(sc, true);
> > +       }
> 
> Coding style...
> 
> > +       if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
> > +               ath5k_rfkill_set_intr(sc, false);
> > +       }
> 
> Ditto..
> 
> > +       /* enable RFKILL when stopping HW so Wifi LED is turned off */
> > +       ath5k_rfkill_enable(sc);
> 
> Odd, but ok :)
> 
> This looks really close and the remaining changes are pretty small.  If
> you want, I can take care of the above and resubmit it with your s-o-b
> so you don't have to go through another respin.

If that is your offer, maybe you could just do your own patch on top?

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ath5k: added cfg80211 based rfkill support
  2009-06-09 19:00       ` John W. Linville
@ 2009-06-09 19:19         ` Bob Copeland
  2009-06-10  3:43         ` [PATCH] ath5k: minor rfkill cleanup Bob Copeland
  1 sibling, 0 replies; 10+ messages in thread
From: Bob Copeland @ 2009-06-09 19:19 UTC (permalink / raw)
  To: John W. Linville; +Cc: Tobias Doerffel, ath5k-devel, linux-wireless

On Tue, Jun 9, 2009 at 3:00 PM, John W. Linville<linville@tuxdriver.com> wrote:
>>
>> This looks really close and the remaining changes are pretty small.  If
>> you want, I can take care of the above and resubmit it with your s-o-b
>> so you don't have to go through another respin.
>
> If that is your offer, maybe you could just do your own patch on top?

Sure, works for me.

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ath5k: added cfg80211 based rfkill support
  2009-06-09 18:26     ` Bob Copeland
  2009-06-09 19:00       ` John W. Linville
@ 2009-06-09 21:31       ` Tobias Doerffel
  2009-06-09 21:57         ` [ath5k-devel] " Bob Copeland
  1 sibling, 1 reply; 10+ messages in thread
From: Tobias Doerffel @ 2009-06-09 21:31 UTC (permalink / raw)
  To: Bob Copeland; +Cc: ath5k-devel, linux-wireless

[-- Attachment #1: Type: Text/Plain, Size: 495 bytes --]

Hi,

Am Dienstag, 9. Juni 2009 20:26:12 schrieb Bob Copeland:
> > +       /* enable RFKILL when stopping HW so Wifi LED is turned off */
> > +       ath5k_rfkill_enable(sc);
>
> Odd, but ok :)
Why odd? As a user if I disable Wifi (i.e. enable rfkill, be it via software 
or rfkill switch), I do not want the LED to be active anymore. It also might 
have minimal influence on power consumption ;-)

Regarding the other changes I'd agree on an additional patch made up by you.

Toby

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [ath5k-devel] [PATCH] ath5k: added cfg80211 based rfkill support
  2009-06-09 21:31       ` [PATCH] ath5k: added cfg80211 based rfkill support Tobias Doerffel
@ 2009-06-09 21:57         ` Bob Copeland
  0 siblings, 0 replies; 10+ messages in thread
From: Bob Copeland @ 2009-06-09 21:57 UTC (permalink / raw)
  To: Tobias Doerffel; +Cc: ath5k-devel, linux-wireless

On Tue, Jun 9, 2009 at 5:31 PM, Tobias
Doerffel<tobias.doerffel@gmail.com> wrote:
> Hi,
>
> Am Dienstag, 9. Juni 2009 20:26:12 schrieb Bob Copeland:
>> > +       /* enable RFKILL when stopping HW so Wifi LED is turned off */
>> > +       ath5k_rfkill_enable(sc);
>>
>> Odd, but ok :)
> Why odd? As a user if I disable Wifi (i.e. enable rfkill, be it via software
> or rfkill switch), I do not want the LED to be active anymore. It also might
> have minimal influence on power consumption ;-)

No, I agree it is fine as-is, the oddness is just naming confusion (stop calls
rfkill_enable, sort of a double negative).  But I don't have anything better.

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] ath5k: minor rfkill cleanup
  2009-06-09 19:00       ` John W. Linville
  2009-06-09 19:19         ` Bob Copeland
@ 2009-06-10  3:43         ` Bob Copeland
  1 sibling, 0 replies; 10+ messages in thread
From: Bob Copeland @ 2009-06-10  3:43 UTC (permalink / raw)
  To: John W. Linville; +Cc: Tobias Doerffel, ath5k-devel, linux-wireless

Always enable rfkill since the ifdefs in the code is not really worth
the Kconfig option.  Also fix a few code style things, and remove the
usage of the ah_gpio[] array so we can remove it later.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
---
 drivers/net/wireless/ath/ath5k/Kconfig  |    8 --------
 drivers/net/wireless/ath/ath5k/Makefile |    2 +-
 drivers/net/wireless/ath/ath5k/ath5k.h  |    5 -----
 drivers/net/wireless/ath/ath5k/base.c   |    5 +----
 drivers/net/wireless/ath/ath5k/base.h   |    2 --
 drivers/net/wireless/ath/ath5k/rfkill.c |   12 ++++++------
 6 files changed, 8 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index 4863f4b..509b6f9 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -39,11 +39,3 @@ config ATH5K_DEBUG
 
 	  modprobe ath5k debug=0x00000400
 
-config ATH5K_RFKILL
-	bool "Atheros 5xxx rfkill support"
-	depends on ATH5K
-	default y
-	---help---
-	  Include support for enabling/disabling WiFi via rfkill switch
-	  with Atheros 5xxx cards
-
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
index f1e281c..090dc6d 100644
--- a/drivers/net/wireless/ath/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -11,6 +11,6 @@ ath5k-y				+= reset.o
 ath5k-y				+= attach.o
 ath5k-y				+= base.o
 ath5k-y				+= led.o
+ath5k-y				+= rfkill.o
 ath5k-$(CONFIG_ATH5K_DEBUG)	+= debug.o
-ath5k-$(CONFIG_ATH5K_RFKILL)	+= rfkill.o
 obj-$(CONFIG_ATH5K)		+= ath5k.o
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 4c84e30..6358233 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1257,13 +1257,8 @@ extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
 extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level);
 
 /* rfkill Functions */
-#ifdef CONFIG_ATH5K_RFKILL
 extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
 extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
-#else
-static inline void ath5k_rfkill_hw_start(struct ath5k_hw *ah) {}
-static inline void ath5k_rfkill_hw_stop(struct ath5k_hw *ah) {}
-#endif
 
 /* Misc functions */
 int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index f55675c..55f7de0 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2530,12 +2530,9 @@ ath5k_intr(int irq, void *dev_id)
 				 */
 				ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
 			}
-#ifdef CONFIG_ATH5K_RFKILL
 			if (status & AR5K_INT_GPIO)
-			{
 				tasklet_schedule(&sc->rf_kill.toggleq);
-			}
-#endif
+
 		}
 	} while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
 
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 7a0ecdd..f9b7f2f 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -177,9 +177,7 @@ struct ath5k_softc {
 	struct tasklet_struct	txtq;		/* tx intr tasklet */
 	struct ath5k_led	tx_led;		/* tx led */
 
-#ifdef CONFIG_ATH5K_RFKILL
 	struct ath5k_rfkill	rf_kill;
-#endif
 
 	spinlock_t		block;		/* protects beacon */
 	struct tasklet_struct	beacontq;	/* beacon intr tasklet */
diff --git a/drivers/net/wireless/ath/ath5k/rfkill.c b/drivers/net/wireless/ath/ath5k/rfkill.c
index 492ada9..41a877b 100644
--- a/drivers/net/wireless/ath/ath5k/rfkill.c
+++ b/drivers/net/wireless/ath/ath5k/rfkill.c
@@ -56,10 +56,12 @@ static inline void ath5k_rfkill_enable(struct ath5k_softc *sc)
 static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, bool enable)
 {
 	struct ath5k_hw *ah = sc->ah;
+	u32 curval;
+
 	ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio);
-	ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio);
+	curval = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio);
 	ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ?
-					!!ah->ah_gpio[0] : !ah->ah_gpio[0]);
+					!!curval : !curval);
 }
 
 static bool
@@ -97,9 +99,8 @@ ath5k_rfkill_hw_start(struct ath5k_hw *ah)
 	ath5k_rfkill_disable(sc);
 
 	/* enable interrupt for rfkill switch */
-	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
+	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
 		ath5k_rfkill_set_intr(sc, true);
-	}
 }
 
 
@@ -109,9 +110,8 @@ ath5k_rfkill_hw_stop(struct ath5k_hw *ah)
 	struct ath5k_softc *sc = ah->ah_sc;
 
 	/* disable interrupt for rfkill switch */
-	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
+	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
 		ath5k_rfkill_set_intr(sc, false);
-	}
 
 	tasklet_kill(&sc->rf_kill.toggleq);
 
-- 
1.6.0.6



^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-06-10  3:44 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-07 11:40 [PATCH] ath5k: added cfg80211 based rfkill support Tobias Doerffel
2009-06-07 12:28 ` Johannes Berg
2009-06-07 15:07 ` [ath5k-devel] " Bob Copeland
2009-06-09 15:33   ` Tobias Doerffel
2009-06-09 18:26     ` Bob Copeland
2009-06-09 19:00       ` John W. Linville
2009-06-09 19:19         ` Bob Copeland
2009-06-10  3:43         ` [PATCH] ath5k: minor rfkill cleanup Bob Copeland
2009-06-09 21:31       ` [PATCH] ath5k: added cfg80211 based rfkill support Tobias Doerffel
2009-06-09 21:57         ` [ath5k-devel] " Bob Copeland

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.