From owner-svn-src-head@freebsd.org Sat Aug 8 01:10:20 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E79CF9B5676; Sat, 8 Aug 2015 01:10:19 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D58FCDC9; Sat, 8 Aug 2015 01:10:19 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.14.9/8.14.9) with ESMTP id t781AJK3044742; Sat, 8 Aug 2015 01:10:19 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by repo.freebsd.org (8.14.9/8.14.9/Submit) id t781AJUf044737; Sat, 8 Aug 2015 01:10:19 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201508080110.t781AJUf044737@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Sat, 8 Aug 2015 01:10:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r286437 - in head/sys: dev/ath dev/ath/ath_rate/sample dev/bwi dev/bwn dev/if_ndis dev/ipw dev/iwi dev/iwn dev/malo dev/mwl dev/ral dev/usb/wlan dev/wi dev/wpi dev/wtap net80211 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 08 Aug 2015 01:10:20 -0000 Author: adrian Date: Sat Aug 8 01:10:17 2015 New Revision: 286437 URL: https://svnweb.freebsd.org/changeset/base/286437 Log: 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. Modified: head/sys/dev/ath/ath_rate/sample/sample.c head/sys/dev/ath/ath_rate/sample/sample.h head/sys/dev/ath/if_ath.c head/sys/dev/ath/if_ath_beacon.c head/sys/dev/ath/if_ath_debug.h head/sys/dev/ath/if_ath_keycache.c head/sys/dev/ath/if_ath_misc.h head/sys/dev/ath/if_ath_rx.c head/sys/dev/ath/if_ath_rx_edma.c head/sys/dev/ath/if_ath_sysctl.c head/sys/dev/ath/if_ath_tdma.c head/sys/dev/ath/if_ath_tx.c head/sys/dev/ath/if_ath_tx_edma.c head/sys/dev/ath/if_athvar.h head/sys/dev/bwi/bwimac.c head/sys/dev/bwi/bwiphy.c head/sys/dev/bwi/bwirf.c head/sys/dev/bwi/if_bwi.c head/sys/dev/bwi/if_bwivar.h head/sys/dev/bwn/if_bwn.c head/sys/dev/bwn/if_bwnvar.h head/sys/dev/if_ndis/if_ndis.c head/sys/dev/if_ndis/if_ndisvar.h head/sys/dev/ipw/if_ipw.c head/sys/dev/ipw/if_ipwvar.h head/sys/dev/iwi/if_iwi.c head/sys/dev/iwi/if_iwivar.h head/sys/dev/iwn/if_iwn.c head/sys/dev/iwn/if_iwnvar.h head/sys/dev/malo/if_malo.c head/sys/dev/malo/if_malo.h head/sys/dev/mwl/if_mwl.c head/sys/dev/mwl/if_mwl_pci.c head/sys/dev/mwl/if_mwlvar.h head/sys/dev/ral/if_ral_pci.c head/sys/dev/ral/rt2560.c head/sys/dev/ral/rt2560var.h head/sys/dev/ral/rt2661.c head/sys/dev/ral/rt2661var.h head/sys/dev/ral/rt2860.c head/sys/dev/ral/rt2860var.h head/sys/dev/usb/wlan/if_rsu.c head/sys/dev/usb/wlan/if_rsureg.h head/sys/dev/usb/wlan/if_rum.c head/sys/dev/usb/wlan/if_rumvar.h head/sys/dev/usb/wlan/if_run.c head/sys/dev/usb/wlan/if_runvar.h head/sys/dev/usb/wlan/if_uath.c head/sys/dev/usb/wlan/if_uathvar.h head/sys/dev/usb/wlan/if_upgt.c head/sys/dev/usb/wlan/if_upgtvar.h head/sys/dev/usb/wlan/if_ural.c head/sys/dev/usb/wlan/if_uralvar.h head/sys/dev/usb/wlan/if_urtw.c head/sys/dev/usb/wlan/if_urtwn.c head/sys/dev/usb/wlan/if_urtwnreg.h head/sys/dev/usb/wlan/if_urtwvar.h head/sys/dev/usb/wlan/if_zyd.c head/sys/dev/usb/wlan/if_zydreg.h head/sys/dev/wi/if_wi.c head/sys/dev/wi/if_wi_pccard.c head/sys/dev/wi/if_wi_pci.c head/sys/dev/wi/if_wivar.h head/sys/dev/wpi/if_wpi.c head/sys/dev/wpi/if_wpivar.h head/sys/dev/wtap/if_wtap.c head/sys/dev/wtap/if_wtapvar.h head/sys/net80211/ieee80211.c head/sys/net80211/ieee80211_ddb.c head/sys/net80211/ieee80211_freebsd.c head/sys/net80211/ieee80211_ioctl.c head/sys/net80211/ieee80211_output.c head/sys/net80211/ieee80211_power.c head/sys/net80211/ieee80211_proto.c head/sys/net80211/ieee80211_proto.h head/sys/net80211/ieee80211_regdomain.c head/sys/net80211/ieee80211_scan_sta.c head/sys/net80211/ieee80211_var.h Modified: head/sys/dev/ath/ath_rate/sample/sample.c ============================================================================== --- head/sys/dev/ath/ath_rate/sample/sample.c Sat Aug 8 00:57:27 2015 (r286436) +++ head/sys/dev/ath/ath_rate/sample/sample.c Sat Aug 8 01:10:17 2015 (r286437) @@ -488,7 +488,8 @@ ath_rate_findrate(struct ath_softc *sc, #define RATE(ix) (DOT11RATE(ix) / 2) struct sample_node *sn = ATH_NODE_SAMPLE(an); struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc); - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; const HAL_RATE_TABLE *rt = sc->sc_currates; const int size_bin = size_to_bin(frameLen); int rix, mrr, best_rix, change_rates; @@ -855,7 +856,8 @@ ath_rate_tx_complete(struct ath_softc *s const struct ath_rc_series *rc, const struct ath_tx_status *ts, int frame_size, int nframes, int nbad) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct sample_node *sn = ATH_NODE_SAMPLE(an); int final_rix, short_tries, long_tries; const HAL_RATE_TABLE *rt = sc->sc_currates; @@ -1301,7 +1303,8 @@ static int ath_rate_sysctl_stats(SYSCTL_HANDLER_ARGS) { struct ath_softc *sc = arg1; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; int error, v; v = 0; Modified: head/sys/dev/ath/ath_rate/sample/sample.h ============================================================================== --- head/sys/dev/ath/ath_rate/sample/sample.h Sat Aug 8 00:57:27 2015 (r286436) +++ head/sys/dev/ath/ath_rate/sample/sample.h Sat Aug 8 01:10:17 2015 (r286437) @@ -134,7 +134,8 @@ static unsigned calc_usecs_unicast_packe int long_retries, int is_ht40) { const HAL_RATE_TABLE *rt = sc->sc_currates; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; int rts, cts; unsigned t_slot = 20; Modified: head/sys/dev/ath/if_ath.c ============================================================================== --- head/sys/dev/ath/if_ath.c Sat Aug 8 00:57:27 2015 (r286436) +++ head/sys/dev/ath/if_ath.c Sat Aug 8 01:10:17 2015 (r286437) @@ -151,15 +151,15 @@ static struct ieee80211vap *ath_vap_crea const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void ath_vap_delete(struct ieee80211vap *); -static void ath_init(struct ath_softc *); -static void ath_stop_locked(struct ath_softc *); -static void ath_stop(struct ath_softc *); +static void ath_init(void *); +static void ath_stop_locked(struct ifnet *); +static void ath_stop(struct ifnet *); static int ath_reset_vap(struct ieee80211vap *, u_long); -static int ath_transmit(struct ieee80211com *, struct mbuf *); +static int ath_transmit(struct ifnet *ifp, struct mbuf *m); +static void ath_qflush(struct ifnet *ifp); static int ath_media_change(struct ifnet *); static void ath_watchdog(void *); -static int ath_ioctl(struct ieee80211com *, u_long, void *); -static void ath_parent(struct ieee80211com *); +static int ath_ioctl(struct ifnet *, u_long, caddr_t); static void ath_fatal_proc(void *, int); static void ath_bmiss_vap(struct ieee80211vap *); static void ath_bmiss_proc(void *, int); @@ -571,19 +571,34 @@ ath_fetch_mac_kenv(struct ath_softc *sc, int ath_attach(u_int16_t devid, struct ath_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp; + struct ieee80211com *ic; struct ath_hal *ah = NULL; HAL_STATUS status; int error = 0, i; u_int wmodes; + uint8_t macaddr[IEEE80211_ADDR_LEN]; int rx_chainmask, tx_chainmask; HAL_OPS_CONFIG ah_config; DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid); + CURVNET_SET(vnet0); + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(sc->sc_dev, "can not if_alloc()\n"); + error = ENOSPC; + CURVNET_RESTORE(); + goto bad; + } + ic = ifp->if_l2com; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(sc->sc_dev); + if_initname(ifp, device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev)); + CURVNET_RESTORE(); + /* * Configure the initial configuration data. * @@ -717,8 +732,8 @@ ath_attach(u_int16_t devid, struct ath_s sc->sc_tq = taskqueue_create("ath_taskq", M_NOWAIT, taskqueue_thread_enqueue, &sc->sc_tq); - taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", - device_get_nameunit(sc->sc_dev)); + taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, + "%s taskq", ifp->if_xname); TASK_INIT(&sc->sc_rxtask, 0, sc->sc_rx.recv_tasklet, sc); TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc); @@ -861,6 +876,17 @@ ath_attach(u_int16_t devid, struct ath_s ath_led_config(sc); ath_hal_setledstate(ah, HAL_LED_INIT); + ifp->if_softc = sc; + ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; + ifp->if_transmit = ath_transmit; + ifp->if_qflush = ath_qflush; + ifp->if_ioctl = ath_ioctl; + ifp->if_init = ath_init; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; + IFQ_SET_READY(&ifp->if_snd); + + ic->ic_ifp = ifp; /* XXX not right but it's not used anywhere important */ ic->ic_phytype = IEEE80211_T_OFDM; ic->ic_opmode = IEEE80211_M_STA; @@ -1182,11 +1208,11 @@ ath_attach(u_int16_t devid, struct ath_s sc->sc_hasveol = ath_hal_hasveol(ah); /* get mac address from kenv first, then hardware */ - if (ath_fetch_mac_kenv(sc, ic->ic_macaddr) == 0) { + if (ath_fetch_mac_kenv(sc, macaddr) == 0) { /* Tell the HAL now about the new MAC */ - ath_hal_setmac(ah, ic->ic_macaddr); + ath_hal_setmac(ah, macaddr); } else { - ath_hal_getmac(ah, ic->ic_macaddr); + ath_hal_getmac(ah, macaddr); } if (sc->sc_hasbmask) @@ -1195,15 +1221,12 @@ ath_attach(u_int16_t devid, struct ath_s /* NB: used to size node table key mapping array */ ic->ic_max_keyix = sc->sc_keymax; /* call MI attach routine. */ - ieee80211_ifattach(ic); + ieee80211_ifattach(ic, macaddr); ic->ic_setregdomain = ath_setregdomain; ic->ic_getradiocaps = ath_getradiocaps; sc->sc_opmode = HAL_M_STA; /* override default methods */ - ic->ic_ioctl = ath_ioctl; - ic->ic_parent = ath_parent; - ic->ic_transmit = ath_transmit; ic->ic_newassoc = ath_newassoc; ic->ic_updateslot = ath_updateslot; ic->ic_wme.wme_update = ath_wme_update; @@ -1299,6 +1322,16 @@ bad2: bad: if (ah) ath_hal_detach(ah); + + /* + * To work around scoping issues with CURVNET_SET/CURVNET_RESTORE.. + */ + if (ifp != NULL && ifp->if_vnet) { + CURVNET_SET(ifp->if_vnet); + if_free(ifp); + CURVNET_RESTORE(); + } else if (ifp != NULL) + if_free(ifp); sc->sc_invalid = 1; return error; } @@ -1306,6 +1339,10 @@ bad: int ath_detach(struct ath_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; + + DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n", + __func__, ifp->if_flags); /* * NB: the order of these is important: @@ -1330,14 +1367,14 @@ ath_detach(struct ath_softc *sc) ATH_LOCK(sc); ath_power_set_power_state(sc, HAL_PM_AWAKE); ath_power_setpower(sc, HAL_PM_AWAKE); + ATH_UNLOCK(sc); /* * Stop things cleanly. */ - ath_stop_locked(sc); - ATH_UNLOCK(sc); + ath_stop(ifp); - ieee80211_ifdetach(&sc->sc_ic); + ieee80211_ifdetach(ifp->if_l2com); taskqueue_free(sc->sc_tq); #ifdef ATH_TX99_DIAG if (sc->sc_tx99 != NULL) @@ -1357,6 +1394,10 @@ ath_detach(struct ath_softc *sc) ath_tx_cleanup(sc); ath_hal_detach(sc->sc_ah); /* NB: sets chip in full sleep */ + CURVNET_SET(ifp->if_vnet); + if_free(ifp); + CURVNET_RESTORE(); + return 0; } @@ -1432,7 +1473,7 @@ ath_vap_create(struct ieee80211com *ic, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac0[IEEE80211_ADDR_LEN]) { - struct ath_softc *sc = ic->ic_softc; + struct ath_softc *sc = ic->ic_ifp->if_softc; struct ath_vap *avp; struct ieee80211vap *vap; uint8_t mac[IEEE80211_ADDR_LEN]; @@ -1540,7 +1581,8 @@ ath_vap_create(struct ieee80211com *ic, vap = &avp->av_vap; /* XXX can't hold mutex across if_alloc */ ATH_UNLOCK(sc); - error = ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); + error = ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, + bssid, mac); ATH_LOCK(sc); if (error != 0) { device_printf(sc->sc_dev, "%s: error %d creating vap\n", @@ -1674,8 +1716,7 @@ ath_vap_create(struct ieee80211com *ic, ATH_UNLOCK(sc); /* complete setup */ - ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status, - mac); + ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status); return vap; bad2: reclaim_address(sc, mac); @@ -1690,7 +1731,8 @@ static void ath_vap_delete(struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; - struct ath_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct ath_softc *sc = ifp->if_softc; struct ath_hal *ah = sc->sc_ah; struct ath_vap *avp = ATH_VAP(vap); @@ -1699,7 +1741,7 @@ ath_vap_delete(struct ieee80211vap *vap) ATH_UNLOCK(sc); DPRINTF(sc, ATH_DEBUG_RESET, "%s: called\n", __func__); - if (sc->sc_running) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { /* * Quiesce the hardware while we remove the vap. In * particular we need to reclaim all references to @@ -1782,7 +1824,7 @@ ath_vap_delete(struct ieee80211vap *vap) #endif free(avp, M_80211_VAP); - if (sc->sc_running) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { /* * Restart rx+tx machines if still running (RUNNING will * be reset if we just destroyed the last vap). @@ -1809,9 +1851,13 @@ ath_vap_delete(struct ieee80211vap *vap) void ath_suspend(struct ath_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n", + __func__, ifp->if_flags); - sc->sc_resume_up = ic->ic_nrunning != 0; + sc->sc_resume_up = (ifp->if_flags & IFF_UP) != 0; ieee80211_suspend_all(ic); /* @@ -1852,7 +1898,8 @@ ath_suspend(struct ath_softc *sc) static void ath_reset_keycache(struct ath_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; int i; @@ -1894,7 +1941,8 @@ ath_update_chainmasks(struct ath_softc * void ath_resume(struct ath_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; HAL_STATUS status; @@ -1967,8 +2015,12 @@ ath_resume(struct ath_softc *sc) void ath_shutdown(struct ath_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; + + DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n", + __func__, ifp->if_flags); - ath_stop(sc); + ath_stop(ifp); /* NB: no point powering down chip as we're about to reboot */ } @@ -1979,6 +2031,7 @@ void ath_intr(void *arg) { struct ath_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; struct ath_hal *ah = sc->sc_ah; HAL_INT status = 0; uint32_t txqs; @@ -2017,11 +2070,12 @@ ath_intr(void *arg) ath_power_set_power_state(sc, HAL_PM_AWAKE); ATH_UNLOCK(sc); - if (sc->sc_ic.ic_nrunning == 0 && sc->sc_running == 0) { + if ((ifp->if_flags & IFF_UP) == 0 || + (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { HAL_INT status; - DPRINTF(sc, ATH_DEBUG_ANY, "%s: ic_nrunning %d sc_running %d\n", - __func__, sc->sc_ic.ic_nrunning, sc->sc_running); + DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags 0x%x\n", + __func__, ifp->if_flags); ath_hal_getisr(ah, &status); /* clear ISR */ ath_hal_intrset(ah, 0); /* disable further intr's */ ATH_PCU_UNLOCK(sc); @@ -2259,6 +2313,7 @@ static void ath_fatal_proc(void *arg, int pending) { struct ath_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; u_int32_t *state; u_int32_t len; void *sp; @@ -2279,13 +2334,13 @@ ath_fatal_proc(void *arg, int pending) "0x%08x 0x%08x 0x%08x, 0x%08x 0x%08x 0x%08x\n", state[0], state[1] , state[2], state[3], state[4], state[5]); } - ath_reset(sc, ATH_RESET_NOLOSS); + ath_reset(ifp, ATH_RESET_NOLOSS); } static void ath_bmiss_vap(struct ieee80211vap *vap) { - struct ath_softc *sc = vap->iv_ic->ic_softc; + struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; /* * Workaround phantom bmiss interrupts by sanity-checking @@ -2306,6 +2361,8 @@ ath_bmiss_vap(struct ieee80211vap *vap) ATH_UNLOCK(sc); if ((vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) == 0) { + struct ifnet *ifp = vap->iv_ic->ic_ifp; + struct ath_softc *sc = ifp->if_softc; u_int64_t lastrx = sc->sc_lastrx; u_int64_t tsf = ath_hal_gettsf64(sc->sc_ah); /* XXX should take a locked ref to iv_bss */ @@ -2363,6 +2420,7 @@ static void ath_bmiss_proc(void *arg, int pending) { struct ath_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; uint32_t hangs; DPRINTF(sc, ATH_DEBUG_ANY, "%s: pending %u\n", __func__, pending); @@ -2380,12 +2438,12 @@ ath_bmiss_proc(void *arg, int pending) * to clear. */ if (ath_hal_gethangstate(sc->sc_ah, 0xff, &hangs) && hangs != 0) { - ath_reset(sc, ATH_RESET_NOLOSS); + ath_reset(ifp, ATH_RESET_NOLOSS); device_printf(sc->sc_dev, "bb hang detected (0x%x), resetting\n", hangs); } else { - ath_reset(sc, ATH_RESET_NOLOSS); - ieee80211_beacon_miss(&sc->sc_ic); + ath_reset(ifp, ATH_RESET_NOLOSS); + ieee80211_beacon_miss(ifp->if_l2com); } /* Force a beacon resync, in case they've drifted */ @@ -2405,7 +2463,8 @@ ath_bmiss_proc(void *arg, int pending) static void ath_settkipmic(struct ath_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; if ((ic->ic_cryptocaps & IEEE80211_CRYPTO_TKIP) && !sc->sc_wmetkipmic) { if (ic->ic_flags & IEEE80211_F_WME) { @@ -2419,9 +2478,11 @@ ath_settkipmic(struct ath_softc *sc) } static void -ath_init(struct ath_softc *sc) +ath_init(void *arg) { - struct ieee80211com *ic = &sc->sc_ic; + struct ath_softc *sc = (struct ath_softc *) arg; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; HAL_STATUS status; @@ -2440,7 +2501,7 @@ ath_init(struct ath_softc *sc) * Stop anything previously setup. This is safe * whether this is the first time through or not. */ - ath_stop_locked(sc); + ath_stop_locked(ifp); /* * The basic interface to setting the hardware in a good @@ -2566,7 +2627,7 @@ ath_init(struct ath_softc *sc) DPRINTF(sc, ATH_DEBUG_RESET, "%s: imask=0x%x\n", __func__, sc->sc_imask); - sc->sc_running = 1; + ifp->if_drv_flags |= IFF_DRV_RUNNING; callout_reset(&sc->sc_wd_ch, hz, ath_watchdog, sc); ath_hal_intrset(ah, sc->sc_imask); @@ -2582,10 +2643,14 @@ ath_init(struct ath_softc *sc) } static void -ath_stop_locked(struct ath_softc *sc) +ath_stop_locked(struct ifnet *ifp) { + struct ath_softc *sc = ifp->if_softc; struct ath_hal *ah = sc->sc_ah; + DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n", + __func__, sc->sc_invalid, ifp->if_flags); + ATH_LOCK_ASSERT(sc); /* @@ -2593,7 +2658,7 @@ ath_stop_locked(struct ath_softc *sc) */ ath_power_set_power_state(sc, HAL_PM_AWAKE); - if (sc->sc_running) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { /* * Shutdown the hardware and driver: * reset 802.11 state machine @@ -2615,7 +2680,7 @@ ath_stop_locked(struct ath_softc *sc) #endif callout_stop(&sc->sc_wd_ch); sc->sc_wd_timer = 0; - sc->sc_running = 0; + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; if (!sc->sc_invalid) { if (sc->sc_softled) { callout_stop(&sc->sc_ledtimer); @@ -2767,11 +2832,12 @@ ath_reset_grablock(struct ath_softc *sc, */ static void -ath_stop(struct ath_softc *sc) +ath_stop(struct ifnet *ifp) { - + struct ath_softc *sc = ifp->if_softc; + ATH_LOCK(sc); - ath_stop_locked(sc); + ath_stop_locked(ifp); ATH_UNLOCK(sc); } @@ -2783,9 +2849,10 @@ ath_stop(struct ath_softc *sc) * to reset or reload hardware state. */ int -ath_reset(struct ath_softc *sc, ATH_RESET_TYPE reset_type) +ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type) { - struct ieee80211com *ic = &sc->sc_ic; + struct ath_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; HAL_STATUS status; int i; @@ -2947,6 +3014,15 @@ ath_reset(struct ath_softc *sc, ATH_RESE } } + /* + * This may have been set during an ath_start() call which + * set this once it detected a concurrent TX was going on. + * So, clear it. + */ + IF_LOCK(&ifp->if_snd); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + IF_UNLOCK(&ifp->if_snd); + ATH_LOCK(sc); ath_power_restore_power_state(sc); ATH_UNLOCK(sc); @@ -2968,7 +3044,8 @@ static int ath_reset_vap(struct ieee80211vap *vap, u_long cmd) { struct ieee80211com *ic = vap->iv_ic; - struct ath_softc *sc = ic->ic_softc; + struct ifnet *ifp = ic->ic_ifp; + struct ath_softc *sc = ifp->if_softc; struct ath_hal *ah = sc->sc_ah; switch (cmd) { @@ -2983,7 +3060,7 @@ ath_reset_vap(struct ieee80211vap *vap, return 0; } /* XXX? Full or NOLOSS? */ - return ath_reset(sc, ATH_RESET_FULL); + return ath_reset(ifp, ATH_RESET_FULL); } struct ath_buf * @@ -3143,12 +3220,24 @@ ath_getbuf(struct ath_softc *sc, ath_buf bf = _ath_getbuf_locked(sc, ATH_BUFTYPE_NORMAL); ATH_TXBUF_UNLOCK(sc); if (bf == NULL) { + struct ifnet *ifp = sc->sc_ifp; + DPRINTF(sc, ATH_DEBUG_XMIT, "%s: stop queue\n", __func__); sc->sc_stats.ast_tx_qstop++; + IF_LOCK(&ifp->if_snd); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + IF_UNLOCK(&ifp->if_snd); } return bf; } +static void +ath_qflush(struct ifnet *ifp) +{ + + /* XXX TODO */ +} + /* * Transmit a single frame. * @@ -3156,9 +3245,10 @@ ath_getbuf(struct ath_softc *sc, ath_buf * fails, so don't free the node reference here. */ static int -ath_transmit(struct ieee80211com *ic, struct mbuf *m) +ath_transmit(struct ifnet *ifp, struct mbuf *m) { - struct ath_softc *sc = ic->ic_softc; + struct ieee80211com *ic = ifp->if_l2com; + struct ath_softc *sc = ic->ic_ifp->if_softc; struct ieee80211_node *ni; struct mbuf *next; struct ath_buf *bf; @@ -3173,7 +3263,10 @@ ath_transmit(struct ieee80211com *ic, st DPRINTF(sc, ATH_DEBUG_XMIT, "%s: sc_inreset_cnt > 0; bailing\n", __func__); ATH_PCU_UNLOCK(sc); + IF_LOCK(&ifp->if_snd); sc->sc_stats.ast_tx_qstop++; + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + IF_UNLOCK(&ifp->if_snd); ATH_KTR(sc, ATH_KTR_TX, 0, "ath_start_task: OACTIVE, finish"); return (ENOBUFS); /* XXX should be EINVAL or? */ } @@ -3213,6 +3306,8 @@ ath_transmit(struct ieee80211com *ic, st if ((!(m->m_flags & M_EAPOL)) && (ATH_NODE(ni)->an_swq_depth > sc->sc_txq_node_maxdepth)) { sc->sc_stats.ast_tx_nodeq_overflow++; + m_freem(m); + m = NULL; retval = ENOBUFS; goto finish; } @@ -3236,6 +3331,8 @@ ath_transmit(struct ieee80211com *ic, st if ((!(m->m_flags & M_EAPOL)) && (sc->sc_txbuf_cnt <= sc->sc_txq_data_minfree)) { sc->sc_stats.ast_tx_nobuf++; + m_freem(m); + m = NULL; retval = ENOBUFS; goto finish; } @@ -3263,6 +3360,11 @@ ath_transmit(struct ieee80211com *ic, st * above. */ sc->sc_stats.ast_tx_nobuf++; + IF_LOCK(&ifp->if_snd); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + IF_UNLOCK(&ifp->if_snd); + m_freem(m); + m = NULL; retval = ENOBUFS; goto finish; } @@ -3284,13 +3386,8 @@ ath_transmit(struct ieee80211com *ic, st DPRINTF(sc, ATH_DEBUG_XMIT, "%s: out of txfrag buffers\n", __func__); sc->sc_stats.ast_tx_nofrag++; - if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); - /* - * XXXGL: is mbuf valid after ath_txfrag_setup? If yes, - * we shouldn't free it but return back. - */ + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); ath_freetx(m); - m = NULL; goto bad; } @@ -3332,6 +3429,12 @@ ath_transmit(struct ieee80211com *ic, st } } + /* + * Bump the ifp output counter. + * + * XXX should use atomics? + */ + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); nextfrag: /* * Pass the frame to the h/w for transmission. @@ -3351,7 +3454,7 @@ nextfrag: next = m->m_nextpkt; if (ath_tx_start(sc, ni, bf, m)) { bad: - if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); reclaim: bf->bf_m = NULL; bf->bf_node = NULL; @@ -3435,7 +3538,8 @@ ath_media_change(struct ifnet *ifp) static void ath_key_update_begin(struct ieee80211vap *vap) { - struct ath_softc *sc = vap->iv_ic->ic_softc; + struct ifnet *ifp = vap->iv_ic->ic_ifp; + struct ath_softc *sc = ifp->if_softc; DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__); taskqueue_block(sc->sc_tq); @@ -3444,7 +3548,8 @@ ath_key_update_begin(struct ieee80211vap static void ath_key_update_end(struct ieee80211vap *vap) { - struct ath_softc *sc = vap->iv_ic->ic_softc; + struct ifnet *ifp = vap->iv_ic->ic_ifp; + struct ath_softc *sc = ifp->if_softc; DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__); taskqueue_unblock(sc->sc_tq); @@ -3475,41 +3580,32 @@ ath_update_promisc(struct ieee80211com * static void ath_update_mcast_hw(struct ath_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; u_int32_t mfilt[2]; /* calculate and install multicast filter */ - if (ic->ic_allmulti == 0) { - struct ieee80211vap *vap; - struct ifnet *ifp; + if ((ifp->if_flags & IFF_ALLMULTI) == 0) { struct ifmultiaddr *ifma; - /* * Merge multicast addresses to form the hardware filter. */ mfilt[0] = mfilt[1] = 0; - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - ifp = vap->iv_ifp; - if_maddr_rlock(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - caddr_t dl; - uint32_t val; - uint8_t pos; - - /* calculate XOR of eight 6bit values */ - dl = LLADDR((struct sockaddr_dl *) - ifma->ifma_addr); - val = LE_READ_4(dl + 0); - pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ - val; - val = LE_READ_4(dl + 3); - pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ - val; - pos &= 0x3f; - mfilt[pos / 32] |= (1 << (pos % 32)); - } - if_maddr_runlock(ifp); + if_maddr_rlock(ifp); /* XXX need some fiddling to remove? */ + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + caddr_t dl; + u_int32_t val; + u_int8_t pos; + + /* calculate XOR of eight 6bit values */ + dl = LLADDR((struct sockaddr_dl *) ifma->ifma_addr); + val = LE_READ_4(dl + 0); + pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; + val = LE_READ_4(dl + 3); + pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; + pos &= 0x3f; + mfilt[pos / 32] |= (1 << (pos % 32)); } + if_maddr_runlock(ifp); } else mfilt[0] = mfilt[1] = ~0; @@ -3542,7 +3638,7 @@ ath_update_mcast(struct ieee80211com *ic void ath_mode_init(struct ath_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; struct ath_hal *ah = sc->sc_ah; u_int32_t rfilt; @@ -3553,8 +3649,15 @@ ath_mode_init(struct ath_softc *sc) /* configure operational mode */ ath_hal_setopmode(ah); + DPRINTF(sc, ATH_DEBUG_STATE | ATH_DEBUG_MODE, + "%s: ah=%p, ifp=%p, if_addr=%p\n", + __func__, + ah, + ifp, + (ifp == NULL) ? NULL : ifp->if_addr); + /* handle any link-level address change */ - ath_hal_setmac(ah, ic->ic_macaddr); + ath_hal_setmac(ah, IF_LLADDR(ifp)); /* calculate and install multicast filter */ ath_update_mcast_hw(sc); @@ -3566,7 +3669,7 @@ ath_mode_init(struct ath_softc *sc) void ath_setslottime(struct ath_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; u_int usec; @@ -3650,11 +3753,12 @@ static void ath_reset_proc(void *arg, int pending) { struct ath_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; #if 0 device_printf(sc->sc_dev, "%s: resetting\n", __func__); #endif - ath_reset(sc, ATH_RESET_NOLOSS); + ath_reset(ifp, ATH_RESET_NOLOSS); } /* @@ -3664,6 +3768,7 @@ static void ath_bstuck_proc(void *arg, int pending) { struct ath_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; uint32_t hangs = 0; if (ath_hal_gethangstate(sc->sc_ah, 0xff, &hangs) && hangs != 0) @@ -3681,7 +3786,7 @@ ath_bstuck_proc(void *arg, int pending) * This assumes that there's no simultaneous channel mode change * occuring. */ - ath_reset(sc, ATH_RESET_NOLOSS); + ath_reset(ifp, ATH_RESET_NOLOSS); } static void @@ -4051,7 +4156,7 @@ static struct ieee80211_node * ath_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) { struct ieee80211com *ic = vap->iv_ic; - struct ath_softc *sc = ic->ic_softc; + struct ath_softc *sc = ic->ic_ifp->if_softc; const size_t space = sizeof(struct ath_node) + sc->sc_rc->arc_space; struct ath_node *an; @@ -4078,7 +4183,7 @@ static void ath_node_cleanup(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_softc; + struct ath_softc *sc = ic->ic_ifp->if_softc; DPRINTF(sc, ATH_DEBUG_NODE, "%s: %6D: an %p\n", __func__, ni->ni_macaddr, ":", ATH_NODE(ni)); @@ -4093,7 +4198,7 @@ static void ath_node_free(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_softc; + struct ath_softc *sc = ic->ic_ifp->if_softc; DPRINTF(sc, ATH_DEBUG_NODE, "%s: %6D: an %p\n", __func__, ni->ni_macaddr, ":", ATH_NODE(ni)); @@ -4105,7 +4210,7 @@ static void ath_node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise) { struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_softc; + struct ath_softc *sc = ic->ic_ifp->if_softc; struct ath_hal *ah = sc->sc_ah; *rssi = ic->ic_node_getrssi(ni); @@ -4243,7 +4348,8 @@ ath_txq_update(struct ath_softc *sc, int { #define ATH_EXPONENT_TO_VALUE(v) ((1<sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ath_txq *txq = sc->sc_ac2q[ac]; struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac]; struct ath_hal *ah = sc->sc_ah; @@ -4316,7 +4422,7 @@ ath_txq_update(struct ath_softc *sc, int int ath_wme_update(struct ieee80211com *ic) { - struct ath_softc *sc = ic->ic_softc; + struct ath_softc *sc = ic->ic_ifp->if_softc; return !ath_txq_update(sc, WME_AC_BE) || !ath_txq_update(sc, WME_AC_BK) || @@ -4367,7 +4473,8 @@ ath_tx_update_stats(struct ath_softc *sc struct ath_buf *bf) { struct ieee80211_node *ni = bf->bf_node; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; int sr, lr, pri; if (ts->ts_status == 0) { @@ -4722,6 +4829,7 @@ static void ath_tx_proc_q0(void *arg, int npending) { struct ath_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; uint32_t txqs; ATH_PCU_LOCK(sc); @@ -4742,6 +4850,9 @@ ath_tx_proc_q0(void *arg, int npending) sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); if (TXQACTIVE(txqs, sc->sc_cabq->axq_qnum)) ath_tx_processq(sc, sc->sc_cabq, 1); + IF_LOCK(&ifp->if_snd); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + IF_UNLOCK(&ifp->if_snd); sc->sc_wd_timer = 0; if (sc->sc_softled) @@ -4766,6 +4877,7 @@ static void ath_tx_proc_q0123(void *arg, int npending) { struct ath_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; int nacked; uint32_t txqs; @@ -4799,6 +4911,9 @@ ath_tx_proc_q0123(void *arg, int npendin if (nacked) sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); + IF_LOCK(&ifp->if_snd); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + IF_UNLOCK(&ifp->if_snd); sc->sc_wd_timer = 0; if (sc->sc_softled) @@ -4822,6 +4937,7 @@ static void ath_tx_proc(void *arg, int npending) { struct ath_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; int i, nacked; uint32_t txqs; @@ -4847,6 +4963,10 @@ ath_tx_proc(void *arg, int npending) if (nacked) sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); + /* XXX check this inside of IF_LOCK? */ + IF_LOCK(&ifp->if_snd); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + IF_UNLOCK(&ifp->if_snd); sc->sc_wd_timer = 0; if (sc->sc_softled) @@ -5157,7 +5277,7 @@ ath_tx_draintxq(struct ath_softc *sc, st txq->axq_aggr_depth--; #ifdef ATH_DEBUG if (sc->sc_debug & ATH_DEBUG_RESET) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; int status = 0; /* @@ -5302,8 +5422,9 @@ void ath_legacy_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type) { struct ath_hal *ah = sc->sc_ah; - struct ath_buf *bf_last; + struct ifnet *ifp = sc->sc_ifp; int i; + struct ath_buf *bf_last; (void) ath_stoptxdma(sc); @@ -5355,12 +5476,15 @@ ath_legacy_tx_drain(struct ath_softc *sc ath_printtxbuf(sc, bf, sc->sc_bhalq, 0, ath_hal_txprocdesc(ah, bf->bf_lastds, &bf->bf_status.ds_txstat) == HAL_OK); - ieee80211_dump_pkt(&sc->sc_ic, + ieee80211_dump_pkt(ifp->if_l2com, mtod(bf->bf_m, const uint8_t *), bf->bf_m->m_len, 0, -1); } } #endif /* ATH_DEBUG */ + IF_LOCK(&ifp->if_snd); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + IF_UNLOCK(&ifp->if_snd); sc->sc_wd_timer = 0; } @@ -5391,7 +5515,8 @@ ath_chan_change(struct ath_softc *sc, st static int ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; int ret = 0; @@ -5526,6 +5651,9 @@ finish: ath_hal_intrset(ah, sc->sc_imask); ATH_PCU_UNLOCK(sc); + IF_LOCK(&ifp->if_snd); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + IF_UNLOCK(&ifp->if_snd); ath_txrx_start(sc); /* XXX ath_start? */ @@ -5541,7 +5669,8 @@ ath_calibrate(void *arg) { struct ath_softc *sc = arg; struct ath_hal *ah = sc->sc_ah; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; HAL_BOOL longCal, isCalDone = AH_TRUE; HAL_BOOL aniCal, shortCal = AH_FALSE; int nextcal; @@ -5667,12 +5796,12 @@ restart: static void *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***