svn commit: r286410 - 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/iwn sys/dev/malo sys/dev/mwl sys/dev/ral ...

Gleb Smirnoff glebius at FreeBSD.org
Fri Aug 7 11:43:17 UTC 2015


Author: glebius
Date: Fri Aug  7 11:43:14 2015
New Revision: 286410
URL: https://svnweb.freebsd.org/changeset/base/286410

Log:
  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 Olivier Cochard, gjb@, mmoll@,
  op@ and lev@, who also participated in testing. Details here:
  
  https://wiki.freebsd.org/projects/ifnet/net80211
  
  Still, drivers: ndis, wtap, mwl, ipw, bwn, wi, upgt, uath were not
  tested. Changes to mwl, ipw, bwn, wi, upgt are trivial and chances
  of problems are low. The wtap wasn't compilable even before this change.
  But the ndis driver is complex, and it is likely to be broken with this
  commit. Help with testing and debugging it is appreciated.
  
  Differential Revision:	D2655, D2740
  Sponsored by:	Nginx, Inc.
  Sponsored by:	Netflix

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_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
  head/tools/tools/iwn/iwnstats/main.c

Modified: head/etc/network.subr
==============================================================================
--- head/etc/network.subr	Fri Aug  7 10:48:52 2015	(r286409)
+++ head/etc/network.subr	Fri Aug  7 11:43:14 2015	(r286410)
@@ -1249,6 +1249,70 @@ ifscript_down()
 	fi
 }
 
+# wlan_up
+#	Create IEEE802.3 interfaces.
+#
+wlan_up()
+{
+	local _list _iflist wlan parent ifn
+	_list=
+	_iflist=$*
+
+	for wlan in `set | egrep ^wlans_[a-z]+[0-9]+=[a-z]+[0-9]+`; do
+		# Parse wlans_$parent=$ifn
+		wlan=`echo $wlan | sed -E 's/wlans_([a-z]+[0-9]+)=([a-z]+[0-9]+)/\1:\2/'`
+		OIFS=$IFS; IFS=:; set -- $wlan; parent=$1; ifn=$2; IFS=$OIFS
+		case $_iflist in
+		""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn)	;;
+		*)	continue ;;
+		esac
+		# Skip if ${ifn} already exists.
+		if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then
+			continue
+		fi
+		${IFCONFIG_CMD} ${ifn} create wlandev ${parent}
+		if [ $? -eq 0 ]; then
+			_list="$_list $ifn"
+		fi
+	done
+	if [ -n "${_list# }" ]; then
+		echo "Created wlan(4) interfaces: ${_list# }."
+	fi
+	debug "Created wlan(4)s: ${_list# }"
+}
+
+# wlan_down
+#	Destroy IEEE802.3 interfaces.
+#
+wlan_down()
+{
+	local _list _iflist wlan parent ifn
+	_list=
+	_iflist=$*
+
+	for wlan in `set | egrep ^wlans_[a-z]+[0-9]+=[a-z]+[0-9]+`; do
+		# Parse wlans_$parent=$ifn
+		wlan=`echo $wlan | sed -E 's/wlans_([a-z]+[0-9]+)=([a-z]+[0-9]+)/\1:\2/'`
+		OIFS=$IFS; IFS=:; set -- $wlan; parent=$1; ifn=$2; IFS=$OIFS
+		case $_iflist in
+		""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn)	;;
+		*)	continue ;;
+		esac
+		# Skip if ${ifn} doesn't exists.
+		if ! ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then
+			continue
+		fi
+		${IFCONFIG_CMD} -n ${ifn} destroy
+		if [ $? -eq 0 ]; then
+			_list="$_list $ifn"
+		fi
+	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 +1462,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	Fri Aug  7 10:48:52 2015	(r286409)
+++ head/etc/rc.d/netif	Fri Aug  7 11:43:14 2015	(r286410)
@@ -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.3 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	Fri Aug  7 10:48:52 2015	(r286409)
+++ head/sys/dev/ath/ath_rate/sample/sample.c	Fri Aug  7 11:43:14 2015	(r286410)
@@ -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	Fri Aug  7 10:48:52 2015	(r286409)
+++ head/sys/dev/ath/ath_rate/sample/sample.h	Fri Aug  7 11:43:14 2015	(r286410)
@@ -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	Fri Aug  7 10:48:52 2015	(r286409)
+++ head/sys/dev/ath/if_ath.c	Fri Aug  7 11:43:14 2015	(r286410)
@@ -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(void *);
-static void	ath_stop_locked(struct ifnet *);
-static void	ath_stop(struct ifnet *);
+static void	ath_init(struct ath_softc *);
+static void	ath_stop_locked(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 +571,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 +717,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 +861,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 +1182,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 +1195,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 +1299,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 +1306,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 +1330,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_locked(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 +1357,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;
 }
 
@@ -1473,7 +1432,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_ifp->if_softc;
+	struct ath_softc *sc = ic->ic_softc;
 	struct ath_vap *avp;
 	struct ieee80211vap *vap;
 	uint8_t mac[IEEE80211_ADDR_LEN];
@@ -1581,8 +1540,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 +1674,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,8 +1690,7 @@ static void
 ath_vap_delete(struct ieee80211vap *vap)
 {
 	struct ieee80211com *ic = vap->iv_ic;
-	struct ifnet *ifp = ic->ic_ifp;
-	struct ath_softc *sc = ifp->if_softc;
+	struct ath_softc *sc = ic->ic_softc;
 	struct ath_hal *ah = sc->sc_ah;
 	struct ath_vap *avp = ATH_VAP(vap);
 
@@ -1741,7 +1699,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
@@ -1824,7 +1782,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 +1809,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 +1852,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,8 +1894,7 @@ 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;
 
@@ -2015,12 +1967,8 @@ 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_stop(sc);
 	/* NB: no point powering down chip as we're about to reboot */
 }
 
@@ -2031,7 +1979,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 +2017,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);
@@ -2313,7 +2259,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,13 +2279,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(ifp, ATH_RESET_NOLOSS);
+	ath_reset(sc, ATH_RESET_NOLOSS);
 }
 
 static void
 ath_bmiss_vap(struct ieee80211vap *vap)
 {
-	struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+	struct ath_softc *sc = vap->iv_ic->ic_softc;
 
 	/*
 	 * Workaround phantom bmiss interrupts by sanity-checking
@@ -2361,8 +2306,6 @@ 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 */
@@ -2420,7 +2363,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);
@@ -2438,12 +2380,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 */
@@ -2463,8 +2405,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) {
@@ -2478,11 +2419,9 @@ ath_settkipmic(struct ath_softc *sc)
 }
 
 static void
-ath_init(void *arg)
+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;
 
@@ -2501,7 +2440,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_locked(sc);
 
 	/*
 	 * The basic interface to setting the hardware in a good
@@ -2627,7 +2566,7 @@ 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);
 
@@ -2643,14 +2582,10 @@ ath_init(void *arg)
 }
 
 static void
-ath_stop_locked(struct ifnet *ifp)
+ath_stop_locked(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);
 
 	/*
@@ -2658,7 +2593,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
@@ -2680,7 +2615,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);
@@ -2832,12 +2767,11 @@ ath_reset_grablock(struct ath_softc *sc,
  */
 
 static void
-ath_stop(struct ifnet *ifp)
+ath_stop(struct ath_softc *sc)
 {
-	struct ath_softc *sc = ifp->if_softc;
-
+	
 	ATH_LOCK(sc);
-	ath_stop_locked(ifp);
+	ath_stop_locked(sc);
 	ATH_UNLOCK(sc);
 }
 
@@ -2849,10 +2783,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 ath_softc *sc = ifp->if_softc;
-	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
 	HAL_STATUS status;
 	int i;
@@ -3014,15 +2947,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);
@@ -3044,8 +2968,7 @@ 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 = ifp->if_softc;
+	struct ath_softc *sc = ic->ic_softc;
 	struct ath_hal *ah = sc->sc_ah;
 
 	switch (cmd) {
@@ -3060,7 +2983,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 *
@@ -3220,24 +3143,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.
  *
@@ -3245,10 +3156,9 @@ 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_ifp->if_softc;
+	struct ath_softc *sc = ic->ic_softc;
 	struct ieee80211_node *ni;
 	struct mbuf *next;
 	struct ath_buf *bf;
@@ -3263,10 +3173,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? */
 	}
@@ -3306,8 +3213,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;
 	}
@@ -3331,8 +3236,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;
 	}
@@ -3360,11 +3263,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;
 	}
@@ -3386,8 +3284,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;
 	}
 
@@ -3429,12 +3332,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.
@@ -3454,7 +3351,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;
@@ -3538,8 +3435,7 @@ ath_media_change(struct ifnet *ifp)
 static void
 ath_key_update_begin(struct ieee80211vap *vap)
 {
-	struct ifnet *ifp = vap->iv_ic->ic_ifp;
-	struct ath_softc *sc = ifp->if_softc;
+	struct ath_softc *sc =  vap->iv_ic->ic_softc;
 
 	DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__);
 	taskqueue_block(sc->sc_tq);
@@ -3548,8 +3444,7 @@ ath_key_update_begin(struct ieee80211vap
 static void
 ath_key_update_end(struct ieee80211vap *vap)
 {
-	struct ifnet *ifp = vap->iv_ic->ic_ifp;
-	struct ath_softc *sc = ifp->if_softc;
+	struct ath_softc *sc =  vap->iv_ic->ic_softc;
 
 	DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__);
 	taskqueue_unblock(sc->sc_tq);
@@ -3580,32 +3475,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;
 
@@ -3638,7 +3542,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;
 
@@ -3649,15 +3553,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);
@@ -3669,7 +3566,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;
 
@@ -3753,12 +3650,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);
 }
 
 /*
@@ -3768,7 +3664,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)
@@ -3786,7 +3681,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
@@ -4156,7 +4051,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_ifp->if_softc;
+	struct ath_softc *sc = ic->ic_softc;
 	const size_t space = sizeof(struct ath_node) + sc->sc_rc->arc_space;
 	struct ath_node *an;
 
@@ -4183,7 +4078,7 @@ static void
 ath_node_cleanup(struct ieee80211_node *ni)
 {
 	struct ieee80211com *ic = ni->ni_ic;
-	struct ath_softc *sc = ic->ic_ifp->if_softc;
+	struct ath_softc *sc = ic->ic_softc;
 
 	DPRINTF(sc, ATH_DEBUG_NODE, "%s: %6D: an %p\n", __func__,
 	    ni->ni_macaddr, ":", ATH_NODE(ni));
@@ -4198,7 +4093,7 @@ static void
 ath_node_free(struct ieee80211_node *ni)
 {
 	struct ieee80211com *ic = ni->ni_ic;
-	struct ath_softc *sc = ic->ic_ifp->if_softc;
+	struct ath_softc *sc = ic->ic_softc;
 
 	DPRINTF(sc, ATH_DEBUG_NODE, "%s: %6D: an %p\n", __func__,
 	    ni->ni_macaddr, ":", ATH_NODE(ni));
@@ -4210,7 +4105,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_ifp->if_softc;
+	struct ath_softc *sc = ic->ic_softc;
 	struct ath_hal *ah = sc->sc_ah;
 
 	*rssi = ic->ic_node_getrssi(ni);
@@ -4348,8 +4243,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;
@@ -4422,7 +4316,7 @@ ath_txq_update(struct ath_softc *sc, int
 int
 ath_wme_update(struct ieee80211com *ic)
 {
-	struct ath_softc *sc = ic->ic_ifp->if_softc;
+	struct ath_softc *sc = ic->ic_softc;
 
 	return !ath_txq_update(sc, WME_AC_BE) ||
 	    !ath_txq_update(sc, WME_AC_BK) ||
@@ -4473,8 +4367,7 @@ ath_tx_update_stats(struct ath_softc *sc
     struct ath_buf *bf)
 {

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


More information about the svn-src-all mailing list