diff -uNr madwifi-orig/driver/if_ath.c madwifi-gpio-proc/driver/if_ath.c
--- madwifi-orig/driver/if_ath.c	2004-05-27 01:39:12.000000000 +0200
+++ madwifi-gpio-proc/driver/if_ath.c	2004-06-01 17:10:20.000000000 +0200
@@ -139,6 +139,12 @@
 static  int     ath_xchanmode = AH_TRUE;        /* enable extended channels */
 static  int     ath_ctlpkt_type=-1;             /* Control pkt type to filter */
 
+#ifdef SOFTLED
+void
+ath_update_LED (struct net_device *dev, struct ath_hal *ah, 
+                struct ieee80211com *ic, u_int32_t event);
+#endif /* SOFTLED */
+
 #ifdef AR_DEBUG
 int	ath_debug = 0;
 #define	IFF_DUMPPKTS(_ic)	(ath_debug || netif_msg_dumppkts(_ic))
@@ -385,8 +391,9 @@
 
 	DPRINTF(("ath_detach flags %x\n", dev->flags));
 #ifdef SOFTLED 
+	/* turn off LED */
 	sc->sc_ic.ic_beaconCnt = 0;
-	ath_hal_gpioSet(sc->sc_ah,sc->sc_ic.ic_ledPin,1);
+	ath_hal_gpioSet(sc->sc_ah,sc->sc_ic.ic_ledPin,sc->sc_ic.ic_ledInverse);
 #endif
 	ath_stop(dev);
 	sc->sc_invalid = 1;
@@ -440,6 +447,12 @@
 	}
 	if (!ath_hal_intrpend(ah))		/* shared irq, not for us */
 		return IRQ_NONE;
+#ifdef SOFTLED
+	/* XXX WARNING: this is a very ugly hack! XXX */
+	if (sc->sc_ic.ic_caps & IEEE80211_C_SOFTLED) {
+		ath_update_LED(dev, ah, &sc->sc_ic, POLL_EVENT);
+	}
+#endif
 	if ((dev->flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) {
 		DPRINTF(("ath_intr: flags 0x%x\n", dev->flags));
 		ath_hal_getisr(ah, &status);	/* clear ISR */
@@ -1678,37 +1691,49 @@
 ath_update_LED (struct net_device *dev, struct ath_hal *ah, 
                 struct ieee80211com *ic, u_int32_t event)
 {
+	static unsigned int nextjiffies=0;
 	static unsigned int state=1;
-	int rateOn, rateOff, diff;
+	static unsigned int rfkillstate=1;
+	int rfkill, ifup;
+	//int rateOn, rateOff, diff;
 	
-	if (ic->ic_state != IEEE80211_S_RUN) {
-		// Device is in scan mode, searching for AP
-		/* We flash the LED on for 5s and off for 200ms */
-		if (ic->ic_beaconCnt >= (2+state*48)) {
+	ath_hal_gpioCfgInput(ah,ic->ic_rfKillPin);
+	rfkill = ath_hal_gpioGet(ah,ic->ic_rfKillPin);
+	if (rfkill != rfkillstate) {
+		printk("%s: rfKill state changed to %i\n", dev->name, rfkill);
+		rfkillstate = rfkill;
+		if (rfkill == 0) {
+			/* turn off LED */
 			ath_hal_gpioCfgOutput(ah,ic->ic_ledPin);
-			ath_hal_gpioSet(ah,ic->ic_ledPin,state);
-			state ^= 1;
-			ic->ic_beaconCnt = 0;
+			ath_hal_gpioSet(ah,ic->ic_ledPin, ic->ic_ledInverse);
+			return;
 		}
 	}
+	
+	if (jiffies < nextjiffies) return;
+
+	if (ic->ic_state != IEEE80211_S_RUN) {
+		/* Device is in scan mode, searching for AP */
+		nextjiffies = jiffies + (66 - state*20)*HZ/100;
+		state ^= 1;
+	}
 	else {
 		switch(event) {
 		case TRANSMIT_EVENT:
-		case RECEIVE_EVENT:
-			rateOn = 20;
-			rateOff = 2;
-			diff = rateOn-rateOff;
-			if (ic->ic_beaconCnt >= (rateOff + state*diff)) {
-				ath_hal_gpioCfgOutput(ah,ic->ic_ledPin);
-				ath_hal_gpioSet(ah,ic->ic_ledPin,state);
-				state ^= 1;
-				ic->ic_beaconCnt = 0;
-			}
+			state ^= 1;
+			nextjiffies = jiffies + 5*HZ/100;
 			break;
+		case RECEIVE_EVENT:
 		default:
+			nextjiffies = jiffies + 5*HZ/100;
+			state = 1;
 			break;
 		}
 	}
+	ifup = ((dev->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP));
+
+	ath_hal_gpioCfgOutput(ah,ic->ic_ledPin);
+	ath_hal_gpioSet(ah,ic->ic_ledPin,(state & ifup) ^ ic->ic_ledInverse);
 }
 #endif
 
@@ -3329,8 +3354,11 @@
 	ATH_REGDOMAIN	= 8,
 	ATH_XCHANMODE	= 9,
 	ATH_CTLPKT	= 10,
+	ATH_GPIO	= 11,
 };
 static	char ath_dump[12];
+#define ATH_GPIO_COUNT 6
+static	int ath_gpio_buffer[2];
 
 static int
 ath_sysctl_handler(ctl_table *ctl, int write, struct file *filp,
@@ -3359,6 +3387,58 @@
 	return ret;
 }
 
+#ifdef SOFTLED
+static int
+ath_gpio_sysctl_handler(ctl_table *ctl, int write, struct file *filp,
+	void *buffer, size_t *lenp)
+{
+	int ret, i;
+	struct net_device *dev;
+	struct ath_hal *ah;
+	/*static char textbuf[ATH_GPIO_COUNT * 5 + 1];
+	char textbuf2[5];*/
+
+	dev = dev_get_by_name("ath0");		/* XXX */
+	if (!dev) {
+		printk("%s: no ath0 device\n", __func__);
+		return EINVAL;
+	}
+	ah = ((struct ath_softc*)dev->priv)->sc_ah;
+	if (write) {
+		ret = proc_dointvec(ctl, write, filp, buffer, lenp);
+		if (ret != 0) return ret;
+		if (ath_gpio_buffer[0] < 0 || ath_gpio_buffer[0] > ATH_GPIO_COUNT)
+			return EINVAL;
+		if (ath_gpio_buffer[1] < 0 || ath_gpio_buffer[1] > 1)
+			return EINVAL;
+		ath_hal_gpioCfgOutput(ah, ath_gpio_buffer[0]);
+		ath_hal_gpioSet(ah, ath_gpio_buffer[0], ath_gpio_buffer[1]);
+		return 0;
+	} else {
+		for (i = 0; i<ATH_GPIO_COUNT; i++) {
+			ath_hal_gpioCfgInput(ah, i);
+			printk("GPIO %i: %i\n", i, ath_hal_gpioGet(ah, i));
+		}
+		*lenp = 0;
+		return 0;
+		/*if (textbuf[0] == '\0') {
+			for (i = 0; i<ATH_GPIO_COUNT; i++) {
+				ath_hal_gpioCfgInput(ah, i);
+				sprintf(textbuf2, "%i: %i\n", i, ath_hal_gpioGet(ah, i));
+				strcat(textbuf, textbuf2);
+			}
+			i = strlen(textbuf) - filp->f_pos;
+			copy_to_user(buffer, textbuf[filp->f_pos], i);
+			put_user(i, lenp);
+		} else {
+			textbuf[0] = '\0';
+			put_user(0, lenp);
+		}*/
+		
+	}
+}
+#endif /* SOFTLED */
+
 static int
 ath_sysctl_dump(ctl_table *ctl, int write, struct file *filp,
 	void *buffer, size_t *lenp)
@@ -3414,6 +3494,10 @@
 	  sizeof(ath_xchanmode),0444,	NULL,	ath_sysctl_handler },
 	{ ATH_CTLPKT,		"ctlpkt",	&ath_ctlpkt_type,
 	  sizeof(ath_ctlpkt_type),0644, NULL,	ath_sysctl_handler },
+#ifdef SOFTLED
+	{ ATH_GPIO,		"gpio",		&ath_gpio_buffer,
+	  sizeof(ath_gpio_buffer),0644, NULL,	ath_gpio_sysctl_handler },
+#endif /* SOFTLED */
 	{ 0 }
 };
 static ctl_table ath_ath_table[] = {
diff -uNr madwifi-orig/driver/if_ath_pci.c madwifi-gpio-proc/driver/if_ath_pci.c
--- madwifi-orig/driver/if_ath_pci.c	2004-05-27 01:39:12.000000000 +0200
+++ madwifi-gpio-proc/driver/if_ath_pci.c	2004-06-01 17:03:44.000000000 +0200
@@ -167,9 +167,11 @@
 	if ((id->vendor == 0x168c) && 
 	    ((id->device == 0x1014) || (id->device==0x12))) {
 		ath_sc->sc_ic.ic_ledPin = 0;
+		ath_sc->sc_ic.ic_ledInverse = 1;
 		ath_sc->sc_ic.ic_rfKillPin = 1;
 	} else {
 		ath_sc->sc_ic.ic_ledPin = 1;
+		ath_sc->sc_ic.ic_ledInverse = 0;
 		ath_sc->sc_ic.ic_rfKillPin = 0;
 	}
 	ath_hal_gpioCfgOutput(ath_sc->sc_ah, ath_sc->sc_ic.ic_ledPin);
diff -uNr madwifi-orig/driver/if_athvar.h madwifi-gpio-proc/driver/if_athvar.h
--- madwifi-orig/driver/if_athvar.h	2004-05-27 01:39:12.000000000 +0200
+++ madwifi-gpio-proc/driver/if_athvar.h	2004-05-31 14:16:35.000000000 +0200
@@ -257,15 +257,15 @@
 
 #ifdef SOFTLED
 #define ath_hal_gpioCfgOutput(_ah, _gpio) \
-        ((*(_ah)->ah_gpioCfgOutput)((_ah), (_gpio)));
+        ((*(_ah)->ah_gpioCfgOutput)((_ah), (_gpio)))
 #define ath_hal_gpioCfgInput(_ah, _gpio) \
-        ((*(_ah)->ah_gpioCfgInput)((_ah), (_gpio)));
+        ((*(_ah)->ah_gpioCfgInput)((_ah), (_gpio)))
 #define ath_hal_gpioGet(_ah, _gpio) \
-        ((*(_ah)->ah_gpioGet)((_ah), (_gpio)));
+        ((*(_ah)->ah_gpioGet)((_ah), (_gpio)))
 #define ath_hal_gpioSet(_ah, _gpio, _b) \
-        ((*(_ah)->ah_gpioSet)((_ah), (_gpio), (_b)));
+        ((*(_ah)->ah_gpioSet)((_ah), (_gpio), (_b)))
 #define ath_hal_gpioSetIntr(_ah, _gpioSel, _b) \
-        ((*(_ah)->ah_gpioSetIntr)((_ah), (_sel), (_b)));
+        ((*(_ah)->ah_gpioSetIntr)((_ah), (_sel), (_b)))
 #endif
 
 #define	ath_hal_setopmode(_ah) \
diff -uNr madwifi-orig/wlan/if_ieee80211.h madwifi-gpio-proc/wlan/if_ieee80211.h
--- madwifi-orig/wlan/if_ieee80211.h	2004-05-27 01:39:51.000000000 +0200
+++ madwifi-gpio-proc/wlan/if_ieee80211.h	2004-06-01 17:00:04.000000000 +0200
@@ -753,6 +753,7 @@
 #ifdef SOFTLED
         u_int16_t               ic_beaconCnt;   /* becaon Count for LEDs */
         u_int16_t               ic_ledPin;      /* GPIO pin for soft LED */
+        u_int8_t                ic_ledInverse;  /* Is LED pin inverse? */
         u_int16_t               ic_rfKillPin;   /* GPIO pin for RF Kill */
 #endif
 #ifdef CONFIG_PROC_FS
