diff -x CVS -x .tmp_versions -uNr madwifi-orig/driver/if_ath.c madwifi-led/driver/if_ath.c --- madwifi-orig/driver/if_ath.c 2004-06-11 02:26:59.000000000 +0200 +++ madwifi-led/driver/if_ath.c 2004-06-11 02:41:46.000000000 +0200 @@ -139,6 +139,20 @@ static int ath_xchanmode = AH_TRUE; /* enable extended channels */ static int ath_ctlpkt_type=-1; /* Control pkt type to filter */ +#ifdef SOFTLED + +/* a constant timer rate is used instead of only calling the ath_led_timer() + because the rfKill pin needs to be polled yet */ +#define ATH_LED_TICK HZ/10 + +void +ath_led_timer (unsigned long data); + +void +ath_update_LED (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)) @@ -368,6 +382,18 @@ printk("%s: 802.11 address: %s\n", dev->name, ether_sprintf(dev->dev_addr)); + +#ifdef SOFTLED + ic->ic_ledStateList = 0; + ic->ic_ledStateLLen = 0; + ic->ic_rfKillState = 1; + /* start LED timer */ + init_timer(&ic->ic_ledTimer); + ic->ic_ledTimer.data = (unsigned long)sc; + ic->ic_ledTimer.function = ath_led_timer; + ic->ic_ledTimer.expires = jiffies + ATH_LED_TICK; + add_timer(&ic->ic_ledTimer); +#endif return 0; bad2: ath_desc_free(sc); @@ -385,8 +411,10 @@ DPRINTF(("ath_detach flags %x\n", dev->flags)); #ifdef SOFTLED - sc->sc_ic.ic_beaconCnt = 0; - ath_hal_gpioSet(sc->sc_ah,sc->sc_ic.ic_ledPin,1); + /* stop LED timer */ + del_timer_sync(&sc->sc_ic.ic_ledTimer); + /* turn off LED */ + ath_hal_gpioSet(sc->sc_ah,sc->sc_ic.ic_ledPin,sc->sc_ic.ic_ledInverse); #endif ath_stop(dev); sc->sc_invalid = 1; @@ -1675,40 +1703,86 @@ #ifdef SOFTLED void -ath_update_LED (struct net_device *dev, struct ath_hal *ah, - struct ieee80211com *ic, u_int32_t event) +ath_led_timer (unsigned long data) { - static unsigned int state=1; - 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_gpioCfgOutput(ah,ic->ic_ledPin); - ath_hal_gpioSet(ah,ic->ic_ledPin,state); - state ^= 1; - ic->ic_beaconCnt = 0; - } - } - 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; - } - break; - default: - break; + struct ath_softc *sc = (struct ath_softc*)data; + struct ath_hal *ah = sc->sc_ah; + struct ieee80211com *ic = &sc->sc_ic; + int state, rfkill, ifup; + + if (sc->sc_invalid != 0) { + mod_timer(&ic->ic_ledTimer, jiffies + ATH_LED_TICK); + return; + } + + /* XXX insert appropriate rfkill pin existence condition */ + if (ic->ic_rfKillPin < 6) { + ath_hal_gpioCfgInput(ah,ic->ic_rfKillPin); + rfkill = ath_hal_gpioGet(ah,ic->ic_rfKillPin); + if (rfkill != ic->ic_rfKillState) { + printk("%s: rfKill state changed to %i\n", + ic->ic_dev.name, rfkill); + ic->ic_rfKillState = rfkill; } + } else rfkill = 1; + + state = ic->ic_ledStateList & 1; + ifup = ((ic->ic_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 & rfkill) ^ ic->ic_ledInverse); + + if (ic->ic_ledStateLLen > 0) { + /* shift LED "program" by one - go to next "instruction" */ + ic->ic_ledStateList >>= 1; + ic->ic_ledStateLLen--; + } + + if (ic->ic_ledStateLLen == 0 && ic->ic_state != IEEE80211_S_RUN) { + /* in scan mode, add another cycle */ + ic->ic_ledStateList = 0x00ff; + ic->ic_ledStateLLen = 16; + } + + mod_timer(&ic->ic_ledTimer, jiffies + ATH_LED_TICK); +} + +void +ath_update_LED (struct ath_hal *ah, struct ieee80211com *ic, + u_int32_t event) +{ + switch(event) { + case TRANSMIT_EVENT: + if (ic->ic_ledStateLLen > 0) return; + ic->ic_ledStateList = 6; /* xxx110 = short off, permanent on */ + ic->ic_ledStateLLen = 2; /* 2 states + permanent on */ + break; + case RECEIVE_EVENT: + /* only blink on RX in monitor mode */ + if (ic->ic_ledStateLLen > 0 || ic->ic_opmode != IEEE80211_M_MONITOR) + return; + ic->ic_ledStateList = 1; /* xxx001 = short on, permanent off */ + ic->ic_ledStateLLen = 2; /* 2 states + permanent off */ + break; + case STATE_EVENT+IEEE80211_S_INIT: + case STATE_EVENT+IEEE80211_S_SCAN: + case STATE_EVENT+IEEE80211_S_AUTH: + case STATE_EVENT+IEEE80211_S_ASSOC: + ic->ic_ledStateList = 0x01f; /* 0000011111b: 500ms on, 500ms off */ + ic->ic_ledStateLLen = 10; + break; + case STATE_EVENT+IEEE80211_S_RUN: + /* LED is on for normal operation and off for monitor */ + ic->ic_ledStateList = (ic->ic_opmode == IEEE80211_M_MONITOR)?0:1; + ic->ic_ledStateLLen = 0; + break; + default: + /* do nothing... yet */ + return; } + //printk("processed event %i\n", event); + /* XXX: run right now instead of later */ + // ath_led_timer((unsigned long)ah->ah_sc); } #endif @@ -1948,7 +2022,7 @@ bf->bf_skb = NULL; #ifdef SOFTLED if (ic->ic_caps & IEEE80211_C_SOFTLED) { - ath_update_LED(dev, ah, ic, RECEIVE_EVENT); + ath_update_LED(ah, ic, RECEIVE_EVENT); } #endif ath_rx_capture(dev, ds, skb); @@ -1999,7 +2073,7 @@ } #ifdef SOFTLED if (ic->ic_caps & IEEE80211_C_SOFTLED) { - ath_update_LED(dev, ah, ic, RECEIVE_EVENT); + ath_update_LED(ah, ic, RECEIVE_EVENT); } #endif ieee80211_input(dev, skb, @@ -2331,7 +2405,7 @@ spin_unlock_bh(&sc->sc_txqlock[qNum]); #ifdef SOFTLED - ath_update_LED(dev, ah, ic, TRANSMIT_EVENT); + ath_update_LED(ah, ic, TRANSMIT_EVENT); #endif ath_hal_txstart(ah, qNum); @@ -2727,6 +2801,11 @@ DPRINTF(("%s: %s -> %s\n", __func__, stname[ostate], stname[nstate])); ath_hal_setledstate(ah, leds[nstate]); /* set LED */ +#ifdef SOFTLED + if (ostate != nstate && (ic->ic_caps & IEEE80211_C_SOFTLED)) { + ath_update_LED(ah, ic, STATE_EVENT + nstate); + } +#endif netif_stop_queue(dev); /* before we do anything else */ if (nstate == IEEE80211_S_INIT) { diff -x CVS -x .tmp_versions -uNr madwifi-orig/driver/if_ath_pci.c madwifi-led/driver/if_ath_pci.c --- madwifi-orig/driver/if_ath_pci.c 2004-05-27 01:39:12.000000000 +0200 +++ madwifi-led/driver/if_ath_pci.c 2004-06-11 12:55:10.000000000 +0200 @@ -160,20 +160,19 @@ dev->name, athname ? athname : "Atheros ???", phymem, dev->irq); #ifdef SOFTLED ath_sc = dev->priv; - ath_sc->sc_ic.ic_beaconCnt = 0; /* Check to see if we have an IBM card */ printk ("Vendor = 0x%x id=0x%x subsys: %d\n",id->vendor,id->device, id->subdevice); if ((id->vendor == 0x168c) && ((id->device == 0x1014) || (id->device==0x12))) { ath_sc->sc_ic.ic_ledPin = 0; - ath_sc->sc_ic.ic_rfKillPin = 1; + 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); - ath_hal_gpioSet(ath_sc->sc_ah,ath_sc->sc_ic.ic_ledPin,0); ath_sc->sc_ic.ic_caps |= IEEE80211_C_SOFTLED; #endif diff -x CVS -x .tmp_versions -uNr madwifi-orig/wlan/if_ieee80211.h madwifi-led/wlan/if_ieee80211.h --- madwifi-orig/wlan/if_ieee80211.h 2004-05-27 01:39:51.000000000 +0200 +++ madwifi-led/wlan/if_ieee80211.h 2004-06-11 02:39:50.000000000 +0200 @@ -751,9 +751,13 @@ void *ic_wep_ctx; /* wep crypt context */ u_int32_t ic_iv; /* initial vector for wep */ #ifdef SOFTLED - u_int16_t ic_beaconCnt; /* becaon Count for LEDs */ u_int16_t ic_ledPin; /* GPIO pin for soft LED */ u_int16_t ic_rfKillPin; /* GPIO pin for RF Kill */ + u_int8_t ic_ledInverse; /* Is LED pin inverse? */ + u_int16_t ic_rfKillState; /* last read RF Kill GPIO state */ + struct timer_list ic_ledTimer; /* timer for SOFTLED blinking */ + u_int32_t ic_ledStateList; /* bit array of future LED states */ + u_int8_t ic_ledStateLLen; /* number of used StateList bits */ #endif #ifdef CONFIG_PROC_FS char ic_procname[12];/* e.g. wlan%d */ @@ -826,6 +830,8 @@ #define POLL_EVENT 1 /* Poll event for LED update */ #define TRANSMIT_EVENT 2 /* xmit event for LED update */ #define RECEIVE_EVENT 3 /* rcv event for LED update */ +#define STATE_EVENT 4 /* range of events for HAL state */ +#define STATE_EVENT_MAX STATE_EVENT+IEEE80211_S_RUN /* max event */ #endif u_int8_t ieee80211_get_rssi(struct ieee80211_node*); diff -x CVS -x .tmp_versions -uNr madwifi-orig/wlan/if_ieee80211subr.c madwifi-led/wlan/if_ieee80211subr.c --- madwifi-orig/wlan/if_ieee80211subr.c 2004-05-27 01:39:51.000000000 +0200 +++ madwifi-led/wlan/if_ieee80211subr.c 2004-06-10 23:39:56.000000000 +0200 @@ -1161,27 +1161,15 @@ if (ic->ic_state == IEEE80211_S_SCAN) { if (subtype != IEEE80211_FC0_SUBTYPE_BEACON && subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) { -#ifdef SOFTLED - ic->ic_beaconCnt++; -#endif goto out; } } else { #if 0 if (ic->ic_opmode != IEEE80211_M_IBSS && subtype == IEEE80211_FC0_SUBTYPE_BEACON) { -#ifdef SOFTLED - ic->ic_beaconCnt++; -#endif goto out; } #endif -#ifdef SOFTLED - if (ic->ic_opmode != IEEE80211_M_IBSS && - subtype == IEEE80211_FC0_SUBTYPE_BEACON) { - ic->ic_beaconCnt++; - } -#endif } if (netif_msg_debug(ic)) { @@ -3012,9 +3000,6 @@ IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); ieee80211_add_recvhist(ni, rssi, rstamp, rantenna); memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp)); -#ifdef SOFTLED - ic->ic_beaconCnt++; -#endif ni->ni_intval = le16_to_cpu(*(u_int16_t *)bintval); ni->ni_capinfo = le16_to_cpu(*(u_int16_t *)capinfo); ni->ni_chan = &ic->ic_channels[chan];