diff options
| author | Adrian Chadd <adrian@FreeBSD.org> | 2015-08-08 01:10:17 +0000 |
|---|---|---|
| committer | Adrian Chadd <adrian@FreeBSD.org> | 2015-08-08 01:10:17 +0000 |
| commit | ba2c1fbc03f312b978f76f7b6c67eec6afa80bf8 (patch) | |
| tree | 5973a9059f73ed5abf84d6d98e44f1953e764064 /sys/dev/ral | |
| parent | 721b581722c3a383f02036d009db4473590e3f88 (diff) | |
Notes
Diffstat (limited to 'sys/dev/ral')
| -rw-r--r-- | sys/dev/ral/if_ral_pci.c | 1 | ||||
| -rw-r--r-- | sys/dev/ral/rt2560.c | 305 | ||||
| -rw-r--r-- | sys/dev/ral/rt2560var.h | 9 | ||||
| -rw-r--r-- | sys/dev/ral/rt2661.c | 289 | ||||
| -rw-r--r-- | sys/dev/ral/rt2661var.h | 7 | ||||
| -rw-r--r-- | sys/dev/ral/rt2860.c | 274 | ||||
| -rw-r--r-- | sys/dev/ral/rt2860var.h | 7 |
7 files changed, 543 insertions, 349 deletions
diff --git a/sys/dev/ral/if_ral_pci.c b/sys/dev/ral/if_ral_pci.c index 42ec03424bdf..519b4ca30d78 100644 --- a/sys/dev/ral/if_ral_pci.c +++ b/sys/dev/ral/if_ral_pci.c @@ -28,7 +28,6 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/lock.h> #include <sys/malloc.h> -#include <sys/mbuf.h> #include <sys/module.h> #include <sys/mutex.h> #include <sys/rman.h> diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c index ea9c4162b8f8..29ce8cbf8014 100644 --- a/sys/dev/ral/rt2560.c +++ b/sys/dev/ral/rt2560.c @@ -127,10 +127,10 @@ static int rt2560_tx_mgt(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); static int rt2560_tx_data(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); -static int rt2560_transmit(struct ieee80211com *, struct mbuf *); -static void rt2560_start(struct rt2560_softc *); +static void rt2560_start_locked(struct ifnet *); +static void rt2560_start(struct ifnet *); static void rt2560_watchdog(void *); -static void rt2560_parent(struct ieee80211com *); +static int rt2560_ioctl(struct ifnet *, u_long, caddr_t); static void rt2560_bbp_write(struct rt2560_softc *, uint8_t, uint8_t); static uint8_t rt2560_bbp_read(struct rt2560_softc *, uint8_t); @@ -149,8 +149,7 @@ static void rt2560_set_basicrates(struct rt2560_softc *, const struct ieee80211_rateset *); static void rt2560_update_led(struct rt2560_softc *, int, int); static void rt2560_set_bssid(struct rt2560_softc *, const uint8_t *); -static void rt2560_set_macaddr(struct rt2560_softc *, - const uint8_t *); +static void rt2560_set_macaddr(struct rt2560_softc *, uint8_t *); static void rt2560_get_macaddr(struct rt2560_softc *, uint8_t *); static void rt2560_update_promisc(struct ieee80211com *); static const char *rt2560_get_rf(int); @@ -198,9 +197,11 @@ int rt2560_attach(device_t dev, int id) { struct rt2560_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; - uint8_t bands; + struct ieee80211com *ic; + struct ifnet *ifp; int error; + uint8_t bands; + uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_dev = dev; @@ -208,7 +209,6 @@ rt2560_attach(device_t dev, int id) MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); - mbufq_init(&sc->sc_snd, ifqmaxlen); /* retrieve RT2560 rev. no */ sc->asic_rev = RAL_READ(sc, RT2560_CSR0); @@ -252,9 +252,27 @@ rt2560_attach(device_t dev, int id) goto fail5; } + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(sc->sc_dev, "can not if_alloc()\n"); + goto fail6; + } + ic = ifp->if_l2com; + /* retrieve MAC address */ - rt2560_get_macaddr(sc, ic->ic_macaddr); + rt2560_get_macaddr(sc, macaddr); + + ifp->if_softc = sc; + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_init = rt2560_init; + ifp->if_ioctl = rt2560_ioctl; + ifp->if_start = rt2560_start; + 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(dev); ic->ic_opmode = IEEE80211_M_STA; @@ -285,7 +303,7 @@ rt2560_attach(device_t dev, int id) setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic); + ieee80211_ifattach(ic, macaddr); ic->ic_raw_xmit = rt2560_raw_xmit; ic->ic_updateslot = rt2560_update_slot; ic->ic_update_promisc = rt2560_update_promisc; @@ -295,8 +313,6 @@ rt2560_attach(device_t dev, int id) ic->ic_vap_create = rt2560_vap_create; ic->ic_vap_delete = rt2560_vap_delete; - ic->ic_parent = rt2560_parent; - ic->ic_transmit = rt2560_transmit; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -325,6 +341,7 @@ rt2560_attach(device_t dev, int id) return 0; +fail6: rt2560_free_rx_ring(sc, &sc->rxq); fail5: rt2560_free_tx_ring(sc, &sc->bcnq); fail4: rt2560_free_tx_ring(sc, &sc->prioq); fail3: rt2560_free_tx_ring(sc, &sc->atimq); @@ -338,12 +355,12 @@ int rt2560_detach(void *xsc) { struct rt2560_softc *sc = xsc; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; rt2560_stop(sc); ieee80211_ifdetach(ic); - mbufq_drain(&sc->sc_snd); rt2560_free_tx_ring(sc, &sc->txq); rt2560_free_tx_ring(sc, &sc->atimq); @@ -351,6 +368,8 @@ rt2560_detach(void *xsc) rt2560_free_tx_ring(sc, &sc->bcnq); rt2560_free_rx_ring(sc, &sc->rxq); + if_free(ifp); + mtx_destroy(&sc->sc_mtx); return 0; @@ -362,7 +381,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct rt2560_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; struct rt2560_vap *rvp; struct ieee80211vap *vap; @@ -375,7 +394,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_MBSS: /* XXXRP: TBD */ if (!TAILQ_EMPTY(&ic->ic_vaps)) { - device_printf(sc->sc_dev, "only 1 vap supported\n"); + if_printf(ifp, "only 1 vap supported\n"); return NULL; } if (opmode == IEEE80211_M_STA) @@ -384,8 +403,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_WDS: if (TAILQ_EMPTY(&ic->ic_vaps) || ic->ic_opmode != IEEE80211_M_HOSTAP) { - device_printf(sc->sc_dev, - "wds only supported in ap mode\n"); + if_printf(ifp, "wds only supported in ap mode\n"); return NULL; } /* @@ -396,12 +414,15 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, flags &= ~IEEE80211_CLONE_BSSID; break; default: - device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); + if_printf(ifp, "unknown opmode %d\n", opmode); return NULL; } - rvp = malloc(sizeof(struct rt2560_vap), M_80211_VAP, M_WAITOK | M_ZERO); + rvp = (struct rt2560_vap *) malloc(sizeof(struct rt2560_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (rvp == NULL) + return NULL; vap = &rvp->ral_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); /* override state transition machine */ rvp->ral_newstate = vap->iv_newstate; @@ -410,8 +431,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status, mac); + ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); if (TAILQ_FIRST(&ic->ic_vaps) == vap) ic->ic_opmode = opmode; return vap; @@ -431,8 +451,9 @@ void rt2560_resume(void *xsc) { struct rt2560_softc *sc = xsc; + struct ifnet *ifp = sc->sc_ifp; - if (sc->sc_ic.ic_nrunning > 0) + if (ifp->if_flags & IFF_UP) rt2560_init(sc); } @@ -742,7 +763,8 @@ static int rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rt2560_vap *rvp = RT2560_VAP(vap); - struct rt2560_softc *sc = vap->iv_ic->ic_softc; + struct ifnet *ifp = vap->iv_ic->ic_ifp; + struct rt2560_softc *sc = ifp->if_softc; int error; if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) { @@ -770,8 +792,7 @@ rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) vap->iv_opmode == IEEE80211_M_MBSS) { m = ieee80211_beacon_alloc(ni, &rvp->ral_bo); if (m == NULL) { - device_printf(sc->sc_dev, - "could not allocate beacon\n"); + if_printf(ifp, "could not allocate beacon\n"); return ENOBUFS; } ieee80211_ref_node(ni); @@ -905,13 +926,14 @@ rt2560_encryption_intr(struct rt2560_softc *sc) static void rt2560_tx_intr(struct rt2560_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct mbuf *m; + uint32_t flags; + int retrycnt; struct ieee80211vap *vap; struct ieee80211_node *ni; - uint32_t flags; - int retrycnt, status; bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map, BUS_DMASYNC_POSTREAD); @@ -939,7 +961,7 @@ rt2560_tx_intr(struct rt2560_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS, &retrycnt, NULL); - status = 0; + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); break; case RT2560_TX_SUCCESS_RETRY: @@ -951,7 +973,7 @@ rt2560_tx_intr(struct rt2560_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS, &retrycnt, NULL); - status = 0; + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); break; case RT2560_TX_FAIL_RETRY: @@ -963,7 +985,7 @@ rt2560_tx_intr(struct rt2560_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_FAILURE, &retrycnt, NULL); - status = 1; + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); break; case RT2560_TX_FAIL_INVALID: @@ -971,16 +993,16 @@ rt2560_tx_intr(struct rt2560_softc *sc) default: device_printf(sc->sc_dev, "sending data frame failed " "0x%08x\n", flags); - status = 1; + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } bus_dmamap_sync(sc->txq.data_dmat, data->map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->txq.data_dmat, data->map); - - ieee80211_tx_complete(ni, m, status); - data->ni = NULL; + m_freem(m); data->m = NULL; + ieee80211_free_node(data->ni); + data->ni = NULL; /* descriptor is no longer valid */ desc->flags &= ~htole32(RT2560_TX_VALID); @@ -997,13 +1019,19 @@ rt2560_tx_intr(struct rt2560_softc *sc) if (sc->prioq.queued == 0 && sc->txq.queued == 0) sc->sc_tx_timer = 0; - if (sc->txq.queued < RT2560_TX_RING_COUNT - 1) - rt2560_start(sc); + if (sc->txq.queued < RT2560_TX_RING_COUNT - 1) { + sc->sc_flags &= ~RT2560_F_DATA_OACTIVE; + if ((sc->sc_flags & + (RT2560_F_DATA_OACTIVE | RT2560_F_PRIO_OACTIVE)) == 0) + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + rt2560_start_locked(ifp); + } } static void rt2560_prio_intr(struct rt2560_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct ieee80211_node *ni; @@ -1075,8 +1103,13 @@ rt2560_prio_intr(struct rt2560_softc *sc) if (sc->prioq.queued == 0 && sc->txq.queued == 0) sc->sc_tx_timer = 0; - if (sc->prioq.queued < RT2560_PRIO_RING_COUNT) - rt2560_start(sc); + if (sc->prioq.queued < RT2560_PRIO_RING_COUNT) { + sc->sc_flags &= ~RT2560_F_PRIO_OACTIVE; + if ((sc->sc_flags & + (RT2560_F_DATA_OACTIVE | RT2560_F_PRIO_OACTIVE)) == 0) + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + rt2560_start_locked(ifp); + } } /* @@ -1086,7 +1119,8 @@ rt2560_prio_intr(struct rt2560_softc *sc) static void rt2560_decryption_intr(struct rt2560_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rt2560_rx_desc *desc; struct rt2560_rx_data *data; bus_addr_t physaddr; @@ -1112,13 +1146,13 @@ rt2560_decryption_intr(struct rt2560_softc *sc) break; if (data->drop) { - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto skip; } if ((le32toh(desc->flags) & RT2560_RX_CIPHER_MASK) != 0 && (le32toh(desc->flags) & RT2560_RX_ICV_ERROR)) { - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto skip; } @@ -1131,7 +1165,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc) */ mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (mnew == NULL) { - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto skip; } @@ -1154,7 +1188,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc) panic("%s: could not load old rx mbuf", device_get_name(sc->sc_dev)); } - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto skip; } @@ -1167,6 +1201,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc) desc->physaddr = htole32(physaddr); /* finalize mbuf */ + m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; @@ -1286,7 +1321,8 @@ rt2560_beacon_update(struct ieee80211vap *vap, int item) static void rt2560_beacon_expire(struct rt2560_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct rt2560_vap *rvp = RT2560_VAP(vap); struct rt2560_tx_data *data; @@ -1327,6 +1363,7 @@ void rt2560_intr(void *arg) { struct rt2560_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; uint32_t r; RAL_LOCK(sc); @@ -1335,7 +1372,7 @@ rt2560_intr(void *arg) RAL_WRITE(sc, RT2560_CSR8, 0xffffffff); /* don't re-enable interrupts if we're shutting down */ - if (!(sc->sc_flags & RT2560_F_RUNNING)) { + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { RAL_UNLOCK(sc); return; } @@ -1403,7 +1440,8 @@ static void rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc, uint32_t flags, int len, int rate, int encrypt, bus_addr_t physaddr) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint16_t plcp_length; int remainder; @@ -1878,57 +1916,55 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, return 0; } -static int -rt2560_transmit(struct ieee80211com *ic, struct mbuf *m) -{ - struct rt2560_softc *sc = ic->ic_softc; - int error; - - RAL_LOCK(sc); - if ((sc->sc_flags & RT2560_F_RUNNING) == 0) { - RAL_UNLOCK(sc); - return (ENXIO); - } - error = mbufq_enqueue(&sc->sc_snd, m); - if (error) { - RAL_UNLOCK(sc); - return (error); - } - rt2560_start(sc); - RAL_UNLOCK(sc); - - return (0); -} - static void -rt2560_start(struct rt2560_softc *sc) +rt2560_start_locked(struct ifnet *ifp) { - struct ieee80211_node *ni; + struct rt2560_softc *sc = ifp->if_softc; struct mbuf *m; + struct ieee80211_node *ni; RAL_LOCK_ASSERT(sc); - while (sc->txq.queued < RT2560_TX_RING_COUNT - 1 && - (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + for (;;) { + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + if (sc->txq.queued >= RT2560_TX_RING_COUNT - 1) { + IFQ_DRV_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + sc->sc_flags |= RT2560_F_DATA_OACTIVE; + break; + } ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; if (rt2560_tx_data(sc, m, ni) != 0) { - if_inc_counter(ni->ni_vap->iv_ifp, - IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); break; } + sc->sc_tx_timer = 5; } } static void +rt2560_start(struct ifnet *ifp) +{ + struct rt2560_softc *sc = ifp->if_softc; + + RAL_LOCK(sc); + rt2560_start_locked(ifp); + RAL_UNLOCK(sc); +} + +static void rt2560_watchdog(void *arg) { struct rt2560_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; RAL_LOCK_ASSERT(sc); - KASSERT(sc->sc_flags & RT2560_F_RUNNING, ("not running")); + KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); if (sc->sc_invalid) /* card ejected */ return; @@ -1937,33 +1973,51 @@ rt2560_watchdog(void *arg) rt2560_tx_intr(sc); if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { - device_printf(sc->sc_dev, "device timeout\n"); + if_printf(ifp, "device timeout\n"); rt2560_init_locked(sc); - counter_u64_add(sc->sc_ic.ic_oerrors, 1); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); /* NB: callout is reset in rt2560_init() */ return; } callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc); } -static void -rt2560_parent(struct ieee80211com *ic) +static int +rt2560_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - struct rt2560_softc *sc = ic->ic_softc; - int startall = 0; + struct rt2560_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; - RAL_LOCK(sc); - if (ic->ic_nrunning > 0) { - if ((sc->sc_flags & RT2560_F_RUNNING) == 0) { - rt2560_init_locked(sc); - startall = 1; - } else - rt2560_update_promisc(ic); - } else if (sc->sc_flags & RT2560_F_RUNNING) - rt2560_stop_locked(sc); - RAL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); + switch (cmd) { + case SIOCSIFFLAGS: + RAL_LOCK(sc); + if (ifp->if_flags & IFF_UP) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + rt2560_init_locked(sc); + startall = 1; + } else + rt2560_update_promisc(ic); + } else { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + rt2560_stop_locked(sc); + } + RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); + break; + case SIOCGIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; + case SIOCGIFADDR: + error = ether_ioctl(ifp, cmd, data); + break; + default: + error = EINVAL; + break; + } + return error; } static void @@ -2047,7 +2101,8 @@ rt2560_rf_write(struct rt2560_softc *sc, uint8_t reg, uint32_t val) static void rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint8_t power, tmp; u_int i, chan; @@ -2146,7 +2201,8 @@ rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c) static void rt2560_set_channel(struct ieee80211com *ic) { - struct rt2560_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rt2560_softc *sc = ifp->if_softc; RAL_LOCK(sc); rt2560_set_chan(sc, ic->ic_curchan); @@ -2182,7 +2238,8 @@ rt2560_disable_rf_tune(struct rt2560_softc *sc) static void rt2560_enable_tsf_sync(struct rt2560_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint16_t logcwmin, preload; uint32_t tmp; @@ -2223,7 +2280,8 @@ rt2560_enable_tsf(struct rt2560_softc *sc) static void rt2560_update_plcp(struct rt2560_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; /* no short preamble for 1Mbps */ RAL_WRITE(sc, RT2560_PLCP1MCSR, 0x00700400); @@ -2302,7 +2360,8 @@ rt2560_set_basicrates(struct rt2560_softc *sc, const struct ieee80211_rateset *rs) { #define RV(r) ((r) & IEEE80211_RATE_VAL) - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t mask = 0; uint8_t rate; int i; @@ -2347,7 +2406,7 @@ rt2560_set_bssid(struct rt2560_softc *sc, const uint8_t *bssid) } static void -rt2560_set_macaddr(struct rt2560_softc *sc, const uint8_t *addr) +rt2560_set_macaddr(struct rt2560_softc *sc, uint8_t *addr) { uint32_t tmp; @@ -2385,13 +2444,13 @@ rt2560_update_promisc(struct ieee80211com *ic) tmp = RAL_READ(sc, RT2560_RXCSR0); tmp &= ~RT2560_DROP_NOT_TO_ME; - if (ic->ic_promisc == 0) + if (!(ic->ic_ifp->if_flags & IFF_PROMISC)) tmp |= RT2560_DROP_NOT_TO_ME; RAL_WRITE(sc, RT2560_RXCSR0, tmp); DPRINTF(sc, "%s promiscuous mode\n", - (ic->ic_promisc > 0) ? "entering" : "leaving"); + (ic->ic_ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving"); } static const char * @@ -2457,17 +2516,19 @@ rt2560_read_config(struct rt2560_softc *sc) static void rt2560_scan_start(struct ieee80211com *ic) { - struct rt2560_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rt2560_softc *sc = ifp->if_softc; /* abort TSF synchronization */ RAL_WRITE(sc, RT2560_CSR14, 0); - rt2560_set_bssid(sc, ieee80211broadcastaddr); + rt2560_set_bssid(sc, ifp->if_broadcastaddr); } static void rt2560_scan_end(struct ieee80211com *ic) { - struct rt2560_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rt2560_softc *sc = ifp->if_softc; struct ieee80211vap *vap = ic->ic_scan->ss_vap; rt2560_enable_tsf_sync(sc); @@ -2561,8 +2622,8 @@ static void rt2560_init_locked(struct rt2560_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; int i; @@ -2593,7 +2654,7 @@ rt2560_init_locked(struct rt2560_softc *sc) for (i = 0; i < N(rt2560_def_mac); i++) RAL_WRITE(sc, rt2560_def_mac[i].reg, rt2560_def_mac[i].val); - rt2560_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); + rt2560_set_macaddr(sc, IF_LLADDR(ifp)); /* set basic rate set (will be updated later) */ RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x153); @@ -2623,7 +2684,7 @@ rt2560_init_locked(struct rt2560_softc *sc) if (ic->ic_opmode != IEEE80211_M_HOSTAP && ic->ic_opmode != IEEE80211_M_MBSS) tmp |= RT2560_DROP_TODS; - if (ic->ic_promisc == 0) + if (!(ifp->if_flags & IFF_PROMISC)) tmp |= RT2560_DROP_NOT_TO_ME; } RAL_WRITE(sc, RT2560_RXCSR0, tmp); @@ -2638,7 +2699,8 @@ rt2560_init_locked(struct rt2560_softc *sc) /* enable interrupts */ RAL_WRITE(sc, RT2560_CSR8, RT2560_INTR_MASK); - sc->sc_flags |= RT2560_F_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + ifp->if_drv_flags |= IFF_DRV_RUNNING; callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc); #undef N @@ -2648,19 +2710,21 @@ static void rt2560_init(void *priv) { struct rt2560_softc *sc = priv; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; RAL_LOCK(sc); rt2560_init_locked(sc); RAL_UNLOCK(sc); - if (sc->sc_flags & RT2560_F_RUNNING) + if (ifp->if_drv_flags & IFF_DRV_RUNNING) ieee80211_start_all(ic); /* start all vap's */ } static void rt2560_stop_locked(struct rt2560_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; volatile int *flags = &sc->sc_flags; RAL_LOCK_ASSERT(sc); @@ -2671,8 +2735,8 @@ rt2560_stop_locked(struct rt2560_softc *sc) callout_stop(&sc->watchdog_ch); sc->sc_tx_timer = 0; - if (sc->sc_flags & RT2560_F_RUNNING) { - sc->sc_flags &= ~RT2560_F_RUNNING; + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); /* abort Tx */ RAL_WRITE(sc, RT2560_TXCSR0, RT2560_ABORT_TX); @@ -2694,6 +2758,7 @@ rt2560_stop_locked(struct rt2560_softc *sc) rt2560_reset_tx_ring(sc, &sc->bcnq); rt2560_reset_rx_ring(sc, &sc->rxq); } + sc->sc_flags &= ~(RT2560_F_PRIO_OACTIVE | RT2560_F_DATA_OACTIVE); } void @@ -2711,24 +2776,29 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct rt2560_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rt2560_softc *sc = ifp->if_softc; RAL_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(sc->sc_flags & RT2560_F_RUNNING)) { + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENETDOWN; } if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + sc->sc_flags |= RT2560_F_PRIO_OACTIVE; RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENOBUFS; /* XXX */ } + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + if (params == NULL) { /* * Legacy path; interpret frame contents to decide @@ -2750,6 +2820,7 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; bad: + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); RAL_UNLOCK(sc); return EIO; /* XXX */ diff --git a/sys/dev/ral/rt2560var.h b/sys/dev/ral/rt2560var.h index 3a5fef981080..b6a8d68e9236 100644 --- a/sys/dev/ral/rt2560var.h +++ b/sys/dev/ral/rt2560var.h @@ -105,13 +105,13 @@ struct rt2560_vap { #define RT2560_VAP(vap) ((struct rt2560_vap *)(vap)) struct rt2560_softc { - struct ieee80211com sc_ic; - struct mtx sc_mtx; - struct mbufq sc_snd; + struct ifnet *sc_ifp; device_t sc_dev; bus_space_tag_t sc_st; bus_space_handle_t sc_sh; + struct mtx sc_mtx; + struct callout watchdog_ch; int sc_tx_timer; @@ -152,7 +152,8 @@ struct rt2560_softc { struct rt2560_tx_radiotap_header sc_txtap; int sc_txtap_len; #define RT2560_F_INPUT_RUNNING 0x1 -#define RT2560_F_RUNNING 0x2 +#define RT2560_F_PRIO_OACTIVE 0x2 +#define RT2560_F_DATA_OACTIVE 0x4 int sc_flags; }; diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c index c77d4f88df76..15a2364a2c74 100644 --- a/sys/dev/ral/rt2661.c +++ b/sys/dev/ral/rt2661.c @@ -121,12 +121,12 @@ static int rt2661_tx_data(struct rt2661_softc *, struct mbuf *, struct ieee80211_node *, int); static int rt2661_tx_mgt(struct rt2661_softc *, struct mbuf *, struct ieee80211_node *); -static int rt2661_transmit(struct ieee80211com *, struct mbuf *); -static void rt2661_start(struct rt2661_softc *); +static void rt2661_start_locked(struct ifnet *); +static void rt2661_start(struct ifnet *); static int rt2661_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static void rt2661_watchdog(void *); -static void rt2661_parent(struct ieee80211com *); +static int rt2661_ioctl(struct ifnet *, u_long, caddr_t); static void rt2661_bbp_write(struct rt2661_softc *, uint8_t, uint8_t); static uint8_t rt2661_bbp_read(struct rt2661_softc *, uint8_t); @@ -197,19 +197,27 @@ int rt2661_attach(device_t dev, int id) { struct rt2661_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; + struct ifnet *ifp; uint32_t val; int error, ac, ntries; uint8_t bands; + uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_id = id; sc->sc_dev = dev; + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(sc->sc_dev, "can not if_alloc()\n"); + return ENOMEM; + } + ic = ifp->if_l2com; + mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); - mbufq_init(&sc->sc_snd, ifqmaxlen); /* wait for NIC to initialize */ for (ntries = 0; ntries < 1000; ntries++) { @@ -225,7 +233,7 @@ rt2661_attach(device_t dev, int id) } /* retrieve RF rev. no and various other things from EEPROM */ - rt2661_read_eeprom(sc, ic->ic_macaddr); + rt2661_read_eeprom(sc, macaddr); device_printf(dev, "MAC/BBP RT%X, RF %s\n", val, rt2661_get_rf(sc->rf_rev)); @@ -255,6 +263,17 @@ rt2661_attach(device_t dev, int id) goto fail3; } + ifp->if_softc = sc; + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_init = rt2661_init; + ifp->if_ioctl = rt2661_ioctl; + ifp->if_start = rt2661_start; + 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(dev); ic->ic_opmode = IEEE80211_M_STA; @@ -286,7 +305,7 @@ rt2661_attach(device_t dev, int id) setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic); + ieee80211_ifattach(ic, macaddr); #if 0 ic->ic_wme.wme_update = rt2661_wme_update; #endif @@ -296,8 +315,7 @@ rt2661_attach(device_t dev, int id) ic->ic_updateslot = rt2661_update_slot; ic->ic_update_promisc = rt2661_update_promisc; ic->ic_raw_xmit = rt2661_raw_xmit; - ic->ic_transmit = rt2661_transmit; - ic->ic_parent = rt2661_parent; + ic->ic_vap_create = rt2661_vap_create; ic->ic_vap_delete = rt2661_vap_delete; @@ -321,6 +339,7 @@ fail3: rt2661_free_tx_ring(sc, &sc->mgtq); fail2: while (--ac >= 0) rt2661_free_tx_ring(sc, &sc->txq[ac]); fail1: mtx_destroy(&sc->sc_mtx); + if_free(ifp); return error; } @@ -328,14 +347,14 @@ int rt2661_detach(void *xsc) { struct rt2661_softc *sc = xsc; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; RAL_LOCK(sc); rt2661_stop_locked(sc); RAL_UNLOCK(sc); ieee80211_ifdetach(ic); - mbufq_drain(&sc->sc_snd); rt2661_free_tx_ring(sc, &sc->txq[0]); rt2661_free_tx_ring(sc, &sc->txq[1]); @@ -344,6 +363,8 @@ rt2661_detach(void *xsc) rt2661_free_tx_ring(sc, &sc->mgtq); rt2661_free_rx_ring(sc, &sc->rxq); + if_free(ifp); + mtx_destroy(&sc->sc_mtx); return 0; @@ -355,7 +376,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct rt2661_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; struct rt2661_vap *rvp; struct ieee80211vap *vap; @@ -368,7 +389,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_MBSS: /* XXXRP: TBD */ if (!TAILQ_EMPTY(&ic->ic_vaps)) { - device_printf(sc->sc_dev, "only 1 vap supported\n"); + if_printf(ifp, "only 1 vap supported\n"); return NULL; } if (opmode == IEEE80211_M_STA) @@ -377,8 +398,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_WDS: if (TAILQ_EMPTY(&ic->ic_vaps) || ic->ic_opmode != IEEE80211_M_HOSTAP) { - device_printf(sc->sc_dev, - "wds only supported in ap mode\n"); + if_printf(ifp, "wds only supported in ap mode\n"); return NULL; } /* @@ -389,12 +409,15 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, flags &= ~IEEE80211_CLONE_BSSID; break; default: - device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); + if_printf(ifp, "unknown opmode %d\n", opmode); return NULL; } - rvp = malloc(sizeof(struct rt2661_vap), M_80211_VAP, M_WAITOK | M_ZERO); + rvp = (struct rt2661_vap *) malloc(sizeof(struct rt2661_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (rvp == NULL) + return NULL; vap = &rvp->ral_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); /* override state transition machine */ rvp->ral_newstate = vap->iv_newstate; @@ -405,8 +428,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status, mac); + ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); if (TAILQ_FIRST(&ic->ic_vaps) == vap) ic->ic_opmode = opmode; return vap; @@ -442,8 +464,9 @@ void rt2661_resume(void *xsc) { struct rt2661_softc *sc = xsc; + struct ifnet *ifp = sc->sc_ifp; - if (sc->sc_ic.ic_nrunning > 0) + if (ifp->if_flags & IFF_UP) rt2661_init(sc); } @@ -747,7 +770,7 @@ rt2661_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rt2661_vap *rvp = RT2661_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct rt2661_softc *sc = ic->ic_softc; + struct rt2661_softc *sc = ic->ic_ifp->if_softc; int error; if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) { @@ -846,10 +869,11 @@ rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t addr) static void rt2661_tx_intr(struct rt2661_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; struct rt2661_tx_ring *txq; struct rt2661_tx_data *data; uint32_t val; - int error, qid, retrycnt; + int qid, retrycnt; struct ieee80211vap *vap; for (;;) { @@ -887,7 +911,7 @@ rt2661_tx_intr(struct rt2661_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS, &retrycnt, NULL); - error = 0; + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); break; case RT2661_TX_RETRY_FAIL: @@ -899,14 +923,14 @@ rt2661_tx_intr(struct rt2661_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_FAILURE, &retrycnt, NULL); - error = 1; + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); break; default: /* other failure */ device_printf(sc->sc_dev, "sending data frame failed 0x%08x\n", val); - error = 1; + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } DPRINTFN(sc, 15, "tx done q=%d idx=%u\n", qid, txq->stat); @@ -915,12 +939,17 @@ rt2661_tx_intr(struct rt2661_softc *sc) if (++txq->stat >= txq->count) /* faster than % count */ txq->stat = 0; - ieee80211_tx_complete(ni, m, error); + if (m->m_flags & M_TXCB) + ieee80211_process_callback(ni, m, + RT2661_TX_RESULT(val) != RT2661_TX_SUCCESS); + m_freem(m); + ieee80211_free_node(ni); } sc->sc_tx_timer = 0; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rt2661_start(sc); + rt2661_start_locked(ifp); } static void @@ -958,7 +987,8 @@ rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *txq) static void rt2661_rx_intr(struct rt2661_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rt2661_rx_desc *desc; struct rt2661_rx_data *data; bus_addr_t physaddr; @@ -987,12 +1017,12 @@ rt2661_rx_intr(struct rt2661_softc *sc) */ DPRINTFN(sc, 5, "PHY or CRC error flags 0x%08x\n", le32toh(desc->flags)); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto skip; } if ((le32toh(desc->flags) & RT2661_RX_CIPHER_MASK) != 0) { - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto skip; } @@ -1005,7 +1035,7 @@ rt2661_rx_intr(struct rt2661_softc *sc) */ mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (mnew == NULL) { - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto skip; } @@ -1028,7 +1058,7 @@ rt2661_rx_intr(struct rt2661_softc *sc) panic("%s: could not load old rx mbuf", device_get_name(sc->sc_dev)); } - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto skip; } @@ -1041,6 +1071,7 @@ rt2661_rx_intr(struct rt2661_softc *sc) desc->physaddr = htole32(physaddr); /* finalize mbuf */ + m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; @@ -1125,6 +1156,7 @@ void rt2661_intr(void *arg) { struct rt2661_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; uint32_t r1, r2; RAL_LOCK(sc); @@ -1134,7 +1166,7 @@ rt2661_intr(void *arg) RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff); /* don't re-enable interrupts if we're shutting down */ - if (!(sc->sc_flags & RAL_RUNNING)) { + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { RAL_UNLOCK(sc); return; } @@ -1210,7 +1242,8 @@ rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc, uint32_t flags, uint16_t xflags, int len, int rate, const bus_dma_segment_t *segs, int nsegs, int ac) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint16_t plcp_length; int i, remainder; @@ -1428,7 +1461,8 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, int ac) { struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rt2661_tx_ring *txq = &sc->txq[ac]; struct rt2661_tx_desc *desc; struct rt2661_tx_data *data; @@ -1570,31 +1604,10 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, return 0; } -static int -rt2661_transmit(struct ieee80211com *ic, struct mbuf *m) -{ - struct rt2661_softc *sc = ic->ic_softc; - int error; - - RAL_LOCK(sc); - if ((sc->sc_flags & RAL_RUNNING) == 0) { - RAL_UNLOCK(sc); - return (ENXIO); - } - error = mbufq_enqueue(&sc->sc_snd, m); - if (error) { - RAL_UNLOCK(sc); - return (error); - } - rt2661_start(sc); - RAL_UNLOCK(sc); - - return (0); -} - static void -rt2661_start(struct rt2661_softc *sc) +rt2661_start_locked(struct ifnet *ifp) { + struct rt2661_softc *sc = ifp->if_softc; struct mbuf *m; struct ieee80211_node *ni; int ac; @@ -1602,50 +1615,69 @@ rt2661_start(struct rt2661_softc *sc) RAL_LOCK_ASSERT(sc); /* prevent management frames from being sent if we're not ready */ - if (!(sc->sc_flags & RAL_RUNNING) || sc->sc_invalid) + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) || sc->sc_invalid) return; - while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + for (;;) { + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + ac = M_WME_GETAC(m); if (sc->txq[ac].queued >= RT2661_TX_RING_COUNT - 1) { /* there is no place left in this ring */ - mbufq_prepend(&sc->sc_snd, m); + IFQ_DRV_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; } ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; if (rt2661_tx_data(sc, m, ni, ac) != 0) { ieee80211_free_node(ni); - if_inc_counter(ni->ni_vap->iv_ifp, - IFCOUNTER_OERRORS, 1); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); break; } + sc->sc_tx_timer = 5; } } +static void +rt2661_start(struct ifnet *ifp) +{ + struct rt2661_softc *sc = ifp->if_softc; + + RAL_LOCK(sc); + rt2661_start_locked(ifp); + RAL_UNLOCK(sc); +} + static int rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct rt2661_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rt2661_softc *sc = ifp->if_softc; RAL_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(sc->sc_flags & RAL_RUNNING)) { + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENETDOWN; } if (sc->mgtq.queued >= RT2661_MGT_RING_COUNT) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENOBUFS; /* XXX */ } + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + /* * Legacy path; interpret frame contents to decide * precisely how to send the frame. @@ -1659,6 +1691,7 @@ rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; bad: + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); RAL_UNLOCK(sc); return EIO; /* XXX */ @@ -1668,42 +1701,61 @@ static void rt2661_watchdog(void *arg) { struct rt2661_softc *sc = (struct rt2661_softc *)arg; + struct ifnet *ifp = sc->sc_ifp; RAL_LOCK_ASSERT(sc); - KASSERT(sc->sc_flags & RAL_RUNNING, ("not running")); + KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); if (sc->sc_invalid) /* card ejected */ return; if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { - device_printf(sc->sc_dev, "device timeout\n"); + if_printf(ifp, "device timeout\n"); rt2661_init_locked(sc); - counter_u64_add(sc->sc_ic.ic_oerrors, 1); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); /* NB: callout is reset in rt2661_init() */ return; } callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc); } -static void -rt2661_parent(struct ieee80211com *ic) +static int +rt2661_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - struct rt2661_softc *sc = ic->ic_softc; - int startall = 0; + struct rt2661_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; - RAL_LOCK(sc); - if (ic->ic_nrunning > 0) { - if ((sc->sc_flags & RAL_RUNNING) == 0) { - rt2661_init_locked(sc); - startall = 1; - } else - rt2661_update_promisc(ic); - } else if (sc->sc_flags & RAL_RUNNING) - rt2661_stop_locked(sc); - RAL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); + switch (cmd) { + case SIOCSIFFLAGS: + RAL_LOCK(sc); + if (ifp->if_flags & IFF_UP) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + rt2661_init_locked(sc); + startall = 1; + } else + rt2661_update_promisc(ic); + } else { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + rt2661_stop_locked(sc); + } + RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); + break; + case SIOCGIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; + case SIOCGIFADDR: + error = ether_ioctl(ifp, cmd, data); + break; + default: + error = EINVAL; + break; + } + return error; } static void @@ -1827,7 +1879,8 @@ rt2661_select_antenna(struct rt2661_softc *sc) static void rt2661_enable_mrr(struct rt2661_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; tmp = RAL_READ(sc, RT2661_TXRX_CSR4); @@ -1843,7 +1896,8 @@ rt2661_enable_mrr(struct rt2661_softc *sc) static void rt2661_set_txpreamble(struct rt2661_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; tmp = RAL_READ(sc, RT2661_TXRX_CSR4); @@ -1860,7 +1914,8 @@ rt2661_set_basicrates(struct rt2661_softc *sc, const struct ieee80211_rateset *rs) { #define RV(r) ((r) & IEEE80211_RATE_VAL) - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t mask = 0; uint8_t rate; int i; @@ -1929,7 +1984,8 @@ rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c) static void rt2661_set_chan(struct rt2661_softc *sc, struct ieee80211_channel *c) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; const struct rfprog *rfprog; uint8_t bbp3, bbp94 = RT2661_BBPR94_DEFAULT; int8_t power; @@ -2032,13 +2088,13 @@ rt2661_update_promisc(struct ieee80211com *ic) tmp = RAL_READ(sc, RT2661_TXRX_CSR0); tmp &= ~RT2661_DROP_NOT_TO_ME; - if (ic->ic_promisc == 0) + if (!(ic->ic_ifp->if_flags & IFF_PROMISC)) tmp |= RT2661_DROP_NOT_TO_ME; RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp); DPRINTF(sc, "%s promiscuous mode\n", - (ic->ic_promisc > 0) ? "entering" : "leaving"); + (ic->ic_ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving"); } /* @@ -2047,7 +2103,7 @@ rt2661_update_promisc(struct ieee80211com *ic) static int rt2661_wme_update(struct ieee80211com *ic) { - struct rt2661_softc *sc = ic->ic_softc; + struct rt2661_softc *sc = ic->ic_ifp->if_softc; const struct wmeParams *wmep; wmep = ic->ic_wme.wme_chanParams.cap_wmeParams; @@ -2245,8 +2301,8 @@ static void rt2661_init_locked(struct rt2661_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp, sta[3]; int i, error, ntries; @@ -2255,7 +2311,7 @@ rt2661_init_locked(struct rt2661_softc *sc) if ((sc->sc_flags & RAL_FW_LOADED) == 0) { error = rt2661_load_microcode(sc); if (error != 0) { - device_printf(sc->sc_dev, + if_printf(ifp, "%s: could not load 8051 microcode, error %d\n", __func__, error); return; @@ -2308,7 +2364,7 @@ rt2661_init_locked(struct rt2661_softc *sc) for (i = 0; i < N(rt2661_def_mac); i++) RAL_WRITE(sc, rt2661_def_mac[i].reg, rt2661_def_mac[i].val); - rt2661_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); + rt2661_set_macaddr(sc, IF_LLADDR(ifp)); /* set host ready */ RAL_WRITE(sc, RT2661_MAC_CSR1, 3); @@ -2347,7 +2403,7 @@ rt2661_init_locked(struct rt2661_softc *sc) if (ic->ic_opmode != IEEE80211_M_HOSTAP && ic->ic_opmode != IEEE80211_M_MBSS) tmp |= RT2661_DROP_TODS; - if (ic->ic_promisc == 0) + if (!(ifp->if_flags & IFF_PROMISC)) tmp |= RT2661_DROP_NOT_TO_ME; } @@ -2369,7 +2425,8 @@ rt2661_init_locked(struct rt2661_softc *sc) /* kick Rx */ RAL_WRITE(sc, RT2661_RX_CNTL_CSR, 1); - sc->sc_flags |= RAL_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + ifp->if_drv_flags |= IFF_DRV_RUNNING; callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc); #undef N @@ -2379,21 +2436,23 @@ static void rt2661_init(void *priv) { struct rt2661_softc *sc = priv; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; RAL_LOCK(sc); rt2661_init_locked(sc); RAL_UNLOCK(sc); - if (sc->sc_flags & RAL_RUNNING) + if (ifp->if_drv_flags & IFF_DRV_RUNNING) ieee80211_start_all(ic); /* start all vap's */ } void rt2661_stop_locked(struct rt2661_softc *sc) { - volatile int *flags = &sc->sc_flags; + struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; + volatile int *flags = &sc->sc_flags; while (*flags & RAL_INPUT_RUNNING) msleep(sc, &sc->sc_mtx, 0, "ralrunning", hz/10); @@ -2401,8 +2460,8 @@ rt2661_stop_locked(struct rt2661_softc *sc) callout_stop(&sc->watchdog_ch); sc->sc_tx_timer = 0; - if (sc->sc_flags & RAL_RUNNING) { - sc->sc_flags &= ~RAL_RUNNING; + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); /* abort Tx (for all 5 Tx rings) */ RAL_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16); @@ -2446,6 +2505,7 @@ rt2661_stop(void *priv) static int rt2661_load_microcode(struct rt2661_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; const struct firmware *fp; const char *imagename; int ntries, error; @@ -2457,7 +2517,7 @@ rt2661_load_microcode(struct rt2661_softc *sc) case 0x0302: imagename = "rt2561fw"; break; case 0x0401: imagename = "rt2661fw"; break; default: - device_printf(sc->sc_dev, "%s: unexpected pci device id 0x%x, " + if_printf(ifp, "%s: unexpected pci device id 0x%x, " "don't know how to retrieve firmware\n", __func__, sc->sc_id); return EINVAL; @@ -2466,8 +2526,7 @@ rt2661_load_microcode(struct rt2661_softc *sc) fp = firmware_get(imagename); RAL_LOCK(sc); if (fp == NULL) { - device_printf(sc->sc_dev, - "%s: unable to retrieve firmware image %s\n", + if_printf(ifp, "%s: unable to retrieve firmware image %s\n", __func__, imagename); return EINVAL; } @@ -2498,8 +2557,8 @@ rt2661_load_microcode(struct rt2661_softc *sc) DELAY(100); } if (ntries == 500) { - device_printf(sc->sc_dev, - "%s: timeout waiting for MCU to initialize\n", __func__); + if_printf(ifp, "%s: timeout waiting for MCU to initialize\n", + __func__); error = EIO; } else error = 0; @@ -2667,7 +2726,8 @@ rt2661_prepare_beacon(struct rt2661_softc *sc, struct ieee80211vap *vap) static void rt2661_enable_tsf_sync(struct rt2661_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; @@ -2751,19 +2811,21 @@ rt2661_get_rssi(struct rt2661_softc *sc, uint8_t raw) static void rt2661_scan_start(struct ieee80211com *ic) { - struct rt2661_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rt2661_softc *sc = ifp->if_softc; uint32_t tmp; /* abort TSF synchronization */ tmp = RAL_READ(sc, RT2661_TXRX_CSR9); RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0xffffff); - rt2661_set_bssid(sc, ieee80211broadcastaddr); + rt2661_set_bssid(sc, ifp->if_broadcastaddr); } static void rt2661_scan_end(struct ieee80211com *ic) { - struct rt2661_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rt2661_softc *sc = ifp->if_softc; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); rt2661_enable_tsf_sync(sc); @@ -2774,7 +2836,8 @@ rt2661_scan_end(struct ieee80211com *ic) static void rt2661_set_channel(struct ieee80211com *ic) { - struct rt2661_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rt2661_softc *sc = ifp->if_softc; RAL_LOCK(sc); rt2661_set_chan(sc, ic->ic_curchan); diff --git a/sys/dev/ral/rt2661var.h b/sys/dev/ral/rt2661var.h index 7ea16f623d57..9927d138fa71 100644 --- a/sys/dev/ral/rt2661var.h +++ b/sys/dev/ral/rt2661var.h @@ -97,13 +97,13 @@ struct rt2661_vap { #define RT2661_VAP(vap) ((struct rt2661_vap *)(vap)) struct rt2661_softc { - struct ieee80211com sc_ic; - struct mtx sc_mtx; - struct mbufq sc_snd; + struct ifnet *sc_ifp; device_t sc_dev; bus_space_tag_t sc_st; bus_space_handle_t sc_sh; + struct mtx sc_mtx; + struct callout watchdog_ch; int sc_tx_timer; @@ -117,7 +117,6 @@ struct rt2661_softc { int sc_flags; #define RAL_FW_LOADED 0x1 #define RAL_INPUT_RUNNING 0x2 -#define RAL_RUNNING 0x4 int sc_id; struct ieee80211_channel *sc_curchan; diff --git a/sys/dev/ral/rt2860.c b/sys/dev/ral/rt2860.c index b3c737d67c66..782fa1f9780b 100644 --- a/sys/dev/ral/rt2860.c +++ b/sys/dev/ral/rt2860.c @@ -122,10 +122,10 @@ static int rt2860_raw_xmit(struct ieee80211_node *, struct mbuf *, static int rt2860_tx_raw(struct rt2860_softc *, struct mbuf *, struct ieee80211_node *, const struct ieee80211_bpf_params *params); -static int rt2860_transmit(struct ieee80211com *, struct mbuf *); -static void rt2860_start(struct rt2860_softc *); +static void rt2860_start(struct ifnet *); +static void rt2860_start_locked(struct ifnet *); static void rt2860_watchdog(void *); -static void rt2860_parent(struct ieee80211com *); +static int rt2860_ioctl(struct ifnet *, u_long, caddr_t); static void rt2860_mcu_bbp_write(struct rt2860_softc *, uint8_t, uint8_t); static uint8_t rt2860_mcu_bbp_read(struct rt2860_softc *, uint8_t); static void rt2860_rf_write(struct rt2860_softc *, uint8_t, uint32_t); @@ -156,7 +156,7 @@ static void rt2860_set_bssid(struct rt2860_softc *, const uint8_t *); static void rt2860_set_macaddr(struct rt2860_softc *, const uint8_t *); static void rt2860_update_promisc(struct ieee80211com *); static void rt2860_updateslot(struct ieee80211com *); -static void rt2860_updateprot(struct rt2860_softc *); +static void rt2860_updateprot(struct ifnet *); static int rt2860_updateedca(struct ieee80211com *); #ifdef HW_CRYPTO static int rt2860_set_key(struct ieee80211com *, struct ieee80211_node *, @@ -230,19 +230,27 @@ int rt2860_attach(device_t dev, int id) { struct rt2860_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; + struct ifnet *ifp; uint32_t tmp; int error, ntries, qid; uint8_t bands; + uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_dev = dev; sc->sc_debug = 0; + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(sc->sc_dev, "can not if_alloc()\n"); + return ENOMEM; + } + ic = ifp->if_l2com; + mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); - mbufq_init(&sc->sc_snd, ifqmaxlen); /* wait for NIC to initialize */ for (ntries = 0; ntries < 100; ntries++) { @@ -265,11 +273,11 @@ rt2860_attach(device_t dev, int id) sc->sc_flags |= RT2860_ADVANCED_PS; /* retrieve RF rev. no and various other things from EEPROM */ - rt2860_read_eeprom(sc, ic->ic_macaddr); + rt2860_read_eeprom(sc, macaddr); device_printf(sc->sc_dev, "MAC/BBP RT%X (rev 0x%04X), " "RF %s (MIMO %dT%dR), address %6D\n", sc->mac_ver, sc->mac_rev, rt2860_get_rf(sc->rf_rev), - sc->ntxchains, sc->nrxchains, ic->ic_macaddr, ":"); + sc->ntxchains, sc->nrxchains, macaddr, ":"); /* * Allocate Tx (4 EDCAs + HCCA + Mgt) and Rx rings. @@ -296,6 +304,17 @@ rt2860_attach(device_t dev, int id) sc->mgtqid = (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) ? WME_AC_VO : 5; + ifp->if_softc = sc; + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_init = rt2860_init; + ifp->if_ioctl = rt2860_ioctl; + ifp->if_start = rt2860_start; + 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(dev); ic->ic_opmode = IEEE80211_M_STA; @@ -326,7 +345,7 @@ rt2860_attach(device_t dev, int id) setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic); + ieee80211_ifattach(ic, macaddr); ic->ic_wme.wme_update = rt2860_updateedca; ic->ic_scan_start = rt2860_scan_start; @@ -338,8 +357,7 @@ rt2860_attach(device_t dev, int id) sc->sc_node_free = ic->ic_node_free; ic->ic_node_free = rt2860_node_free; ic->ic_newassoc = rt2860_newassoc; - ic->ic_transmit = rt2860_transmit; - ic->ic_parent = rt2860_parent; + ic->ic_vap_create = rt2860_vap_create; ic->ic_vap_delete = rt2860_vap_delete; @@ -363,6 +381,7 @@ fail3: rt2860_free_rx_ring(sc, &sc->rxq); fail2: while (--qid >= 0) rt2860_free_tx_ring(sc, &sc->txq[qid]); fail1: mtx_destroy(&sc->sc_mtx); + if_free(ifp); return error; } @@ -370,7 +389,8 @@ int rt2860_detach(void *xsc) { struct rt2860_softc *sc = xsc; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; int qid; RAL_LOCK(sc); @@ -378,12 +398,14 @@ rt2860_detach(void *xsc) RAL_UNLOCK(sc); ieee80211_ifdetach(ic); - mbufq_drain(&sc->sc_snd); + for (qid = 0; qid < 6; qid++) rt2860_free_tx_ring(sc, &sc->txq[qid]); rt2860_free_rx_ring(sc, &sc->rxq); rt2860_free_tx_pool(sc); + if_free(ifp); + mtx_destroy(&sc->sc_mtx); return 0; @@ -409,8 +431,9 @@ void rt2860_resume(void *xsc) { struct rt2860_softc *sc = xsc; + struct ifnet *ifp = sc->sc_ifp; - if (sc->sc_ic.ic_nrunning > 0) + if (ifp->if_flags & IFF_UP) rt2860_init(sc); } @@ -420,7 +443,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct rt2860_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; struct rt2860_vap *rvp; struct ieee80211vap *vap; @@ -433,7 +456,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_MBSS: /* XXXRP: TBD */ if (!TAILQ_EMPTY(&ic->ic_vaps)) { - device_printf(sc->sc_dev, "only 1 vap supported\n"); + if_printf(ifp, "only 1 vap supported\n"); return NULL; } if (opmode == IEEE80211_M_STA) @@ -442,8 +465,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_WDS: if (TAILQ_EMPTY(&ic->ic_vaps) || ic->ic_opmode != IEEE80211_M_HOSTAP) { - device_printf(sc->sc_dev, - "wds only supported in ap mode\n"); + if_printf(ifp, "wds only supported in ap mode\n"); return NULL; } /* @@ -454,12 +476,14 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, flags &= ~IEEE80211_CLONE_BSSID; break; default: - device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); + if_printf(ifp, "unknown opmode %d\n", opmode); return NULL; } - rvp = malloc(sizeof(struct rt2860_vap), M_80211_VAP, M_WAITOK | M_ZERO); + rvp = malloc(sizeof(struct rt2860_vap), M_80211_VAP, M_NOWAIT | M_ZERO); + if (rvp == NULL) + return NULL; vap = &rvp->ral_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); /* override state transition machine */ rvp->ral_newstate = vap->iv_newstate; @@ -473,8 +497,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status, mac); + ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); if (TAILQ_FIRST(&ic->ic_vaps) == vap) ic->ic_opmode = opmode; return vap; @@ -806,7 +829,7 @@ rt2860_free_rx_ring(struct rt2860_softc *sc, struct rt2860_rx_ring *ring) static void rt2860_updatestats(struct rt2860_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; /* * In IBSS or HostAP modes (when the hardware sends beacons), the @@ -833,7 +856,7 @@ static void rt2860_newassoc(struct ieee80211_node *ni, int isnew) { struct ieee80211com *ic = ni->ni_ic; - struct rt2860_softc *sc = ic->ic_softc; + struct rt2860_softc *sc = ic->ic_ifp->if_softc; uint8_t wcid; wcid = IEEE80211_AID(ni->ni_associd); @@ -852,7 +875,7 @@ static void rt2860_node_free(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct rt2860_softc *sc = ic->ic_softc; + struct rt2860_softc *sc = ic->ic_ifp->if_softc; uint8_t wcid; if (ni->ni_associd != 0) { @@ -900,7 +923,7 @@ rt2860_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rt2860_vap *rvp = RT2860_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct rt2860_softc *sc = ic->ic_softc; + struct rt2860_softc *sc = ic->ic_ifp->if_softc; uint32_t tmp; int error; @@ -1078,6 +1101,7 @@ rt2860_intr_coherent(struct rt2860_softc *sc) static void rt2860_drain_stats_fifo(struct rt2860_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; struct ieee80211_node *ni; uint32_t stat; int retrycnt; @@ -1113,8 +1137,7 @@ rt2860_drain_stats_fifo(struct rt2860_softc *sc) } else { ieee80211_ratectl_tx_complete(ni->ni_vap, ni, IEEE80211_RATECTL_TX_FAILURE, &retrycnt, NULL); - if_inc_counter(ni->ni_vap->iv_ifp, - IFCOUNTER_OERRORS, 1); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } } } @@ -1122,6 +1145,7 @@ rt2860_drain_stats_fifo(struct rt2860_softc *sc) static void rt2860_tx_intr(struct rt2860_softc *sc, int qid) { + struct ifnet *ifp = sc->sc_ifp; struct rt2860_tx_ring *ring = &sc->txq[qid]; uint32_t hw; @@ -1139,11 +1163,15 @@ rt2860_tx_intr(struct rt2860_softc *sc, int qid) ieee80211_process_callback(data->ni, data->m, 0); } - ieee80211_tx_complete(data->ni, data->m, 0); - data->ni = NULL; + m_freem(data->m); + ieee80211_free_node(data->ni); data->m = NULL; + data->ni = NULL; + SLIST_INSERT_HEAD(&sc->data_pool, data, next); ring->data[ring->next] = NULL; + + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); } ring->queued--; ring->next = (ring->next + 1) % RT2860_TX_RING_COUNT; @@ -1152,7 +1180,8 @@ rt2860_tx_intr(struct rt2860_softc *sc, int qid) sc->sc_tx_timer = 0; if (ring->queued < RT2860_TX_RING_COUNT) sc->qfullmsk &= ~(1 << qid); - rt2860_start(sc); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + rt2860_start_locked(ifp); } /* @@ -1177,7 +1206,8 @@ static void rt2860_rx_intr(struct rt2860_softc *sc) { struct rt2860_rx_radiotap_header *tap; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *m, *m1; @@ -1204,7 +1234,7 @@ rt2860_rx_intr(struct rt2860_softc *sc) if (__predict_false(rxd->flags & htole32(RT2860_RX_CRCERR | RT2860_RX_ICVERR))) { - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto skip; } @@ -1213,14 +1243,14 @@ rt2860_rx_intr(struct rt2860_softc *sc) /* report MIC failures to net80211 for TKIP */ ic->ic_stats.is_rx_locmicfail++; ieee80211_michael_mic_failure(ic, 0/* XXX */); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto skip; } #endif m1 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (__predict_false(m1 == NULL)) { - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto skip; } @@ -1244,7 +1274,7 @@ rt2860_rx_intr(struct rt2860_softc *sc) } /* physical address may have changed */ rxd->sdp0 = htole32(physaddr); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); goto skip; } @@ -1259,6 +1289,7 @@ rt2860_rx_intr(struct rt2860_softc *sc) rxwi = mtod(m, struct rt2860_rxwi *); /* finalize mbuf */ + m->m_pkthdr.rcvif = ifp; m->m_data = (caddr_t)(rxwi + 1); m->m_pkthdr.len = m->m_len = le16toh(rxwi->len) & 0xfff; @@ -1368,7 +1399,7 @@ rt2860_tbtt_intr(struct rt2860_softc *sc) #endif /* check if protection mode has changed */ if ((sc->sc_ic_flags ^ ic->ic_flags) & IEEE80211_F_USEPROT) { - rt2860_updateprot(sc); + rt2860_updateprot(ic); sc->sc_ic_flags = ic->ic_flags; } #endif @@ -1377,7 +1408,7 @@ rt2860_tbtt_intr(struct rt2860_softc *sc) static void rt2860_gp_intr(struct rt2860_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); DPRINTFN(2, ("GP timeout state=%d\n", vap->iv_state)); @@ -1449,7 +1480,8 @@ rt2860_intr(void *arg) static int rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = ni->ni_vap; struct rt2860_tx_ring *ring; struct rt2860_tx_data *data; @@ -1693,13 +1725,14 @@ rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct rt2860_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rt2860_softc *sc = ifp->if_softc; int error; RAL_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(sc->sc_flags & RT2860_RUNNNING)) { + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); @@ -1721,6 +1754,7 @@ rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, if (error != 0) { /* NB: m is reclaimed on tx failure */ ieee80211_free_node(ni); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } sc->sc_tx_timer = 5; RAL_UNLOCK(sc); @@ -1731,7 +1765,8 @@ static int rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = ni->ni_vap; struct rt2860_tx_ring *ring; struct rt2860_tx_data *data; @@ -1938,46 +1973,41 @@ rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m, return 0; } -static int -rt2860_transmit(struct ieee80211com *ic, struct mbuf *m) +static void +rt2860_start(struct ifnet *ifp) { - struct rt2860_softc *sc = ic->ic_softc; - int error; + struct rt2860_softc *sc = ifp->if_softc; RAL_LOCK(sc); - if ((sc->sc_flags & RT2860_RUNNNING) == 0) { - RAL_UNLOCK(sc); - return (ENXIO); - } - error = mbufq_enqueue(&sc->sc_snd, m); - if (error) { - RAL_UNLOCK(sc); - return (error); - } - rt2860_start(sc); + rt2860_start_locked(ifp); RAL_UNLOCK(sc); - - return (0); } static void -rt2860_start(struct rt2860_softc *sc) +rt2860_start_locked(struct ifnet *ifp) { + struct rt2860_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; RAL_LOCK_ASSERT(sc); - if ((sc->sc_flags & RT2860_RUNNNING) == 0) + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || + (ifp->if_drv_flags & IFF_DRV_OACTIVE)) return; - while (!SLIST_EMPTY(&sc->data_pool) && sc->qfullmsk == 0 && - (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + for (;;) { + if (SLIST_EMPTY(&sc->data_pool) || sc->qfullmsk != 0) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; if (rt2860_tx(sc, m, ni) != 0) { - if_inc_counter(ni->ni_vap->iv_ifp, - IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); continue; } sc->sc_tx_timer = 5; @@ -1988,42 +2018,61 @@ static void rt2860_watchdog(void *arg) { struct rt2860_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; RAL_LOCK_ASSERT(sc); - KASSERT(sc->sc_flags & RT2860_RUNNNING, ("not running")); + KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); if (sc->sc_invalid) /* card ejected */ return; if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { - device_printf(sc->sc_dev, "device timeout\n"); + if_printf(ifp, "device timeout\n"); rt2860_stop_locked(sc); rt2860_init_locked(sc); - counter_u64_add(sc->sc_ic.ic_oerrors, 1); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); return; } callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc); } -static void -rt2860_parent(struct ieee80211com *ic) +static int +rt2860_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - struct rt2860_softc *sc = ic->ic_softc; - int startall = 0; + struct rt2860_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *)data; + int error = 0, startall = 0; - RAL_LOCK(sc); - if (ic->ic_nrunning> 0) { - if (!(sc->sc_flags & RT2860_RUNNNING)) { - rt2860_init_locked(sc); - startall = 1; - } else - rt2860_update_promisc(ic); - } else if (sc->sc_flags & RT2860_RUNNNING) - rt2860_stop_locked(sc); - RAL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); + switch (cmd) { + case SIOCSIFFLAGS: + RAL_LOCK(sc); + if (ifp->if_flags & IFF_UP) { + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + rt2860_init_locked(sc); + startall = 1; + } else + rt2860_update_promisc(ic); + } else { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + rt2860_stop_locked(sc); + } + RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); + break; + case SIOCGIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; + case SIOCSIFADDR: + error = ether_ioctl(ifp, cmd, data); + break; + default: + error = EINVAL; + break; + } + return error; } /* @@ -2246,7 +2295,8 @@ rt2860_enable_mrr(struct rt2860_softc *sc) static void rt2860_set_txpreamble(struct rt2860_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; tmp = RAL_READ(sc, RT2860_AUTO_RSP_CFG); @@ -2261,7 +2311,8 @@ rt2860_set_basicrates(struct rt2860_softc *sc, const struct ieee80211_rateset *rs) { #define RV(r) ((r) & IEEE80211_RATE_VAL) - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t mask = 0; uint8_t rate; int i; @@ -2282,7 +2333,8 @@ rt2860_set_basicrates(struct rt2860_softc *sc, static void rt2860_scan_start(struct ieee80211com *ic) { - struct rt2860_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rt2860_softc *sc = ifp->if_softc; uint32_t tmp; tmp = RAL_READ(sc, RT2860_BCN_TIME_CFG); @@ -2295,7 +2347,8 @@ rt2860_scan_start(struct ieee80211com *ic) static void rt2860_scan_end(struct ieee80211com *ic) { - struct rt2860_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rt2860_softc *sc = ifp->if_softc; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); if (vap->iv_state == IEEE80211_S_RUN) { @@ -2307,7 +2360,8 @@ rt2860_scan_end(struct ieee80211com *ic) static void rt2860_set_channel(struct ieee80211com *ic) { - struct rt2860_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct rt2860_softc *sc = ifp->if_softc; RAL_LOCK(sc); rt2860_switch_chan(sc, ic->ic_curchan); @@ -3059,9 +3113,10 @@ rt2860_updateslot(struct ieee80211com *ic) } static void -rt2860_updateprot(struct rt2860_softc *sc) +rt2860_updateprot(struct ifnet *ifp) { - struct ieee80211com *ic = &sc->sc_ic; + struct rt2860_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL; @@ -3090,7 +3145,7 @@ rt2860_update_promisc(struct ieee80211com *ic) tmp = RAL_READ(sc, RT2860_RX_FILTR_CFG); tmp &= ~RT2860_DROP_NOT_MYBSS; - if (ic->ic_promisc == 0) + if (!(ic->ic_ifp->if_flags & IFF_PROMISC)) tmp |= RT2860_DROP_NOT_MYBSS; RAL_WRITE(sc, RT2860_RX_FILTR_CFG, tmp); } @@ -3098,7 +3153,7 @@ rt2860_update_promisc(struct ieee80211com *ic) static int rt2860_updateedca(struct ieee80211com *ic) { - struct rt2860_softc *sc = ic->ic_softc; + struct rt2860_softc *sc = ic->ic_ifp->if_softc; const struct wmeParams *wmep; int aci; @@ -3270,7 +3325,8 @@ rt2860_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, static int8_t rt2860_rssi2dbm(struct rt2860_softc *sc, uint8_t rssi, uint8_t rxchain) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211_channel *c = ic->ic_curchan; int delta; @@ -3745,7 +3801,8 @@ rt5390_bbp_init(struct rt2860_softc *sc) static int rt2860_txrx_enable(struct rt2860_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; int ntries; @@ -3791,21 +3848,22 @@ static void rt2860_init(void *arg) { struct rt2860_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; RAL_LOCK(sc); rt2860_init_locked(sc); RAL_UNLOCK(sc); - if (sc->sc_flags & RT2860_RUNNNING) + if (ifp->if_drv_flags & IFF_DRV_RUNNING) ieee80211_start_all(ic); } static void rt2860_init_locked(struct rt2860_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; uint8_t bbp1, bbp3; int i, qid, ridx, ntries, error; @@ -3841,7 +3899,7 @@ rt2860_init_locked(struct rt2860_softc *sc) return; } - rt2860_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); + rt2860_set_macaddr(sc, IF_LLADDR(ifp)); /* init Tx power for all Tx rates (from EEPROM) */ for (ridx = 0; ridx < 5; ridx++) { @@ -4038,7 +4096,7 @@ rt2860_init_locked(struct rt2860_softc *sc) RAL_WRITE(sc, RT2860_TX_RTS_CFG, tmp); /* setup initial protection mode */ - rt2860_updateprot(sc); + rt2860_updateprot(ifp); /* turn radio LED on */ rt2860_set_leds(sc, RT2860_LED_RADIO); @@ -4057,7 +4115,8 @@ rt2860_init_locked(struct rt2860_softc *sc) if (sc->sc_flags & RT2860_ADVANCED_PS) rt2860_mcu_cmd(sc, RT2860_MCU_CMD_PSLEVEL, sc->pslevel, 0); - sc->sc_flags |= RT2860_RUNNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + ifp->if_drv_flags |= IFF_DRV_RUNNING; callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc); } @@ -4075,15 +4134,16 @@ rt2860_stop(void *arg) static void rt2860_stop_locked(struct rt2860_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; int qid; - if (sc->sc_flags & RT2860_RUNNNING) + if (ifp->if_drv_flags & IFF_DRV_RUNNING) rt2860_set_leds(sc, 0); /* turn all LEDs off */ callout_stop(&sc->watchdog_ch); sc->sc_tx_timer = 0; - sc->sc_flags &= ~RT2860_RUNNNING; + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); /* disable interrupts */ RAL_WRITE(sc, RT2860_INT_MASK, 0); @@ -4234,7 +4294,8 @@ rt3090_set_rx_antenna(struct rt2860_softc *sc, int aux) static void rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; u_int chan, group; chan = ieee80211_chan2ieee(ic, c); @@ -4303,7 +4364,8 @@ rt2860_setup_beacon(struct rt2860_softc *sc, struct ieee80211vap *vap) static void rt2860_enable_tsf_sync(struct rt2860_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; diff --git a/sys/dev/ral/rt2860var.h b/sys/dev/ral/rt2860var.h index 3779e5beb1d1..28a3d59b8263 100644 --- a/sys/dev/ral/rt2860var.h +++ b/sys/dev/ral/rt2860var.h @@ -115,13 +115,13 @@ struct rt2860_vap { #define RT2860_VAP(vap) ((struct rt2860_vap *)(vap)) struct rt2860_softc { - struct ieee80211com sc_ic; - struct mbufq sc_snd; - struct mtx sc_mtx; + struct ifnet *sc_ifp; device_t sc_dev; bus_space_tag_t sc_st; bus_space_handle_t sc_sh; + struct mtx sc_mtx; + struct callout watchdog_ch; int sc_invalid; @@ -139,7 +139,6 @@ struct rt2860_softc { #define RT2860_ENABLED (1 << 0) #define RT2860_ADVANCED_PS (1 << 1) #define RT2860_PCIE (1 << 2) -#define RT2860_RUNNNING (1 << 3) struct ieee80211_node *wcid2ni[RT2860_WCID_MAX]; |
