diff options
Diffstat (limited to 'sys/dev/mwl')
-rw-r--r-- | sys/dev/mwl/if_mwl.c | 509 | ||||
-rw-r--r-- | sys/dev/mwl/if_mwl_pci.c | 1 | ||||
-rw-r--r-- | sys/dev/mwl/if_mwlvar.h | 6 |
3 files changed, 204 insertions, 312 deletions
diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c index 0997500..42264ac 100644 --- a/sys/dev/mwl/if_mwl.c +++ b/sys/dev/mwl/if_mwl.c @@ -91,17 +91,17 @@ static struct ieee80211vap *mwl_vap_create(struct ieee80211com *, static void mwl_vap_delete(struct ieee80211vap *); static int mwl_setupdma(struct mwl_softc *); static int mwl_hal_reset(struct mwl_softc *sc); -static int mwl_init_locked(struct mwl_softc *); -static void mwl_init(void *); -static void mwl_stop_locked(struct ifnet *, int); +static int mwl_init(struct mwl_softc *); +static void mwl_parent(struct ieee80211com *); static int mwl_reset(struct ieee80211vap *, u_long); -static void mwl_stop(struct ifnet *, int); -static void mwl_start(struct ifnet *); +static void mwl_stop(struct mwl_softc *); +static void mwl_start(struct mwl_softc *); +static int mwl_transmit(struct ieee80211com *, struct mbuf *); static int mwl_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static int mwl_media_change(struct ifnet *); static void mwl_watchdog(void *); -static int mwl_ioctl(struct ifnet *, u_long, caddr_t); +static int mwl_ioctl(struct ieee80211com *, u_long, void *); static void mwl_radar_proc(void *, int); static void mwl_chanswitch_proc(void *, int); static void mwl_bawatchdog_proc(void *, int); @@ -229,12 +229,11 @@ enum { ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK|IEEE80211_FC0_SUBTYPE_MASK)) == \ (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON)) #define IFF_DUMPPKTS_RECV(sc, wh) \ - (((sc->sc_debug & MWL_DEBUG_RECV) && \ - ((sc->sc_debug & MWL_DEBUG_RECV_ALL) || !IS_BEACON(wh))) || \ - (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) + ((sc->sc_debug & MWL_DEBUG_RECV) && \ + ((sc->sc_debug & MWL_DEBUG_RECV_ALL) || !IS_BEACON(wh))) #define IFF_DUMPPKTS_XMIT(sc) \ - ((sc->sc_debug & MWL_DEBUG_XMIT) || \ - (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) + (sc->sc_debug & MWL_DEBUG_XMIT) + #define DPRINTF(sc, m, fmt, ...) do { \ if (sc->sc_debug & (m)) \ printf(fmt, __VA_ARGS__); \ @@ -246,16 +245,10 @@ enum { static void mwl_printrxbuf(const struct mwl_rxbuf *bf, u_int ix); static void mwl_printtxbuf(const struct mwl_txbuf *bf, u_int qnum, u_int ix); #else -#define IFF_DUMPPKTS_RECV(sc, wh) \ - ((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) -#define IFF_DUMPPKTS_XMIT(sc) \ - ((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) -#define DPRINTF(sc, m, fmt, ...) do { \ - (void) sc; \ -} while (0) -#define KEYPRINTF(sc, k, mac) do { \ - (void) sc; \ -} while (0) +#define IFF_DUMPPKTS_RECV(sc, wh) do {} while (0) +#define IFF_DUMPPKTS_XMIT(sc) do {} while (0) +#define DPRINTF(sc, m, fmt, ...) do {} while (0) +#define KEYPRINTF(sc, k, mac) do {} while (0) #endif static MALLOC_DEFINE(M_MWLDEV, "mwldev", "mwl driver dma buffers"); @@ -293,34 +286,22 @@ WR4(struct mwl_softc *sc, bus_size_t off, uint32_t val) int mwl_attach(uint16_t devid, struct mwl_softc *sc) { - struct ifnet *ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; struct mwl_hal *mh; int error = 0; DPRINTF(sc, MWL_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "cannot if_alloc()\n"); - return ENOSPC; - } - ic = ifp->if_l2com; - /* * Setup the RX free list lock early, so it can be consistently * removed. */ MWL_RXFREE_INIT(sc); - /* set these up early for if_printf use */ - if_initname(ifp, device_get_name(sc->sc_dev), - device_get_unit(sc->sc_dev)); - mh = mwl_hal_attach(sc->sc_dev, devid, sc->sc_io1h, sc->sc_io1t, sc->sc_dmat); if (mh == NULL) { - if_printf(ifp, "unable to attach HAL\n"); + device_printf(sc->sc_dev, "unable to attach HAL\n"); error = EIO; goto bad; } @@ -331,12 +312,12 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) * needed so setting up the wrong mode isn't a big deal. */ if (mwl_hal_fwload(mh, NULL) != 0) { - if_printf(ifp, "unable to setup builtin firmware\n"); + device_printf(sc->sc_dev, "unable to setup builtin firmware\n"); error = EIO; goto bad1; } if (mwl_hal_gethwspecs(mh, &sc->sc_hwspecs) != 0) { - if_printf(ifp, "unable to fetch h/w specs\n"); + device_printf(sc->sc_dev, "unable to fetch h/w specs\n"); error = EIO; goto bad1; } @@ -356,7 +337,8 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) */ error = mwl_dma_setup(sc); if (error != 0) { - if_printf(ifp, "failed to setup descriptors: %d\n", error); + device_printf(sc->sc_dev, "failed to setup descriptors: %d\n", + error); goto bad1; } error = mwl_setupdma(sc); /* push to firmware */ @@ -365,11 +347,12 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) callout_init(&sc->sc_timer, 1); callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); sc->sc_tq = taskqueue_create("mwl_taskq", M_NOWAIT, taskqueue_thread_enqueue, &sc->sc_tq); taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, - "%s taskq", ifp->if_xname); + "%s taskq", device_get_nameunit(sc->sc_dev)); TASK_INIT(&sc->sc_rxtask, 0, mwl_rx_proc, sc); TASK_INIT(&sc->sc_radartask, 0, mwl_radar_proc, sc); @@ -378,8 +361,9 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) /* NB: insure BK queue is the lowest priority h/w queue */ if (!mwl_tx_setup(sc, WME_AC_BK, MWL_WME_AC_BK)) { - if_printf(ifp, "unable to setup xmit queue for %s traffic!\n", - ieee80211_wme_acnames[WME_AC_BK]); + device_printf(sc->sc_dev, + "unable to setup xmit queue for %s traffic!\n", + ieee80211_wme_acnames[WME_AC_BK]); error = EIO; goto bad2; } @@ -403,16 +387,6 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) } TASK_INIT(&sc->sc_txtask, 0, mwl_tx_proc, sc); - ifp->if_softc = sc; - ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; - ifp->if_start = mwl_start; - ifp->if_ioctl = mwl_ioctl; - ifp->if_init = mwl_init; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(sc->sc_dev); /* XXX not right but it's not used anywhere important */ @@ -480,8 +454,10 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) ic->ic_headroom = sizeof(struct mwltxrec) - sizeof(struct ieee80211_frame); + IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->sc_hwspecs.macAddr); + /* call MI attach routine. */ - ieee80211_ifattach(ic, sc->sc_hwspecs.macAddr); + ieee80211_ifattach(ic); ic->ic_setregdomain = mwl_setregdomain; ic->ic_getradiocaps = mwl_getradiocaps; /* override default methods */ @@ -491,6 +467,9 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) ic->ic_update_mcast = mwl_update_mcast; ic->ic_update_promisc = mwl_update_promisc; ic->ic_wme.wme_update = mwl_wme_update; + ic->ic_transmit = mwl_transmit; + ic->ic_ioctl = mwl_ioctl; + ic->ic_parent = mwl_parent; ic->ic_node_alloc = mwl_node_alloc; sc->sc_node_cleanup = ic->ic_node_cleanup; @@ -537,7 +516,6 @@ bad1: mwl_hal_detach(mh); bad: MWL_RXFREE_DESTROY(sc); - if_free(ifp); sc->sc_invalid = 1; return error; } @@ -545,13 +523,11 @@ bad: int mwl_detach(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n", - __func__, ifp->if_flags); + struct ieee80211com *ic = &sc->sc_ic; - mwl_stop(ifp, 1); + MWL_LOCK(sc); + mwl_stop(sc); + MWL_UNLOCK(sc); /* * NB: the order of these is important: * o call the 802.11 layer before detaching the hal to @@ -570,7 +546,7 @@ mwl_detach(struct mwl_softc *sc) MWL_RXFREE_DESTROY(sc); mwl_tx_cleanup(sc); mwl_hal_detach(sc->sc_mh); - if_free(ifp); + mbufq_drain(&sc->sc_snd); return 0; } @@ -601,7 +577,7 @@ assign_address(struct mwl_softc *sc, uint8_t mac[IEEE80211_ADDR_LEN], int clone) } static void -reclaim_address(struct mwl_softc *sc, uint8_t mac[IEEE80211_ADDR_LEN]) +reclaim_address(struct mwl_softc *sc, const uint8_t mac[IEEE80211_ADDR_LEN]) { int i = mac[0] >> 2; if (i != 0 || --sc->sc_nbssid0 == 0) @@ -614,8 +590,7 @@ mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac0[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_hal *mh = sc->sc_mh; struct ieee80211vap *vap, *apvap; struct mwl_hal_vap *hvap; @@ -661,17 +636,7 @@ mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, return NULL; } - mvp = (struct mwl_vap *) malloc(sizeof(struct mwl_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (mvp == NULL) { - if (hvap != NULL) { - mwl_hal_delvap(hvap); - if ((flags & IEEE80211_CLONE_MACADDR) == 0) - reclaim_address(sc, mac); - } - /* XXX msg */ - return NULL; - } + mvp = malloc(sizeof(struct mwl_vap), M_80211_VAP, M_WAITOK | M_ZERO); mvp->mv_hvap = hvap; if (opmode == IEEE80211_M_WDS) { /* @@ -686,9 +651,7 @@ mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, KASSERT(mvp->mv_ap_hvap != NULL, ("no ap vap")); } vap = &mvp->mv_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); - if (hvap != NULL) - IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override with driver methods */ mvp->mv_newstate = vap->iv_newstate; vap->iv_newstate = mwl_newstate; @@ -713,7 +676,8 @@ mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_4; /* complete setup */ - ieee80211_vap_attach(vap, mwl_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, mwl_media_change, ieee80211_media_status, + mac); switch (vap->iv_opmode) { case IEEE80211_M_HOSTAP: @@ -752,14 +716,13 @@ static void mwl_vap_delete(struct ieee80211vap *vap) { struct mwl_vap *mvp = MWL_VAP(vap); - struct ifnet *parent = vap->iv_ic->ic_ifp; - struct mwl_softc *sc = parent->if_softc; + struct mwl_softc *sc = vap->iv_ic->ic_softc; struct mwl_hal *mh = sc->sc_mh; struct mwl_hal_vap *hvap = mvp->mv_hvap; enum ieee80211_opmode opmode = vap->iv_opmode; /* XXX disallow ap vap delete if WDS still present */ - if (parent->if_drv_flags & IFF_DRV_RUNNING) { + if (sc->sc_running) { /* quiesce h/w while we remove the vap */ mwl_hal_intrset(mh, 0); /* disable interrupts */ } @@ -786,31 +749,31 @@ mwl_vap_delete(struct ieee80211vap *vap) } mwl_cleartxq(sc, vap); free(mvp, M_80211_VAP); - if (parent->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_running) mwl_hal_intrset(mh, sc->sc_imask); } void mwl_suspend(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n", - __func__, ifp->if_flags); - - mwl_stop(ifp, 1); + MWL_LOCK(sc); + mwl_stop(sc); + MWL_UNLOCK(sc); } void mwl_resume(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; + int error = EDOOFUS; - DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n", - __func__, ifp->if_flags); + MWL_LOCK(sc); + if (sc->sc_ic.ic_nrunning > 0) + error = mwl_init(sc); + MWL_UNLOCK(sc); - if (ifp->if_flags & IFF_UP) - mwl_init(sc); + if (error == 0) + ieee80211_start_all(&sc->sc_ic); /* start all vap's */ } void @@ -818,7 +781,9 @@ mwl_shutdown(void *arg) { struct mwl_softc *sc = arg; - mwl_stop(sc->sc_ifp, 1); + MWL_LOCK(sc); + mwl_stop(sc); + MWL_UNLOCK(sc); } /* @@ -884,8 +849,7 @@ static void mwl_radar_proc(void *arg, int pending) { struct mwl_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; DPRINTF(sc, MWL_DEBUG_ANY, "%s: radar detected, pending %u\n", __func__, pending); @@ -902,8 +866,7 @@ static void mwl_chanswitch_proc(void *arg, int pending) { struct mwl_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; DPRINTF(sc, MWL_DEBUG_ANY, "%s: channel switch notice, pending %u\n", __func__, pending); @@ -1031,8 +994,7 @@ mwl_setupdma(struct mwl_softc *sc) static int mwl_setcurchanrates(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct ieee80211_rateset *rs; MWL_HAL_TXRATE rates; @@ -1145,8 +1107,7 @@ mwl_map2regioncode(const struct ieee80211_regdomain *rd) static int mwl_hal_reset(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mwl_hal *mh = sc->sc_mh; mwl_hal_setantenna(mh, WL_ANTENNATYPE_RX, sc->sc_rxantenna); @@ -1168,28 +1129,24 @@ mwl_hal_reset(struct mwl_softc *sc) } static int -mwl_init_locked(struct mwl_softc *sc) +mwl_init(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct mwl_hal *mh = sc->sc_mh; int error = 0; - DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags 0x%x\n", - __func__, ifp->if_flags); - MWL_LOCK_ASSERT(sc); /* * Stop anything previously setup. This is safe * whether this is the first time through or not. */ - mwl_stop_locked(ifp, 0); + mwl_stop(sc); /* * Push vap-independent state to the firmware. */ if (!mwl_hal_reset(sc)) { - if_printf(ifp, "unable to reset hardware\n"); + device_printf(sc->sc_dev, "unable to reset hardware\n"); return EIO; } @@ -1198,7 +1155,7 @@ mwl_init_locked(struct mwl_softc *sc) */ error = mwl_startrecv(sc); if (error != 0) { - if_printf(ifp, "unable to start recv logic\n"); + device_printf(sc->sc_dev, "unable to start recv logic\n"); return error; } @@ -1221,7 +1178,7 @@ mwl_init_locked(struct mwl_softc *sc) | MACREQ_A2HRIC_BIT_TX_ACK ; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_running = 1; mwl_hal_intrset(mh, sc->sc_imask); callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc); @@ -1229,54 +1186,21 @@ mwl_init_locked(struct mwl_softc *sc) } static void -mwl_init(void *arg) +mwl_stop(struct mwl_softc *sc) { - struct mwl_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - int error = 0; - - DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags 0x%x\n", - __func__, ifp->if_flags); - - MWL_LOCK(sc); - error = mwl_init_locked(sc); - MWL_UNLOCK(sc); - - if (error == 0) - ieee80211_start_all(ic); /* start all vap's */ -} - -static void -mwl_stop_locked(struct ifnet *ifp, int disable) -{ - struct mwl_softc *sc = ifp->if_softc; - - DPRINTF(sc, MWL_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n", - __func__, sc->sc_invalid, ifp->if_flags); MWL_LOCK_ASSERT(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (sc->sc_running) { /* * Shutdown the hardware and driver. */ - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + sc->sc_running = 0; callout_stop(&sc->sc_watchdog); sc->sc_tx_timer = 0; mwl_draintxq(sc); } } -static void -mwl_stop(struct ifnet *ifp, int disable) -{ - struct mwl_softc *sc = ifp->if_softc; - - MWL_LOCK(sc); - mwl_stop_locked(ifp, disable); - MWL_UNLOCK(sc); -} - static int mwl_reset_vap(struct ieee80211vap *vap, int state) { @@ -1319,8 +1243,7 @@ mwl_reset(struct ieee80211vap *vap, u_long cmd) if (hvap != NULL) { /* WDS, MONITOR, etc. */ struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_hal *mh = sc->sc_mh; /* XXX handle DWDS sta vap change */ @@ -1386,24 +1309,41 @@ mwl_puttxbuf_tail(struct mwl_txq *txq, struct mwl_txbuf *bf) MWL_TXQ_UNLOCK(txq); } +static int +mwl_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct mwl_softc *sc = ic->ic_softc; + int error; + + MWL_LOCK(sc); + if (!sc->sc_running) { + MWL_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + MWL_UNLOCK(sc); + return (error); + } + mwl_start(sc); + MWL_UNLOCK(sc); + return (0); +} + static void -mwl_start(struct ifnet *ifp) +mwl_start(struct mwl_softc *sc) { - struct mwl_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mwl_txbuf *bf; struct mbuf *m; struct mwl_txq *txq = NULL; /* XXX silence gcc */ int nqueued; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) + MWL_LOCK_ASSERT(sc); + if (!sc->sc_running || sc->sc_invalid) return; nqueued = 0; - for (;;) { - bf = NULL; - IFQ_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { /* * Grab the node for the destination. */ @@ -1421,8 +1361,6 @@ mwl_start(struct ifnet *ifp) ieee80211_free_node(ni); #ifdef MWL_TX_NODROP sc->sc_stats.mst_tx_qstop++; - /* XXX blocks other traffic */ - ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; #else DPRINTF(sc, MWL_DEBUG_XMIT, @@ -1436,7 +1374,8 @@ mwl_start(struct ifnet *ifp) * Pass the frame to the h/w for transmission. */ if (mwl_tx_start(sc, ni, bf, m)) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); mwl_puttxbuf_head(txq, bf); ieee80211_free_node(ni); continue; @@ -1474,12 +1413,11 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_txbuf *bf; struct mwl_txq *txq; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) { + if (!sc->sc_running || sc->sc_invalid) { ieee80211_free_node(ni); m_freem(m); return ENETDOWN; @@ -1496,8 +1434,6 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, bf = mwl_gettxbuf(sc, txq); if (bf == NULL) { sc->sc_stats.mst_tx_qstop++; - /* XXX blocks other traffic */ - ifp->if_drv_flags |= IFF_DRV_OACTIVE; ieee80211_free_node(ni); m_freem(m); return ENOBUFS; @@ -1506,7 +1442,6 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, * Pass the frame to the h/w for transmission. */ if (mwl_tx_start(sc, ni, bf, m)) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); mwl_puttxbuf_head(txq, bf); ieee80211_free_node(ni); @@ -1581,7 +1516,7 @@ static int mwl_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) { - struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct mwl_softc *sc = vap->iv_ic->ic_softc; if (k->wk_keyix != IEEE80211_KEYIX_NONE || (k->wk_flags & IEEE80211_KEY_GROUP)) { @@ -1609,7 +1544,7 @@ mwl_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, static int mwl_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) { - struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct mwl_softc *sc = vap->iv_ic->ic_softc; struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; MWL_HAL_KEYVAL hk; const uint8_t bcastaddr[IEEE80211_ADDR_LEN] = @@ -1676,7 +1611,7 @@ mwl_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, #define IEEE80211_IS_STATICKEY(k) \ (((k)->wk_flags & (GRPXMIT|IEEE80211_KEY_RECV)) == \ (GRPXMIT|IEEE80211_KEY_RECV)) - struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct mwl_softc *sc = vap->iv_ic->ic_softc; struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; const struct ieee80211_cipher *cip = k->wk_cipher; const uint8_t *macaddr; @@ -1791,7 +1726,6 @@ mwl_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, static void mwl_setmcastfilter(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; #if 0 struct ether_multi *enm; struct ether_multistep estep; @@ -1815,17 +1749,13 @@ mwl_setmcastfilter(struct mwl_softc *sc) } ifp->if_flags &= ~IFF_ALLMULTI; mwl_hal_setmcast(sc->sc_mh, nmc, macs); -#else - /* XXX no mcast filter support; we get everything */ - ifp->if_flags |= IFF_ALLMULTI; #endif } static int mwl_mode_init(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mwl_hal *mh = sc->sc_mh; /* @@ -1834,7 +1764,7 @@ mwl_mode_init(struct mwl_softc *sc) * identify internal requests (from the bridge) * versus external requests such as for tcpdump. */ - mwl_hal_setpromisc(mh, (ifp->if_flags & IFF_PROMISC) && + mwl_hal_setpromisc(mh, ic->ic_promisc > 0 && ic->ic_opmode != IEEE80211_M_HOSTAP); mwl_setmcastfilter(sc); @@ -1864,8 +1794,7 @@ mwl_update_promisc(struct ieee80211com *ic) { struct mwl_softc *sc = ic->ic_softc; - mwl_hal_setpromisc(sc->sc_mh, - (ic->ic_ifp->if_flags & IFF_PROMISC) != 0); + mwl_hal_setpromisc(sc->sc_mh, ic->ic_promisc > 0); } /* @@ -1882,7 +1811,7 @@ mwl_updateslot(struct ieee80211com *ic) int prot; /* NB: can be called early; suppress needless cmds */ - if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if (!sc->sc_running) return; /* @@ -2004,7 +1933,6 @@ mwl_desc_setup(struct mwl_softc *sc, const char *name, struct mwl_descdma *dd, int nbuf, size_t bufsize, int ndesc, size_t descsize) { - struct ifnet *ifp = sc->sc_ifp; uint8_t *ds; int error; @@ -2032,7 +1960,7 @@ mwl_desc_setup(struct mwl_softc *sc, const char *name, NULL, /* lockarg */ &dd->dd_dmat); if (error != 0) { - if_printf(ifp, "cannot allocate %s DMA tag\n", dd->dd_name); + device_printf(sc->sc_dev, "cannot allocate %s DMA tag\n", dd->dd_name); return error; } @@ -2041,7 +1969,7 @@ mwl_desc_setup(struct mwl_softc *sc, const char *name, BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dd->dd_dmamap); if (error != 0) { - if_printf(ifp, "unable to alloc memory for %u %s descriptors, " + device_printf(sc->sc_dev, "unable to alloc memory for %u %s descriptors, " "error %u\n", nbuf * ndesc, dd->dd_name, error); goto fail1; } @@ -2051,7 +1979,7 @@ mwl_desc_setup(struct mwl_softc *sc, const char *name, mwl_load_cb, &dd->dd_desc_paddr, BUS_DMA_NOWAIT); if (error != 0) { - if_printf(ifp, "unable to map %s descriptors, error %u\n", + device_printf(sc->sc_dev, "unable to map %s descriptors, error %u\n", dd->dd_name, error); goto fail2; } @@ -2109,7 +2037,6 @@ mwl_txq_reset(struct mwl_softc *sc, struct mwl_txq *txq) static int mwl_txdma_setup(struct mwl_softc *sc, struct mwl_txq *txq) { - struct ifnet *ifp = sc->sc_ifp; int error, bsize, i; struct mwl_txbuf *bf; struct mwl_txdesc *ds; @@ -2124,7 +2051,7 @@ mwl_txdma_setup(struct mwl_softc *sc, struct mwl_txq *txq) bsize = mwl_txbuf * sizeof(struct mwl_txbuf); bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO); if (bf == NULL) { - if_printf(ifp, "malloc of %u tx buffers failed\n", + device_printf(sc->sc_dev, "malloc of %u tx buffers failed\n", mwl_txbuf); return ENOMEM; } @@ -2137,7 +2064,7 @@ mwl_txdma_setup(struct mwl_softc *sc, struct mwl_txq *txq) error = bus_dmamap_create(sc->sc_dmat, BUS_DMA_NOWAIT, &bf->bf_dmamap); if (error != 0) { - if_printf(ifp, "unable to create dmamap for tx " + device_printf(sc->sc_dev, "unable to create dmamap for tx " "buffer %u, error %u\n", i, error); return error; } @@ -2172,7 +2099,6 @@ mwl_txdma_cleanup(struct mwl_softc *sc, struct mwl_txq *txq) static int mwl_rxdma_setup(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; int error, jumbosize, bsize, i; struct mwl_rxbuf *bf; struct mwl_jumbo *rbuf; @@ -2196,7 +2122,7 @@ mwl_rxdma_setup(struct mwl_softc *sc) * us while frames are processed. */ if (mwl_rxbuf < 2*mwl_rxdesc) { - if_printf(ifp, + device_printf(sc->sc_dev, "too few rx dma buffers (%d); increasing to %d\n", mwl_rxbuf, 2*mwl_rxdesc); mwl_rxbuf = 2*mwl_rxdesc; @@ -2217,7 +2143,7 @@ mwl_rxdma_setup(struct mwl_softc *sc) NULL, /* lockarg */ &sc->sc_rxdmat); if (error != 0) { - if_printf(ifp, "could not create rx DMA tag\n"); + device_printf(sc->sc_dev, "could not create rx DMA tag\n"); return error; } @@ -2225,7 +2151,7 @@ mwl_rxdma_setup(struct mwl_softc *sc) BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->sc_rxmap); if (error != 0) { - if_printf(ifp, "could not alloc %ju bytes of rx DMA memory\n", + device_printf(sc->sc_dev, "could not alloc %ju bytes of rx DMA memory\n", (uintmax_t) sc->sc_rxmemsize); return error; } @@ -2235,7 +2161,7 @@ mwl_rxdma_setup(struct mwl_softc *sc) mwl_load_cb, &sc->sc_rxmem_paddr, BUS_DMA_NOWAIT); if (error != 0) { - if_printf(ifp, "could not load rx DMA map\n"); + device_printf(sc->sc_dev, "could not load rx DMA map\n"); return error; } @@ -2245,7 +2171,7 @@ mwl_rxdma_setup(struct mwl_softc *sc) bsize = mwl_rxdesc * sizeof(struct mwl_rxbuf); bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO); if (bf == NULL) { - if_printf(ifp, "malloc of %u rx buffers failed\n", bsize); + device_printf(sc->sc_dev, "malloc of %u rx buffers failed\n", bsize); return error; } sc->sc_rxdma.dd_bufptr = bf; @@ -2329,7 +2255,7 @@ static struct ieee80211_node * mwl_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) { struct ieee80211com *ic = vap->iv_ic; - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; const size_t space = sizeof(struct mwl_node); struct mwl_node *mn; @@ -2346,7 +2272,7 @@ static void mwl_node_cleanup(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_node *mn = MWL_NODE(ni); DPRINTF(sc, MWL_DEBUG_NODE, "%s: ni %p ic %p staid %d\n", @@ -2441,7 +2367,7 @@ static void mwl_node_drain(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_node *mn = MWL_NODE(ni); DPRINTF(sc, MWL_DEBUG_NODE, "%s: ni %p vap %p staid %d\n", @@ -2696,8 +2622,7 @@ mwl_rx_proc(void *arg, int npending) #define IEEE80211_DIR_DSTODS(wh) \ ((((const struct ieee80211_frame *)wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) struct mwl_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mwl_rxbuf *bf; struct mwl_rxdesc *ds; struct mbuf *m; @@ -2744,7 +2669,7 @@ mwl_rx_proc(void *arg, int npending) #endif status = ds->Status; if (status & EAGLE_RXD_STATUS_DECRYPT_ERR_MASK) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); sc->sc_stats.mst_rx_crypto++; /* * NB: Check EAGLE_RXD_STATUS_GENERAL_DECRYPT_ERR @@ -2840,7 +2765,6 @@ mwl_rx_proc(void *arg, int npending) data, sc, 0, EXT_NET_DRV); m->m_data += off - hdrlen; m->m_pkthdr.len = m->m_len = pktlen; - m->m_pkthdr.rcvif = ifp; /* NB: dma buffer assumed read-only */ /* @@ -2890,8 +2814,6 @@ mwl_rx_proc(void *arg, int npending) ieee80211_dump_pkt(ic, mtod(m, caddr_t), len, ds->Rate, rssi); } - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); - /* dispatch */ ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) wh); @@ -2918,11 +2840,10 @@ rx_next: rx_stop: sc->sc_rxnext = bf; - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && - !IFQ_IS_EMPTY(&ifp->if_snd)) { + if (mbufq_first(&sc->sc_snd) != NULL) { /* NB: kick fw; the tx thread may have been preempted */ mwl_hal_txstart(sc->sc_mh, 0); - mwl_start(ifp); + mwl_start(sc); } #undef IEEE80211_DIR_DSTODS } @@ -2987,8 +2908,7 @@ static int mwl_txq_update(struct mwl_softc *sc, int ac) { #define MWL_EXPONENT_TO_VALUE(v) ((1<<v)-1) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mwl_txq *txq = sc->sc_ac2q[ac]; struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac]; struct mwl_hal *mh = sc->sc_mh; @@ -3016,7 +2936,7 @@ mwl_txq_update(struct mwl_softc *sc, int ac) static int mwl_wme_update(struct ieee80211com *ic) { - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; return !mwl_txq_update(sc, WME_AC_BE) || !mwl_txq_update(sc, WME_AC_BK) || @@ -3173,8 +3093,7 @@ mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf * { #define IEEE80211_DIR_DSTODS(wh) \ ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; int error, iswep, ismcast; int hdrlen, copyhdrlen, pktlen; @@ -3391,7 +3310,7 @@ mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf * ds->TxPriority = txq->qnum; break; default: - if_printf(ifp, "bogus frame type 0x%x (%s)\n", + device_printf(sc->sc_dev, "bogus frame type 0x%x (%s)\n", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__); sc->sc_stats.mst_tx_badframetype++; m_freem(m0); @@ -3408,7 +3327,6 @@ mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf * STAILQ_INSERT_TAIL(&txq->active, bf, bf_list); MWL_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); sc->sc_tx_timer = 5; MWL_TXQ_UNLOCK(txq); @@ -3434,8 +3352,7 @@ mwl_tx_processq(struct mwl_softc *sc, struct mwl_txq *txq) { #define EAGLE_TXD_STATUS_MCAST \ (EAGLE_TXD_STATUS_MULTICAST_TX | EAGLE_TXD_STATUS_BROADCAST_TX) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mwl_txbuf *bf; struct mwl_txdesc *ds; struct ieee80211_node *ni; @@ -3497,32 +3414,18 @@ mwl_tx_processq(struct mwl_softc *sc, struct mwl_txq *txq) if (bf->bf_m->m_flags & M_FF) sc->sc_stats.mst_ff_txerr++; } - /* - * Do any tx complete callback. Note this must - * be done before releasing the node reference. - * XXX no way to figure out if frame was ACK'd - */ - if (bf->bf_m->m_flags & M_TXCB) { + if (bf->bf_m->m_flags & M_TXCB) /* XXX strip fw len in case header inspected */ m_adj(bf->bf_m, sizeof(uint16_t)); - ieee80211_process_callback(ni, bf->bf_m, - (status & EAGLE_TXD_STATUS_OK) == 0); - } - /* - * Reclaim reference to node. - * - * NB: the node may be reclaimed here if, for example - * this is a DEAUTH message that was sent and the - * node was timed out due to inactivity. - */ - ieee80211_free_node(ni); - } + ieee80211_tx_complete(ni, bf->bf_m, + (status & EAGLE_TXD_STATUS_OK) == 0); + } else + m_freem(bf->bf_m); ds->Status = htole32(EAGLE_TXD_STATUS_IDLE); bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); - m_freem(bf->bf_m); mwl_puttxbuf_tail(txq, bf); } @@ -3538,7 +3441,6 @@ static void mwl_tx_proc(void *arg, int npending) { struct mwl_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; int nreaped; /* @@ -3555,12 +3457,11 @@ mwl_tx_proc(void *arg, int npending) nreaped += mwl_tx_processq(sc, &sc->sc_txq[3]); if (nreaped != 0) { - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->sc_tx_timer = 0; - if (!IFQ_IS_EMPTY(&ifp->if_snd)) { + if (mbufq_first(&sc->sc_snd) != NULL) { /* NB: kick fw; the tx thread may have been preempted */ mwl_hal_txstart(sc->sc_mh, 0); - mwl_start(ifp); + mwl_start(sc); } } } @@ -3587,8 +3488,7 @@ mwl_tx_draintxq(struct mwl_softc *sc, struct mwl_txq *txq) MWL_TXQ_UNLOCK(txq); #ifdef MWL_DEBUG if (sc->sc_debug & MWL_DEBUG_RESET) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct mwltxrec *tr = mtod(bf->bf_m, const struct mwltxrec *); mwl_printtxbuf(bf, txq->qnum, ix); @@ -3616,12 +3516,10 @@ mwl_tx_draintxq(struct mwl_softc *sc, struct mwl_txq *txq) static void mwl_draintxq(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; int i; for (i = 0; i < MWL_NUM_TX_QUEUES; i++) mwl_tx_draintxq(sc, &sc->sc_txq[i]); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->sc_tx_timer = 0; } @@ -3671,7 +3569,7 @@ static int mwl_recv_action(struct ieee80211_node *ni, const struct ieee80211_frame *wh, const uint8_t *frm, const uint8_t *efrm) { - struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct mwl_softc *sc = ni->ni_ic->ic_softc; const struct ieee80211_action *ia; ia = (const struct ieee80211_action *) frm; @@ -3692,7 +3590,7 @@ static int mwl_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int dialogtoken, int baparamset, int batimeout) { - struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct mwl_softc *sc = ni->ni_ic->ic_softc; struct ieee80211vap *vap = ni->ni_vap; struct mwl_node *mn = MWL_NODE(ni); struct mwl_bastate *bas; @@ -3764,7 +3662,7 @@ static int mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int code, int baparamset, int batimeout) { - struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct mwl_softc *sc = ni->ni_ic->ic_softc; struct mwl_bastate *bas; bas = tap->txa_private; @@ -3830,7 +3728,7 @@ mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, static void mwl_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) { - struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct mwl_softc *sc = ni->ni_ic->ic_softc; struct mwl_bastate *bas; bas = tap->txa_private; @@ -3923,8 +3821,7 @@ static int mwl_chan_set(struct mwl_softc *sc, struct ieee80211_channel *chan) { struct mwl_hal *mh = sc->sc_mh; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; MWL_HAL_CHANNEL hchan; int maxtxpow; @@ -3980,8 +3877,7 @@ mwl_chan_set(struct mwl_softc *sc, struct ieee80211_channel *chan) static void mwl_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; DPRINTF(sc, MWL_DEBUG_STATE, "%s\n", __func__); } @@ -3989,8 +3885,7 @@ mwl_scan_start(struct ieee80211com *ic) static void mwl_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; DPRINTF(sc, MWL_DEBUG_STATE, "%s\n", __func__); } @@ -3998,8 +3893,7 @@ mwl_scan_end(struct ieee80211com *ic) static void mwl_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; (void) mwl_chan_set(sc, ic->ic_curchan); } @@ -4014,7 +3908,7 @@ static void mwl_startcsa(struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; MWL_HAL_CHANNEL hchan; if (sc->sc_csapending) @@ -4215,8 +4109,7 @@ mwl_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) struct mwl_hal_vap *hvap = mvp->mv_hvap; struct ieee80211com *ic = vap->iv_ic; struct ieee80211_node *ni = NULL; - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_hal *mh = sc->sc_mh; enum ieee80211_state ostate = vap->iv_state; int error; @@ -4398,7 +4291,7 @@ static void mwl_newassoc(struct ieee80211_node *ni, int isnew) { struct ieee80211vap *vap = ni->ni_vap; - struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct mwl_softc *sc = vap->iv_ic->ic_softc; struct mwl_node *mn = MWL_NODE(ni); MWL_HAL_PEERINFO pi; uint16_t aid; @@ -4454,7 +4347,7 @@ static int mwl_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd, int nchan, struct ieee80211_channel chans[]) { - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_hal *mh = sc->sc_mh; const MWL_HAL_CHANNELINFO *ci; int i; @@ -4472,7 +4365,7 @@ mwl_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd, IEEE80211_IS_CHAN_HT40(c) ? MWL_CH_40_MHz_WIDTH : MWL_CH_20_MHz_WIDTH, &ci); } else { - if_printf(ic->ic_ifp, + device_printf(sc->sc_dev, "%s: channel %u freq %u/0x%x not 2.4/5GHz\n", __func__, c->ic_ieee, c->ic_freq, c->ic_flags); return EINVAL; @@ -4498,7 +4391,7 @@ mwl_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd, goto next; } } - if_printf(ic->ic_ifp, + device_printf(sc->sc_dev, "%s: no cal data for channel %u ext %u freq %u/0x%x\n", __func__, c->ic_ieee, c->ic_extieee, c->ic_freq, c->ic_flags); @@ -4654,7 +4547,7 @@ static void mwl_getradiocaps(struct ieee80211com *ic, int maxchans, int *nchans, struct ieee80211_channel chans[]) { - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; getchannels(sc, maxchans, nchans, chans); } @@ -4662,8 +4555,7 @@ mwl_getradiocaps(struct ieee80211com *ic, static int mwl_getchannels(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; /* * Use the channel info from the hal to craft the @@ -4768,25 +4660,24 @@ mwl_txq_dump(struct mwl_txq *txq) static void mwl_watchdog(void *arg) { - struct mwl_softc *sc; - struct ifnet *ifp; + struct mwl_softc *sc = arg; - sc = arg; callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc); if (sc->sc_tx_timer == 0 || --sc->sc_tx_timer > 0) return; - ifp = sc->sc_ifp; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->sc_invalid) { + if (sc->sc_running && !sc->sc_invalid) { if (mwl_hal_setkeepalive(sc->sc_mh)) - if_printf(ifp, "transmit timeout (firmware hung?)\n"); + device_printf(sc->sc_dev, + "transmit timeout (firmware hung?)\n"); else - if_printf(ifp, "transmit timeout\n"); + device_printf(sc->sc_dev, + "transmit timeout\n"); #if 0 - mwl_reset(ifp); + mwl_reset(sc); mwl_txq_dump(&sc->sc_txq[0]);/*XXX*/ #endif - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); sc->sc_stats.mst_watchdog++; } } @@ -4885,28 +4776,22 @@ mwl_ioctl_reset(struct mwl_softc *sc, struct mwl_diag *md) } #endif /* MWL_DIAGAPI */ -static int -mwl_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +mwl_parent(struct ieee80211com *ic) { -#define IS_RUNNING(ifp) \ - ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - struct mwl_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *)data; - int error = 0, startall; + struct mwl_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - MWL_LOCK(sc); - startall = 0; - if (IS_RUNNING(ifp)) { + MWL_LOCK(sc); + if (ic->ic_nrunning > 0) { + if (sc->sc_running) { /* * To avoid rescanning another access point, * do not call mwl_init() here. Instead, * only reflect promisc mode settings. */ mwl_mode_init(sc); - } else if (ifp->if_flags & IFF_UP) { + } else { /* * Beware of being called during attach/detach * to reset promiscuous mode. In that case we @@ -4917,30 +4802,42 @@ mwl_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) * probably a better way to deal with this. */ if (!sc->sc_invalid) { - mwl_init_locked(sc); /* XXX lose error */ + mwl_init(sc); /* XXX lose error */ startall = 1; } - } else - mwl_stop_locked(ifp, 1); - MWL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; + } + } else + mwl_stop(sc); + MWL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); +} + +static int +mwl_ioctl(struct ieee80211com *ic, u_long cmd, void *data) +{ + struct mwl_softc *sc = ic->ic_softc; + struct ifreq *ifr = data; + int error = 0; + + switch (cmd) { case SIOCGMVSTATS: mwl_hal_gethwstats(sc->sc_mh, &sc->sc_stats.hw_stats); +#if 0 /* NB: embed these numbers to get a consistent view */ sc->sc_stats.mst_tx_packets = ifp->if_get_counter(ifp, IFCOUNTER_OPACKETS); sc->sc_stats.mst_rx_packets = ifp->if_get_counter(ifp, IFCOUNTER_IPACKETS); +#endif /* * NB: Drop the softc lock in case of a page fault; * we'll accept any potential inconsisentcy in the * statistics. The alternative is to copy the data * to a local structure. */ - return copyout(&sc->sc_stats, - ifr->ifr_data, sizeof (sc->sc_stats)); + return (copyout(&sc->sc_stats, + ifr->ifr_data, sizeof (sc->sc_stats))); #ifdef MWL_DIAGAPI case SIOCGMVDIAG: /* XXX check privs */ @@ -4952,18 +4849,11 @@ mwl_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) MWL_UNLOCK(sc); break; #endif /* MWL_DIAGAPI */ - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; default: - error = EINVAL; + error = ENOTTY; break; } - return error; -#undef IS_RUNNING + return (error); } #ifdef MWL_DEBUG @@ -5003,9 +4893,8 @@ mwl_sysctlattach(struct mwl_softc *sc) static void mwl_announce(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - if_printf(ifp, "Rev A%d hardware, v%d.%d.%d.%d firmware (regioncode %d)\n", + device_printf(sc->sc_dev, "Rev A%d hardware, v%d.%d.%d.%d firmware (regioncode %d)\n", sc->sc_hwspecs.hwVersion, (sc->sc_hwspecs.fwReleaseNumber>>24) & 0xff, (sc->sc_hwspecs.fwReleaseNumber>>16) & 0xff, @@ -5018,20 +4907,20 @@ mwl_announce(struct mwl_softc *sc) int i; for (i = 0; i <= WME_AC_VO; i++) { struct mwl_txq *txq = sc->sc_ac2q[i]; - if_printf(ifp, "Use hw queue %u for %s traffic\n", + device_printf(sc->sc_dev, "Use hw queue %u for %s traffic\n", txq->qnum, ieee80211_wme_acnames[i]); } } if (bootverbose || mwl_rxdesc != MWL_RXDESC) - if_printf(ifp, "using %u rx descriptors\n", mwl_rxdesc); + device_printf(sc->sc_dev, "using %u rx descriptors\n", mwl_rxdesc); if (bootverbose || mwl_rxbuf != MWL_RXBUF) - if_printf(ifp, "using %u rx buffers\n", mwl_rxbuf); + device_printf(sc->sc_dev, "using %u rx buffers\n", mwl_rxbuf); if (bootverbose || mwl_txbuf != MWL_TXBUF) - if_printf(ifp, "using %u tx buffers\n", mwl_txbuf); + device_printf(sc->sc_dev, "using %u tx buffers\n", mwl_txbuf); if (bootverbose && mwl_hal_ismbsscapable(sc->sc_mh)) - if_printf(ifp, "multi-bss support\n"); + device_printf(sc->sc_dev, "multi-bss support\n"); #ifdef MWL_TX_NODROP if (bootverbose) - if_printf(ifp, "no tx drop\n"); + device_printf(sc->sc_dev, "no tx drop\n"); #endif } diff --git a/sys/dev/mwl/if_mwl_pci.c b/sys/dev/mwl/if_mwl_pci.c index ef7009c..d9da128 100644 --- a/sys/dev/mwl/if_mwl_pci.c +++ b/sys/dev/mwl/if_mwl_pci.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/lock.h> #include <sys/malloc.h> +#include <sys/mbuf.h> #include <sys/mutex.h> #include <sys/errno.h> diff --git a/sys/dev/mwl/if_mwlvar.h b/sys/dev/mwl/if_mwlvar.h index 7071ba0..4a4b338 100644 --- a/sys/dev/mwl/if_mwlvar.h +++ b/sys/dev/mwl/if_mwlvar.h @@ -244,7 +244,8 @@ struct mwl_vap { #define MWL_VAP_CONST(vap) ((const struct mwl_vap *)(vap)) struct mwl_softc { - struct ifnet *sc_ifp; /* interface common */ + struct ieee80211com sc_ic; + struct mbufq sc_snd; struct mwl_stats sc_stats; /* interface statistics */ int sc_debug; device_t sc_dev; @@ -257,7 +258,8 @@ struct mwl_softc { struct taskqueue *sc_tq; /* private task queue */ struct callout sc_watchdog; int sc_tx_timer; - unsigned int sc_invalid : 1, /* disable hardware accesses */ + unsigned int sc_running : 1, + sc_invalid : 1, /* disable hardware accesses */ sc_recvsetup:1, /* recv setup */ sc_csapending:1,/* 11h channel switch pending */ sc_radarena : 1,/* radar detection enabled */ |