diff options
Diffstat (limited to 'sys/dev/iwi/if_iwi.c')
| -rw-r--r-- | sys/dev/iwi/if_iwi.c | 78 |
1 files changed, 42 insertions, 36 deletions
diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index 6957f9b9a87d..a551448c6907 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); #include <sys/namei.h> #include <sys/linker.h> #include <sys/firmware.h> -#include <sys/kthread.h> #include <sys/taskqueue.h> #include <machine/bus.h> @@ -154,6 +153,7 @@ static void iwi_media_status(struct ifnet *, struct ifmediareq *); static int iwi_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void iwi_wme_init(struct iwi_softc *); static int iwi_wme_setparams(struct iwi_softc *, struct ieee80211com *); +static void iwi_update_wme(void *, int); static int iwi_wme_update(struct ieee80211com *); static uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t); static void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int, @@ -291,6 +291,7 @@ iwi_attach(device_t dev) TASK_INIT(&sc->sc_radiofftask, 0, iwi_radio_off, sc); TASK_INIT(&sc->sc_restarttask, 0, iwi_restart, sc); TASK_INIT(&sc->sc_disassoctask, 0, iwi_disassoc, sc); + TASK_INIT(&sc->sc_wmetask, 0, iwi_update_wme, sc); callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0); callout_init_mtx(&sc->sc_rftimer, &sc->sc_mtx, 0); @@ -418,16 +419,11 @@ iwi_attach(device_t dev) ic->ic_vap_create = iwi_vap_create; ic->ic_vap_delete = iwi_vap_delete; - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap)); - - sc->sc_rxtap_len = sizeof sc->sc_rxtap; - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(IWI_RX_RADIOTAP_PRESENT); - - sc->sc_txtap_len = sizeof sc->sc_txtap; - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(IWI_TX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + IWI_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + IWI_RX_RADIOTAP_PRESENT); iwi_sysctlattach(sc); iwi_ledattach(sc); @@ -459,17 +455,16 @@ iwi_detach(device_t dev) struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; - iwi_stop(sc); - - bpfdetach(ifp); - ieee80211_ifdetach(ic); - /* NB: do early to drain any pending tasks */ ieee80211_draintask(ic, &sc->sc_radiontask); ieee80211_draintask(ic, &sc->sc_radiofftask); ieee80211_draintask(ic, &sc->sc_restarttask); ieee80211_draintask(ic, &sc->sc_disassoctask); + iwi_stop(sc); + + ieee80211_ifdetach(ic); + iwi_put_firmware(sc); iwi_release_fw_dma(sc); @@ -1082,6 +1077,18 @@ iwi_wme_setparams(struct iwi_softc *sc, struct ieee80211com *ic) #undef IWI_USEC #undef IWI_EXP2 +static void +iwi_update_wme(void *arg, int npending) +{ + struct ieee80211com *ic = arg; + struct iwi_softc *sc = ic->ic_ifp->if_softc; + IWI_LOCK_DECL; + + IWI_LOCK(sc); + (void) iwi_wme_setparams(sc, ic); + IWI_UNLOCK(sc); +} + static int iwi_wme_update(struct ieee80211com *ic) { @@ -1091,13 +1098,13 @@ iwi_wme_update(struct ieee80211com *ic) /* * We may be called to update the WME parameters in * the adapter at various places. If we're already - * associated then initiate the request immediately - * (via the taskqueue); otherwise we assume the params - * will get sent down to the adapter as part of the - * work iwi_auth_and_assoc does. + * associated then initiate the request immediately; + * otherwise we assume the params will get sent down + * to the adapter as part of the work iwi_auth_and_assoc + * does. */ if (vap->iv_state == IEEE80211_S_RUN) - (void) iwi_wme_setparams(sc, ic); + ieee80211_runtask(ic, &sc->sc_wmetask); return (0); } @@ -1183,11 +1190,7 @@ iwi_setcurchan(struct iwi_softc *sc, int chan) struct ieee80211com *ic = ifp->if_l2com; sc->curchan = chan; - - sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq = - htole16(ic->ic_curchan->ic_freq); - sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags = - htole16(ic->ic_curchan->ic_flags); + ieee80211_radiotap_chan_change(ic); } static void @@ -1199,6 +1202,7 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, struct mbuf *mnew, *m; struct ieee80211_node *ni; int type, error, framelen; + int8_t rssi, nf; IWI_LOCK_DECL; framelen = le16toh(frame->len); @@ -1270,24 +1274,25 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, m_adj(m, sizeof (struct iwi_hdr) + sizeof (struct iwi_frame)); - if (bpf_peers_present(ifp->if_bpf)) { + rssi = frame->rssi_dbm; + nf = -95; + if (ieee80211_radiotap_active(ic)) { struct iwi_rx_radiotap_header *tap = &sc->sc_rxtap; tap->wr_flags = 0; + tap->wr_antsignal = rssi; + tap->wr_antnoise = nf; tap->wr_rate = iwi_cvtrate(frame->rate); - tap->wr_antsignal = frame->signal; tap->wr_antenna = frame->antenna; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } IWI_UNLOCK(sc); ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); if (ni != NULL) { - type = ieee80211_input(ni, m, frame->rssi_dbm, 0, 0); + type = ieee80211_input(ni, m, rssi, nf); ieee80211_free_node(ni); } else - type = ieee80211_input_all(ic, m, frame->rssi_dbm, 0, 0); + type = ieee80211_input_all(ic, m, rssi, nf); IWI_LOCK(sc); if (sc->sc_softled) { @@ -1622,8 +1627,11 @@ iwi_fatal_error_intr(struct iwi_softc *sc) { struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); device_printf(sc->sc_dev, "firmware error\n"); + if (vap != NULL) + ieee80211_cancel_scan(vap); ieee80211_runtask(ic, &sc->sc_restarttask); sc->flags &= ~IWI_FLAG_BUSY; @@ -1836,12 +1844,12 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni, wh = mtod(m0, struct ieee80211_frame *); } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct iwi_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } data = &txq->data[txq->cur]; @@ -1952,8 +1960,6 @@ iwi_start_locked(struct ifnet *ifp) break; } - BPF_MTAP(ifp, m); - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; if (iwi_tx_start(ifp, m, ni, ac) != 0) { ieee80211_free_node(ni); |
