summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ic/rtw.c177
-rw-r--r--sys/dev/ic/rtwvar.h44
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;
};