diff options
-rw-r--r-- | sys/dev/ic/rtw.c | 177 | ||||
-rw-r--r-- | sys/dev/ic/rtwvar.h | 44 |
2 files changed, 205 insertions, 16 deletions
diff --git a/sys/dev/ic/rtw.c b/sys/dev/ic/rtw.c index de567dacc1a..57e2f15c6d6 100644 --- a/sys/dev/ic/rtw.c +++ b/sys/dev/ic/rtw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtw.c,v 1.17 2005/02/17 18:28:05 reyk Exp $ */ +/* $OpenBSD: rtw.c,v 1.18 2005/02/19 03:33:30 jsg Exp $ */ /* $NetBSD: rtw.c,v 1.29 2004/12/27 19:49:16 dyoung Exp $ */ /*- * Copyright (c) 2004, 2005 David Young. All rights reserved. @@ -211,6 +211,12 @@ struct mbuf *rtw_80211_dequeue(struct rtw_softc *, struct ifqueue *, int, void rtw_recv_beacon(struct rtw_softc *, struct mbuf *, struct ieee80211_node *, int, int, uint32_t); +void rtw_led_attach(struct rtw_softc *); +void rtw_led_init(struct rtw_regs *); +void rtw_led_slowblink(void *); +void rtw_led_fastblink(void *); +void rtw_led_set(struct rtw_led_state *, struct rtw_regs *, int); +void rtw_led_newstate(struct rtw_softc *, enum ieee80211_state); #ifdef RTW_DEBUG void rtw_print_txdesc(struct rtw_softc *, const char *, @@ -1378,6 +1384,9 @@ rtw_intr_rx(struct rtw_softc *sc, u_int16_t isr) m->m_flags |= M_HASFCS; wh = mtod(m, struct ieee80211_frame *); + + if (!IS_BEACON(wh->i_fc[0])) + sc->sc_led_state.ls_event |= RTW_LED_S_RX; /* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */ ni = ieee80211_find_rxnode(&sc->sc_ic, wh); @@ -2525,6 +2534,167 @@ out: return rc; } +void +rtw_led_init(struct rtw_regs *regs) +{ + u_int8_t cfg0, cfg1; + + rtw_set_access(regs, RTW_ACCESS_CONFIG); + + cfg0 = RTW_READ8(regs, RTW_CONFIG0); + cfg0 |= RTW_CONFIG0_LEDGPOEN; + RTW_WRITE8(regs, RTW_CONFIG0, cfg0); + + cfg1 = RTW_READ8(regs, RTW_CONFIG1); + RTW_DPRINTF(RTW_DEBUG_LED, + ("%s: read %" PRIx8 " from reg[CONFIG1]\n", __func__, cfg1)); + + cfg1 &= ~RTW_CONFIG1_LEDS_MASK; + cfg1 |= RTW_CONFIG1_LEDS_TX_RX; + RTW_WRITE8(regs, RTW_CONFIG1, cfg1); + + rtw_set_access(regs, RTW_ACCESS_NONE); +} + +/* + * IEEE80211_S_INIT: LED1 off + * + * IEEE80211_S_AUTH, + * IEEE80211_S_ASSOC, + * IEEE80211_S_SCAN: LED1 blinks @ 1 Hz, blinks at 5Hz for tx/rx + * + * IEEE80211_S_RUN: LED1 on, blinks @ 5Hz for tx/rx + */ +void +rtw_led_newstate(struct rtw_softc *sc, enum ieee80211_state nstate) +{ + struct rtw_led_state *ls; + + ls = &sc->sc_led_state; + + switch (nstate) { + case IEEE80211_S_INIT: + rtw_led_init(&sc->sc_regs); + timeout_del(&ls->ls_slow_ch); + timeout_del(&ls->ls_fast_ch); + ls->ls_slowblink = 0; + ls->ls_actblink = 0; + ls->ls_default = 0; + break; + case IEEE80211_S_SCAN: + timeout_add(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS); + timeout_add(&ls->ls_fast_ch, RTW_LED_FAST_TICKS); + /*FALLTHROUGH*/ + case IEEE80211_S_AUTH: + case IEEE80211_S_ASSOC: + ls->ls_default = RTW_LED1; + ls->ls_actblink = RTW_LED1; + ls->ls_slowblink = RTW_LED1; + break; + case IEEE80211_S_RUN: + ls->ls_slowblink = 0; + break; + } + rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); +} + +void +rtw_led_set(struct rtw_led_state *ls, struct rtw_regs *regs, int hwverid) +{ + u_int8_t led_condition; + bus_size_t ofs; + u_int8_t mask, newval, val; + + led_condition = ls->ls_default; + + if (ls->ls_state & RTW_LED_S_SLOW) + led_condition ^= ls->ls_slowblink; + if (ls->ls_state & (RTW_LED_S_RX|RTW_LED_S_TX)) + led_condition ^= ls->ls_actblink; + + RTW_DPRINTF(RTW_DEBUG_LED, + ("%s: LED condition %" PRIx8 "\n", __func__, led_condition)); + + switch (hwverid) { + default: + case 'F': + ofs = RTW_PSR; + newval = mask = RTW_PSR_LEDGPO0 | RTW_PSR_LEDGPO1; + if (led_condition & RTW_LED0) + newval &= ~RTW_PSR_LEDGPO0; + if (led_condition & RTW_LED1) + newval &= ~RTW_PSR_LEDGPO1; + break; + case 'D': + ofs = RTW_9346CR; + mask = RTW_9346CR_EEM_MASK | RTW_9346CR_EEDI | RTW_9346CR_EECS; + newval = RTW_9346CR_EEM_PROGRAM; + if (led_condition & RTW_LED0) + newval |= RTW_9346CR_EEDI; + if (led_condition & RTW_LED1) + newval |= RTW_9346CR_EECS; + break; + } + val = RTW_READ8(regs, ofs); + RTW_DPRINTF(RTW_DEBUG_LED, + ("%s: read %" PRIx8 " from reg[%#02x]\n", __func__, val, ofs)); + val &= ~mask; + val |= newval; + RTW_WRITE8(regs, ofs, val); + RTW_DPRINTF(RTW_DEBUG_LED, + ("%s: wrote %" PRIx8 " to reg[%#02x]\n", __func__, val, ofs)); + RTW_SYNC(regs, ofs, ofs); +} + +void +rtw_led_fastblink(void *arg) +{ + int ostate, s; + struct rtw_softc *sc = (struct rtw_softc *)arg; + struct rtw_led_state *ls = &sc->sc_led_state; + + s = splnet(); + ostate = ls->ls_state; + ls->ls_state ^= ls->ls_event; + + if ((ls->ls_event & RTW_LED_S_TX) == 0) + ls->ls_state &= ~RTW_LED_S_TX; + + if ((ls->ls_event & RTW_LED_S_RX) == 0) + ls->ls_state &= ~RTW_LED_S_RX; + + ls->ls_event = 0; + + if (ostate != ls->ls_state) + rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); + splx(s); + + timeout_add(&ls->ls_fast_ch, RTW_LED_FAST_TICKS); +} + +void +rtw_led_slowblink(void *arg) +{ + int s; + struct rtw_softc *sc = (struct rtw_softc *)arg; + struct rtw_led_state *ls = &sc->sc_led_state; + + s = splnet(); + ls->ls_state ^= RTW_LED_S_SLOW; + rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid); + splx(s); + timeout_add(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS); +} + +void +rtw_led_attach(struct rtw_softc *sc) +{ + struct rtw_led_state *ls = &sc->sc_led_state; + + timeout_set(&ls->ls_fast_ch, rtw_led_fastblink, sc); + timeout_set(&ls->ls_slow_ch, rtw_led_slowblink, sc); +} + int rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { @@ -2980,6 +3150,7 @@ rtw_start(struct ifnet *ifp) SIMPLEQ_INSERT_TAIL(&tsb->tsb_dirtyq, ts, ts_q); if (tsb != &sc->sc_txsoft_blk[RTW_TXPRIBCN]) { + sc->sc_led_state.ls_event |= RTW_LED_S_TX; tsb->tsb_tx_timer = 5; ifp->if_timer = 1; } @@ -3115,6 +3286,8 @@ rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) ostate = ic->ic_state; + rtw_led_newstate(sc, nstate); + if (nstate == IEEE80211_S_INIT) { timeout_del(&sc->sc_scan_to); sc->sc_cur_chan = IEEE80211_CHAN_ANY; @@ -3714,6 +3887,8 @@ rtw_attach(struct rtw_softc *sc) rtw_set80211props(&sc->sc_ic); + rtw_led_attach(sc); + /* * Call MI attach routines. */ diff --git a/sys/dev/ic/rtwvar.h b/sys/dev/ic/rtwvar.h index ff45b26f9e1..48f78a1af98 100644 --- a/sys/dev/ic/rtwvar.h +++ b/sys/dev/ic/rtwvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rtwvar.h,v 1.6 2005/02/14 12:49:29 jsg Exp $ */ +/* $OpenBSD: rtwvar.h,v 1.7 2005/02/19 03:33:30 jsg Exp $ */ /* $NetBSD: rtwvar.h,v 1.10 2004/12/26 22:37:57 mycroft Exp $ */ /*- * Copyright (c) 2004, 2005 David Young. All rights reserved. @@ -59,8 +59,9 @@ #define RTW_DEBUG_PHYBITIO 0x040000 #define RTW_DEBUG_TIMEOUT 0x080000 #define RTW_DEBUG_BUGS 0x100000 -#define RTW_DEBUG_BEACON 0x200000 -#define RTW_DEBUG_MAX 0x3fffff +#define RTW_DEBUG_BEACON 0x200000 +#define RTW_DEBUG_LED 0x400000 +#define RTW_DEBUG_MAX 0x7fffff extern int rtw_debug; #define RTW_DPRINTF(__flags, __x) \ @@ -73,15 +74,6 @@ extern int rtw_debug; #define DPRINTF(__sc, __flags, __x) #endif /* RTW_DEBUG */ -#if 0 -enum rtw_rftype { - RTW_RFTYPE_INTERSIL = 0, - RTW_RFTYPE_RFMD, - RTW_RFTYPE_PHILIPS, - RTW_RFTYPE_MAXIM -}; -#endif - enum rtw_locale { RTW_LOCALE_USA = 0, RTW_LOCALE_EUROPE, @@ -345,6 +337,29 @@ struct rtw_sa2400 { typedef void (*rtw_pwrstate_t)(struct rtw_regs *, enum rtw_pwrstate, int, int); +union rtw_keys { + u_int8_t rk_keys[4][16]; + u_int32_t rk_words[16]; +}; + +#define RTW_LED_SLOW_TICKS MAX(1, hz/2) +#define RTW_LED_FAST_TICKS MAX(1, hz/10) + +struct rtw_led_state { +#define RTW_LED0 0x1 +#define RTW_LED1 0x2 + u_int8_t ls_slowblink:2; + u_int8_t ls_actblink:2; + u_int8_t ls_default:2; + u_int8_t ls_state; + u_int8_t ls_event; +#define RTW_LED_S_RX 0x1 +#define RTW_LED_S_TX 0x2 +#define RTW_LED_S_SLOW 0x4 + struct timeout ls_slow_ch; + struct timeout ls_fast_ch; +}; + struct rtw_softc { struct device sc_dev; struct ieee80211com sc_ic; @@ -352,9 +367,6 @@ struct rtw_softc { bus_dma_tag_t sc_dmat; u_int32_t sc_flags; -#if 0 - enum rtw_rftype sc_rftype; -#endif enum rtw_attach_state sc_attach_state; enum rtw_rfchipid sc_rfchipid; enum rtw_locale sc_locale; @@ -418,8 +430,10 @@ struct rtw_softc { struct rtw_tx_radiotap_header tap; u_int8_t pad[64]; } sc_txtapu; + union rtw_keys sc_keys; int sc_txkey; struct ifqueue sc_beaconq; + struct rtw_led_state sc_led_state; int sc_hwverid; }; |