diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2008-01-22 21:26:26 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2008-01-22 21:26:26 +0000 |
commit | 898665056b485d72c86d494e2988eabe1a372c39 (patch) | |
tree | 3404c9651d0aad2c2c15ac985da911852a63f8c1 /sys | |
parent | 1162c7d346f4c8e28e2f334df2a65348c9934e46 (diff) |
- Fix some ifconfig up / down tweaks.
- Make monitor mode work again.
- Enable fast channel switching.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/if_upgt.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/sys/dev/usb/if_upgt.c b/sys/dev/usb/if_upgt.c index e4b00b9d55e..f86ad604c93 100644 --- a/sys/dev/usb/if_upgt.c +++ b/sys/dev/usb/if_upgt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_upgt.c,v 1.26 2008/01/21 19:37:36 mglocker Exp $ */ +/* $OpenBSD: if_upgt.c,v 1.27 2008/01/22 21:26:25 mglocker Exp $ */ /* * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org> @@ -1141,6 +1141,7 @@ upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct ifaddr *ifa; struct ifreq *ifr; int s, error = 0; + uint8_t chan; s = splnet(); @@ -1166,11 +1167,26 @@ upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) case SIOCDELMULTI: ifr = (struct ifreq *)data; error = (cmd == SIOCADDMULTI) ? - ether_addmulti(ifr, &ic->ic_ac) : - ether_delmulti(ifr, &ic->ic_ac); + ether_addmulti(ifr, &ic->ic_ac) : + ether_delmulti(ifr, &ic->ic_ac); if (error == ENETRESET) error = 0; break; + case SIOCS80211CHANNEL: + /* allow fast channel switching in monitor mode */ + error = ieee80211_ioctl(ifp, cmd, data); + if (error == ENETRESET && + ic->ic_opmode == IEEE80211_M_MONITOR) { + if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == + (IFF_UP | IFF_RUNNING)) { + ic->ic_bss->ni_chan = ic->ic_ibss_chan; + chan = ieee80211_chan2ieee(ic, + ic->ic_bss->ni_chan); + upgt_set_channel(sc, chan); + } + error = 0; + } + break; default: error = ieee80211_ioctl(ifp, cmd, data); break; @@ -1207,12 +1223,13 @@ upgt_init(struct ifnet *ifp) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - if (ic->ic_opmode == IEEE80211_M_MONITOR) + upgt_set_macfilter(sc, IEEE80211_S_SCAN); + + if (ic->ic_opmode == IEEE80211_M_MONITOR) { + upgt_set_channel(sc, sc->sc_cur_chan); ieee80211_new_state(ic, IEEE80211_S_RUN, -1); - else { - upgt_set_macfilter(sc, IEEE80211_S_SCAN); + } else ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - } return (0); } @@ -1236,13 +1253,19 @@ upgt_stop(struct upgt_softc *sc) int upgt_media_change(struct ifnet *ifp) { + struct upgt_softc *sc = ifp->if_softc; int error; + DPRINTF(1, "%s: %s\n", sc->sc_dev.dv_xname, __func__); + if ((error = ieee80211_media_change(ifp) != ENETRESET)) return (error); - if (ifp->if_flags & (IFF_UP | IFF_RUNNING)) + if (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { + /* give pending USB transfers a chance to finish */ + usbd_delay_ms(sc->sc_udev, 100); upgt_init(ifp); + } return (0); } @@ -1314,7 +1337,8 @@ upgt_newstate_task(void *arg) ni = ic->ic_bss; - upgt_set_macfilter(sc, IEEE80211_S_RUN); + if (ic->ic_opmode != IEEE80211_M_MONITOR) + upgt_set_macfilter(sc, IEEE80211_S_RUN); upgt_set_led(sc, UPGT_LED_ON); break; } |