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; if_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