diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2011-01-06 17:45:37 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2011-01-06 17:45:37 +0000 |
commit | c6c59da2d5a1c24c96a790dce1b88efe452190e4 (patch) | |
tree | c5605c33e7e0585496bfb906b70c1a4097e4c9ba | |
parent | a95c7bc1320904a3339e9e7cf46bc1b03724db44 (diff) |
create STA entry for our BSS upon association.
update Rx filter after association.
move RECV_START command outside of rx_enable since rx_enable callback
is not allowed to fail.
-rw-r--r-- | sys/dev/usb/if_athn_usb.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/sys/dev/usb/if_athn_usb.c b/sys/dev/usb/if_athn_usb.c index 7b921bb5353..a61f287b12b 100644 --- a/sys/dev/usb/if_athn_usb.c +++ b/sys/dev/usb/if_athn_usb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_athn_usb.c,v 1.1 2011/01/06 07:27:15 damien Exp $ */ +/* $OpenBSD: if_athn_usb.c,v 1.2 2011/01/06 17:45:36 damien Exp $ */ /*- * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr> @@ -1004,9 +1004,11 @@ athn_usb_newstate_cb(struct athn_usb_softc *usc, void *arg) { struct athn_usb_cmd_newstate *cmd = arg; struct athn_softc *sc = &usc->sc_sc; + struct athn_ops *ops = &sc->ops; struct ieee80211com *ic = &sc->sc_ic; enum ieee80211_state ostate; - uint32_t imask; + uint32_t reg, imask; + uint8_t sta_index; int s, error; timeout_del(&sc->calib_to); @@ -1015,27 +1017,38 @@ athn_usb_newstate_cb(struct athn_usb_softc *usc, void *arg) ostate = ic->ic_state; DPRINTF(("newstate %d -> %d\n", ostate, cmd->state)); + if (ostate == IEEE80211_S_RUN) { + sta_index = ((struct athn_node *)ic->ic_bss)->sta_index; + (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE, + &sta_index, sizeof(sta_index), NULL); + } switch (cmd->state) { case IEEE80211_S_INIT: + ops->gpio_write(sc, sc->led_pin, 1); break; case IEEE80211_S_SCAN: + /* Make the LED blink while scanning. */ + ops->gpio_write(sc, sc->led_pin, + !ops->gpio_read(sc, sc->led_pin)); (void)athn_usb_switch_chan(sc, ic->ic_bss->ni_chan, NULL); timeout_add_msec(&sc->scan_to, 200); break; case IEEE80211_S_AUTH: + ops->gpio_write(sc, sc->led_pin, 1); error = athn_usb_switch_chan(sc, ic->ic_bss->ni_chan, NULL); break; case IEEE80211_S_ASSOC: break; case IEEE80211_S_RUN: + ops->gpio_write(sc, sc->led_pin, 0); + if (ic->ic_opmode == IEEE80211_M_MONITOR) break; -#if 0 + /* Create node entry for our BSS. */ error = athn_usb_create_node(usc, ic->ic_bss); -#endif - athn_set_bss(sc, ic->ic_bss); + athn_set_bss(sc, ic->ic_bss); athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); #ifndef IEEE80211_STA_ONLY if (ic->ic_opmode == IEEE80211_M_HOSTAP) { @@ -1049,11 +1062,15 @@ athn_usb_newstate_cb(struct athn_usb_softc *usc, void *arg) /* Enable beacon miss interrupts. */ imask = htobe32(AR_IMR_BMISS); - /* XXX rxfilter */ + /* Stop receiving beacons from other BSS. */ + reg = AR_READ(sc, AR_RX_FILTER); + reg = (reg & ~AR_RX_FILTER_BEACON) | + AR_RX_FILTER_MYBEACON; + AR_WRITE(sc, AR_RX_FILTER, reg); + AR_WRITE_BARRIER(sc); } athn_usb_wmi_xcmd(usc, AR_WMI_CMD_ENABLE_INTR, &imask, sizeof(imask), NULL); - break; } (void)sc->sc_newstate(ic, cmd->state, cmd->arg); @@ -1066,7 +1083,7 @@ athn_usb_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, { struct athn_usb_softc *usc = ic->ic_softc; - if (/*ic->ic_opmode != IEEE80211_M_HOSTAP ||*/ !isnew) + if (ic->ic_opmode != IEEE80211_M_HOSTAP || !isnew) return; /* Do it in a process context. */ ieee80211_ref_node(ni); @@ -1218,9 +1235,6 @@ athn_usb_create_node(struct athn_usb_softc *usc, struct ieee80211_node *ni) void athn_usb_rx_enable(struct athn_softc *sc) { - struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; - - (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV); AR_WRITE(sc, AR_CR, AR_CR_RXE); AR_WRITE_BARRIER(sc); } @@ -1254,6 +1268,10 @@ athn_usb_switch_chan(struct athn_softc *sc, struct ieee80211_channel *c, /* Set transmit power values for new channel. */ ops->set_txpower(sc, c, extc); + error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV); + if (error != 0) + goto fail; + athn_rx_start(sc); mode = htobe16(IEEE80211_IS_CHAN_2GHZ(c) ? @@ -2151,6 +2169,10 @@ athn_usb_init(struct ifnet *ifp) if (error != 0) goto fail; + error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV); + if (error != 0) + goto fail; + athn_rx_start(sc); /* Create main interface on target. */ @@ -2301,5 +2323,6 @@ athn_usb_stop(struct ifnet *ifp) /* Flush Rx stream. */ if (usc->rx_stream.m != NULL) m_freem(usc->rx_stream.m); + usc->rx_stream.m = NULL; usc->rx_stream.left = 0; } |