commit eeba043ed1230c2e427d50b01057c63836ba3a25 Author: Jiri Slaby Date: Mon Jul 16 08:35:17 2007 +0200 leds diff --git a/ath.c b/ath.c index 2b95442..77c5acc 100644 --- a/ath.c +++ b/ath.c @@ -60,10 +60,16 @@ enum { ATH_DEBUG_BEACON = 0x00000080, /* beacon handling */ ATH_DEBUG_INTR = 0x00001000, /* ISR */ ATH_DEBUG_CALIBRATE = 0x00010000, /* periodic calibration */ + ATH_DEBUG_LED = 0x00100000, /* led management */ ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */ ATH_DEBUG_ANY = 0xffffffff }; +enum { + ATH_LED_TX, + ATH_LED_RX, +}; + static int ath_calinterval = ATH_SHORT_CALIB; static int countrycode = CTRY_DEFAULT; @@ -108,6 +114,8 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = { }; MODULE_DEVICE_TABLE(pci, ath_pci_id_table); +static void ath_led_event(struct ath_softc *, int); + #if AR_DEBUG static void ath_printrxbuf(struct ath_buf *bf, int done) { @@ -206,6 +214,8 @@ static void ath_tasklet_tx(unsigned long data) ath_tx_processq(sc, sc->txq); ieee80211_wake_queue(sc->hw, 0); + + ath_led_event(sc, ATH_LED_TX); } static int ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf) @@ -408,6 +418,8 @@ accept: ath_dump_skb(skb, 1); __ieee80211_rx(sc->hw, skb, &rxs); + sc->led_rxrate = ds->ds_rxstat.rs_rate; + ath_led_event(sc, ATH_LED_RX); next: list_move_tail(&bf->list, &sc->rxbuf); } while (ath_rxbuf_init(sc, bf) == 0); @@ -700,12 +712,10 @@ static int ath_stop_locked(struct ath_softc *sc) ieee80211_stop_queues(sc->hw); if (!sc->invalid) { - if (sc->softled) { -#ifdef BLE - del_timer(&sc->ledtimer); - ath5k_hw_set_gpio(ah, sc->ledpin, !sc->ledon); - sc->blinking = 0; -#endif + if (sc->led_soft) { + del_timer_sync(&sc->led_tim); + ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on); + sc->led_blinking = 0; } ath5k_hw_set_intr(ah, 0); } @@ -766,59 +776,63 @@ static int ath_stop_hw(struct ath_softc *sc) static void ath_setcurmode(struct ath_softc *sc, unsigned int mode) { -#ifdef BLE - /* from Atheros NDIS driver, w/ permission */ - static const struct { - u16 rate; /* tx/rx 802.11 rate */ - u16 timeOn; /* LED on time (ms) */ - u16 timeOff; /* LED off time (ms) */ - } blinkrates[] = { - { 108, 40, 10 }, - { 96, 44, 11 }, - { 72, 50, 13 }, - { 48, 57, 14 }, - { 36, 67, 16 }, - { 24, 80, 20 }, - { 22, 100, 25 }, - { 18, 133, 34 }, - { 12, 160, 40 }, - { 10, 200, 50 }, - { 6, 240, 58 }, - { 4, 267, 66 }, - { 2, 400, 100 }, - { 0, 500, 130 } - }; -#endif - const struct ath5k_rate_table* rt=ath5k_hw_get_rate_table(sc->ah, mode); -// unsigned int i, j; - - BUG_ON(rt == NULL); -#ifdef BLE - memset(sc->hwmap, 0, sizeof(sc->hwmap)); - for (i = 0; i < 32; i++) { - u8 ix = rt->rate_code_to_index[i]; - if (ix == 0xff) { - sc->hwmap[i].ledon = msecs_to_jiffies(500); - sc->hwmap[i].ledoff = msecs_to_jiffies(130); - continue; + if (unlikely(sc->led_soft)) { + /* from Atheros NDIS driver, w/ permission */ + static const struct { + u16 rate; /* tx/rx 802.11 rate */ + u16 timeOn; /* LED on time (ms) */ + u16 timeOff; /* LED off time (ms) */ + } blinkrates[] = { + { 108, 40, 10 }, + { 96, 44, 11 }, + { 72, 50, 13 }, + { 48, 57, 14 }, + { 36, 67, 16 }, + { 24, 80, 20 }, + { 22, 100, 25 }, + { 18, 133, 34 }, + { 12, 160, 40 }, + { 10, 200, 50 }, + { 6, 240, 58 }, + { 4, 267, 66 }, + { 2, 400, 100 }, + { 0, 500, 130 } + }; + const struct ath5k_rate_table* rt = + ath5k_hw_get_rate_table(sc->ah, mode); + unsigned int i, j; + + BUG_ON(rt == NULL); + + memset(sc->hwmap, 0, sizeof(sc->hwmap)); + for (i = 0; i < 32; i++) { + u8 ix = rt->rate_code_to_index[i]; + if (ix == 0xff) { + sc->hwmap[i].ledon = msecs_to_jiffies(500); + sc->hwmap[i].ledoff = msecs_to_jiffies(130); + continue; + } + sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD; + if (SHPREAMBLE_FLAG(ix) || rt->rates[ix].modulation == + MODULATION_OFDM) + sc->hwmap[i].txflags |= + IEEE80211_RADIOTAP_F_SHORTPRE; + /* receive frames include FCS */ + sc->hwmap[i].rxflags = sc->hwmap[i].txflags | + IEEE80211_RADIOTAP_F_FCS; + /* setup blink rate table to avoid per-packet lookup */ + for (j = 0; j < ARRAY_SIZE(blinkrates) - 1; j++) + if (blinkrates[j].rate == /* XXX why 7f? */ + (rt->rates[ix].dot11_rate&0x7f)) + break; + + sc->hwmap[i].ledon = msecs_to_jiffies(blinkrates[j]. + timeOn); + sc->hwmap[i].ledoff = msecs_to_jiffies(blinkrates[j]. + timeOff); } - sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD; - if (SHPREAMBLE_FLAG(ix) || rt->rates[ix].modulation == - MODULATION_OFDM) - sc->hwmap[i].txflags |= IEEE80211_RADIOTAP_F_SHORTPRE; - /* receive frames include FCS */ - sc->hwmap[i].rxflags = sc->hwmap[i].txflags | - IEEE80211_RADIOTAP_F_FCS; - /* setup blink rate table to avoid per-packet lookup */ - for (j = 0; j < ARRAY_SIZE(blinkrates) - 1; j++) - if (blinkrates[j].rate == /* XXX why 7f? */ - (rt->rates[ix].dot11_rate & 0x7f)) - break; - - sc->hwmap[i].ledon = msecs_to_jiffies(blinkrates[j].timeOn); - sc->hwmap[i].ledoff = msecs_to_jiffies(blinkrates[j].timeOff); } -#endif + sc->curmode = mode; } @@ -953,6 +967,8 @@ static int ath_tx(struct ieee80211_hw *hw, struct sk_buff *skb, ath_dump_skb(skb, 0); + sc->led_txrate = ctl->tx_rate; + spin_lock_irqsave(&sc->txbuflock, flags); if (list_empty(&sc->txbuf)) { if (net_ratelimit()) @@ -1180,6 +1196,51 @@ static void ath_calibrate(unsigned long data) msecs_to_jiffies(ath_calinterval * 1000)); } +static void ath_led_off(unsigned long data) +{ + struct ath_softc *sc = (void *)data; + + if (sc->led_endblink) + sc->led_blinking = 0; + else { + sc->led_endblink = 0; + ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on); + mod_timer(&sc->led_tim, jiffies + sc->led_off); + } +} + +/* + * Blink the LED according to the specified on/off times. + */ +static void ath_led_blink(struct ath_softc *sc, unsigned int on, + unsigned int off) +{ + DPRINTF(sc, ATH_DEBUG_LED, "%s: on %u off %u\n", __func__, on, off); + ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on); + sc->led_blinking = 1; + sc->led_endblink = 0; + sc->led_off = off; + mod_timer(&sc->led_tim, jiffies + on); +} + +static void ath_led_event(struct ath_softc *sc, int event) +{ + if (likely(!sc->led_soft)) + return; + if (unlikely(sc->led_blinking)) /* don't interrupt active blink */ + return; + switch (event) { + case ATH_LED_TX: + ath_led_blink(sc, sc->hwmap[sc->led_txrate].ledon, + sc->hwmap[sc->led_txrate].ledoff); + break; + case ATH_LED_RX: + ath_led_blink(sc, sc->hwmap[sc->led_rxrate].ledon, + sc->hwmap[sc->led_rxrate].ledoff); + break; + } +} + static irqreturn_t ath_intr(int irq, void *dev_id) { struct ath_softc *sc = dev_id; @@ -1713,26 +1774,30 @@ static int ath_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) tasklet_init(&sc->rxtq, ath_tasklet_rx, (unsigned long)sc); tasklet_init(&sc->txtq, ath_tasklet_tx, (unsigned long)sc); setup_timer(&sc->calib_tim, ath_calibrate, (unsigned long)sc); -#ifdef BLE - setup_timer(&sc->sc_ledtimer, ath_led_off, (unsigned long)sc); - - sc->blinking = 0; - sc->ledstate = 1; - sc->ledon = 0; /* low true */ - sc->ledidle = msecs_to_jiffies(2700); /* 2.7sec */ + setup_timer(&sc->led_tim, ath_led_off, (unsigned long)sc); + sc->led_blinking = 0; + sc->led_on = 0; /* low true */ /* * Auto-enable soft led processing for IBM cards and for * 5211 minipci cards. Users can also manually enable/disable * support with a sysctl. */ - sc->sc_softled = (devid == PCI_DEVICE_ID_ATHEROS_AR5212_IBM || - devid == PCI_DEVICE_ID_ATHEROS_AR5211); - if (sc->sc_softled) { - ath5k_hw_set_gpio_output(ah, sc->sc_ledpin); - ath5k_hw_set_gpio(ah, sc->sc_ledpin, !sc->sc_ledon); + if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM || + pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) { + sc->led_soft = 1; + sc->led_pin = 0; } - + /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */ + if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) { + sc->led_soft = 1; + sc->led_pin = 0; + } + if (sc->led_soft) { + ath5k_hw_set_gpio_output(ah, sc->led_pin); + ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on); + } +#ifdef BLE sc->sc_mcastkey = ath_hal_getmcastkeysearch(ah); /* @@ -1963,8 +2028,8 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath_softc *sc = hw->priv; - if (sc->softled) - ath5k_hw_set_gpio(sc->ah, sc->ledpin, 1); + if (sc->led_soft) + ath5k_hw_set_gpio(sc->ah, sc->led_pin, 1); ath_stop_hw(sc); pci_save_state(pdev); @@ -1997,9 +2062,9 @@ static int ath_pci_resume(struct pci_dev *pdev) pci_write_config_byte(pdev, 0x41, 0); ath_init(sc); - if (sc->softled) { - ath5k_hw_set_gpio_output(sc->ah, sc->ledpin); - ath5k_hw_set_gpio(sc->ah, sc->ledpin, 0); + if (sc->led_soft) { + ath5k_hw_set_gpio_output(sc->ah, sc->led_pin); + ath5k_hw_set_gpio(sc->ah, sc->led_pin, 0); } return 0; diff --git a/ath.h b/ath.h index 25393f7..61019ad 100644 --- a/ath.h +++ b/ath.h @@ -148,7 +148,6 @@ struct ath_softc { #endif unsigned int invalid : 1, /* disable hardware accesses */ mrretry : 1, /* multi-rate retry support */ - softled : 1, /* enable LED gpio status */ xxx:1; #ifdef BLE sc_splitmic: 1, /* split TKIP MIC keys */ @@ -156,9 +155,6 @@ struct ath_softc { sc_diversity : 1,/* enable rx diversity */ sc_lockslottime : 1,/* lock slot time value */ sc_hasveol : 1, /* tx VEOL support */ - sc_ledstate: 1, /* LED on/off state */ - sc_blinking: 1, /* LED blink operation active */ - sc_endblink: 1, /* finish LED blink operation */ sc_mcastkey: 1, /* mcast key cache search */ sc_hasclrkey:1; /* CLR key supported */ /* rate tables */ @@ -170,15 +166,14 @@ struct ath_softc { #ifdef BLE u16 sc_curtxpow; /* current tx power limit */ u8 sc_rixmap[256]; /* IEEE to h/w rate table ix */ - +#endif struct { -// int ieeerate; /* IEEE rate */ u8 rxflags; /* radiotap rx flags */ u8 txflags; /* radiotap tx flags */ u16 ledon; /* softled on time */ u16 ledoff; /* softled off time */ } hwmap[32]; /* h/w rate ix mappings */ - +#ifdef BLE u8 sc_protrix; /* protection rate index */ u_int sc_txantenna; /* tx antenna (fixed or auto) */ #endif @@ -187,16 +182,17 @@ struct ath_softc { DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */ u8 bssidmask[ETH_ALEN]; - unsigned int ledpin; /* GPIO pin for driving LED */ -#ifdef BLE - u_int sc_ledon; /* pin setting for LED on */ - u_int sc_ledidle; /* idle polling interval */ - int sc_ledevent; /* time of last LED event */ - u8 sc_rxrate; /* current rx rate for LED */ - u8 sc_txrate; /* current tx rate for LED */ - u16 sc_ledoff; /* off time for current blink */ - struct timer_list sc_ledtimer; /* led off timer */ + unsigned int led_pin, /* GPIO pin for driving LED */ + led_on, /* pin setting for LED on */ + led_off, /* off time for current blink */ + led_blinking: 1,/* LED blink operation active */ + led_endblink: 1,/* finish LED blink operation */ + led_soft: 1; /* enable LED gpio status */ + struct timer_list led_tim; /* led off timer */ + u8 led_rxrate; /* current rx rate for LED */ + u8 led_txrate; /* current tx rate for LED */ +#ifdef BLE union { struct ath_tx_radiotap_header th; u8 pad[64]; diff --git a/ath/if_ath.c b/ath/if_ath.c index 264724f..960e48a 100644 --- a/ath/if_ath.c +++ b/ath/if_ath.c @@ -2,12 +2,6 @@ #define LE_READ_2(_p) (le16_to_cpu(get_unaligned((__le16 *)(_p)))) #define LE_READ_4(_p) (le32_to_cpu(get_unaligned((__le32 *)(_p)))) -enum { - ATH_LED_TX, - ATH_LED_RX, - ATH_LED_POLL, -}; - static const char *hal_status_desc[] = { "Everything went O.K.", "Unable to allocate memory for ath_hal", @@ -3543,66 +3537,7 @@ ath_newassoc(struct ieee80211_node *ni, int isnew) ath_setup_stationkey(ni); } } -#endif -/* - * Turn the LED off: flip the pin and then set a timer so no - * update will happen for the specified duration. - */ -static void -ath_led_off(unsigned long arg) -{ - struct ath_softc *sc = (struct ath_softc *) arg; - - if(sc->sc_endblink == 1){ - /* part of ath_led_done() */ - sc->sc_blinking = 0; - } else{ - ath5k_hw_set_gpio(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon); - sc->sc_endblink = 1; - mod_timer(&sc->sc_ledtimer, jiffies + sc->sc_ledoff); - } -} -#ifdef BLE -/* - * Blink the LED according to the specified on/off times. - */ -static void -ath_led_blink(struct ath_softc *sc, int on, int off) -{ - DPRINTF(sc, ATH_DEBUG_LED, "%s: on %u off %u\n", __func__, on, off); - ath5k_hw_set_gpio(sc->sc_ah, sc->sc_ledpin, sc->sc_ledon); - sc->sc_blinking = 1; - sc->sc_endblink = 0; - sc->sc_ledoff = off; - mod_timer(&sc->sc_ledtimer, jiffies + on); -} - -static void -ath_led_event(struct ath_softc *sc, int event) -{ - - sc->sc_ledevent = jiffies; /* time of last event */ - if (sc->sc_blinking) /* don't interrupt active blink */ - return; - switch (event) { - case ATH_LED_POLL: - ath_led_blink(sc, sc->sc_hwmap[0].ledon, - sc->sc_hwmap[0].ledoff); - break; - case ATH_LED_TX: - ath_led_blink(sc, sc->sc_hwmap[sc->sc_txrate].ledon, - sc->sc_hwmap[sc->sc_txrate].ledoff); - break; - case ATH_LED_RX: - ath_led_blink(sc, sc->sc_hwmap[sc->sc_rxrate].ledon, - sc->sc_hwmap[sc->sc_rxrate].ledoff); - break; - } -} -#endif - -#ifdef BLE static int ath_rawdev_attach(struct ath_softc *sc) {