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/wi | |
parent | 721b581722c3a383f02036d009db4473590e3f88 (diff) | |
download | src-ba2c1fbc03f312b978f76f7b6c67eec6afa80bf8.tar.gz src-ba2c1fbc03f312b978f76f7b6c67eec6afa80bf8.zip |
Revert the wifi ifnet changes until things are more baked and tested.
* 286410
* 286413
* 286416
The initial commit broke a variety of debug and features that aren't
in the GENERIC kernels but are enabled in other platforms.
Notes
Notes:
svn path=/head/; revision=286437
Diffstat (limited to 'sys/dev/wi')
-rw-r--r-- | sys/dev/wi/if_wi.c | 382 | ||||
-rw-r--r-- | sys/dev/wi/if_wi_pccard.c | 1 | ||||
-rw-r--r-- | sys/dev/wi/if_wi_pci.c | 17 | ||||
-rw-r--r-- | sys/dev/wi/if_wivar.h | 8 |
4 files changed, 247 insertions, 161 deletions
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index f8af23138340..b316d46dae74 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -116,9 +116,11 @@ static struct ieee80211vap *wi_vap_create(struct ieee80211com *, const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void wi_vap_delete(struct ieee80211vap *vap); -static int wi_transmit(struct ieee80211com *, struct mbuf *); -static void wi_start(struct wi_softc *); -static int wi_start_tx(struct wi_softc *, struct wi_frame *, struct mbuf *); +static void wi_stop_locked(struct wi_softc *sc, int disable); +static void wi_start_locked(struct ifnet *); +static void wi_start(struct ifnet *); +static int wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr, + struct mbuf *m0); static int wi_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static int wi_newstate_sta(struct ieee80211vap *, enum ieee80211_state, int); @@ -129,8 +131,10 @@ static void wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf); static int wi_reset(struct wi_softc *); static void wi_watchdog(void *); -static void wi_parent(struct ieee80211com *); +static int wi_ioctl(struct ifnet *, u_long, caddr_t); static void wi_media_status(struct ifnet *, struct ifmediareq *); +static uint64_t wi_get_counter(struct ifnet *, ift_counter); + static void wi_rx_intr(struct wi_softc *); static void wi_tx_intr(struct wi_softc *); static void wi_tx_ex_intr(struct wi_softc *); @@ -149,10 +153,10 @@ static int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int); static int wi_cmd(struct wi_softc *, int, int, int, int); static int wi_seek_bap(struct wi_softc *, int, int); static int wi_read_bap(struct wi_softc *, int, int, void *, int); -static int wi_write_bap(struct wi_softc *, int, int, const void *, int); +static int wi_write_bap(struct wi_softc *, int, int, void *, int); static int wi_mwrite_bap(struct wi_softc *, int, int, struct mbuf *, int); static int wi_read_rid(struct wi_softc *, int, void *, int *); -static int wi_write_rid(struct wi_softc *, int, const void *, int); +static int wi_write_rid(struct wi_softc *, int, void *, int); static int wi_write_appie(struct wi_softc *, int, const struct ieee80211_appie *); static void wi_scan_start(struct ieee80211com *); @@ -233,7 +237,8 @@ int wi_attach(device_t dev) { struct wi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; + struct ifnet *ifp; int i, nrates, buflen; u_int16_t val; u_int8_t ratebuf[2 + IEEE80211_RATE_SIZE]; @@ -244,6 +249,15 @@ wi_attach(device_t dev) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; int error; + uint8_t macaddr[IEEE80211_ADDR_LEN]; + + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(dev, "can not if_alloc\n"); + wi_free(dev); + return ENOSPC; + } + ic = ifp->if_l2com; sc->sc_firmware_type = WI_NOTYPE; sc->wi_cmd_count = 500; @@ -295,7 +309,6 @@ wi_attach(device_t dev) mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0); - mbufq_init(&sc->sc_snd, ifqmaxlen); /* * Read the station address. @@ -304,13 +317,12 @@ wi_attach(device_t dev) * the probe to fail. */ buflen = IEEE80211_ADDR_LEN; - error = wi_read_rid(sc, WI_RID_MAC_NODE, &ic->ic_macaddr, &buflen); + error = wi_read_rid(sc, WI_RID_MAC_NODE, macaddr, &buflen); if (error != 0) { buflen = IEEE80211_ADDR_LEN; - error = wi_read_rid(sc, WI_RID_MAC_NODE, &ic->ic_macaddr, - &buflen); + error = wi_read_rid(sc, WI_RID_MAC_NODE, macaddr, &buflen); } - if (error || IEEE80211_ADDR_EQ(&ic->ic_macaddr, empty_macaddr)) { + if (error || IEEE80211_ADDR_EQ(macaddr, empty_macaddr)) { if (error != 0) device_printf(dev, "mac read failed %d\n", error); else { @@ -321,6 +333,18 @@ wi_attach(device_t dev) return (error); } + 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_ioctl = wi_ioctl; + ifp->if_start = wi_start; + ifp->if_init = wi_init; + ifp->if_get_counter = wi_get_counter; + 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_phytype = IEEE80211_T_DS; @@ -434,17 +458,16 @@ wi_attach(device_t dev) sc->sc_portnum = WI_DEFAULT_PORT; - ieee80211_ifattach(ic); + ieee80211_ifattach(ic, macaddr); ic->ic_raw_xmit = wi_raw_xmit; ic->ic_scan_start = wi_scan_start; ic->ic_scan_end = wi_scan_end; ic->ic_set_channel = wi_set_channel; + ic->ic_vap_create = wi_vap_create; ic->ic_vap_delete = wi_vap_delete; ic->ic_update_mcast = wi_update_mcast; ic->ic_update_promisc = wi_update_promisc; - ic->ic_transmit = wi_transmit; - ic->ic_parent = wi_parent; ieee80211_radiotap_attach(ic, &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), @@ -460,6 +483,7 @@ wi_attach(device_t dev) if (error) { device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); ieee80211_ifdetach(ic); + if_free(sc->sc_ifp); wi_free(dev); return error; } @@ -471,20 +495,21 @@ int wi_detach(device_t dev) { struct wi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; WI_LOCK(sc); /* check if device was removed */ sc->wi_gone |= !bus_child_present(dev); - wi_stop(sc, 0); + wi_stop_locked(sc, 0); WI_UNLOCK(sc); ieee80211_ifdetach(ic); bus_teardown_intr(dev, sc->irq, sc->wi_intrhand); + if_free(sc->sc_ifp); wi_free(dev); - mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); } @@ -495,16 +520,19 @@ wi_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 wi_softc *sc = ic->ic_softc; + struct wi_softc *sc = ic->ic_ifp->if_softc; struct wi_vap *wvp; struct ieee80211vap *vap; if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return NULL; - wvp = malloc(sizeof(struct wi_vap), M_80211_VAP, M_WAITOK | M_ZERO); + wvp = (struct wi_vap *) malloc(sizeof(struct wi_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (wvp == NULL) + return NULL; vap = &wvp->wv_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); vap->iv_max_aid = WI_MAX_AID; @@ -538,7 +566,7 @@ wi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, } /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, wi_media_status, mac); + ieee80211_vap_attach(vap, ieee80211_media_change, wi_media_status); ic->ic_opmode = opmode; return vap; } @@ -557,9 +585,7 @@ wi_shutdown(device_t dev) { struct wi_softc *sc = device_get_softc(dev); - WI_LOCK(sc); wi_stop(sc, 1); - WI_UNLOCK(sc); return (0); } @@ -567,12 +593,12 @@ void wi_intr(void *arg) { struct wi_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; u_int16_t status; WI_LOCK(sc); - if (sc->wi_gone || !sc->sc_enabled || - (sc->sc_flags & WI_FLAGS_RUNNING) == 0) { + if (sc->wi_gone || !sc->sc_enabled || (ifp->if_flags & IFF_UP) == 0) { CSR_WRITE_2(sc, WI_INT_EN, 0); CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); WI_UNLOCK(sc); @@ -591,8 +617,9 @@ wi_intr(void *arg) wi_tx_ex_intr(sc); if (status & WI_EV_INFO) wi_info_intr(sc); - if (mbufq_first(&sc->sc_snd) != NULL) - wi_start(sc); + if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && + !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + wi_start_locked(ifp); /* Re-enable interrupts. */ CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); @@ -615,7 +642,7 @@ wi_enable(struct wi_softc *sc) static int wi_setup_locked(struct wi_softc *sc, int porttype, int mode, - const uint8_t mac[IEEE80211_ADDR_LEN]) + uint8_t mac[IEEE80211_ADDR_LEN]) { int i; @@ -649,25 +676,26 @@ wi_setup_locked(struct wi_softc *sc, int porttype, int mode, return 0; } -void -wi_init(struct wi_softc *sc) +static void +wi_init_locked(struct wi_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; int wasenabled; WI_LOCK_ASSERT(sc); wasenabled = sc->sc_enabled; if (wasenabled) - wi_stop(sc, 1); + wi_stop_locked(sc, 1); - if (wi_setup_locked(sc, sc->sc_porttype, 3, - sc->sc_ic.ic_macaddr) != 0) { - device_printf(sc->sc_dev, "interface not running\n"); - wi_stop(sc, 1); + if (wi_setup_locked(sc, sc->sc_porttype, 3, IF_LLADDR(ifp)) != 0) { + if_printf(ifp, "interface not running\n"); + wi_stop_locked(sc, 1); return; } - sc->sc_flags |= WI_FLAGS_RUNNING; + ifp->if_drv_flags |= IFF_DRV_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc); @@ -675,8 +703,24 @@ wi_init(struct wi_softc *sc) } void -wi_stop(struct wi_softc *sc, int disable) +wi_init(void *arg) +{ + struct wi_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + WI_LOCK(sc); + wi_init_locked(sc); + WI_UNLOCK(sc); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ieee80211_start_all(ic); /* start all vap's */ +} + +static void +wi_stop_locked(struct wi_softc *sc, int disable) { + struct ifnet *ifp = sc->sc_ifp; WI_LOCK_ASSERT(sc); @@ -692,13 +736,22 @@ wi_stop(struct wi_softc *sc, int disable) sc->sc_tx_timer = 0; sc->sc_false_syns = 0; - sc->sc_flags &= ~WI_FLAGS_RUNNING; + ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING); +} + +void +wi_stop(struct wi_softc *sc, int disable) +{ + WI_LOCK(sc); + wi_stop_locked(sc, disable); + WI_UNLOCK(sc); } static void wi_set_channel(struct ieee80211com *ic) { - struct wi_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct wi_softc *sc = ifp->if_softc; DPRINTF(("%s: channel %d, %sscanning\n", __func__, ieee80211_chan2ieee(ic, ic->ic_curchan), @@ -713,7 +766,8 @@ wi_set_channel(struct ieee80211com *ic) static void wi_scan_start(struct ieee80211com *ic) { - struct wi_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct wi_softc *sc = ifp->if_softc; struct ieee80211_scan_state *ss = ic->ic_scan; DPRINTF(("%s\n", __func__)); @@ -736,7 +790,8 @@ wi_scan_start(struct ieee80211com *ic) static void wi_scan_end(struct ieee80211com *ic) { - struct wi_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct wi_softc *sc = ifp->if_softc; DPRINTF(("%s: restore port type %d\n", __func__, sc->sc_porttype)); @@ -769,8 +824,9 @@ static int wi_newstate_sta(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ieee80211com *ic = vap->iv_ic; + struct ifnet *ifp = ic->ic_ifp; struct ieee80211_node *bss; - struct wi_softc *sc = ic->ic_softc; + struct wi_softc *sc = ifp->if_softc; DPRINTF(("%s: %s -> %s\n", __func__, ieee80211_state_name[vap->iv_state], @@ -838,8 +894,9 @@ static int wi_newstate_hostap(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ieee80211com *ic = vap->iv_ic; + struct ifnet *ifp = ic->ic_ifp; struct ieee80211_node *bss; - struct wi_softc *sc = ic->ic_softc; + struct wi_softc *sc = ifp->if_softc; int error; DPRINTF(("%s: %s -> %s\n", __func__, @@ -896,30 +953,10 @@ wi_newstate_hostap(struct ieee80211vap *vap, enum ieee80211_state nstate, int ar return error; } -static int -wi_transmit(struct ieee80211com *ic, struct mbuf *m) -{ - struct wi_softc *sc = ic->ic_softc; - int error; - - WI_LOCK(sc); - if ((sc->sc_flags & WI_FLAGS_RUNNING) == 0) { - WI_UNLOCK(sc); - return (ENXIO); - } - error = mbufq_enqueue(&sc->sc_snd, m); - if (error) { - WI_UNLOCK(sc); - return (error); - } - wi_start(sc); - WI_UNLOCK(sc); - return (0); -} - static void -wi_start(struct wi_softc *sc) +wi_start_locked(struct ifnet *ifp) { + struct wi_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct ieee80211_frame *wh; struct mbuf *m0; @@ -935,8 +972,15 @@ wi_start(struct wi_softc *sc) memset(&frmhdr, 0, sizeof(frmhdr)); cur = sc->sc_txnext; - while (sc->sc_txd[cur].d_len == 0 && - (m0 = mbufq_dequeue(&sc->sc_snd)) != NULL) { + for (;;) { + IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); + if (m0 == NULL) + break; + if (sc->sc_txd[cur].d_len != 0) { + IFQ_DRV_PREPEND(&ifp->if_snd, m0); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } ni = (struct ieee80211_node *) m0->m_pkthdr.rcvif; /* reconstruct 802.3 header */ @@ -985,16 +1029,28 @@ wi_start(struct wi_softc *sc) m_adj(m0, sizeof(struct ieee80211_frame)); frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len); ieee80211_free_node(ni); - if (wi_start_tx(sc, &frmhdr, m0)) + if (wi_start_tx(ifp, &frmhdr, m0)) continue; sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf; + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); } } +static void +wi_start(struct ifnet *ifp) +{ + struct wi_softc *sc = ifp->if_softc; + + WI_LOCK(sc); + wi_start_locked(ifp); + WI_UNLOCK(sc); +} + static int -wi_start_tx(struct wi_softc *sc, struct wi_frame *frmhdr, struct mbuf *m0) +wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr, struct mbuf *m0) { + struct wi_softc *sc = ifp->if_softc; int cur = sc->sc_txnext; int fid, off, error; @@ -1004,13 +1060,13 @@ wi_start_tx(struct wi_softc *sc, struct wi_frame *frmhdr, struct mbuf *m0) || wi_mwrite_bap(sc, fid, off, m0, m0->m_pkthdr.len) != 0; m_freem(m0); if (error) { - counter_u64_add(sc->sc_ic.ic_oerrors, 1); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); return -1; } sc->sc_txd[cur].d_len = off; if (sc->sc_txcur == cur) { if (wi_cmd(sc, WI_CMD_TX | WI_RECLAIM, fid, 0, 0)) { - device_printf(sc->sc_dev, "xmit failed\n"); + if_printf(ifp, "xmit failed\n"); sc->sc_txd[cur].d_len = 0; return -1; } @@ -1024,8 +1080,9 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = ic->ic_ifp; struct ieee80211vap *vap = ni->ni_vap; - struct wi_softc *sc = ic->ic_softc; + struct wi_softc *sc = ifp->if_softc; struct ieee80211_key *k; struct ieee80211_frame *wh; struct wi_frame frmhdr; @@ -1041,6 +1098,7 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0, memset(&frmhdr, 0, sizeof(frmhdr)); cur = sc->sc_txnext; if (sc->sc_txd[cur].d_len != 0) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; rc = ENOBUFS; goto out; } @@ -1071,7 +1129,7 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0, (caddr_t)&frmhdr.wi_whdr); m_adj(m0, sizeof(struct ieee80211_frame)); frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len); - if (wi_start_tx(sc, &frmhdr, m0) < 0) { + if (wi_start_tx(ifp, &frmhdr, m0) < 0) { m0 = NULL; rc = EIO; goto out; @@ -1102,7 +1160,7 @@ wi_reset(struct wi_softc *sc) } sc->sc_reset = 1; if (i == WI_INIT_TRIES) { - device_printf(sc->sc_dev, "reset failed\n"); + if_printf(sc->sc_ifp, "reset failed\n"); return error; } @@ -1120,6 +1178,7 @@ static void wi_watchdog(void *arg) { struct wi_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; WI_LOCK_ASSERT(sc); @@ -1127,52 +1186,65 @@ wi_watchdog(void *arg) return; if (sc->sc_tx_timer && --sc->sc_tx_timer == 0) { - device_printf(sc->sc_dev, "device timeout\n"); - counter_u64_add(sc->sc_ic.ic_oerrors, 1); - wi_init(sc); + if_printf(ifp, "device timeout\n"); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + wi_init_locked(ifp->if_softc); return; } callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc); } -static void -wi_parent(struct ieee80211com *ic) +static int +wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - struct wi_softc *sc = ic->ic_softc; - int startall = 0; + struct wi_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; - WI_LOCK(sc); - /* - * Can't do promisc and hostap at the same time. If all that's - * changing is the promisc flag, try to short-circuit a call to - * wi_init() by just setting PROMISC in the hardware. - */ - if (ic->ic_nrunning > 0) { - if (ic->ic_opmode != IEEE80211_M_HOSTAP && - sc->sc_flags & WI_FLAGS_RUNNING) { - if (ic->ic_promisc > 0 && - (sc->sc_flags & WI_FLAGS_PROMISC) == 0) { - wi_write_val(sc, WI_RID_PROMISC, 1); - sc->sc_flags |= WI_FLAGS_PROMISC; - } else if (ic->ic_promisc == 0 && - (sc->sc_flags & WI_FLAGS_PROMISC) != 0) { - wi_write_val(sc, WI_RID_PROMISC, 0); - sc->sc_flags &= ~WI_FLAGS_PROMISC; + switch (cmd) { + case SIOCSIFFLAGS: + WI_LOCK(sc); + /* + * Can't do promisc and hostap at the same time. If all that's + * changing is the promisc flag, try to short-circuit a call to + * wi_init() by just setting PROMISC in the hardware. + */ + if (ifp->if_flags & IFF_UP) { + if (ic->ic_opmode != IEEE80211_M_HOSTAP && + ifp->if_drv_flags & IFF_DRV_RUNNING) { + if ((ifp->if_flags ^ sc->sc_if_flags) & IFF_PROMISC) { + wi_write_val(sc, WI_RID_PROMISC, + (ifp->if_flags & IFF_PROMISC) != 0); + } else { + wi_init_locked(sc); + startall = 1; + } } else { - wi_init(sc); + wi_init_locked(sc); startall = 1; } } else { - wi_init(sc); - startall = 1; + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + wi_stop_locked(sc, 1); + sc->wi_gone = 0; } - } else if (sc->sc_flags & WI_FLAGS_RUNNING) { - wi_stop(sc, 1); - sc->wi_gone = 0; + sc->sc_if_flags = ifp->if_flags; + WI_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; } - WI_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); + return error; } static void @@ -1180,7 +1252,7 @@ wi_media_status(struct ifnet *ifp, struct ifmediareq *imr) { struct ieee80211vap *vap = ifp->if_softc; struct ieee80211com *ic = vap->iv_ic; - struct wi_softc *sc = ic->ic_softc; + struct wi_softc *sc = ic->ic_ifp->if_softc; u_int16_t val; int rate, len; @@ -1208,7 +1280,8 @@ wi_media_status(struct ifnet *ifp, struct ifmediareq *imr) static void wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN]) { - 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 ieee80211_node *ni = vap->iv_bss; @@ -1222,7 +1295,7 @@ wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN]) * indicator of the firmware's BSSID. Damp spurious * change-of-BSSID indications. */ - if (ic->ic_promisc > 0 && + if ((ifp->if_flags & IFF_PROMISC) != 0 && !ppsratecheck(&sc->sc_last_syn, &sc->sc_false_syns, WI_MAX_FALSE_SYNS)) return; @@ -1243,7 +1316,8 @@ wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN]) static __noinline void wi_rx_intr(struct wi_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct wi_frame frmhdr; struct mbuf *m; struct ieee80211_frame *wh; @@ -1258,7 +1332,7 @@ wi_rx_intr(struct wi_softc *sc) /* First read in the frame header */ if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) { CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); DPRINTF(("wi_rx_intr: read fid %x failed\n", fid)); return; } @@ -1269,7 +1343,7 @@ wi_rx_intr(struct wi_softc *sc) status = le16toh(frmhdr.wi_status); if (status & WI_STAT_ERRSTAT) { CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status)); return; } @@ -1284,7 +1358,7 @@ wi_rx_intr(struct wi_softc *sc) if (off + len > MCLBYTES) { if (ic->ic_opmode != IEEE80211_M_MONITOR) { CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); DPRINTF(("wi_rx_intr: oversized packet\n")); return; } else @@ -1297,7 +1371,7 @@ wi_rx_intr(struct wi_softc *sc) m = m_gethdr(M_NOWAIT, MT_DATA); if (m == NULL) { CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); - counter_u64_add(ic->ic_ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); DPRINTF(("wi_rx_intr: MGET failed\n")); return; } @@ -1306,6 +1380,7 @@ wi_rx_intr(struct wi_softc *sc) wi_read_bap(sc, fid, sizeof(frmhdr), m->m_data + sizeof(struct ieee80211_frame), len); m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + len; + m->m_pkthdr.rcvif = ifp; CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); @@ -1350,6 +1425,7 @@ wi_rx_intr(struct wi_softc *sc) static __noinline void wi_tx_ex_intr(struct wi_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; struct wi_frame frmhdr; int fid; @@ -1364,7 +1440,7 @@ wi_tx_ex_intr(struct wi_softc *sc) */ if ((status & WI_TXSTAT_DISCONNECT) == 0) { if (ppsratecheck(&lasttxerror, &curtxeps, wi_txerate)) { - device_printf(sc->sc_dev, "tx failed"); + if_printf(ifp, "tx failed"); if (status & WI_TXSTAT_RET_ERR) printf(", retry limit exceeded"); if (status & WI_TXSTAT_AGED_ERR) @@ -1379,7 +1455,7 @@ wi_tx_ex_intr(struct wi_softc *sc) printf(", status=0x%x", status); printf("\n"); } - counter_u64_add(sc->sc_ic.ic_oerrors, 1); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } else DPRINTF(("port disconnected\n")); } else @@ -1390,6 +1466,7 @@ wi_tx_ex_intr(struct wi_softc *sc) static __noinline void wi_tx_intr(struct wi_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; int fid, cur; if (sc->wi_gone) @@ -1400,17 +1477,19 @@ wi_tx_intr(struct wi_softc *sc) cur = sc->sc_txcur; if (sc->sc_txd[cur].d_fid != fid) { - device_printf(sc->sc_dev, "bad alloc %x != %x, cur %d nxt %d\n", + if_printf(ifp, "bad alloc %x != %x, cur %d nxt %d\n", fid, sc->sc_txd[cur].d_fid, cur, sc->sc_txnext); return; } sc->sc_tx_timer = 0; sc->sc_txd[cur].d_len = 0; sc->sc_txcur = cur = (cur + 1) % sc->sc_ntxbuf; - if (sc->sc_txd[cur].d_len != 0) { + if (sc->sc_txd[cur].d_len == 0) + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + else { if (wi_cmd(sc, WI_CMD_TX | WI_RECLAIM, sc->sc_txd[cur].d_fid, 0, 0)) { - device_printf(sc->sc_dev, "xmit failed\n"); + if_printf(ifp, "xmit failed\n"); sc->sc_txd[cur].d_len = 0; } else { sc->sc_tx_timer = 5; @@ -1421,7 +1500,7 @@ wi_tx_intr(struct wi_softc *sc) static __noinline void wi_info_intr(struct wi_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); int i, fid, len, off; u_int16_t ltbuf[2]; @@ -1495,15 +1574,32 @@ finish: CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO); } +static uint64_t +wi_get_counter(struct ifnet *ifp, ift_counter cnt) +{ + struct wi_softc *sc; + + sc = if_getsoftc(ifp); + + switch (cnt) { + case IFCOUNTER_COLLISIONS: + return (sc->sc_stats.wi_tx_single_retries + + sc->sc_stats.wi_tx_multi_retries + + sc->sc_stats.wi_tx_retry_limit); + default: + return (if_get_counter_default(ifp, cnt)); + } +} + static int wi_write_multi(struct wi_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211vap *vap; - struct wi_mcast mlist; + struct ifnet *ifp = sc->sc_ifp; int n; + struct ifmultiaddr *ifma; + struct wi_mcast mlist; - if (ic->ic_allmulti > 0 || ic->ic_promisc > 0) { + if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { allmulti: memset(&mlist, 0, sizeof(mlist)); return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist, @@ -1511,23 +1607,17 @@ allmulti: } n = 0; - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - struct ifnet *ifp; - struct ifmultiaddr *ifma; - - ifp = vap->iv_ifp; - if_maddr_rlock(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - if (n >= 16) - goto allmulti; - IEEE80211_ADDR_COPY(&mlist.wi_mcast[n], - (LLADDR((struct sockaddr_dl *)ifma->ifma_addr))); - n++; - } - if_maddr_runlock(ifp); + if_maddr_rlock(ifp); + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + if (n >= 16) + goto allmulti; + IEEE80211_ADDR_COPY(&mlist.wi_mcast[n], + (LLADDR((struct sockaddr_dl *)ifma->ifma_addr))); + n++; } + if_maddr_runlock(ifp); return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist, IEEE80211_ADDR_LEN * n); } @@ -1548,7 +1638,7 @@ wi_update_promisc(struct ieee80211com *ic) /* XXX handle WEP special case handling? */ wi_write_val(sc, WI_RID_PROMISC, (ic->ic_opmode == IEEE80211_M_MONITOR || - (ic->ic_promisc > 0))); + (ic->ic_ifp->if_flags & IFF_PROMISC))); WI_UNLOCK(sc); } @@ -1847,7 +1937,7 @@ wi_read_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen) } static int -wi_write_bap(struct wi_softc *sc, int id, int off, const void *buf, int buflen) +wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen) { int error, cnt; @@ -1859,7 +1949,7 @@ wi_write_bap(struct wi_softc *sc, int id, int off, const void *buf, int buflen) return error; } cnt = (buflen + 1) / 2; - CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, (const uint16_t *)buf, cnt); + CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, (u_int16_t *)buf, cnt); sc->sc_bap_off += cnt * 2; return 0; @@ -1949,7 +2039,7 @@ wi_read_rid(struct wi_softc *sc, int rid, void *buf, int *buflenp) } static int -wi_write_rid(struct wi_softc *sc, int rid, const void *buf, int buflen) +wi_write_rid(struct wi_softc *sc, int rid, void *buf, int buflen) { int error; u_int16_t ltbuf[2]; diff --git a/sys/dev/wi/if_wi_pccard.c b/sys/dev/wi/if_wi_pccard.c index 414dc20dba1b..fd70e77074a7 100644 --- a/sys/dev/wi/if_wi_pccard.c +++ b/sys/dev/wi/if_wi_pccard.c @@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$"); #include <sys/malloc.h> #include <sys/socket.h> #include <sys/systm.h> -#include <sys/mbuf.h> #include <sys/module.h> #include <sys/bus.h> diff --git a/sys/dev/wi/if_wi_pci.c b/sys/dev/wi/if_wi_pci.c index b218c2479a69..198c599ef54a 100644 --- a/sys/dev/wi/if_wi_pci.c +++ b/sys/dev/wi/if_wi_pci.c @@ -238,9 +238,7 @@ wi_pci_suspend(device_t dev) { struct wi_softc *sc = device_get_softc(dev); - WI_LOCK(sc); wi_stop(sc, 1); - WI_UNLOCK(sc); return (0); } @@ -249,15 +247,16 @@ static int wi_pci_resume(device_t dev) { struct wi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; - WI_LOCK(sc); - if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) { + if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) return (0); - WI_UNLOCK(sc); + + if (ifp->if_flags & IFF_UP) { + ifp->if_init(ifp->if_softc); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ifp->if_start(ifp); } - if (ic->ic_nrunning > 0) - wi_init(sc); - WI_UNLOCK(sc); + return (0); } diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h index 9b668cc0e114..f163744ef834 100644 --- a/sys/dev/wi/if_wivar.h +++ b/sys/dev/wi/if_wivar.h @@ -68,8 +68,7 @@ struct wi_vap { #define WI_VAP(vap) ((struct wi_vap *)(vap)) struct wi_softc { - struct ieee80211com sc_ic; - struct mbufq sc_snd; + struct ifnet *sc_ifp; device_t sc_dev; struct mtx sc_mtx; struct callout sc_watchdog; @@ -108,6 +107,7 @@ struct wi_softc { int wi_cmd_count; int sc_flags; + int sc_if_flags; int sc_bap_id; int sc_bap_off; @@ -152,8 +152,6 @@ struct wi_softc { #define WI_FLAGS_HAS_ROAMING 0x0020 #define WI_FLAGS_HAS_FRAGTHR 0x0200 #define WI_FLAGS_HAS_DBMADJUST 0x0400 -#define WI_FLAGS_RUNNING 0x0800 -#define WI_FLAGS_PROMISC 0x1000 struct wi_card_ident { u_int16_t card_id; @@ -182,7 +180,7 @@ int wi_shutdown(device_t); int wi_alloc(device_t, int); void wi_free(device_t); extern devclass_t wi_devclass; +void wi_init(void *); void wi_intr(void *); int wi_mgmt_xmit(struct wi_softc *, caddr_t, int); void wi_stop(struct wi_softc *, int); -void wi_init(struct wi_softc *); |