Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Aug 2015 08:56:40 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r287197 - in head: etc etc/rc.d sys/dev/ath sys/dev/ath/ath_rate/sample sys/dev/bwi sys/dev/bwn sys/dev/if_ndis sys/dev/ipw sys/dev/iwi sys/dev/iwm sys/dev/iwn sys/dev/malo sys/dev/mwl ...
Message-ID:  <201508270856.t7R8ue0q046082@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Thu Aug 27 08:56:39 2015
New Revision: 287197
URL: https://svnweb.freebsd.org/changeset/base/287197

Log:
  Replay r286410. Change KPI of how device drivers that provide wireless
  connectivity interact with the net80211 stack.
  
  Historical background: originally wireless devices created an interface,
  just like Ethernet devices do. Name of an interface matched the name of
  the driver that created. Later, wlan(4) layer was introduced, and the
  wlanX interfaces become the actual interface, leaving original ones as
  "a parent interface" of wlanX. Kernelwise, the KPI between net80211 layer
  and a driver became a mix of methods that pass a pointer to struct ifnet
  as identifier and methods that pass pointer to struct ieee80211com. From
  user point of view, the parent interface just hangs on in the ifconfig
  list, and user can't do anything useful with it.
  
  Now, the struct ifnet goes away. The struct ieee80211com is the only
  KPI between a device driver and net80211. Details:
  
  - The struct ieee80211com is embedded into drivers softc.
  - Packets are sent via new ic_transmit method, which is very much like
    the previous if_transmit.
  - Bringing parent up/down is done via new ic_parent method, which notifies
    driver about any changes: number of wlan(4) interfaces, number of them
    in promisc or allmulti state.
  - Device specific ioctls (if any) are received on new ic_ioctl method.
  - Packets/errors accounting are done by the stack. In certain cases, when
    driver experiences errors and can not attribute them to any specific
    interface, driver updates ic_oerrors or ic_ierrors counters.
  
  Details on interface configuration with new world order:
  - A sequence of commands needed to bring up wireless DOESN"T change.
  - /etc/rc.conf parameters DON'T change.
  - List of devices that can be used to create wlan(4) interfaces is
    now provided by net.wlan.devices sysctl.
  
  Most drivers in this change were converted by me, except of wpi(4),
  that was done by Andriy Voskoboinyk. Big thanks to Kevin Lo for testing
  changes to at least 8 drivers. Thanks to pluknet@, Oliver Hartmann,
  Olivier Cochard, gjb@, mmoll@, op@ and lev@, who also participated in
  testing.
  
  Reviewed by:	adrian
  Sponsored by:	Netflix
  Sponsored by:	Nginx, Inc.

Modified:
  head/etc/network.subr
  head/etc/rc.d/netif
  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_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/iwm/if_iwm.c
  head/sys/dev/iwm/if_iwm_mac_ctxt.c
  head/sys/dev/iwm/if_iwm_phy_ctxt.c
  head/sys/dev/iwm/if_iwm_power.c
  head/sys/dev/iwm/if_iwm_scan.c
  head/sys/dev/iwm/if_iwmvar.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_macio.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
  head/tools/tools/iwn/iwnstats/main.c

Modified: head/etc/network.subr
==============================================================================
--- head/etc/network.subr	Thu Aug 27 08:15:32 2015	(r287196)
+++ head/etc/network.subr	Thu Aug 27 08:56:39 2015	(r287197)
@@ -1249,6 +1249,89 @@ ifscript_down()
 	fi
 }
 
+# wlan_up
+#	Create IEEE802.11 interfaces.
+#
+wlan_up()
+{
+	local _list _iflist parent child_wlans child create_args debug_flags
+	_list=
+	_iflist=$*
+
+	# Parse wlans_$parent="$child ..."
+	for parent in `set | sed -nE 's/wlans_([a-z]+[0-9]+)=.*/\1/p'`; do
+		child_wlans=`get_if_var $parent wlans_IF`
+		for child in ${child_wlans}; do
+			create_args="wlandev $parent `get_if_var $child create_args_IF`"
+			debug_flags="`get_if_var $child wlandebug_IF`"
+			case $_iflist in
+			""|$child|$child\ *|*\ $child\ *|*\ $child)	;;
+			*)	continue ;;
+			esac
+			# Skip if ${child} already exists.
+			if ${IFCONFIG_CMD} $child > /dev/null 2>&1; then
+				continue
+			fi
+			if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then
+				${IFCONFIG_CMD} $child create ${create_args} && cfg=0
+				if [ $? -eq 0 ]; then
+					_list="$_list $child"
+				fi
+				if [ -n "${debug_flags}" ]; then
+					wlandebug -i $child ${debug_flags}
+				fi
+			else
+				i=`${IFCONFIG_CMD} wlan create ${create_args}`
+				# XXXGL: wlandebug should accept any name
+				if [ -n "${debug_flags}" ]; then
+					wlandebug -i $i ${debug_flags}
+				fi
+				${IFCONFIG_CMD} $i name $child && cfg=0
+				if [ $? -eq 0 ]; then
+					_list="$_list $child"
+				fi
+			fi
+		done
+	done
+	if [ -n "${_list# }" ]; then
+		echo "Created wlan(4) interfaces: ${_list# }."
+	fi
+	debug "Created wlan(4)s: ${_list# }"
+}
+
+# wlan_down
+#	Destroy IEEE802.11 interfaces.
+#
+wlan_down()
+{
+	local _list _iflist parent child_wlans child
+	_list=
+	_iflist=$*
+
+	# Parse wlans_$parent="$child ..."
+	for parent in `set | sed -nE 's/wlans_([a-z]+[0-9]+)=.*/\1/p'`; do
+		child_wlans=`get_if_var $parent wlans_IF`
+		for child in ${child_wlans}; do
+			case $_iflist in
+			""|$child|$child\ *|*\ $child\ *|*\ $child)	;;
+			*)	continue ;;
+			esac
+			# Skip if ${child} doesn't exists.
+			if ! ${IFCONFIG_CMD} $child > /dev/null 2>&1; then
+				continue
+			fi
+			${IFCONFIG_CMD} -n ${child} destroy
+			if [ $? -eq 0 ]; then
+				_list="$_list $child"
+			fi
+		done
+	done
+	if [ -n "${_list# }" ]; then
+		echo "Destroyed wlan(4) interfaces: ${_list# }."
+	fi
+	debug "Destroyed wlan(4)s: ${_list# }"
+}
+
 # clone_up
 #	Create cloneable interfaces.
 #
@@ -1398,6 +1481,9 @@ clone_down()
 #	Create and configure child interfaces.  Return 0 if child
 #	interfaces are created.
 #
+#	XXXGL: the wlan code in this functions is superseded by wlan_up(),
+#	and will go away soon.
+#
 childif_create()
 {
 	local cfg child child_vlans child_wlans create_args debug_flags ifn i

Modified: head/etc/rc.d/netif
==============================================================================
--- head/etc/rc.d/netif	Thu Aug 27 08:15:32 2015	(r287196)
+++ head/etc/rc.d/netif	Thu Aug 27 08:56:39 2015	(r287197)
@@ -37,6 +37,8 @@ name="netif"
 rcvar="${name}_enable"
 start_cmd="netif_start"
 stop_cmd="netif_stop"
+wlanup_cmd="wlan_up"
+wlandown_cmd="wlan_down"
 cloneup_cmd="clone_up"
 clonedown_cmd="clone_down"
 clear_cmd="doclear"
@@ -65,6 +67,9 @@ netif_start()
 		trap : 2
 	fi
 
+	# Create IEEE802.11 interface
+	wlan_up $cmdifn
+
 	# Create cloned interfaces
 	clone_up $cmdifn
 
@@ -91,12 +96,14 @@ netif_start()
 netif_stop()
 {
 	_clone_down=1
+	_wlan_down=1
 	netif_stop0 $*
 }
 
 doclear()
 {
 	_clone_down=
+	_wlan_down=
 	netif_stop0 $*
 }
 
@@ -111,6 +118,11 @@ netif_stop0()
 	# Deconfigure the interface(s)
 	netif_common ifn_stop $cmdifn
 
+	# Destroy wlan interfaces
+	if [ -n "$_wlan_down" ]; then
+		wlan_down $cmdifn
+	fi
+
 	# Destroy cloned interfaces
 	if [ -n "$_clone_down" ]; then
 		clone_down $cmdifn

Modified: head/sys/dev/ath/ath_rate/sample/sample.c
==============================================================================
--- head/sys/dev/ath/ath_rate/sample/sample.c	Thu Aug 27 08:15:32 2015	(r287196)
+++ head/sys/dev/ath/ath_rate/sample/sample.c	Thu Aug 27 08:56:39 2015	(r287197)
@@ -488,8 +488,7 @@ 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 ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211com *ic = &sc->sc_ic;
 	const HAL_RATE_TABLE *rt = sc->sc_currates;
 	const int size_bin = size_to_bin(frameLen);
 	int rix, mrr, best_rix, change_rates;
@@ -856,8 +855,7 @@ 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 ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211com *ic = &sc->sc_ic;
 	struct sample_node *sn = ATH_NODE_SAMPLE(an);
 	int final_rix, short_tries, long_tries;
 	const HAL_RATE_TABLE *rt = sc->sc_currates;
@@ -1303,8 +1301,7 @@ static int
 ath_rate_sysctl_stats(SYSCTL_HANDLER_ARGS)
 {
 	struct ath_softc *sc = arg1;
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211com *ic = &sc->sc_ic;
 	int error, v;
 
 	v = 0;

Modified: head/sys/dev/ath/ath_rate/sample/sample.h
==============================================================================
--- head/sys/dev/ath/ath_rate/sample/sample.h	Thu Aug 27 08:15:32 2015	(r287196)
+++ head/sys/dev/ath/ath_rate/sample/sample.h	Thu Aug 27 08:56:39 2015	(r287197)
@@ -134,8 +134,7 @@ static unsigned calc_usecs_unicast_packe
 				int long_retries, int is_ht40)
 {
 	const HAL_RATE_TABLE *rt = sc->sc_currates;
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211com *ic = &sc->sc_ic;
 	int rts, cts;
 	
 	unsigned t_slot = 20;

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Thu Aug 27 08:15:32 2015	(r287196)
+++ head/sys/dev/ath/if_ath.c	Thu Aug 27 08:56:39 2015	(r287197)
@@ -151,15 +151,14 @@ 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(void *);
-static void	ath_stop_locked(struct ifnet *);
-static void	ath_stop(struct ifnet *);
+static int	ath_init(struct ath_softc *);
+static void	ath_stop(struct ath_softc *);
 static int	ath_reset_vap(struct ieee80211vap *, u_long);
-static int	ath_transmit(struct ifnet *ifp, struct mbuf *m);
-static void	ath_qflush(struct ifnet *ifp);
+static int	ath_transmit(struct ieee80211com *, struct mbuf *);
 static int	ath_media_change(struct ifnet *);
 static void	ath_watchdog(void *);
-static int	ath_ioctl(struct ifnet *, u_long, caddr_t);
+static int	ath_ioctl(struct ieee80211com *, u_long, void *);
+static void	ath_parent(struct ieee80211com *);
 static void	ath_fatal_proc(void *, int);
 static void	ath_bmiss_vap(struct ieee80211vap *);
 static void	ath_bmiss_proc(void *, int);
@@ -571,34 +570,19 @@ ath_fetch_mac_kenv(struct ath_softc *sc,
 int
 ath_attach(u_int16_t devid, struct ath_softc *sc)
 {
-	struct ifnet *ifp;
-	struct ieee80211com *ic;
+	struct ieee80211com *ic = &sc->sc_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.
 	 *
@@ -732,8 +716,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", ifp->if_xname);
+	taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
+	    device_get_nameunit(sc->sc_dev));
 
 	TASK_INIT(&sc->sc_rxtask, 0, sc->sc_rx.recv_tasklet, sc);
 	TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc);
@@ -876,17 +860,6 @@ 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;
@@ -1208,11 +1181,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, macaddr) == 0) {
+	if (ath_fetch_mac_kenv(sc, ic->ic_macaddr) == 0) {
 		/* Tell the HAL now about the new MAC */
-		ath_hal_setmac(ah, macaddr);
+		ath_hal_setmac(ah, ic->ic_macaddr);
 	} else {
-		ath_hal_getmac(ah, macaddr);
+		ath_hal_getmac(ah, ic->ic_macaddr);
 	}
 
 	if (sc->sc_hasbmask)
@@ -1221,12 +1194,15 @@ 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, macaddr);
+	ieee80211_ifattach(ic);
 	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;
@@ -1322,16 +1298,6 @@ 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;
 }
@@ -1339,10 +1305,6 @@ 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:
@@ -1367,14 +1329,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(ifp);
+	ath_stop(sc);
+	ATH_UNLOCK(sc);
 
-	ieee80211_ifdetach(ifp->if_l2com);
+	ieee80211_ifdetach(&sc->sc_ic);
 	taskqueue_free(sc->sc_tq);
 #ifdef ATH_TX99_DIAG
 	if (sc->sc_tx99 != NULL)
@@ -1394,10 +1356,6 @@ 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;
 }
 
@@ -1581,8 +1539,7 @@ 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, mac);
+	error = ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
 	ATH_LOCK(sc);
 	if (error != 0) {
 		device_printf(sc->sc_dev, "%s: error %d creating vap\n",
@@ -1716,7 +1673,8 @@ ath_vap_create(struct ieee80211com *ic, 
 	ATH_UNLOCK(sc);
 
 	/* complete setup */
-	ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status);
+	ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status,
+	    mac);
 	return vap;
 bad2:
 	reclaim_address(sc, mac);
@@ -1731,7 +1689,6 @@ static void
 ath_vap_delete(struct ieee80211vap *vap)
 {
 	struct ieee80211com *ic = vap->iv_ic;
-	struct ifnet *ifp = ic->ic_ifp;
 	struct ath_softc *sc = ic->ic_softc;
 	struct ath_hal *ah = sc->sc_ah;
 	struct ath_vap *avp = ATH_VAP(vap);
@@ -1741,7 +1698,7 @@ ath_vap_delete(struct ieee80211vap *vap)
 	ATH_UNLOCK(sc);
 
 	DPRINTF(sc, ATH_DEBUG_RESET, "%s: called\n", __func__);
-	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+	if (sc->sc_running) {
 		/*
 		 * Quiesce the hardware while we remove the vap.  In
 		 * particular we need to reclaim all references to
@@ -1770,7 +1727,7 @@ ath_vap_delete(struct ieee80211vap *vap)
 	 * may be being scheduled between sw->hw txq. Tsk.
 	 *
 	 * TODO: figure out why a new node gets allocated somewhere around
-	 * here (after the ath_tx_swq() call; and after an ath_stop_locked()
+	 * here (after the ath_tx_swq() call; and after an ath_stop()
 	 * call!)
 	 */
 
@@ -1824,7 +1781,7 @@ ath_vap_delete(struct ieee80211vap *vap)
 #endif
 	free(avp, M_80211_VAP);
 
-	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+	if (sc->sc_running) {
 		/*
 		 * Restart rx+tx machines if still running (RUNNING will
 		 * be reset if we just destroyed the last vap).
@@ -1851,13 +1808,9 @@ ath_vap_delete(struct ieee80211vap *vap)
 void
 ath_suspend(struct ath_softc *sc)
 {
-	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);
+	struct ieee80211com *ic = &sc->sc_ic;
 
-	sc->sc_resume_up = (ifp->if_flags & IFF_UP) != 0;
+	sc->sc_resume_up = ic->ic_nrunning != 0;
 
 	ieee80211_suspend_all(ic);
 	/*
@@ -1898,8 +1851,7 @@ ath_suspend(struct ath_softc *sc)
 static void
 ath_reset_keycache(struct ath_softc *sc)
 {
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
 	int i;
 
@@ -1941,15 +1893,10 @@ ath_update_chainmasks(struct ath_softc *
 void
 ath_resume(struct ath_softc *sc)
 {
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
 	HAL_STATUS status;
 
-	DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n",
-		__func__, ifp->if_flags);
-
-	/* Re-enable PCIe, re-enable the PCIe bus */
 	ath_hal_enablepcie(ah, 0, 0);
 
 	/*
@@ -2015,12 +1962,10 @@ 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(ifp);
+	ATH_LOCK(sc);
+	ath_stop(sc);
+	ATH_UNLOCK(sc);
 	/* NB: no point powering down chip as we're about to reboot */
 }
 
@@ -2031,7 +1976,6 @@ 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;
@@ -2070,12 +2014,11 @@ ath_intr(void *arg)
 	ath_power_set_power_state(sc, HAL_PM_AWAKE);
 	ATH_UNLOCK(sc);
 
-	if ((ifp->if_flags & IFF_UP) == 0 ||
-	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+	if (sc->sc_ic.ic_nrunning == 0 && sc->sc_running == 0) {
 		HAL_INT status;
 
-		DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags 0x%x\n",
-			__func__, ifp->if_flags);
+		DPRINTF(sc, ATH_DEBUG_ANY, "%s: ic_nrunning %d sc_running %d\n",
+		    __func__, sc->sc_ic.ic_nrunning, sc->sc_running);
 		ath_hal_getisr(ah, &status);	/* clear ISR */
 		ath_hal_intrset(ah, 0);		/* disable further intr's */
 		ATH_PCU_UNLOCK(sc);
@@ -2157,7 +2100,7 @@ ath_intr(void *arg)
 #ifdef IEEE80211_SUPPORT_TDMA
 			if (sc->sc_tdma) {
 				if (sc->sc_tdmaswba == 0) {
-					struct ieee80211com *ic = ifp->if_l2com;
+					struct ieee80211com *ic = &sc->sc_ic;
 					struct ieee80211vap *vap =
 					    TAILQ_FIRST(&ic->ic_vaps);
 					ath_tdma_beacon_send(sc, vap);
@@ -2313,7 +2256,6 @@ 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;
@@ -2334,7 +2276,7 @@ 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(ifp, ATH_RESET_NOLOSS);
+	ath_reset(sc, ATH_RESET_NOLOSS);
 }
 
 static void
@@ -2418,7 +2360,6 @@ 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);
@@ -2436,12 +2377,12 @@ ath_bmiss_proc(void *arg, int pending)
 	 * to clear.
 	 */
 	if (ath_hal_gethangstate(sc->sc_ah, 0xff, &hangs) && hangs != 0) {
-		ath_reset(ifp, ATH_RESET_NOLOSS);
+		ath_reset(sc, ATH_RESET_NOLOSS);
 		device_printf(sc->sc_dev,
 		    "bb hang detected (0x%x), resetting\n", hangs);
 	} else {
-		ath_reset(ifp, ATH_RESET_NOLOSS);
-		ieee80211_beacon_miss(ifp->if_l2com);
+		ath_reset(sc, ATH_RESET_NOLOSS);
+		ieee80211_beacon_miss(&sc->sc_ic);
 	}
 
 	/* Force a beacon resync, in case they've drifted */
@@ -2461,8 +2402,7 @@ ath_bmiss_proc(void *arg, int pending)
 static void
 ath_settkipmic(struct ath_softc *sc)
 {
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211com *ic = &sc->sc_ic;
 
 	if ((ic->ic_cryptocaps & IEEE80211_CRYPTO_TKIP) && !sc->sc_wmetkipmic) {
 		if (ic->ic_flags & IEEE80211_F_WME) {
@@ -2475,19 +2415,15 @@ ath_settkipmic(struct ath_softc *sc)
 	}
 }
 
-static void
-ath_init(void *arg)
+static int
+ath_init(struct ath_softc *sc)
 {
-	struct ath_softc *sc = (struct ath_softc *) arg;
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
 	HAL_STATUS status;
 
-	DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags 0x%x\n",
-		__func__, ifp->if_flags);
+	ATH_LOCK_ASSERT(sc);
 
-	ATH_LOCK(sc);
 	/*
 	 * Force the sleep state awake.
 	 */
@@ -2499,7 +2435,7 @@ ath_init(void *arg)
 	 * Stop anything previously setup.  This is safe
 	 * whether this is the first time through or not.
 	 */
-	ath_stop_locked(ifp);
+	ath_stop(sc);
 
 	/*
 	 * The basic interface to setting the hardware in a good
@@ -2517,8 +2453,7 @@ ath_init(void *arg)
 	    &status)) {
 		device_printf(sc->sc_dev,
 		    "unable to reset hardware; hal status %u\n", status);
-		ATH_UNLOCK(sc);
-		return;
+		return (ENODEV);
 	}
 
 	ATH_RX_LOCK(sc);
@@ -2576,8 +2511,7 @@ ath_init(void *arg)
 	if (ath_startrecv(sc) != 0) {
 		device_printf(sc->sc_dev, "unable to start recv logic\n");
 		ath_power_restore_power_state(sc);
-		ATH_UNLOCK(sc);
-		return;
+		return (ENODEV);
 	}
 
 	/*
@@ -2625,30 +2559,20 @@ ath_init(void *arg)
 	DPRINTF(sc, ATH_DEBUG_RESET, "%s: imask=0x%x\n",
 		__func__, sc->sc_imask);
 
-	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+	sc->sc_running = 1;
 	callout_reset(&sc->sc_wd_ch, hz, ath_watchdog, sc);
 	ath_hal_intrset(ah, sc->sc_imask);
 
 	ath_power_restore_power_state(sc);
-	ATH_UNLOCK(sc);
 
-#ifdef ATH_TX99_DIAG
-	if (sc->sc_tx99 != NULL)
-		sc->sc_tx99->start(sc->sc_tx99);
-	else
-#endif
-	ieee80211_start_all(ic);		/* start all vap's */
+	return (0);
 }
 
 static void
-ath_stop_locked(struct ifnet *ifp)
+ath_stop(struct ath_softc *sc)
 {
-	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);
 
 	/*
@@ -2656,7 +2580,7 @@ ath_stop_locked(struct ifnet *ifp)
 	 */
 	ath_power_set_power_state(sc, HAL_PM_AWAKE);
 
-	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+	if (sc->sc_running) {
 		/*
 		 * Shutdown the hardware and driver:
 		 *    reset 802.11 state machine
@@ -2678,7 +2602,7 @@ ath_stop_locked(struct ifnet *ifp)
 #endif
 		callout_stop(&sc->sc_wd_ch);
 		sc->sc_wd_timer = 0;
-		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+		sc->sc_running = 0;
 		if (!sc->sc_invalid) {
 			if (sc->sc_softled) {
 				callout_stop(&sc->sc_ledtimer);
@@ -2826,20 +2750,6 @@ ath_reset_grablock(struct ath_softc *sc,
 #undef MAX_RESET_ITERATIONS
 
 /*
- * XXX TODO: write ath_reset_releaselock
- */
-
-static void
-ath_stop(struct ifnet *ifp)
-{
-	struct ath_softc *sc = ifp->if_softc;
-
-	ATH_LOCK(sc);
-	ath_stop_locked(ifp);
-	ATH_UNLOCK(sc);
-}
-
-/*
  * Reset the hardware w/o losing operational state.  This is
  * basically a more efficient way of doing ath_stop, ath_init,
  * followed by state transitions to the current 802.11
@@ -2847,10 +2757,9 @@ ath_stop(struct ifnet *ifp)
  * to reset or reload hardware state.
  */
 int
-ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type)
+ath_reset(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
 {
-	struct ieee80211com *ic = ifp->if_l2com;
-	struct ath_softc *sc = ic->ic_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
 	HAL_STATUS status;
 	int i;
@@ -3012,15 +2921,6 @@ ath_reset(struct ifnet *ifp, ATH_RESET_T
 		}
 	}
 
-	/*
-	 * 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);
@@ -3042,7 +2942,6 @@ static int
 ath_reset_vap(struct ieee80211vap *vap, u_long cmd)
 {
 	struct ieee80211com *ic = vap->iv_ic;
-	struct ifnet *ifp = ic->ic_ifp;
 	struct ath_softc *sc = ic->ic_softc;
 	struct ath_hal *ah = sc->sc_ah;
 
@@ -3058,7 +2957,7 @@ ath_reset_vap(struct ieee80211vap *vap, 
 		return 0;
 	}
 	/* XXX? Full or NOLOSS? */
-	return ath_reset(ifp, ATH_RESET_FULL);
+	return ath_reset(sc, ATH_RESET_FULL);
 }
 
 struct ath_buf *
@@ -3218,24 +3117,12 @@ 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.
  *
@@ -3243,9 +3130,8 @@ ath_qflush(struct ifnet *ifp)
  * fails, so don't free the node reference here.
  */
 static int
-ath_transmit(struct ifnet *ifp, struct mbuf *m)
+ath_transmit(struct ieee80211com *ic, struct mbuf *m)
 {
-	struct ieee80211com *ic = ifp->if_l2com;
 	struct ath_softc *sc = ic->ic_softc;
 	struct ieee80211_node *ni;
 	struct mbuf *next;
@@ -3261,10 +3147,7 @@ ath_transmit(struct ifnet *ifp, struct m
 		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? */
 	}
@@ -3304,8 +3187,6 @@ ath_transmit(struct ifnet *ifp, struct m
 	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;
 	}
@@ -3329,8 +3210,6 @@ ath_transmit(struct ifnet *ifp, struct m
 	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;
 	}
@@ -3358,11 +3237,6 @@ ath_transmit(struct ifnet *ifp, struct m
 		 * 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;
 	}
@@ -3384,8 +3258,13 @@ ath_transmit(struct ifnet *ifp, struct m
 		DPRINTF(sc, ATH_DEBUG_XMIT,
 		    "%s: out of txfrag buffers\n", __func__);
 		sc->sc_stats.ast_tx_nofrag++;
-		if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+		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.
+		 */
 		ath_freetx(m);
+		m = NULL;
 		goto bad;
 	}
 
@@ -3427,12 +3306,6 @@ ath_transmit(struct ifnet *ifp, struct m
 		}
 	}
 
-	/*
-	 * 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.
@@ -3452,7 +3325,7 @@ nextfrag:
 	next = m->m_nextpkt;
 	if (ath_tx_start(sc, ni, bf, m)) {
 bad:
-		if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+		if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
 reclaim:
 		bf->bf_m = NULL;
 		bf->bf_node = NULL;
@@ -3576,32 +3449,41 @@ ath_update_promisc(struct ieee80211com *
 static void
 ath_update_mcast_hw(struct ath_softc *sc)
 {
-	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = &sc->sc_ic;
 	u_int32_t mfilt[2];
 
 	/* calculate and install multicast filter */
-	if ((ifp->if_flags & IFF_ALLMULTI) == 0) {
+	if (ic->ic_allmulti == 0) {
+		struct ieee80211vap *vap;
+		struct ifnet *ifp;
 		struct ifmultiaddr *ifma;
+
 		/*
 		 * Merge multicast addresses to form the hardware filter.
 		 */
 		mfilt[0] = mfilt[1] = 0;
-		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));
+		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_runlock(ifp);
 	} else
 		mfilt[0] = mfilt[1] = ~0;
 
@@ -3634,7 +3516,7 @@ ath_update_mcast(struct ieee80211com *ic
 void
 ath_mode_init(struct ath_softc *sc)
 {
-	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
 	u_int32_t rfilt;
 
@@ -3645,15 +3527,8 @@ 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, IF_LLADDR(ifp));
+	ath_hal_setmac(ah, ic->ic_macaddr);
 
 	/* calculate and install multicast filter */
 	ath_update_mcast_hw(sc);
@@ -3665,7 +3540,7 @@ ath_mode_init(struct ath_softc *sc)
 void
 ath_setslottime(struct ath_softc *sc)
 {
-	struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
 	u_int usec;
 
@@ -3749,12 +3624,11 @@ 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(ifp, ATH_RESET_NOLOSS);
+	ath_reset(sc, ATH_RESET_NOLOSS);
 }
 
 /*
@@ -3764,7 +3638,6 @@ 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)
@@ -3782,7 +3655,7 @@ ath_bstuck_proc(void *arg, int pending)
 	 * This assumes that there's no simultaneous channel mode change
 	 * occuring.
 	 */
-	ath_reset(ifp, ATH_RESET_NOLOSS);
+	ath_reset(sc, ATH_RESET_NOLOSS);
 }
 
 static void
@@ -4344,8 +4217,7 @@ ath_txq_update(struct ath_softc *sc, int
 {
 #define	ATH_EXPONENT_TO_VALUE(v)	((1<<v)-1)
 #define	ATH_TXOP_TO_US(v)		(v<<5)
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211com *ic = &sc->sc_ic;
 	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;
@@ -4469,8 +4341,7 @@ ath_tx_update_stats(struct ath_softc *sc
     struct ath_buf *bf)
 {
 	struct ieee80211_node *ni = bf->bf_node;
-	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211com *ic = &sc->sc_ic;
 	int sr, lr, pri;
 
 	if (ts->ts_status == 0) {

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508270856.t7R8ue0q046082>