summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2015-08-07 11:43:14 +0000
committerglebius <glebius@FreeBSD.org>2015-08-07 11:43:14 +0000
commiteb8a90b8596b58df12c5e12dd059fe3c40dad08e (patch)
tree6454e7be9c51af111875a842eec79f4a2ddb1d23
parent94936bfa1d0fc354e859129a11266bc6dac1f589 (diff)
downloadFreeBSD-src-eb8a90b8596b58df12c5e12dd059fe3c40dad08e.zip
FreeBSD-src-eb8a90b8596b58df12c5e12dd059fe3c40dad08e.tar.gz
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
-rw-r--r--etc/network.subr67
-rwxr-xr-xetc/rc.d/netif12
-rw-r--r--sys/dev/ath/ath_rate/sample/sample.c9
-rw-r--r--sys/dev/ath/ath_rate/sample/sample.h3
-rw-r--r--sys/dev/ath/if_ath.c498
-rw-r--r--sys/dev/ath/if_ath_beacon.c6
-rw-r--r--sys/dev/ath/if_ath_debug.h7
-rw-r--r--sys/dev/ath/if_ath_keycache.c6
-rw-r--r--sys/dev/ath/if_ath_misc.h2
-rw-r--r--sys/dev/ath/if_ath_rx.c46
-rw-r--r--sys/dev/ath/if_ath_rx_edma.c10
-rw-r--r--sys/dev/ath/if_ath_sysctl.c12
-rw-r--r--sys/dev/ath/if_ath_tdma.c2
-rw-r--r--sys/dev/ath/if_ath_tx.c31
-rw-r--r--sys/dev/ath/if_ath_tx_edma.c10
-rw-r--r--sys/dev/ath/if_athvar.h7
-rw-r--r--sys/dev/bwi/bwimac.c73
-rw-r--r--sys/dev/bwi/bwiphy.c2
-rw-r--r--sys/dev/bwi/bwirf.c9
-rw-r--r--sys/dev/bwi/if_bwi.c398
-rw-r--r--sys/dev/bwi/if_bwivar.h4
-rw-r--r--sys/dev/bwn/if_bwn.c444
-rw-r--r--sys/dev/bwn/if_bwnvar.h6
-rw-r--r--sys/dev/if_ndis/if_ndis.c998
-rw-r--r--sys/dev/if_ndis/if_ndisvar.h27
-rw-r--r--sys/dev/ipw/if_ipw.c254
-rw-r--r--sys/dev/ipw/if_ipwvar.h4
-rw-r--r--sys/dev/iwi/if_iwi.c306
-rw-r--r--sys/dev/iwi/if_iwivar.h11
-rw-r--r--sys/dev/iwn/if_iwn.c363
-rw-r--r--sys/dev/iwn/if_iwnvar.h8
-rw-r--r--sys/dev/malo/if_malo.c439
-rw-r--r--sys/dev/malo/if_malo.h10
-rw-r--r--sys/dev/mwl/if_mwl.c509
-rw-r--r--sys/dev/mwl/if_mwl_pci.c1
-rw-r--r--sys/dev/mwl/if_mwlvar.h6
-rw-r--r--sys/dev/ral/if_ral_pci.c1
-rw-r--r--sys/dev/ral/rt2560.c307
-rw-r--r--sys/dev/ral/rt2560var.h9
-rw-r--r--sys/dev/ral/rt2661.c289
-rw-r--r--sys/dev/ral/rt2661var.h7
-rw-r--r--sys/dev/ral/rt2860.c274
-rw-r--r--sys/dev/ral/rt2860var.h7
-rw-r--r--sys/dev/usb/wlan/if_rsu.c299
-rw-r--r--sys/dev/usb/wlan/if_rsureg.h9
-rw-r--r--sys/dev/usb/wlan/if_rum.c302
-rw-r--r--sys/dev/usb/wlan/if_rumvar.h7
-rw-r--r--sys/dev/usb/wlan/if_run.c363
-rw-r--r--sys/dev/usb/wlan/if_runvar.h9
-rw-r--r--sys/dev/usb/wlan/if_uath.c308
-rw-r--r--sys/dev/usb/wlan/if_uathvar.h3
-rw-r--r--sys/dev/usb/wlan/if_upgt.c323
-rw-r--r--sys/dev/usb/wlan/if_upgtvar.h6
-rw-r--r--sys/dev/usb/wlan/if_ural.c284
-rw-r--r--sys/dev/usb/wlan/if_uralvar.h7
-rw-r--r--sys/dev/usb/wlan/if_urtw.c338
-rw-r--r--sys/dev/usb/wlan/if_urtwn.c282
-rw-r--r--sys/dev/usb/wlan/if_urtwnreg.h5
-rw-r--r--sys/dev/usb/wlan/if_urtwvar.h6
-rw-r--r--sys/dev/usb/wlan/if_zyd.c299
-rw-r--r--sys/dev/usb/wlan/if_zydreg.h5
-rw-r--r--sys/dev/wi/if_wi.c382
-rw-r--r--sys/dev/wi/if_wi_pccard.c1
-rw-r--r--sys/dev/wi/if_wi_pci.c17
-rw-r--r--sys/dev/wi/if_wivar.h8
-rw-r--r--sys/dev/wpi/if_wpi.c481
-rw-r--r--sys/dev/wpi/if_wpivar.h7
-rw-r--r--sys/dev/wtap/if_wtap.c231
-rw-r--r--sys/dev/wtap/if_wtapvar.h6
-rw-r--r--sys/net80211/ieee80211.c282
-rw-r--r--sys/net80211/ieee80211_ddb.c3
-rw-r--r--sys/net80211/ieee80211_freebsd.c90
-rw-r--r--sys/net80211/ieee80211_ioctl.c71
-rw-r--r--sys/net80211/ieee80211_output.c30
-rw-r--r--sys/net80211/ieee80211_power.c55
-rw-r--r--sys/net80211/ieee80211_proto.c36
-rw-r--r--sys/net80211/ieee80211_proto.h3
-rw-r--r--sys/net80211/ieee80211_regdomain.c3
-rw-r--r--sys/net80211/ieee80211_scan_sta.c26
-rw-r--r--sys/net80211/ieee80211_var.h27
-rw-r--r--tools/tools/iwn/iwnstats/main.c15
81 files changed, 4002 insertions, 6121 deletions
diff --git a/etc/network.subr b/etc/network.subr
index 73ed575..5087a93 100644
--- a/etc/network.subr
+++ b/etc/network.subr
@@ -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
diff --git a/etc/rc.d/netif b/etc/rc.d/netif
index 0915b28..c7b84b9 100755
--- a/etc/rc.d/netif
+++ b/etc/rc.d/netif
@@ -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
diff --git a/sys/dev/ath/ath_rate/sample/sample.c b/sys/dev/ath/ath_rate/sample/sample.c
index 3606e14..815c68b 100644
--- a/sys/dev/ath/ath_rate/sample/sample.c
+++ b/sys/dev/ath/ath_rate/sample/sample.c
@@ -488,8 +488,7 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
#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 *sc, struct ath_node *an,
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;
diff --git a/sys/dev/ath/ath_rate/sample/sample.h b/sys/dev/ath/ath_rate/sample/sample.h
index 1c57dee..5495141 100644
--- a/sys/dev/ath/ath_rate/sample/sample.h
+++ b/sys/dev/ath/ath_rate/sample/sample.h
@@ -134,8 +134,7 @@ static unsigned calc_usecs_unicast_packet(struct ath_softc *sc,
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;
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index 2c935a2b..f40f4fa 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -151,15 +151,15 @@ static struct ieee80211vap *ath_vap_create(struct ieee80211com *,
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, uint8_t *macaddr)
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_softc *sc)
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_softc *sc)
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_softc *sc)
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_softc *sc)
/* 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 char name[IFNAMSIZ], int unit,
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, const char name[IFNAMSIZ], int unit,
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, const char name[IFNAMSIZ], int unit,
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;
+ struct ieee80211com *ic = &sc->sc_ic;
- DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n",
- __func__, ifp->if_flags);
-
- 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 *sc, struct ieee80211_channel *chan)
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, int dowait)
*/
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_TYPE reset_type)
}
}
- /*
- * 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, u_long cmd)
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_type_t btype)
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 mbuf *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 mbuf *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 mbuf *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 mbuf *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 mbuf *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 mbuf *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 *vap)
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 *ic)
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 ac)
{
#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 ac)
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_tx_status *ts,
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) {
@@ -4829,7 +4722,6 @@ 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);
@@ -4850,9 +4742,6 @@ 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)
@@ -4877,7 +4766,6 @@ 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;
@@ -4911,9 +4799,6 @@ ath_tx_proc_q0123(void *arg, int npending)
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)
@@ -4937,7 +4822,6 @@ 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;
@@ -4963,10 +4847,6 @@ 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)
@@ -5277,7 +5157,7 @@ ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
txq->axq_aggr_depth--;
#ifdef ATH_DEBUG
if (sc->sc_debug & ATH_DEBUG_RESET) {
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
int status = 0;
/*
@@ -5422,9 +5302,8 @@ void
ath_legacy_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
{
struct ath_hal *ah = sc->sc_ah;
- struct ifnet *ifp = sc->sc_ifp;
- int i;
struct ath_buf *bf_last;
+ int i;
(void) ath_stoptxdma(sc);
@@ -5476,15 +5355,12 @@ ath_legacy_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
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(ifp->if_l2com,
+ ieee80211_dump_pkt(&sc->sc_ic,
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;
}
@@ -5515,8 +5391,7 @@ ath_chan_change(struct ath_softc *sc, struct ieee80211_channel *chan)
static int
ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
{
- 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 ret = 0;
@@ -5651,9 +5526,6 @@ 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? */
@@ -5669,8 +5541,7 @@ ath_calibrate(void *arg)
{
struct ath_softc *sc = arg;
struct ath_hal *ah = sc->sc_ah;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
HAL_BOOL longCal, isCalDone = AH_TRUE;
HAL_BOOL aniCal, shortCal = AH_FALSE;
int nextcal;
@@ -5796,12 +5667,12 @@ restart:
static void
ath_scan_start(struct ieee80211com *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;
u_int32_t rfilt;
/* XXX calibration timer? */
+ /* XXXGL: is constant ieee80211broadcastaddr a correct choice? */
ATH_LOCK(sc);
sc->sc_scanning = 1;
@@ -5811,18 +5682,17 @@ ath_scan_start(struct ieee80211com *ic)
ATH_PCU_LOCK(sc);
ath_hal_setrxfilter(ah, rfilt);
- ath_hal_setassocid(ah, ifp->if_broadcastaddr, 0);
+ ath_hal_setassocid(ah, ieee80211broadcastaddr, 0);
ATH_PCU_UNLOCK(sc);
DPRINTF(sc, ATH_DEBUG_STATE, "%s: RX filter 0x%x bssid %s aid 0\n",
- __func__, rfilt, ether_sprintf(ifp->if_broadcastaddr));
+ __func__, rfilt, ether_sprintf(ieee80211broadcastaddr));
}
static void
ath_scan_end(struct ieee80211com *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;
u_int32_t rfilt;
@@ -5862,8 +5732,7 @@ ath_scan_end(struct ieee80211com *ic)
static void
ath_update_chw(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct ath_softc *sc = ifp->if_softc;
+ struct ath_softc *sc = ic->ic_softc;
DPRINTF(sc, ATH_DEBUG_STATE, "%s: called\n", __func__);
ath_set_channel(ic);
@@ -5873,8 +5742,7 @@ ath_update_chw(struct ieee80211com *ic)
static void
ath_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct ath_softc *sc = ifp->if_softc;
+ struct ath_softc *sc = ic->ic_softc;
ATH_LOCK(sc);
ath_power_set_power_state(sc, HAL_PM_AWAKE);
@@ -5916,7 +5784,7 @@ static int
ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct ieee80211com *ic = vap->iv_ic;
- struct ath_softc *sc = ic->ic_ifp->if_softc;
+ struct ath_softc *sc = ic->ic_softc;
struct ath_vap *avp = ATH_VAP(vap);
struct ath_hal *ah = sc->sc_ah;
struct ieee80211_node *ni = NULL;
@@ -6252,7 +6120,7 @@ static void
ath_setup_stationkey(struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct ath_softc *sc = vap->iv_ic->ic_softc;
ieee80211_keyix keyix, rxkeyix;
/* XXX should take a locked ref to vap->iv_bss */
@@ -6285,7 +6153,7 @@ ath_newassoc(struct ieee80211_node *ni, int isnew)
{
struct ath_node *an = ATH_NODE(ni);
struct ieee80211vap *vap = ni->ni_vap;
- struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct ath_softc *sc = vap->iv_ic->ic_softc;
const struct ieee80211_txparam *tp = ni->ni_txparms;
an->an_mcastrix = ath_tx_findrix(sc, tp->mcastrate);
@@ -6337,7 +6205,7 @@ static int
ath_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *reg,
int nchans, struct ieee80211_channel chans[])
{
- struct ath_softc *sc = ic->ic_ifp->if_softc;
+ struct ath_softc *sc = ic->ic_softc;
struct ath_hal *ah = sc->sc_ah;
HAL_STATUS status;
@@ -6361,7 +6229,7 @@ static void
ath_getradiocaps(struct ieee80211com *ic,
int maxchans, int *nchans, struct ieee80211_channel chans[])
{
- struct ath_softc *sc = ic->ic_ifp->if_softc;
+ struct ath_softc *sc = ic->ic_softc;
struct ath_hal *ah = sc->sc_ah;
DPRINTF(sc, ATH_DEBUG_REGDOMAIN, "%s: use rd %u cc %d\n",
@@ -6376,8 +6244,7 @@ ath_getradiocaps(struct ieee80211com *ic,
static int
ath_getchannels(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;
@@ -6539,12 +6406,12 @@ static void
ath_watchdog(void *arg)
{
struct ath_softc *sc = arg;
+ struct ieee80211com *ic = &sc->sc_ic;
int do_reset = 0;
ATH_LOCK_ASSERT(sc);
if (sc->sc_wd_timer != 0 && --sc->sc_wd_timer == 0) {
- struct ifnet *ifp = sc->sc_ifp;
uint32_t hangs;
ath_power_set_power_state(sc, HAL_PM_AWAKE);
@@ -6556,7 +6423,7 @@ ath_watchdog(void *arg)
} else
device_printf(sc->sc_dev, "device timeout\n");
do_reset = 1;
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(ic->ic_oerrors, 1);
sc->sc_stats.ast_watchdog++;
ath_power_restore_power_state(sc);
@@ -6582,7 +6449,7 @@ static int
ath_ioctl_ratestats(struct ath_softc *sc, struct ath_rateioctl *rs)
{
struct ath_node *an;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
int error = 0;
@@ -6688,31 +6555,23 @@ bad:
}
#endif /* ATH_DIAGAPI */
-static int
-ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+ath_parent(struct ieee80211com *ic)
{
-#define IS_RUNNING(ifp) \
- ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
- struct ath_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *)data;
- const HAL_RATE_TABLE *rt;
- int error = 0;
+ struct ath_softc *sc = ic->ic_softc;
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (IS_RUNNING(ifp)) {
- /*
- * To avoid rescanning another access point,
- * do not call ath_init() here. Instead,
- * only reflect promisc mode settings.
- */
- ATH_LOCK(sc);
+ ATH_LOCK(sc);
+ if (ic->ic_nrunning > 0) {
+ /*
+ * To avoid rescanning another access point,
+ * do not call ath_init() here. Instead,
+ * only reflect promisc mode settings.
+ */
+ if (sc->sc_running) {
ath_power_set_power_state(sc, HAL_PM_AWAKE);
ath_mode_init(sc);
ath_power_restore_power_state(sc);
- ATH_UNLOCK(sc);
- } else if (ifp->if_flags & IFF_UP) {
+ } else if (!sc->sc_invalid) {
/*
* Beware of being called during attach/detach
* to reset promiscuous mode. In that case we
@@ -6722,26 +6581,40 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
* torn down much of our state. There's
* probably a better way to deal with this.
*/
- if (!sc->sc_invalid)
- ath_init(sc); /* XXX lose error */
- } else {
- ATH_LOCK(sc);
- ath_stop_locked(ifp);
- if (!sc->sc_invalid)
- ath_power_setpower(sc, HAL_PM_FULL_SLEEP);
ATH_UNLOCK(sc);
+ ath_init(sc); /* XXX lose error */
+ return;
}
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGATHSTATS:
+ } else {
+ ath_stop_locked(sc);
+ if (!sc->sc_invalid)
+ ath_power_setpower(sc, HAL_PM_FULL_SLEEP);
+ }
+ ATH_UNLOCK(sc);
+}
+
+static int
+ath_ioctl(struct ieee80211com *ic, u_long cmd, void *data)
+{
+ struct ifreq *ifr = data;
+ struct ath_softc *sc = ic->ic_softc;
+
+ switch (cmd) {
+ case SIOCGATHSTATS: {
+ struct ieee80211vap *vap;
+ struct ifnet *ifp;
+ const HAL_RATE_TABLE *rt;
+
/* NB: embed these numbers to get a consistent view */
- sc->sc_stats.ast_tx_packets = ifp->if_get_counter(ifp,
- IFCOUNTER_OPACKETS);
- sc->sc_stats.ast_rx_packets = ifp->if_get_counter(ifp,
- IFCOUNTER_IPACKETS);
+ sc->sc_stats.ast_tx_packets = 0;
+ sc->sc_stats.ast_rx_packets = 0;
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ ifp = vap->iv_ifp;
+ sc->sc_stats.ast_tx_packets += ifp->if_get_counter(ifp,
+ IFCOUNTER_OPACKETS);
+ sc->sc_stats.ast_rx_packets += ifp->if_get_counter(ifp,
+ IFCOUNTER_IPACKETS);
+ }
sc->sc_stats.ast_tx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgtxrssi);
sc->sc_stats.ast_rx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgrssi);
#ifdef IEEE80211_SUPPORT_TDMA
@@ -6755,10 +6628,13 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
sc->sc_stats.ast_tx_rate |= IEEE80211_RATE_MCS;
return copyout(&sc->sc_stats,
ifr->ifr_data, sizeof (sc->sc_stats));
+ }
case SIOCGATHAGSTATS:
return copyout(&sc->sc_aggr_stats,
ifr->ifr_data, sizeof (sc->sc_aggr_stats));
- case SIOCZATHSTATS:
+ case SIOCZATHSTATS: {
+ int error;
+
error = priv_check(curthread, PRIV_DRIVER);
if (error == 0) {
memset(&sc->sc_stats, 0, sizeof(sc->sc_stats));
@@ -6767,30 +6643,21 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
memset(&sc->sc_intr_stats, 0,
sizeof(sc->sc_intr_stats));
}
- break;
+ return (error);
+ }
#ifdef ATH_DIAGAPI
case SIOCGATHDIAG:
- error = ath_ioctl_diag(sc, (struct ath_diag *) ifr);
- break;
+ return (ath_ioctl_diag(sc, data));
case SIOCGATHPHYERR:
- error = ath_ioctl_phyerr(sc,(struct ath_diag*) ifr);
- break;
+ return (ath_ioctl_phyerr(sc, data));
#endif
case SIOCGATHSPECTRAL:
- error = ath_ioctl_spectral(sc,(struct ath_diag*) ifr);
- break;
+ return (ath_ioctl_spectral(sc, data));
case SIOCGATHNODERATESTATS:
- error = ath_ioctl_ratestats(sc, (struct ath_rateioctl *) ifr);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
+ return (ath_ioctl_ratestats(sc, data));
default:
- error = EINVAL;
- break;
+ return (ENOTTY);
}
- return error;
-#undef IS_RUNNING
}
/*
@@ -6831,8 +6698,7 @@ static void
ath_dfs_tasklet(void *p, int npending)
{
struct ath_softc *sc = (struct ath_softc *) p;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
/*
* If previous processing has found a radar event,
@@ -6864,7 +6730,7 @@ ath_node_powersave(struct ieee80211_node *ni, int enable)
#ifdef ATH_SW_PSQ
struct ath_node *an = ATH_NODE(ni);
struct ieee80211com *ic = ni->ni_ic;
- struct ath_softc *sc = ic->ic_ifp->if_softc;
+ struct ath_softc *sc = ic->ic_softc;
struct ath_vap *avp = ATH_VAP(ni->ni_vap);
/* XXX and no TXQ locks should be held here */
@@ -6931,7 +6797,7 @@ ath_node_set_tim(struct ieee80211_node *ni, int enable)
{
#ifdef ATH_SW_PSQ
struct ieee80211com *ic = ni->ni_ic;
- struct ath_softc *sc = ic->ic_ifp->if_softc;
+ struct ath_softc *sc = ic->ic_softc;
struct ath_node *an = ATH_NODE(ni);
struct ath_vap *avp = ATH_VAP(ni->ni_vap);
int changed = 0;
@@ -7136,7 +7002,7 @@ ath_node_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m)
struct ath_node *an;
struct ath_vap *avp;
struct ieee80211com *ic = ni->ni_ic;
- struct ath_softc *sc = ic->ic_ifp->if_softc;
+ struct ath_softc *sc = ic->ic_softc;
int tid;
/* Just paranoia */
diff --git a/sys/dev/ath/if_ath_beacon.c b/sys/dev/ath/if_ath_beacon.c
index a672c71..41267b3 100644
--- a/sys/dev/ath/if_ath_beacon.c
+++ b/sys/dev/ath/if_ath_beacon.c
@@ -134,7 +134,7 @@ int
ath_beaconq_config(struct ath_softc *sc)
{
#define ATH_EXPONENT_TO_VALUE(v) ((1<<(v))-1)
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ath_hal *ah = sc->sc_ah;
HAL_TXQ_INFO qi;
@@ -464,7 +464,7 @@ ath_beacon_proc(void *arg, int pending)
}
if (sc->sc_stagbeacons) { /* staggered beacons */
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tsftu;
tsftu = ath_hal_gettsf32(ah) >> 10;
@@ -917,7 +917,7 @@ ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap)
((((u_int32_t)(_h)) << 22) | (((u_int32_t)(_l)) >> 10))
#define FUDGE 2
struct ath_hal *ah = sc->sc_ah;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
u_int32_t nexttbtt, intval, tsftu;
u_int32_t nexttbtt_u8, intval_u8;
diff --git a/sys/dev/ath/if_ath_debug.h b/sys/dev/ath/if_ath_debug.h
index 40c0b9a..05d3cf5 100644
--- a/sys/dev/ath/if_ath_debug.h
+++ b/sys/dev/ath/if_ath_debug.h
@@ -91,9 +91,7 @@ enum {
extern uint64_t ath_debug;
-#define IFF_DUMPPKTS(sc, m) \
- ((sc->sc_debug & (m)) || \
- (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
+#define IFF_DUMPPKTS(sc, m) ((sc->sc_debug & (m))
#define DPRINTF(sc, m, fmt, ...) do { \
if (sc->sc_debug & (m)) \
device_printf(sc->sc_dev, fmt, __VA_ARGS__); \
@@ -112,8 +110,7 @@ extern void ath_printtxstatbuf(struct ath_softc *sc, const struct ath_buf *bf,
#else /* ATH_DEBUG */
#define ATH_KTR(_sc, _km, _kf, ...) do { } while (0)
-#define IFF_DUMPPKTS(sc, m) \
- ((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
+#define IFF_DUMPPKTS(sc, m) (0)
#define DPRINTF(sc, m, fmt, ...) do { \
(void) sc; \
} while (0)
diff --git a/sys/dev/ath/if_ath_keycache.c b/sys/dev/ath/if_ath_keycache.c
index fe99f10..b8a77e8 100644
--- a/sys/dev/ath/if_ath_keycache.c
+++ b/sys/dev/ath/if_ath_keycache.c
@@ -425,7 +425,7 @@ int
ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
{
- struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct ath_softc *sc = vap->iv_ic->ic_softc;
/*
* Group key allocation must be handled specially for
@@ -493,7 +493,7 @@ ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
int
ath_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
{
- struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct ath_softc *sc = vap->iv_ic->ic_softc;
struct ath_hal *ah = sc->sc_ah;
const struct ieee80211_cipher *cip = k->wk_cipher;
u_int keyix = k->wk_keyix;
@@ -538,7 +538,7 @@ int
ath_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k,
const u_int8_t mac[IEEE80211_ADDR_LEN])
{
- struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct ath_softc *sc = vap->iv_ic->ic_softc;
return ath_keyset(sc, vap, k, vap->iv_bss);
}
diff --git a/sys/dev/ath/if_ath_misc.h b/sys/dev/ath/if_ath_misc.h
index 711e69e8..ff9a4db 100644
--- a/sys/dev/ath/if_ath_misc.h
+++ b/sys/dev/ath/if_ath_misc.h
@@ -65,7 +65,7 @@ extern void ath_freebuf(struct ath_softc *sc, struct ath_buf *bf);
extern void ath_returnbuf_head(struct ath_softc *sc, struct ath_buf *bf);
extern void ath_returnbuf_tail(struct ath_softc *sc, struct ath_buf *bf);
-extern int ath_reset(struct ifnet *, ATH_RESET_TYPE);
+extern int ath_reset(struct ath_softc *, ATH_RESET_TYPE);
extern void ath_tx_default_comp(struct ath_softc *sc, struct ath_buf *bf,
int fail);
extern void ath_tx_update_ratectrl(struct ath_softc *sc,
diff --git a/sys/dev/ath/if_ath_rx.c b/sys/dev/ath/if_ath_rx.c
index 2779b7a..600d0a5 100644
--- a/sys/dev/ath/if_ath_rx.c
+++ b/sys/dev/ath/if_ath_rx.c
@@ -154,8 +154,7 @@ __FBSDID("$FreeBSD$");
u_int32_t
ath_calcrxfilter(struct ath_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
u_int32_t rfilt;
rfilt = HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST;
@@ -164,7 +163,7 @@ ath_calcrxfilter(struct ath_softc *sc)
if (ic->ic_opmode != IEEE80211_M_STA)
rfilt |= HAL_RX_FILTER_PROBEREQ;
/* XXX ic->ic_monvaps != 0? */
- if (ic->ic_opmode == IEEE80211_M_MONITOR || (ifp->if_flags & IFF_PROMISC))
+ if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_promisc > 0)
rfilt |= HAL_RX_FILTER_PROM;
/*
@@ -330,7 +329,7 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct ath_softc *sc = vap->iv_ic->ic_softc;
uint64_t tsf_beacon_old, tsf_beacon;
uint64_t nexttbtt;
int64_t tsf_delta;
@@ -463,10 +462,9 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
#ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT
static void
-ath_rx_tap_vendor(struct ifnet *ifp, struct mbuf *m,
+ath_rx_tap_vendor(struct ath_softc *sc, struct mbuf *m,
const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf)
{
- struct ath_softc *sc = ifp->if_softc;
/* Fill in the extension bitmap */
sc->sc_rx_th.wr_ext_bitmap = htole32(1 << ATH_RADIOTAP_VENDOR_HEADER);
@@ -529,14 +527,13 @@ ath_rx_tap_vendor(struct ifnet *ifp, struct mbuf *m,
#endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */
static void
-ath_rx_tap(struct ifnet *ifp, struct mbuf *m,
+ath_rx_tap(struct ath_softc *sc, struct mbuf *m,
const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf)
{
#define CHAN_HT20 htole32(IEEE80211_CHAN_HT20)
#define CHAN_HT40U htole32(IEEE80211_CHAN_HT40U)
#define CHAN_HT40D htole32(IEEE80211_CHAN_HT40D)
#define CHAN_HT (CHAN_HT20|CHAN_HT40U|CHAN_HT40D)
- struct ath_softc *sc = ifp->if_softc;
const HAL_RATE_TABLE *rt;
uint8_t rix;
@@ -560,7 +557,7 @@ ath_rx_tap(struct ifnet *ifp, struct mbuf *m,
else if (IEEE80211_IS_CHAN_HT20(sc->sc_curchan))
sc->sc_rx_th.wr_chan_flags |= CHAN_HT20;
} else if (sc->sc_rx_th.wr_rate & IEEE80211_RATE_MCS) { /* HT rate */
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
if ((rs->rs_flags & HAL_RX_2040) == 0)
sc->sc_rx_th.wr_chan_flags |= CHAN_HT20;
@@ -617,8 +614,7 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status,
{
uint64_t rstamp;
int len, type;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
int is_good = 0;
struct ath_rx_edma *re = &sc->sc_rxedma[qtype];
@@ -704,7 +700,7 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status,
rs->rs_keyix-32 : rs->rs_keyix);
}
}
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
rx_error:
/*
* Cleanup any pending partial frame.
@@ -724,9 +720,9 @@ rx_error:
/* NB: bpf needs the mbuf length setup */
len = rs->rs_datalen;
m->m_pkthdr.len = m->m_len = len;
- ath_rx_tap(ifp, m, rs, rstamp, nf);
+ ath_rx_tap(sc, m, rs, rstamp, nf);
#ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT
- ath_rx_tap_vendor(ifp, m, rs, rstamp, nf);
+ ath_rx_tap_vendor(sc, m, rs, rstamp, nf);
#endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */
ieee80211_radiotap_rx_all(ic, m);
}
@@ -749,7 +745,6 @@ rx_accept:
sc->sc_stats.ast_rx_toobig++;
m_freem(re->m_rxpending);
}
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = len;
re->m_rxpending = m;
m = NULL;
@@ -766,10 +761,8 @@ rx_accept:
re->m_rxpending = NULL;
} else {
/*
- * Normal single-descriptor receive; setup
- * the rcvif and packet length.
+ * Normal single-descriptor receive; setup packet length.
*/
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = len;
}
@@ -830,7 +823,6 @@ rx_accept:
rs->rs_antenna |= 0x4;
}
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
sc->sc_stats.ast_ant_rx[rs->rs_antenna]++;
/*
@@ -841,9 +833,9 @@ rx_accept:
* noise setting is filled in above.
*/
if (ieee80211_radiotap_active(ic)) {
- ath_rx_tap(ifp, m, rs, rstamp, nf);
+ ath_rx_tap(sc, m, rs, rstamp, nf);
#ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT
- ath_rx_tap_vendor(ifp, m, rs, rstamp, nf);
+ ath_rx_tap_vendor(sc, m, rs, rstamp, nf);
#endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */
}
@@ -991,10 +983,9 @@ ath_rx_proc(struct ath_softc *sc, int resched)
((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
struct ath_buf *bf;
- struct ifnet *ifp = sc->sc_ifp;
struct ath_hal *ah = sc->sc_ah;
#ifdef IEEE80211_SUPPORT_SUPERG
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
#endif
struct ath_desc *ds;
struct ath_rx_status *rs;
@@ -1189,15 +1180,10 @@ rx_proc_next:
ATH_PCU_UNLOCK(sc);
}
- /* XXX check this inside of IF_LOCK? */
- if (resched && (ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
#ifdef IEEE80211_SUPPORT_SUPERG
+ if (resched)
ieee80211_ff_age_all(ic, 100);
#endif
- if (!IFQ_IS_EMPTY(&ifp->if_snd))
- ath_tx_kick(sc);
- }
-#undef PA2DESC
/*
* Put the hardware to sleep again if we're done with it.
@@ -1219,7 +1205,7 @@ rx_proc_next:
sc->sc_rxproc_cnt--;
ATH_PCU_UNLOCK(sc);
}
-
+#undef PA2DESC
#undef ATH_RX_MAX
/*
diff --git a/sys/dev/ath/if_ath_rx_edma.c b/sys/dev/ath/if_ath_rx_edma.c
index 7aa818f..c3e8d3a 100644
--- a/sys/dev/ath/if_ath_rx_edma.c
+++ b/sys/dev/ath/if_ath_rx_edma.c
@@ -579,9 +579,8 @@ static void
ath_edma_recv_tasklet(void *arg, int npending)
{
struct ath_softc *sc = (struct ath_softc *) arg;
- struct ifnet *ifp = sc->sc_ifp;
#ifdef IEEE80211_SUPPORT_SUPERG
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
#endif
DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: called; npending=%d\n",
@@ -617,14 +616,9 @@ ath_edma_recv_tasklet(void *arg, int npending)
ath_power_restore_power_state(sc);
ATH_UNLOCK(sc);
- /* XXX inside IF_LOCK ? */
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
#ifdef IEEE80211_SUPPORT_SUPERG
- ieee80211_ff_age_all(ic, 100);
+ ieee80211_ff_age_all(ic, 100);
#endif
- if (! IFQ_IS_EMPTY(&ifp->if_snd))
- ath_tx_kick(sc);
- }
if (ath_dfs_tasklet_needed(sc, sc->sc_curchan))
taskqueue_enqueue(sc->sc_tq, &sc->sc_dfstask);
diff --git a/sys/dev/ath/if_ath_sysctl.c b/sys/dev/ath/if_ath_sysctl.c
index eeb8d4b..d8c6bac 100644
--- a/sys/dev/ath/if_ath_sysctl.c
+++ b/sys/dev/ath/if_ath_sysctl.c
@@ -367,7 +367,6 @@ static int
ath_sysctl_tpscale(SYSCTL_HANDLER_ARGS)
{
struct ath_softc *sc = arg1;
- struct ifnet *ifp = sc->sc_ifp;
u_int32_t scale;
int error;
@@ -381,8 +380,7 @@ ath_sysctl_tpscale(SYSCTL_HANDLER_ARGS)
goto finish;
error = !ath_hal_settpscale(sc->sc_ah, scale) ? EINVAL :
- (ifp->if_drv_flags & IFF_DRV_RUNNING) ?
- ath_reset(ifp, ATH_RESET_NOLOSS) : 0;
+ (sc->sc_running) ? ath_reset(sc, ATH_RESET_NOLOSS) : 0;
finish:
ATH_LOCK(sc);
@@ -422,7 +420,6 @@ static int
ath_sysctl_rfkill(SYSCTL_HANDLER_ARGS)
{
struct ath_softc *sc = arg1;
- struct ifnet *ifp = sc->sc_ifp;
struct ath_hal *ah = sc->sc_ah;
u_int rfkill;
int error;
@@ -444,8 +441,7 @@ ath_sysctl_rfkill(SYSCTL_HANDLER_ARGS)
error = EINVAL;
goto finish;
}
- error = (ifp->if_drv_flags & IFF_DRV_RUNNING) ?
- ath_reset(ifp, ATH_RESET_FULL) : 0;
+ error = sc->sc_running ? ath_reset(sc, ATH_RESET_FULL) : 0;
finish:
ATH_LOCK(sc);
@@ -671,8 +667,8 @@ ath_sysctl_intmit(SYSCTL_HANDLER_ARGS)
* doesn't reset ANI related registers, so it'll leave
* things in an inconsistent state.
*/
- if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
- ath_reset(sc->sc_ifp, ATH_RESET_NOLOSS);
+ if (sc->sc_running)
+ ath_reset(sc, ATH_RESET_NOLOSS);
error = 0;
diff --git a/sys/dev/ath/if_ath_tdma.c b/sys/dev/ath/if_ath_tdma.c
index fd23db1..d4c9ccd 100644
--- a/sys/dev/ath/if_ath_tdma.c
+++ b/sys/dev/ath/if_ath_tdma.c
@@ -359,7 +359,7 @@ ath_tdma_update(struct ieee80211_node *ni,
#define TU_TO_TSF(_tu) (((u_int64_t)(_tu)) << 10)
struct ieee80211vap *vap = ni->ni_vap;
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;
const HAL_RATE_TABLE *rt = sc->sc_currates;
u_int64_t tsf, rstamp, nextslot, nexttbtt, nexttbtt_full;
diff --git a/sys/dev/ath/if_ath_tx.c b/sys/dev/ath/if_ath_tx.c
index c15b158..bee6320 100644
--- a/sys/dev/ath/if_ath_tx.c
+++ b/sys/dev/ath/if_ath_tx.c
@@ -1051,8 +1051,7 @@ ath_tx_calc_protection(struct ath_softc *sc, struct ath_buf *bf)
uint16_t flags;
int shortPreamble;
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;
flags = bf->bf_state.bfs_txflags;
rix = bf->bf_state.bfs_rc[0].rix;
@@ -1545,8 +1544,7 @@ ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni,
{
struct ieee80211vap *vap = ni->ni_vap;
struct ath_hal *ah = sc->sc_ah;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
const struct chanAccParams *cap = &ic->ic_wme.wme_chanParams;
int error, iswep, ismcast, isfrag, ismrr;
int keyix, hdrlen, pktlen, try0 = 0;
@@ -2074,8 +2072,7 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
struct ath_buf *bf, struct mbuf *m0,
const struct ieee80211_bpf_params *params)
{
- 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;
struct ieee80211vap *vap = ni->ni_vap;
int error, ismcast, ismrr;
@@ -2340,8 +2337,7 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct ath_softc *sc = ifp->if_softc;
+ struct ath_softc *sc = ic->ic_softc;
struct ath_buf *bf;
struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
int error = 0;
@@ -2364,10 +2360,9 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
ATH_TX_LOCK(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) {
- DPRINTF(sc, ATH_DEBUG_XMIT, "%s: discard frame, %s", __func__,
- (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ?
- "!running" : "invalid");
+ if (!sc->sc_running || sc->sc_invalid) {
+ DPRINTF(sc, ATH_DEBUG_XMIT, "%s: discard frame, r/i: %d/%d",
+ __func__, sc->sc_running, sc->sc_invalid);
m_freem(m);
error = ENETDOWN;
goto bad;
@@ -2424,7 +2419,6 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
}
}
sc->sc_wd_timer = 5;
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
sc->sc_stats.ast_tx_raw++;
/*
@@ -2473,7 +2467,6 @@ bad:
badbad:
ATH_KTR(sc, ATH_KTR_TX, 2, "ath_raw_xmit: bad0: m=%p, params=%p",
m, params);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
sc->sc_stats.ast_tx_raw_fail++;
ieee80211_free_node(ni);
@@ -5731,7 +5724,7 @@ int
ath_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
int dialogtoken, int baparamset, int batimeout)
{
- struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct ath_softc *sc = ni->ni_ic->ic_softc;
int tid = tap->txa_tid;
struct ath_node *an = ATH_NODE(ni);
struct ath_tid *atid = &an->an_tid[tid];
@@ -5809,7 +5802,7 @@ int
ath_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
int status, int code, int batimeout)
{
- struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct ath_softc *sc = ni->ni_ic->ic_softc;
int tid = tap->txa_tid;
struct ath_node *an = ATH_NODE(ni);
struct ath_tid *atid = &an->an_tid[tid];
@@ -5856,7 +5849,7 @@ ath_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
void
ath_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
{
- struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct ath_softc *sc = ni->ni_ic->ic_softc;
int tid = tap->txa_tid;
struct ath_node *an = ATH_NODE(ni);
struct ath_tid *atid = &an->an_tid[tid];
@@ -5991,7 +5984,7 @@ void
ath_bar_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
int status)
{
- struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct ath_softc *sc = ni->ni_ic->ic_softc;
int tid = tap->txa_tid;
struct ath_node *an = ATH_NODE(ni);
struct ath_tid *atid = &an->an_tid[tid];
@@ -6064,7 +6057,7 @@ void
ath_addba_response_timeout(struct ieee80211_node *ni,
struct ieee80211_tx_ampdu *tap)
{
- struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct ath_softc *sc = ni->ni_ic->ic_softc;
int tid = tap->txa_tid;
struct ath_node *an = ATH_NODE(ni);
struct ath_tid *atid = &an->an_tid[tid];
diff --git a/sys/dev/ath/if_ath_tx_edma.c b/sys/dev/ath/if_ath_tx_edma.c
index 7d14920..fdc2b4b 100644
--- a/sys/dev/ath/if_ath_tx_edma.c
+++ b/sys/dev/ath/if_ath_tx_edma.c
@@ -537,7 +537,6 @@ ath_edma_dma_txteardown(struct ath_softc *sc)
static void
ath_edma_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
{
- struct ifnet *ifp = sc->sc_ifp;
int i;
DPRINTF(sc, ATH_DEBUG_RESET, "%s: called\n", __func__);
@@ -579,9 +578,6 @@ ath_edma_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
/* XXX dump out the frames */
- IF_LOCK(&ifp->if_snd);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- IF_UNLOCK(&ifp->if_snd);
sc->sc_wd_timer = 0;
}
@@ -834,12 +830,6 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched)
sc->sc_wd_timer = 0;
- if (idx > 0) {
- IF_LOCK(&sc->sc_ifp->if_snd);
- sc->sc_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- IF_UNLOCK(&sc->sc_ifp->if_snd);
- }
-
/* Kick software scheduler */
/*
* XXX It's inefficient to do this if the FIFO queue is full,
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index 5c5e6cd..2e71ff6 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -555,8 +555,8 @@ struct ath_tx_methods {
};
struct ath_softc {
- struct ifnet *sc_ifp; /* interface common */
- struct ath_stats sc_stats; /* interface statistics */
+ struct ieee80211com sc_ic;
+ struct ath_stats sc_stats; /* device statistics */
struct ath_tx_aggr_stats sc_aggr_stats;
struct ath_intr_stats sc_intr_stats;
uint64_t sc_debug;
@@ -650,7 +650,8 @@ struct ath_softc {
/*
* Second set of flags.
*/
- u_int32_t sc_use_ent : 1,
+ u_int32_t sc_running : 1, /* initialized */
+ sc_use_ent : 1,
sc_rx_stbc : 1,
sc_tx_stbc : 1,
sc_hasenforcetxop : 1, /* support enforce TxOP */
diff --git a/sys/dev/bwi/bwimac.c b/sys/dev/bwi/bwimac.c
index f39ef44..baad7fe 100644
--- a/sys/dev/bwi/bwimac.c
+++ b/sys/dev/bwi/bwimac.c
@@ -832,11 +832,11 @@ bwi_fwimage_is_valid(struct bwi_softc *sc, const struct firmware *fw,
uint8_t fw_type)
{
const struct bwi_fwhdr *hdr;
- struct ifnet *ifp = sc->sc_ifp;
if (fw->datasize < sizeof(*hdr)) {
- if_printf(ifp, "invalid firmware (%s): invalid size %zu\n",
- fw->name, fw->datasize);
+ device_printf(sc->sc_dev,
+ "invalid firmware (%s): invalid size %zu\n",
+ fw->name, fw->datasize);
return 0;
}
@@ -847,25 +847,26 @@ bwi_fwimage_is_valid(struct bwi_softc *sc, const struct firmware *fw,
* Don't verify IV's size, it has different meaning
*/
if (be32toh(hdr->fw_size) != fw->datasize - sizeof(*hdr)) {
- if_printf(ifp, "invalid firmware (%s): size mismatch, "
- "fw %u, real %zu\n", fw->name,
- be32toh(hdr->fw_size),
- fw->datasize - sizeof(*hdr));
+ device_printf(sc->sc_dev,
+ "invalid firmware (%s): size mismatch, "
+ "fw %u, real %zu\n", fw->name,
+ be32toh(hdr->fw_size), fw->datasize - sizeof(*hdr));
return 0;
}
}
if (hdr->fw_type != fw_type) {
- if_printf(ifp, "invalid firmware (%s): type mismatch, "
- "fw \'%c\', target \'%c\'\n", fw->name,
- hdr->fw_type, fw_type);
+ device_printf(sc->sc_dev,
+ "invalid firmware (%s): type mismatch, "
+ "fw \'%c\', target \'%c\'\n", fw->name,
+ hdr->fw_type, fw_type);
return 0;
}
if (hdr->fw_gen != BWI_FW_GEN_1) {
- if_printf(ifp, "invalid firmware (%s): wrong generation, "
- "fw %d, target %d\n", fw->name,
- hdr->fw_gen, BWI_FW_GEN_1);
+ device_printf(sc->sc_dev,
+ "invalid firmware (%s): wrong generation, "
+ "fw %d, target %d\n", fw->name, hdr->fw_gen, BWI_FW_GEN_1);
return 0;
}
return 1;
@@ -1002,7 +1003,6 @@ static int
bwi_mac_fw_load(struct bwi_mac *mac)
{
struct bwi_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
const uint32_t *fw;
uint16_t fw_rev;
int fw_len, i;
@@ -1057,7 +1057,8 @@ bwi_mac_fw_load(struct bwi_mac *mac)
DELAY(10);
}
if (i == NRETRY) {
- if_printf(ifp, "firmware (ucode&pcm) loading timed out\n");
+ device_printf(sc->sc_dev,
+ "firmware (ucode&pcm) loading timed out\n");
return ETIMEDOUT;
}
@@ -1067,12 +1068,14 @@ bwi_mac_fw_load(struct bwi_mac *mac)
fw_rev = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWREV);
if (fw_rev > BWI_FW_VERSION3_REVMAX) {
- if_printf(ifp, "firmware version 4 is not supported yet\n");
+ device_printf(sc->sc_dev,
+ "firmware version 4 is not supported yet\n");
return ENODEV;
}
- if_printf(ifp, "firmware rev 0x%04x, patch level 0x%04x\n", fw_rev,
- MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV));
+ device_printf(sc->sc_dev,
+ "firmware rev 0x%04x, patch level 0x%04x\n", fw_rev,
+ MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV));
return 0;
}
@@ -1132,7 +1135,6 @@ static int
bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw)
{
struct bwi_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
const struct bwi_fwhdr *hdr;
const struct bwi_fw_iv *iv;
int n, i, iv_img_size;
@@ -1155,7 +1157,7 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw)
int sz = 0;
if (iv_img_size < sizeof(iv->iv_ofs)) {
- if_printf(ifp, "invalid IV image, ofs\n");
+ device_printf(sc->sc_dev, "invalid IV image, ofs\n");
return EINVAL;
}
iv_img_size -= sizeof(iv->iv_ofs);
@@ -1165,7 +1167,7 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw)
ofs = __SHIFTOUT(iv_ofs, BWI_FW_IV_OFS_MASK);
if (ofs >= 0x1000) {
- if_printf(ifp, "invalid ofs (0x%04x) "
+ device_printf(sc->sc_dev, "invalid ofs (0x%04x) "
"for %dth iv\n", ofs, i);
return EINVAL;
}
@@ -1174,7 +1176,8 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw)
uint32_t val32;
if (iv_img_size < sizeof(iv->iv_val.val32)) {
- if_printf(ifp, "invalid IV image, val32\n");
+ device_printf(sc->sc_dev,
+ "invalid IV image, val32\n");
return EINVAL;
}
iv_img_size -= sizeof(iv->iv_val.val32);
@@ -1186,7 +1189,8 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw)
uint16_t val16;
if (iv_img_size < sizeof(iv->iv_val.val16)) {
- if_printf(ifp, "invalid IV image, val16\n");
+ device_printf(sc->sc_dev,
+ "invalid IV image, val16\n");
return EINVAL;
}
iv_img_size -= sizeof(iv->iv_val.val16);
@@ -1200,7 +1204,8 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw)
}
if (iv_img_size != 0) {
- if_printf(ifp, "invalid IV image, size left %d\n", iv_img_size);
+ device_printf(sc->sc_dev, "invalid IV image, size left %d\n",
+ iv_img_size);
return EINVAL;
}
return 0;
@@ -1209,19 +1214,19 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw)
static int
bwi_mac_fw_init(struct bwi_mac *mac)
{
- struct ifnet *ifp = mac->mac_sc->sc_ifp;
+ device_t dev = mac->mac_sc->sc_dev;
int error;
error = bwi_mac_fw_load_iv(mac, mac->mac_iv);
if (error) {
- if_printf(ifp, "load IV failed\n");
+ device_printf(dev, "load IV failed\n");
return error;
}
if (mac->mac_iv_ext != NULL) {
error = bwi_mac_fw_load_iv(mac, mac->mac_iv_ext);
if (error)
- if_printf(ifp, "load ExtIV failed\n");
+ device_printf(dev, "load ExtIV failed\n");
}
return error;
}
@@ -1230,8 +1235,7 @@ static void
bwi_mac_opmode_init(struct bwi_mac *mac)
{
struct bwi_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t mac_status;
uint16_t pre_tbtt;
@@ -1280,7 +1284,7 @@ bwi_mac_opmode_init(struct bwi_mac *mac)
break;
}
- if (ic->ic_ifp->if_flags & IFF_PROMISC)
+ if (ic->ic_promisc > 0)
mac_status |= BWI_MAC_STATUS_PROMISC;
CSR_WRITE_4(sc, BWI_MAC_STATUS, mac_status);
@@ -1331,8 +1335,7 @@ bwi_mac_bss_param_init(struct bwi_mac *mac)
{
struct bwi_softc *sc = mac->mac_sc;
struct bwi_phy *phy = &mac->mac_phy;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
const struct ieee80211_rate_table *rt;
struct bwi_retry_lim lim;
uint16_t cw_min;
@@ -1915,8 +1918,7 @@ static void
bwi_mac_lock(struct bwi_mac *mac)
{
struct bwi_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
KASSERT((mac->mac_flags & BWI_MAC_F_LOCKED) == 0,
("mac_flags 0x%x", mac->mac_flags));
@@ -1939,8 +1941,7 @@ static void
bwi_mac_unlock(struct bwi_mac *mac)
{
struct bwi_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
KASSERT(mac->mac_flags & BWI_MAC_F_LOCKED,
("mac_flags 0x%x", mac->mac_flags));
diff --git a/sys/dev/bwi/bwiphy.c b/sys/dev/bwi/bwiphy.c
index 1057a83..60d6bf5 100644
--- a/sys/dev/bwi/bwiphy.c
+++ b/sys/dev/bwi/bwiphy.c
@@ -429,7 +429,7 @@ static void
bwi_phy_init_11b_rev2(struct bwi_mac *mac)
{
/* TODO:11B */
- if_printf(mac->mac_sc->sc_ifp,
+ device_printf(mac->mac_sc->sc_dev,
"%s is not implemented yet\n", __func__);
}
diff --git a/sys/dev/bwi/bwirf.c b/sys/dev/bwi/bwirf.c
index cd0723a..615e6df 100644
--- a/sys/dev/bwi/bwirf.c
+++ b/sys/dev/bwi/bwirf.c
@@ -1260,7 +1260,6 @@ static void
bwi_rf_lo_update_11g(struct bwi_mac *mac)
{
struct bwi_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
struct bwi_rf *rf = &mac->mac_rf;
struct bwi_phy *phy = &mac->mac_phy;
struct bwi_tpctl *tpctl = &mac->mac_tpctl;
@@ -1329,7 +1328,7 @@ bwi_rf_lo_update_11g(struct bwi_mac *mac)
PHY_WRITE(mac, 0x812, 0xb2);
}
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((sc->sc_flags & BWI_F_RUNNING) == 0)
tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac);
PHY_WRITE(mac, 0x80f, 0x8078);
@@ -1352,7 +1351,7 @@ bwi_rf_lo_update_11g(struct bwi_mac *mac)
PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0);
}
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((sc->sc_flags & BWI_F_RUNNING) == 0)
tpctl = NULL;
bwi_rf_lo_adjust(mac, tpctl);
@@ -1462,7 +1461,7 @@ _bwi_rf_lo_update_11g(struct bwi_mac *mac, uint16_t orig_rf7a)
static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] =
{ 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 };
- struct ifnet *ifp = mac->mac_sc->sc_ifp;
+ struct bwi_softc *sc = mac->mac_sc;
struct bwi_rf_lo lo_save, *lo;
uint8_t devi_ctrl = 0;
int idx, adj_rf7a = 0;
@@ -1476,7 +1475,7 @@ _bwi_rf_lo_update_11g(struct bwi_mac *mac, uint16_t orig_rf7a)
for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) {
uint16_t tp_ctrl2, rf7a;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ if ((sc->sc_flags & BWI_F_RUNNING) == 0) {
if (idx == 0) {
bzero(&lo_save, sizeof(lo_save));
} else if (init_rf_atten < 0) {
diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c
index ad41bc6..741f5f1 100644
--- a/sys/dev/bwi/if_bwi.c
+++ b/sys/dev/bwi/if_bwi.c
@@ -102,10 +102,10 @@ static struct ieee80211vap *bwi_vap_create(struct ieee80211com *,
const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN]);
static void bwi_vap_delete(struct ieee80211vap *);
-static void bwi_init(void *);
-static int bwi_ioctl(struct ifnet *, u_long, caddr_t);
-static void bwi_start(struct ifnet *);
-static void bwi_start_locked(struct ifnet *);
+static void bwi_init(struct bwi_softc *);
+static void bwi_parent(struct ieee80211com *);
+static int bwi_transmit(struct ieee80211com *, struct mbuf *);
+static void bwi_start_locked(struct bwi_softc *);
static int bwi_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static void bwi_watchdog(void *);
@@ -352,14 +352,12 @@ bwi_setup_desc32(struct bwi_softc *sc, struct bwi_desc32 *desc_array,
int
bwi_attach(struct bwi_softc *sc)
{
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
device_t dev = sc->sc_dev;
- struct ifnet *ifp;
struct bwi_mac *mac;
struct bwi_phy *phy;
int i, error;
uint8_t bands;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
BWI_LOCK_INIT(sc);
@@ -371,8 +369,8 @@ bwi_attach(struct bwi_softc *sc)
taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
device_get_nameunit(dev));
TASK_INIT(&sc->sc_restart_task, 0, bwi_restart, sc);
-
callout_init_mtx(&sc->sc_calib_ch, &sc->sc_mtx, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
/*
* Initialize sysctl variables
@@ -450,25 +448,6 @@ bwi_attach(struct bwi_softc *sc)
if (error)
goto fail;
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(dev, "can not if_alloc()\n");
- error = ENOSPC;
- goto fail;
- }
- ic = ifp->if_l2com;
-
- /* set these up early for if_printf use */
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
-
- ifp->if_softc = sc;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = bwi_init;
- ifp->if_ioctl = bwi_ioctl;
- ifp->if_start = bwi_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
callout_init_mtx(&sc->sc_watchdog_timer, &sc->sc_mtx, 0);
/*
@@ -485,13 +464,13 @@ bwi_attach(struct bwi_softc *sc)
setbit(&bands, IEEE80211_MODE_11G);
}
- bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, macaddr);
- if (IEEE80211_IS_MULTICAST(macaddr)) {
- bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, macaddr);
- if (IEEE80211_IS_MULTICAST(macaddr)) {
+ bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, ic->ic_macaddr);
+ if (IEEE80211_IS_MULTICAST(ic->ic_macaddr)) {
+ bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, ic->ic_macaddr);
+ if (IEEE80211_IS_MULTICAST(ic->ic_macaddr)) {
device_printf(dev,
"invalid MAC address: %6D\n",
- macaddr, ":");
+ ic->ic_macaddr, ":");
}
}
} else if (phy->phy_mode == IEEE80211_MODE_11A) {
@@ -510,7 +489,6 @@ bwi_attach(struct bwi_softc *sc)
/* XXX use locale */
ieee80211_init_channels(ic, NULL, &bands);
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_caps = IEEE80211_C_STA |
@@ -520,7 +498,7 @@ bwi_attach(struct bwi_softc *sc)
IEEE80211_C_BGSCAN |
IEEE80211_C_MONITOR;
ic->ic_opmode = IEEE80211_M_STA;
- ieee80211_ifattach(ic, macaddr);
+ ieee80211_ifattach(ic);
ic->ic_headroom = sizeof(struct bwi_txbuf_hdr);
@@ -532,6 +510,8 @@ bwi_attach(struct bwi_softc *sc)
ic->ic_scan_start = bwi_scan_start;
ic->ic_scan_end = bwi_scan_end;
ic->ic_set_channel = bwi_set_channel;
+ ic->ic_transmit = bwi_transmit;
+ ic->ic_parent = bwi_parent;
sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
@@ -577,8 +557,7 @@ fail:
int
bwi_detach(struct bwi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
int i;
bwi_stop(sc, 1);
@@ -590,8 +569,8 @@ bwi_detach(struct bwi_softc *sc)
for (i = 0; i < sc->sc_nmac; ++i)
bwi_mac_detach(&sc->sc_mac[i]);
bwi_dma_free(sc);
- if_free(ifp);
taskqueue_free(sc->sc_tq);
+ mbufq_drain(&sc->sc_snd);
BWI_LOCK_DESTROY(sc);
@@ -609,14 +588,11 @@ bwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return NULL;
- bvp = (struct bwi_vap *) malloc(sizeof(struct bwi_vap),
- M_80211_VAP, M_WAITOK | M_ZERO);
- if (bvp == NULL)
- return NULL;
+ bvp = malloc(sizeof(struct bwi_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &bvp->bv_vap;
/* enable s/w bmiss handling for sta mode */
ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
+ flags | IEEE80211_CLONE_NOBEACONS, bssid);
/* override default methods */
bvp->bv_newstate = vap->iv_newstate;
@@ -627,7 +603,8 @@ bwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_init(vap);
/* complete setup */
- ieee80211_vap_attach(vap, bwi_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, bwi_media_change, ieee80211_media_status,
+ mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -651,9 +628,8 @@ bwi_suspend(struct bwi_softc *sc)
void
bwi_resume(struct bwi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- if (ifp->if_flags & IFF_UP)
+ if (sc->sc_ic.ic_nrunning > 0)
bwi_init(sc);
}
@@ -1217,27 +1193,26 @@ bwi_set_clock_delay(struct bwi_softc *sc)
}
static void
-bwi_init(void *xsc)
+bwi_init(struct bwi_softc *sc)
{
- struct bwi_softc *sc = xsc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
BWI_LOCK(sc);
bwi_init_statechg(sc, 1);
BWI_UNLOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_flags & BWI_F_RUNNING)
ieee80211_start_all(ic); /* start all vap's */
}
static void
bwi_init_statechg(struct bwi_softc *sc, int statechg)
{
- struct ifnet *ifp = sc->sc_ifp;
struct bwi_mac *mac;
int error;
+ BWI_ASSERT_LOCKED(sc);
+
bwi_stop_locked(sc, statechg);
bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
@@ -1247,20 +1222,21 @@ bwi_init_statechg(struct bwi_softc *sc, int statechg)
mac = &sc->sc_mac[0];
error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL);
if (error) {
- if_printf(ifp, "%s: error %d on regwin switch\n",
+ device_printf(sc->sc_dev, "%s: error %d on regwin switch\n",
__func__, error);
goto bad;
}
error = bwi_mac_init(mac);
if (error) {
- if_printf(ifp, "%s: error %d on MAC init\n", __func__, error);
+ device_printf(sc->sc_dev, "%s: error %d on MAC init\n",
+ __func__, error);
goto bad;
}
bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN);
bwi_set_bssid(sc, bwi_zero_addr); /* Clear BSSID */
- bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, IF_LLADDR(ifp));
+ bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, sc->sc_ic.ic_macaddr);
bwi_mac_reset_hwkeys(mac);
@@ -1278,7 +1254,8 @@ bwi_init_statechg(struct bwi_softc *sc, int statechg)
CSR_READ_4(sc, BWI_TXSTATUS1);
}
if (i == NRETRY)
- if_printf(ifp, "%s: can't drain TX status\n", __func__);
+ device_printf(sc->sc_dev,
+ "%s: can't drain TX status\n", __func__);
#undef NRETRY
}
@@ -1288,14 +1265,14 @@ bwi_init_statechg(struct bwi_softc *sc, int statechg)
/* Start MAC */
error = bwi_mac_start(mac);
if (error) {
- if_printf(ifp, "%s: error %d starting MAC\n", __func__, error);
+ device_printf(sc->sc_dev, "%s: error %d starting MAC\n",
+ __func__, error);
goto bad;
}
/* Clear stop flag before enabling interrupt */
sc->sc_flags &= ~BWI_F_STOP;
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= BWI_F_RUNNING;
callout_reset(&sc->sc_watchdog_timer, hz, bwi_watchdog, sc);
/* Enable intrs */
@@ -1305,135 +1282,110 @@ bad:
bwi_stop_locked(sc, 1);
}
-static int
-bwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+bwi_parent(struct ieee80211com *ic)
{
-#define IS_RUNNING(ifp) \
- ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
- struct bwi_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
+ struct bwi_softc *sc = ic->ic_softc;
+ int startall = 0;
- switch (cmd) {
- case SIOCSIFFLAGS:
- BWI_LOCK(sc);
- if (IS_RUNNING(ifp)) {
- struct bwi_mac *mac;
- int promisc = -1;
-
- KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
- ("current regwin type %d",
- sc->sc_cur_regwin->rw_type));
- mac = (struct bwi_mac *)sc->sc_cur_regwin;
-
- if ((ifp->if_flags & IFF_PROMISC) &&
- (sc->sc_flags & BWI_F_PROMISC) == 0) {
- promisc = 1;
- sc->sc_flags |= BWI_F_PROMISC;
- } else if ((ifp->if_flags & IFF_PROMISC) == 0 &&
- (sc->sc_flags & BWI_F_PROMISC)) {
- promisc = 0;
- sc->sc_flags &= ~BWI_F_PROMISC;
- }
+ BWI_LOCK(sc);
+ if (ic->ic_nrunning > 0) {
+ struct bwi_mac *mac;
+ int promisc = -1;
- if (promisc >= 0)
- bwi_mac_set_promisc(mac, promisc);
- }
+ KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
+ ("current regwin type %d",
+ sc->sc_cur_regwin->rw_type));
+ mac = (struct bwi_mac *)sc->sc_cur_regwin;
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- bwi_init_statechg(sc, 1);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- bwi_stop_locked(sc, 1);
+ if (ic->ic_promisc > 0 && (sc->sc_flags & BWI_F_PROMISC) == 0) {
+ promisc = 1;
+ sc->sc_flags |= BWI_F_PROMISC;
+ } else if (ic->ic_promisc == 0 &&
+ (sc->sc_flags & BWI_F_PROMISC) != 0) {
+ promisc = 0;
+ sc->sc_flags &= ~BWI_F_PROMISC;
}
- BWI_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
+
+ if (promisc >= 0)
+ bwi_mac_set_promisc(mac, promisc);
}
- return error;
-#undef IS_RUNNING
+ if (ic->ic_nrunning > 0) {
+ if ((sc->sc_flags & BWI_F_RUNNING) == 0) {
+ bwi_init_statechg(sc, 1);
+ startall = 1;
+ }
+ } else if (sc->sc_flags & BWI_F_RUNNING)
+ bwi_stop_locked(sc, 1);
+ BWI_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
-static void
-bwi_start(struct ifnet *ifp)
+static int
+bwi_transmit(struct ieee80211com *ic, struct mbuf *m)
{
- struct bwi_softc *sc = ifp->if_softc;
+ struct bwi_softc *sc = ic->ic_softc;
+ int error;
BWI_LOCK(sc);
- bwi_start_locked(ifp);
+ if ((sc->sc_flags & BWI_F_RUNNING) == 0) {
+ BWI_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ BWI_UNLOCK(sc);
+ return (error);
+ }
+ bwi_start_locked(sc);
BWI_UNLOCK(sc);
+ return (0);
}
static void
-bwi_start_locked(struct ifnet *ifp)
+bwi_start_locked(struct bwi_softc *sc)
{
- struct bwi_softc *sc = ifp->if_softc;
struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
- struct ieee80211_key *k;
struct mbuf *m;
int trans, idx;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
+ BWI_ASSERT_LOCKED(sc);
trans = 0;
idx = tbd->tbd_idx;
- while (tbd->tbd_buf[idx].tb_mbuf == NULL) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */
- if (m == NULL)
- break;
-
+ while (tbd->tbd_buf[idx].tb_mbuf == NULL &&
+ tbd->tbd_used + BWI_TX_NSPRDESC < BWI_TX_NDESC &&
+ (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
wh = mtod(m, struct ieee80211_frame *);
- if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
- k = ieee80211_crypto_encap(ni, m);
- if (k == NULL) {
- ieee80211_free_node(ni);
- m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- continue;
- }
+ if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) != 0 &&
+ ieee80211_crypto_encap(ni, m) == NULL) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
+ ieee80211_free_node(ni);
+ m_freem(m);
+ continue;
}
- wh = NULL; /* Catch any invalid use */
-
if (bwi_encap(sc, idx, m, ni) != 0) {
/* 'm' is freed in bwi_encap() if we reach here */
- if (ni != NULL)
+ if (ni != NULL) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ } else
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
continue;
}
-
trans = 1;
tbd->tbd_used++;
idx = (idx + 1) % BWI_TX_NDESC;
-
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
- if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
}
- tbd->tbd_idx = idx;
+ tbd->tbd_idx = idx;
if (trans)
sc->sc_tx_timer = 5;
}
@@ -1443,13 +1395,12 @@ bwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct bwi_softc *sc = ifp->if_softc;
+ struct bwi_softc *sc = ic->ic_softc;
/* XXX wme? */
struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
int idx, error;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ if ((sc->sc_flags & BWI_F_RUNNING) == 0) {
ieee80211_free_node(ni);
m_freem(m);
return ENETDOWN;
@@ -1472,16 +1423,12 @@ bwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
error = bwi_encap_raw(sc, idx, m, ni, params);
}
if (error == 0) {
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- if (++tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC)
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ tbd->tbd_used++;
tbd->tbd_idx = (idx + 1) % BWI_TX_NDESC;
sc->sc_tx_timer = 5;
- } else {
+ } else
/* NB: m is reclaimed on encap failure */
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- }
BWI_UNLOCK(sc);
return error;
}
@@ -1490,14 +1437,12 @@ static void
bwi_watchdog(void *arg)
{
struct bwi_softc *sc;
- struct ifnet *ifp;
sc = arg;
- ifp = sc->sc_ifp;
BWI_ASSERT_LOCKED(sc);
if (sc->sc_tx_timer != 0 && --sc->sc_tx_timer == 0) {
- if_printf(ifp, "watchdog timeout\n");
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ device_printf(sc->sc_dev, "watchdog timeout\n");
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task);
}
callout_reset(&sc->sc_watchdog_timer, hz, bwi_watchdog, sc);
@@ -1514,7 +1459,6 @@ bwi_stop(struct bwi_softc *sc, int statechg)
static void
bwi_stop_locked(struct bwi_softc *sc, int statechg)
{
- struct ifnet *ifp = sc->sc_ifp;
struct bwi_mac *mac;
int i, error, pwr_off = 0;
@@ -1525,7 +1469,7 @@ bwi_stop_locked(struct bwi_softc *sc, int statechg)
sc->sc_led_blinking = 0;
sc->sc_flags |= BWI_F_STOP;
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ if (sc->sc_flags & BWI_F_RUNNING) {
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
("current regwin type %d", sc->sc_cur_regwin->rw_type));
mac = (struct bwi_mac *)sc->sc_cur_regwin;
@@ -1557,14 +1501,13 @@ bwi_stop_locked(struct bwi_softc *sc, int statechg)
sc->sc_tx_timer = 0;
callout_stop(&sc->sc_watchdog_timer);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_flags &= ~BWI_F_RUNNING;
}
void
bwi_intr(void *xsc)
{
struct bwi_softc *sc = xsc;
- struct ifnet *ifp = sc->sc_ifp;
struct bwi_mac *mac;
uint32_t intr_status;
uint32_t txrx_intr_status[BWI_TXRX_NRING];
@@ -1572,7 +1515,7 @@ bwi_intr(void *xsc)
BWI_LOCK(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
+ if ((sc->sc_flags & BWI_F_RUNNING) == 0 ||
(sc->sc_flags & BWI_F_STOP)) {
BWI_UNLOCK(sc);
return;
@@ -1615,7 +1558,7 @@ bwi_intr(void *xsc)
i, txrx_intr_status[i]);
if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) {
- if_printf(ifp,
+ device_printf(sc->sc_dev,
"%s: intr fatal TX/RX (%d) error 0x%08x\n",
__func__, i, txrx_intr_status[i]);
txrx_error = 1;
@@ -1653,7 +1596,8 @@ bwi_intr(void *xsc)
*/
if (intr_status & BWI_INTR_PHY_TXERR) {
if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) {
- if_printf(ifp, "%s: intr PHY TX error\n", __func__);
+ device_printf(sc->sc_dev, "%s: intr PHY TX error\n",
+ __func__);
taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task);
BWI_UNLOCK(sc);
return;
@@ -1668,7 +1612,7 @@ bwi_intr(void *xsc)
bwi_mac_config_ps(mac);
if (intr_status & BWI_INTR_EO_ATIM)
- if_printf(ifp, "EO_ATIM\n");
+ device_printf(sc->sc_dev, "EO_ATIM\n");
if (intr_status & BWI_INTR_PMQ) {
for (;;) {
@@ -1679,7 +1623,7 @@ bwi_intr(void *xsc)
}
if (intr_status & BWI_INTR_NOISE)
- if_printf(ifp, "intr noise\n");
+ device_printf(sc->sc_dev, "intr noise\n");
if (txrx_intr_status[0] & BWI_TXRX_INTR_RX) {
rx_data = sc->sc_rxeof(sc);
@@ -1728,7 +1672,7 @@ bwi_intr(void *xsc)
static void
bwi_scan_start(struct ieee80211com *ic)
{
- struct bwi_softc *sc = ic->ic_ifp->if_softc;
+ struct bwi_softc *sc = ic->ic_softc;
BWI_LOCK(sc);
/* Enable MAC beacon promiscuity */
@@ -1739,7 +1683,7 @@ bwi_scan_start(struct ieee80211com *ic)
static void
bwi_set_channel(struct ieee80211com *ic)
{
- struct bwi_softc *sc = ic->ic_ifp->if_softc;
+ struct bwi_softc *sc = ic->ic_softc;
struct ieee80211_channel *c = ic->ic_curchan;
struct bwi_mac *mac;
@@ -1765,7 +1709,7 @@ bwi_set_channel(struct ieee80211com *ic)
static void
bwi_scan_end(struct ieee80211com *ic)
{
- struct bwi_softc *sc = ic->ic_ifp->if_softc;
+ struct bwi_softc *sc = ic->ic_softc;
BWI_LOCK(sc);
CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN);
@@ -1777,9 +1721,8 @@ bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct bwi_vap *bvp = BWI_VAP(vap);
struct ieee80211com *ic= vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
+ struct bwi_softc *sc = ic->ic_softc;
enum ieee80211_state ostate = vap->iv_state;
- struct bwi_softc *sc = ifp->if_softc;
struct bwi_mac *mac;
int error;
@@ -2625,8 +2568,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
{
struct bwi_ring_data *rd = &sc->sc_rx_rdata;
struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
int idx, rx_data = 0;
idx = rbd->rbd_idx;
@@ -2645,7 +2587,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
BUS_DMASYNC_POSTREAD);
if (bwi_newbuf(sc, idx, 0)) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto next;
}
@@ -2659,9 +2601,10 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
buflen = le16toh(hdr->rxh_buflen);
if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) {
- if_printf(ifp, "%s: zero length data, hdr_extra %d\n",
- __func__, hdr_extra);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ device_printf(sc->sc_dev,
+ "%s: zero length data, hdr_extra %d\n",
+ __func__, hdr_extra);
+ counter_u64_add(ic->ic_ierrors, 1);
m_freem(m);
goto next;
}
@@ -2670,7 +2613,6 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
rssi = bwi_calc_rssi(sc, hdr);
noise = bwi_calc_noise(sc);
- m->m_pkthdr.rcvif = ifp;
m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr);
m_adj(m, sizeof(*hdr) + wh_ofs);
@@ -2804,7 +2746,6 @@ bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx)
{
struct bwi_ring_data *rd;
struct bwi_txbuf_data *tbd;
- struct ifnet *ifp = sc->sc_ifp;
uint32_t state, val;
int i;
@@ -2825,8 +2766,9 @@ bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx)
DELAY(1000);
}
if (i == NRETRY) {
- if_printf(ifp, "%s: wait for TX ring(%d) stable timed out\n",
- __func__, ring_idx);
+ device_printf(sc->sc_dev,
+ "%s: wait for TX ring(%d) stable timed out\n",
+ __func__, ring_idx);
}
CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0);
@@ -2839,7 +2781,7 @@ bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx)
DELAY(1000);
}
if (i == NRETRY)
- if_printf(ifp, "%s: reset TX ring (%d) timed out\n",
+ device_printf(sc->sc_dev, "%s: reset TX ring (%d) timed out\n",
__func__, ring_idx);
#undef NRETRY
@@ -2947,8 +2889,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
@@ -3024,7 +2965,8 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
*/
M_PREPEND(m, sizeof(*hdr), M_NOWAIT);
if (m == NULL) {
- if_printf(ifp, "%s: prepend TX header failed\n", __func__);
+ device_printf(sc->sc_dev, "%s: prepend TX header failed\n",
+ __func__);
return ENOBUFS;
}
hdr = mtod(m, struct bwi_txbuf_hdr *);
@@ -3073,7 +3015,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
error = bus_dmamap_load_mbuf(sc->sc_buf_dtag, tb->tb_dmap, m,
bwi_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
if (error && error != EFBIG) {
- if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
+ device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
__func__, error);
goto back;
}
@@ -3083,8 +3025,8 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
m_new = m_defrag(m, M_NOWAIT);
if (m_new == NULL) {
- if_printf(ifp, "%s: can't defrag TX buffer\n",
- __func__);
+ device_printf(sc->sc_dev,
+ "%s: can't defrag TX buffer\n", __func__);
error = ENOBUFS;
goto back;
} else {
@@ -3095,7 +3037,8 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
bwi_dma_buf_addr, &paddr,
BUS_DMA_NOWAIT);
if (error) {
- if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
+ device_printf(sc->sc_dev,
+ "%s: can't load TX buffer (2) %d\n",
__func__, error);
goto back;
}
@@ -3137,7 +3080,6 @@ static int
bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m,
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
{
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
@@ -3204,7 +3146,8 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m,
*/
M_PREPEND(m, sizeof(*hdr), M_NOWAIT);
if (m == NULL) {
- if_printf(ifp, "%s: prepend TX header failed\n", __func__);
+ device_printf(sc->sc_dev, "%s: prepend TX header failed\n",
+ __func__);
return ENOBUFS;
}
hdr = mtod(m, struct bwi_txbuf_hdr *);
@@ -3252,14 +3195,15 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m,
struct mbuf *m_new;
if (error != EFBIG) {
- if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
+ device_printf(sc->sc_dev,
+ "%s: can't load TX buffer (1) %d\n",
__func__, error);
goto back;
}
m_new = m_defrag(m, M_NOWAIT);
if (m_new == NULL) {
- if_printf(ifp, "%s: can't defrag TX buffer\n",
- __func__);
+ device_printf(sc->sc_dev,
+ "%s: can't defrag TX buffer\n", __func__);
error = ENOBUFS;
goto back;
}
@@ -3268,7 +3212,8 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m,
bwi_dma_buf_addr, &paddr,
BUS_DMA_NOWAIT);
if (error) {
- if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
+ device_printf(sc->sc_dev,
+ "%s: can't load TX buffer (2) %d\n",
__func__, error);
goto back;
}
@@ -3312,7 +3257,6 @@ bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
static void
bwi_txeof_status32(struct bwi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
uint32_t val, ctrl_base;
int end_idx;
@@ -3327,8 +3271,7 @@ bwi_txeof_status32(struct bwi_softc *sc)
CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
end_idx * sizeof(struct bwi_desc32));
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0)
- ifp->if_start(ifp);
+ bwi_start_locked(sc);
}
static void
@@ -3340,7 +3283,6 @@ bwi_txeof_status64(struct bwi_softc *sc)
static void
_bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
{
- struct ifnet *ifp = sc->sc_ifp;
struct bwi_txbuf_data *tbd;
struct bwi_txbuf *tb;
int ring_idx, buf_idx;
@@ -3348,7 +3290,7 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
struct ieee80211vap *vap;
if (tx_id == 0) {
- if_printf(ifp, "%s: zero tx id\n", __func__);
+ device_printf(sc->sc_dev, "%s: zero tx id\n", __func__);
return;
}
@@ -3369,8 +3311,7 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
bus_dmamap_unload(sc->sc_buf_dtag, tb->tb_dmap);
- ni = tb->tb_ni;
- if (tb->tb_ni != NULL) {
+ if ((ni = tb->tb_ni) != NULL) {
const struct bwi_txbuf_hdr *hdr =
mtod(tb->tb_mbuf, const struct bwi_txbuf_hdr *);
vap = ni->ni_vap;
@@ -3388,24 +3329,14 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
(data_txcnt > 1) ? IEEE80211_RATECTL_TX_SUCCESS :
IEEE80211_RATECTL_TX_FAILURE, &acked, NULL);
}
-
- /*
- * Do any tx complete callback. Note this must
- * be done before releasing the node reference.
- */
- if (tb->tb_mbuf->m_flags & M_TXCB)
- ieee80211_process_callback(ni, tb->tb_mbuf, !acked);
-
- ieee80211_free_node(tb->tb_ni);
+ ieee80211_tx_complete(ni, tb->tb_mbuf, !acked);
tb->tb_ni = NULL;
- }
- m_freem(tb->tb_mbuf);
+ } else
+ m_freem(tb->tb_mbuf);
tb->tb_mbuf = NULL;
if (tbd->tbd_used == 0)
sc->sc_tx_timer = 0;
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
static void
@@ -3437,7 +3368,6 @@ bwi_txeof_status(struct bwi_softc *sc, int end_idx)
static void
bwi_txeof(struct bwi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
for (;;) {
uint32_t tx_status0, tx_status1;
@@ -3460,8 +3390,7 @@ bwi_txeof(struct bwi_softc *sc)
data_txcnt);
}
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0)
- ifp->if_start(ifp);
+ bwi_start_locked(sc);
}
static int
@@ -3709,7 +3638,6 @@ bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
static void
bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid)
{
- struct ifnet *ifp = sc->sc_ifp;
struct bwi_mac *mac;
struct bwi_myaddr_bssid buf;
const uint8_t *p;
@@ -3722,7 +3650,7 @@ bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid)
bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid);
- bcopy(IF_LLADDR(ifp), buf.myaddr, sizeof(buf.myaddr));
+ bcopy(sc->sc_ic.ic_macaddr, buf.myaddr, sizeof(buf.myaddr));
bcopy(bssid, buf.bssid, sizeof(buf.bssid));
n = sizeof(buf) / sizeof(val);
@@ -3745,7 +3673,7 @@ bwi_updateslot(struct ieee80211com *ic)
struct bwi_mac *mac;
BWI_LOCK(sc);
- if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ if (sc->sc_flags & BWI_F_RUNNING) {
DPRINTF(sc, BWI_DBG_80211, "%s\n", __func__);
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
@@ -3761,16 +3689,12 @@ static void
bwi_calibrate(void *xsc)
{
struct bwi_softc *sc = xsc;
-#ifdef INVARIANTS
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-#endif
struct bwi_mac *mac;
BWI_ASSERT_LOCKED(sc);
- KASSERT(ic->ic_opmode != IEEE80211_M_MONITOR,
- ("opmode %d", ic->ic_opmode));
+ KASSERT(sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR,
+ ("opmode %d", sc->sc_ic.ic_opmode));
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
("current regwin type %d", sc->sc_cur_regwin->rw_type));
@@ -3912,8 +3836,7 @@ bwi_led_onoff(const struct bwi_led *led, uint16_t val, int on)
static void
bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t val;
int i;
@@ -3922,7 +3845,7 @@ bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate)
sc->sc_led_blinking = 0;
}
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((sc->sc_flags & BWI_F_RUNNING) == 0)
return;
val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
@@ -4050,13 +3973,12 @@ static void
bwi_restart(void *xsc, int pending)
{
struct bwi_softc *sc = xsc;
- struct ifnet *ifp = sc->sc_ifp;
- if_printf(ifp, "%s begin, help!\n", __func__);
+ device_printf(sc->sc_dev, "%s begin, help!\n", __func__);
BWI_LOCK(sc);
- bwi_init_statechg(xsc, 0);
+ bwi_init_statechg(sc, 0);
#if 0
- bwi_start_locked(ifp);
+ bwi_start_locked(sc);
#endif
BWI_UNLOCK(sc);
}
diff --git a/sys/dev/bwi/if_bwivar.h b/sys/dev/bwi/if_bwivar.h
index d5f09da..07c20fe 100644
--- a/sys/dev/bwi/if_bwivar.h
+++ b/sys/dev/bwi/if_bwivar.h
@@ -541,10 +541,11 @@ struct bwi_vap {
#define BWI_VAP(vap) ((struct bwi_vap *)(vap))
struct bwi_softc {
- struct ifnet *sc_ifp;
uint32_t sc_flags; /* BWI_F_ */
device_t sc_dev;
struct mtx sc_mtx;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
int sc_invalid;
uint32_t sc_cap; /* BWI_CAP_ */
@@ -647,6 +648,7 @@ struct bwi_softc {
#define BWI_F_BUS_INITED 0x1
#define BWI_F_PROMISC 0x2
#define BWI_F_STOP 0x4
+#define BWI_F_RUNNING 0x8
#define BWI_DBG_MAC 0x00000001
#define BWI_DBG_RF 0x00000002
diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
index 39bd06f..15f6f27 100644
--- a/sys/dev/bwn/if_bwn.c
+++ b/sys/dev/bwn/if_bwn.c
@@ -133,13 +133,13 @@ static int bwn_wme = 1;
SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0,
"uses WME support");
-static int bwn_attach_pre(struct bwn_softc *);
+static void bwn_attach_pre(struct bwn_softc *);
static int bwn_attach_post(struct bwn_softc *);
static void bwn_sprom_bugfixes(device_t);
-static void bwn_init(void *);
-static int bwn_init_locked(struct bwn_softc *);
-static int bwn_ioctl(struct ifnet *, u_long, caddr_t);
-static void bwn_start(struct ifnet *);
+static int bwn_init(struct bwn_softc *);
+static void bwn_parent(struct ieee80211com *);
+static void bwn_start(struct bwn_softc *);
+static int bwn_transmit(struct ieee80211com *, struct mbuf *);
static int bwn_attach_core(struct bwn_mac *);
static void bwn_reset_core(struct bwn_mac *, uint32_t);
static int bwn_phy_getinfo(struct bwn_mac *, int);
@@ -197,8 +197,7 @@ static struct ieee80211vap *bwn_vap_create(struct ieee80211com *,
const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN]);
static void bwn_vap_delete(struct ieee80211vap *);
-static void bwn_stop(struct bwn_softc *, int);
-static void bwn_stop_locked(struct bwn_softc *, int);
+static void bwn_stop(struct bwn_softc *);
static int bwn_core_init(struct bwn_mac *);
static void bwn_core_start(struct bwn_mac *);
static void bwn_core_exit(struct bwn_mac *);
@@ -409,7 +408,6 @@ static void bwn_handle_txeof(struct bwn_mac *,
const struct bwn_txstatus *);
static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *);
static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t);
-static void bwn_start_locked(struct ifnet *);
static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *,
struct mbuf *);
static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *);
@@ -930,9 +928,7 @@ bwn_attach(device_t dev)
#endif
if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) {
- error = bwn_attach_pre(sc);
- if (error != 0)
- return (error);
+ bwn_attach_pre(sc);
bwn_sprom_bugfixes(dev);
sc->sc_flags |= BWN_FLAG_ATTACHED;
}
@@ -947,10 +943,7 @@ bwn_attach(device_t dev)
}
}
- mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF,
- M_NOWAIT | M_ZERO);
- if (mac == NULL)
- return (ENOMEM);
+ mac = malloc(sizeof(*mac), M_DEVBUF, M_WAITOK | M_ZERO);
mac->mac_sc = sc;
mac->mac_status = BWN_MAC_STATUS_UNINIT;
if (bwn_bfp != 0)
@@ -1053,11 +1046,8 @@ bwn_is_valid_ether_addr(uint8_t *addr)
static int
bwn_attach_post(struct bwn_softc *sc)
{
- struct ieee80211com *ic;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(sc->sc_dev);
/* XXX not right but it's not used anywhere important */
@@ -1077,12 +1067,14 @@ bwn_attach_post(struct bwn_softc *sc)
ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */
- /* call MI attach routine. */
- ieee80211_ifattach(ic,
+ IEEE80211_ADDR_COPY(ic->ic_macaddr,
bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ?
siba_sprom_get_mac_80211a(sc->sc_dev) :
siba_sprom_get_mac_80211bg(sc->sc_dev));
+ /* call MI attach routine. */
+ ieee80211_ifattach(ic);
+
ic->ic_headroom = sizeof(struct bwn_txhdr);
/* override default methods */
@@ -1090,13 +1082,13 @@ bwn_attach_post(struct bwn_softc *sc)
ic->ic_updateslot = bwn_updateslot;
ic->ic_update_promisc = bwn_update_promisc;
ic->ic_wme.wme_update = bwn_wme_update;
-
ic->ic_scan_start = bwn_scan_start;
ic->ic_scan_end = bwn_scan_end;
ic->ic_set_channel = bwn_set_channel;
-
ic->ic_vap_create = bwn_vap_create;
ic->ic_vap_delete = bwn_vap_delete;
+ ic->ic_transmit = bwn_transmit;
+ ic->ic_parent = bwn_parent;
ieee80211_radiotap_attach(ic,
&sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
@@ -1124,26 +1116,24 @@ bwn_detach(device_t dev)
{
struct bwn_softc *sc = device_get_softc(dev);
struct bwn_mac *mac = sc->sc_curmac;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
int i;
sc->sc_flags |= BWN_FLAG_INVALID;
if (device_is_attached(sc->sc_dev)) {
- bwn_stop(sc, 1);
+ BWN_LOCK(sc);
+ bwn_stop(sc);
+ BWN_UNLOCK(sc);
bwn_dma_free(mac);
callout_drain(&sc->sc_led_blink_ch);
callout_drain(&sc->sc_rfswitch_ch);
callout_drain(&sc->sc_task_ch);
callout_drain(&sc->sc_watchdog_ch);
bwn_phy_detach(mac);
- if (ifp != NULL) {
- ieee80211_draintask(ic, &mac->mac_hwreset);
- ieee80211_draintask(ic, &mac->mac_txpower);
- ieee80211_ifdetach(ic);
- if_free(ifp);
- }
+ ieee80211_draintask(ic, &mac->mac_hwreset);
+ ieee80211_draintask(ic, &mac->mac_txpower);
+ ieee80211_ifdetach(ic);
}
taskqueue_drain(sc->sc_tq, &mac->mac_intrtask);
taskqueue_free(sc->sc_tq);
@@ -1158,52 +1148,25 @@ bwn_detach(device_t dev)
bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq);
if (mac->mac_msi != 0)
pci_release_msi(dev);
-
+ mbufq_drain(&sc->sc_snd);
BWN_LOCK_DESTROY(sc);
return (0);
}
-static int
+static void
bwn_attach_pre(struct bwn_softc *sc)
{
- struct ifnet *ifp;
- int error = 0;
BWN_LOCK_INIT(sc);
TAILQ_INIT(&sc->sc_maclist);
callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0);
callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0);
callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0);
-
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
sc->sc_tq = taskqueue_create_fast("bwn_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));
-
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- error = ENOSPC;
- goto fail;
- }
-
- /* set these up early for if_printf use */
- if_initname(ifp, device_get_name(sc->sc_dev),
- device_get_unit(sc->sc_dev));
-
- ifp->if_softc = sc;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = bwn_init;
- ifp->if_ioctl = bwn_ioctl;
- ifp->if_start = bwn_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- return (0);
-
-fail: BWN_LOCK_DESTROY(sc);
- return (error);
}
static void
@@ -1238,58 +1201,51 @@ bwn_sprom_bugfixes(device_t dev)
#undef BWN_ISDEV
}
-static int
-bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
-#define IS_RUNNING(ifp) \
- ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
- struct bwn_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *)data;
- int error = 0, startall;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- startall = 0;
- if (IS_RUNNING(ifp)) {
- bwn_update_promisc(ic);
- } else if (ifp->if_flags & IFF_UP) {
- if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
- bwn_init(sc);
- startall = 1;
- }
+static void
+bwn_parent(struct ieee80211com *ic)
+{
+ struct bwn_softc *sc = ic->ic_softc;
+ int startall = 0;
+
+ BWN_LOCK(sc);
+ if (ic->ic_nrunning > 0) {
+ if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) {
+ bwn_init(sc);
+ startall = 1;
} else
- bwn_stop(sc, 1);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return (error);
+ bwn_update_promisc(ic);
+ } else if (sc->sc_flags & BWN_FLAG_RUNNING)
+ bwn_stop(sc);
+ BWN_UNLOCK(sc);
+
+ if (startall)
+ ieee80211_start_all(ic);
}
-static void
-bwn_start(struct ifnet *ifp)
+static int
+bwn_transmit(struct ieee80211com *ic, struct mbuf *m)
{
- struct bwn_softc *sc = ifp->if_softc;
+ struct bwn_softc *sc = ic->ic_softc;
+ int error;
BWN_LOCK(sc);
- bwn_start_locked(ifp);
+ if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) {
+ BWN_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ BWN_UNLOCK(sc);
+ return (error);
+ }
+ bwn_start(sc);
BWN_UNLOCK(sc);
+ return (0);
}
static void
-bwn_start_locked(struct ifnet *ifp)
+bwn_start(struct bwn_softc *sc)
{
- struct bwn_softc *sc = ifp->if_softc;
struct bwn_mac *mac = sc->sc_curmac;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
@@ -1298,44 +1254,40 @@ bwn_start_locked(struct ifnet *ifp)
BWN_ASSERT_LOCKED(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL ||
+ if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || mac == NULL ||
mac->mac_status < BWN_MAC_STATUS_STARTED)
return;
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */
- if (m == NULL)
- break;
-
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
if (bwn_tx_isfull(sc, m))
break;
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
if (ni == NULL) {
device_printf(sc->sc_dev, "unexpected NULL ni\n");
m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
continue;
}
- KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__));
wh = mtod(m, struct ieee80211_frame *);
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
k = ieee80211_crypto_encap(ni, m);
if (k == NULL) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
continue;
}
}
wh = NULL; /* Catch any invalid use */
-
if (bwn_tx_start(sc, ni, m) != 0) {
- if (ni != NULL)
+ if (ni != NULL) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ }
continue;
}
-
sc->sc_watchdog_timer = 5;
}
}
@@ -1346,7 +1298,6 @@ bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
struct bwn_dma_ring *dr;
struct bwn_mac *mac = sc->sc_curmac;
struct bwn_pio_txqueue *tq;
- struct ifnet *ifp = sc->sc_ifp;
int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4);
BWN_ASSERT_LOCKED(sc);
@@ -1361,15 +1312,12 @@ bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m)
} else {
tq = bwn_pio_select(mac, M_WME_GETAC(m));
if (tq->tq_free == 0 || pktlen > tq->tq_size ||
- pktlen > (tq->tq_size - tq->tq_used)) {
- tq->tq_stop = 1;
+ pktlen > (tq->tq_size - tq->tq_used))
goto full;
- }
}
return (0);
full:
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ mbufq_prepend(&sc->sc_snd, m);
return (1);
}
@@ -1496,7 +1444,6 @@ bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
struct bwn_dmadesc_generic *desc;
struct bwn_dmadesc_meta *mt;
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache;
int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot };
@@ -1519,7 +1466,7 @@ bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr,
&mt->mt_paddr, BUS_DMA_NOWAIT);
if (error) {
- if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
+ device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
__func__, error);
goto fail;
}
@@ -1539,7 +1486,7 @@ bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m,
bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
if (error && error != EFBIG) {
- if_printf(ifp, "%s: can't load TX buffer (1) %d\n",
+ device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
__func__, error);
goto fail;
}
@@ -1548,7 +1495,8 @@ bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
m_new = m_defrag(m, M_NOWAIT);
if (m_new == NULL) {
- if_printf(ifp, "%s: can't defrag TX buffer\n",
+ device_printf(sc->sc_dev,
+ "%s: can't defrag TX buffer\n",
__func__);
error = ENOBUFS;
goto fail;
@@ -1560,7 +1508,8 @@ bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m)
error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap,
m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT);
if (error) {
- if_printf(ifp, "%s: can't load TX buffer (2) %d\n",
+ device_printf(sc->sc_dev,
+ "%s: can't load TX buffer (2) %d\n",
__func__, error);
goto fail;
}
@@ -1585,11 +1534,10 @@ static void
bwn_watchdog(void *arg)
{
struct bwn_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) {
- if_printf(ifp, "device timeout\n");
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ device_printf(sc->sc_dev, "device timeout\n");
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
}
callout_schedule(&sc->sc_watchdog_ch, hz);
}
@@ -1860,8 +1808,7 @@ static int
bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
memset(ic->ic_channels, 0, sizeof(ic->ic_channels));
ic->ic_nchans = 0;
@@ -2735,11 +2682,10 @@ bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct bwn_softc *sc = ifp->if_softc;
+ struct bwn_softc *sc = ic->ic_softc;
struct bwn_mac *mac = sc->sc_curmac;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
+ if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 ||
mac->mac_status < BWN_MAC_STATUS_STARTED) {
ieee80211_free_node(ni);
m_freem(m);
@@ -2750,7 +2696,6 @@ bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (bwn_tx_isfull(sc, m)) {
ieee80211_free_node(ni);
m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
BWN_UNLOCK(sc);
return (ENOBUFS);
}
@@ -2758,7 +2703,6 @@ bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (bwn_tx_start(sc, ni, m) != 0) {
if (ni != NULL)
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
sc->sc_watchdog_timer = 5;
BWN_UNLOCK(sc);
@@ -2778,7 +2722,7 @@ bwn_updateslot(struct ieee80211com *ic)
struct bwn_mac *mac;
BWN_LOCK(sc);
- if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ if (sc->sc_flags & BWN_FLAG_RUNNING) {
mac = (struct bwn_mac *)sc->sc_curmac;
bwn_set_slot_time(mac,
(ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
@@ -2802,7 +2746,7 @@ bwn_update_promisc(struct ieee80211com *ic)
BWN_LOCK(sc);
mac = sc->sc_curmac;
if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
- if (ic->ic_ifp->if_flags & IFF_PROMISC)
+ if (ic->ic_promisc > 0)
sc->sc_filters |= BWN_MACCTL_PROMISC;
else
sc->sc_filters &= ~BWN_MACCTL_PROMISC;
@@ -2817,7 +2761,7 @@ bwn_update_promisc(struct ieee80211com *ic)
static int
bwn_wme_update(struct ieee80211com *ic)
{
- struct bwn_softc *sc = ic->ic_ifp->if_softc;
+ struct bwn_softc *sc = ic->ic_softc;
struct bwn_mac *mac = sc->sc_curmac;
struct wmeParams *wmep;
int i;
@@ -2839,8 +2783,7 @@ bwn_wme_update(struct ieee80211com *ic)
static void
bwn_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct bwn_softc *sc = ifp->if_softc;
+ struct bwn_softc *sc = ic->ic_softc;
struct bwn_mac *mac;
BWN_LOCK(sc);
@@ -2857,8 +2800,7 @@ bwn_scan_start(struct ieee80211com *ic)
static void
bwn_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct bwn_softc *sc = ifp->if_softc;
+ struct bwn_softc *sc = ic->ic_softc;
struct bwn_mac *mac;
BWN_LOCK(sc);
@@ -2874,8 +2816,7 @@ bwn_scan_end(struct ieee80211com *ic)
static void
bwn_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct bwn_softc *sc = ifp->if_softc;
+ struct bwn_softc *sc = ic->ic_softc;
struct bwn_mac *mac = sc->sc_curmac;
struct bwn_phy *phy = &mac->mac_phy;
int chan, error;
@@ -2931,15 +2872,11 @@ static struct ieee80211vap *
bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
enum ieee80211_opmode opmode, int flags,
const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac0[IEEE80211_ADDR_LEN])
+ const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct ifnet *ifp = ic->ic_ifp;
- struct bwn_softc *sc = ifp->if_softc;
struct ieee80211vap *vap;
struct bwn_vap *bvp;
- uint8_t mac[IEEE80211_ADDR_LEN];
- IEEE80211_ADDR_COPY(mac, mac0);
switch (opmode) {
case IEEE80211_M_HOSTAP:
case IEEE80211_M_MBSS:
@@ -2953,17 +2890,9 @@ bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
return (NULL);
}
- IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0);
-
- bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (bvp == NULL) {
- device_printf(sc->sc_dev, "failed to allocate a buffer\n");
- return (NULL);
- }
+ bvp = malloc(sizeof(struct bwn_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &bvp->bv_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
- IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
/* override with driver methods */
bvp->bv_newstate = vap->iv_newstate;
vap->iv_newstate = bwn_newstate;
@@ -2975,7 +2904,7 @@ bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
+ ieee80211_media_status, mac);
return (vap);
}
@@ -2989,30 +2918,10 @@ bwn_vap_delete(struct ieee80211vap *vap)
free(bvp, M_80211_VAP);
}
-static void
-bwn_init(void *arg)
-{
- struct bwn_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- int error = 0;
-
- DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n",
- __func__, ifp->if_flags);
-
- BWN_LOCK(sc);
- error = bwn_init_locked(sc);
- BWN_UNLOCK(sc);
-
- if (error == 0)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
static int
-bwn_init_locked(struct bwn_softc *sc)
+bwn_init(struct bwn_softc *sc)
{
struct bwn_mac *mac;
- struct ifnet *ifp = sc->sc_ifp;
int error;
BWN_ASSERT_LOCKED(sc);
@@ -3038,7 +2947,7 @@ bwn_init_locked(struct bwn_softc *sc)
bwn_spu_setdelay(mac, 0);
bwn_set_macaddr(mac);
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= BWN_FLAG_RUNNING;
callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc);
callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc);
@@ -3046,19 +2955,9 @@ bwn_init_locked(struct bwn_softc *sc)
}
static void
-bwn_stop(struct bwn_softc *sc, int statechg)
-{
-
- BWN_LOCK(sc);
- bwn_stop_locked(sc, statechg);
- BWN_UNLOCK(sc);
-}
-
-static void
-bwn_stop_locked(struct bwn_softc *sc, int statechg)
+bwn_stop(struct bwn_softc *sc)
{
struct bwn_mac *mac = sc->sc_curmac;
- struct ifnet *ifp = sc->sc_ifp;
BWN_ASSERT_LOCKED(sc);
@@ -3077,7 +2976,7 @@ bwn_stop_locked(struct bwn_softc *sc, int statechg)
bwn_core_exit(mac);
sc->sc_rf_enabled = 0;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_flags &= ~BWN_FLAG_RUNNING;
}
static void
@@ -4441,7 +4340,7 @@ static void
bwn_spu_setdelay(struct bwn_mac *mac, int idle)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t delay; /* microsec */
delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050;
@@ -4479,7 +4378,8 @@ bwn_set_macaddr(struct bwn_mac *mac)
{
bwn_mac_write_bssid(mac);
- bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr);
+ bwn_mac_setfilter(mac, BWN_MACFILTER_SELF,
+ mac->mac_sc->sc_ic.ic_macaddr);
}
static void
@@ -4649,8 +4549,7 @@ static void
bwn_set_opmode(struct bwn_mac *mac)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t ctl;
uint16_t cfp_pretbtt;
@@ -7943,8 +7842,7 @@ bwn_switch_channel(struct bwn_mac *mac, int chan)
{
struct bwn_phy *phy = &(mac->mac_phy);
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t channelcookie, savedcookie;
int error;
@@ -8055,7 +7953,7 @@ bwn_mac_write_bssid(struct bwn_mac *mac)
uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2];
bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid);
- memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN);
+ memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN);
memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid,
IEEE80211_ADDR_LEN);
@@ -8329,9 +8227,8 @@ bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct bwn_vap *bvp = BWN_VAP(vap);
struct ieee80211com *ic= vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
enum ieee80211_state ostate = vap->iv_state;
- struct bwn_softc *sc = ifp->if_softc;
+ struct bwn_softc *sc = ic->ic_softc;
struct bwn_mac *mac = sc->sc_curmac;
int error;
@@ -8370,7 +8267,6 @@ bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/* XXX nothing to do? */
} else if (nstate == IEEE80211_S_RUN) {
memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN);
- memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
bwn_set_opmode(mac);
bwn_set_pretbtt(mac);
bwn_spu_setdelay(mac, 0);
@@ -8386,7 +8282,7 @@ static void
bwn_set_pretbtt(struct bwn_mac *mac)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t pretbtt;
if (ic->ic_opmode == IEEE80211_M_IBSS)
@@ -8444,7 +8340,6 @@ bwn_intrtask(void *arg, int npending)
{
struct bwn_mac *mac = arg;
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
uint32_t merged = 0;
int i, tx = 0, rx = 0;
@@ -8544,10 +8439,8 @@ bwn_intrtask(void *arg, int npending)
bwn_led_event(mac, evt);
}
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
- if (!IFQ_IS_EMPTY(&ifp->if_snd))
- bwn_start_locked(ifp);
- }
+ if (mbufq_first(&sc->sc_snd) != NULL)
+ bwn_start(sc);
BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ);
BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE);
@@ -8559,8 +8452,7 @@ static void
bwn_restart(struct bwn_mac *mac, const char *msg)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
if (mac->mac_status < BWN_MAC_STATUS_INITED)
return;
@@ -8605,7 +8497,7 @@ static void
bwn_intr_tbtt_indication(struct bwn_mac *mac)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
if (ic->ic_opmode != IEEE80211_M_HOSTAP)
bwn_psctl(mac, 0);
@@ -8628,7 +8520,7 @@ static void
bwn_intr_beacon(struct bwn_mac *mac)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t cmd, beacon0, beacon1;
if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
@@ -8917,7 +8809,6 @@ bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
struct bwn_dmadesc_generic *desc;
struct bwn_dmadesc_meta *meta;
struct bwn_rxhdr4 *rxhdr;
- struct ifnet *ifp = sc->sc_ifp;
struct mbuf *m;
uint32_t macstat;
int32_t tmp;
@@ -8930,14 +8821,14 @@ bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
m = meta->mt_m;
if (bwn_dma_newbuf(dr, desc, meta, 0)) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_ierrors, 1);
return;
}
rxhdr = mtod(m, struct bwn_rxhdr4 *);
len = le16toh(rxhdr->frame_len);
if (len <= 0) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_ierrors, 1);
return;
}
if (bwn_dma_check_redzone(dr, m)) {
@@ -8973,7 +8864,6 @@ bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
}
}
- m->m_pkthdr.rcvif = ifp;
m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset;
m_adj(m, dr->dr_frameoffset);
@@ -9060,7 +8950,6 @@ bwn_pio_rxeof(struct bwn_pio_rxqueue *prq)
struct bwn_mac *mac = prq->prq_mac;
struct bwn_softc *sc = mac->mac_sc;
struct bwn_rxhdr4 rxhdr;
- struct ifnet *ifp = sc->sc_ifp;
struct mbuf *m;
uint32_t ctl32, macstat, v32;
unsigned int i, padding;
@@ -9157,7 +9046,6 @@ ready:
}
}
- m->m_pkthdr.rcvif = ifp;
m->m_len = m->m_pkthdr.len = totlen;
bwn_rxeof(prq->prq_mac, m, &rxhdr);
@@ -9302,8 +9190,7 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
struct bwn_softc *sc = mac->mac_sc;
struct ieee80211_frame_min *wh;
struct ieee80211_node *ni;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t macstat;
int padding, rate, rssi = 0, noise = 0, type;
uint16_t phytype, phystat0, phystat3, chanstat;
@@ -9367,8 +9254,6 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */
noise = mac->mac_stats.link_noise;
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
-
BWN_UNLOCK(sc);
ni = ieee80211_find_rxnode(ic, wh);
@@ -9393,9 +9278,6 @@ bwn_dma_handle_txeof(struct bwn_mac *mac,
struct bwn_dmadesc_generic *desc;
struct bwn_dmadesc_meta *meta;
struct bwn_softc *sc = mac->mac_sc;
- struct ieee80211_node *ni;
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
int slot;
BWN_ASSERT_LOCKED(sc);
@@ -9421,37 +9303,22 @@ bwn_dma_handle_txeof(struct bwn_mac *mac,
KASSERT(meta->mt_m != NULL,
("%s:%d: fail", __func__, __LINE__));
- ni = meta->mt_ni;
- m = meta->mt_m;
- if (ni != NULL) {
- /*
- * Do any tx complete callback. Note this must
- * be done before releasing the node reference.
- */
- if (m->m_flags & M_TXCB)
- ieee80211_process_callback(ni, m, 0);
- ieee80211_free_node(ni);
- meta->mt_ni = NULL;
- }
- m_freem(m);
+ ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0);
+ meta->mt_ni = NULL;
meta->mt_m = NULL;
- } else {
+ } else
KASSERT(meta->mt_m == NULL,
("%s:%d: fail", __func__, __LINE__));
- }
dr->dr_usedslot--;
- if (meta->mt_islast) {
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ if (meta->mt_islast)
break;
- }
slot = bwn_dma_nextslot(dr, slot);
}
sc->sc_watchdog_timer = 0;
if (dr->dr_stop) {
KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME,
("%s:%d: fail", __func__, __LINE__));
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
dr->dr_stop = 0;
}
}
@@ -9463,7 +9330,6 @@ bwn_pio_handle_txeof(struct bwn_mac *mac,
struct bwn_pio_txqueue *tq;
struct bwn_pio_txpkt *tp = NULL;
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
BWN_ASSERT_LOCKED(sc);
@@ -9488,13 +9354,7 @@ bwn_pio_handle_txeof(struct bwn_mac *mac,
tp->tp_m = NULL;
TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
sc->sc_watchdog_timer = 0;
- if (tq->tq_stop) {
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- tq->tq_stop = 0;
- }
}
static void
@@ -9502,8 +9362,7 @@ bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags)
{
struct bwn_softc *sc = mac->mac_sc;
struct bwn_phy *phy = &mac->mac_phy;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
unsigned long now;
int result;
@@ -9607,8 +9466,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
struct ieee80211_frame_rts *rts;
const struct ieee80211_txparam *tp;
struct ieee80211vap *vap = ni->ni_vap;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct mbuf *mprot;
unsigned int len;
uint32_t macctl = 0;
@@ -10106,7 +9964,7 @@ static void
bwn_phy_lock(struct bwn_mac *mac)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
KASSERT(siba_get_revid(sc->sc_dev) >= 3,
("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
@@ -10119,7 +9977,7 @@ static void
bwn_phy_unlock(struct bwn_mac *mac)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
KASSERT(siba_get_revid(sc->sc_dev) >= 3,
("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev)));
@@ -10635,8 +10493,7 @@ static void
bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t val;
int i;
@@ -10645,7 +10502,7 @@ bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate)
sc->sc_led_blinking = 0;
}
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0)
return;
val = BWN_READ_2(mac, BWN_GPIO_CONTROL);
@@ -10780,7 +10637,9 @@ bwn_suspend(device_t dev)
{
struct bwn_softc *sc = device_get_softc(dev);
- bwn_stop(sc, 1);
+ BWN_LOCK(sc);
+ bwn_stop(sc);
+ BWN_UNLOCK(sc);
return (0);
}
@@ -10788,10 +10647,14 @@ static int
bwn_resume(device_t dev)
{
struct bwn_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
+ int error = EDOOFUS;
- if (ifp->if_flags & IFF_UP)
- bwn_init(sc);
+ BWN_LOCK(sc);
+ if (sc->sc_ic.ic_nrunning > 0)
+ error = bwn_init(sc);
+ BWN_UNLOCK(sc);
+ if (error == 0)
+ ieee80211_start_all(&sc->sc_ic);
return (0);
}
@@ -10870,8 +10733,7 @@ bwn_phy_lp_init(struct bwn_mac *mac)
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
struct bwn_softc *sc = mac->mac_sc;
const struct bwn_stxtable *st;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
int i, error;
uint16_t tmp;
@@ -11024,8 +10886,7 @@ static uint32_t
bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
}
@@ -11058,8 +10919,7 @@ bwn_phy_lp_readsprom(struct bwn_mac *mac)
{
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
@@ -11098,8 +10958,7 @@ bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
bwn_phy_lp_set_txgain(mac,
IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
@@ -11111,8 +10970,7 @@ bwn_phy_lp_calib(struct bwn_mac *mac)
{
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
const struct bwn_rxcompco *rc = NULL;
struct bwn_txgain ogain;
int i, omode, oafeovr, orf, obbmult;
@@ -11458,8 +11316,7 @@ bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
{
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t iso, tmp[3];
KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
@@ -11730,8 +11587,7 @@ bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
{
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
static const struct bwn_wpair v1[] = {
{ BWN_PHY_AFE_DAC_CTL, 0x50 },
{ BWN_PHY_AFE_CTL, 0x8800 },
@@ -11841,8 +11697,7 @@ bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
{
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
static const struct bwn_smpair v1[] = {
{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
{ BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
@@ -12027,8 +11882,7 @@ bwn_phy_lp_b2062_init(struct bwn_mac *mac)
((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
static const struct bwn_b2062_freq freqdata_tab[] = {
{ 12000, { 6, 6, 6, 6, 10, 6 } },
{ 13000, { 4, 4, 4, 4, 11, 7 } },
@@ -12374,8 +12228,7 @@ bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
#define FLAG_A 0x01
#define FLAG_G 0x02
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
{ BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
{ BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
@@ -12448,8 +12301,7 @@ bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
#define FLAG_A 0x01
#define FLAG_G 0x02
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
{ BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
{ BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
@@ -12667,8 +12519,7 @@ static void
bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
if (mac->mac_phy.rev < 2) {
@@ -12736,8 +12587,7 @@ bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
{
struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
if (user)
plp->plp_crsusr_off = 0;
@@ -13280,8 +13130,7 @@ static void
bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
static struct bwn_txgain_entry txgain_r2[] = {
{ 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
{ 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
@@ -14158,8 +14007,7 @@ bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
struct bwn_txgain_entry te)
{
struct bwn_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
diff --git a/sys/dev/bwn/if_bwnvar.h b/sys/dev/bwn/if_bwnvar.h
index f6647b0..b8295ec 100644
--- a/sys/dev/bwn/if_bwnvar.h
+++ b/sys/dev/bwn/if_bwnvar.h
@@ -656,7 +656,6 @@ struct bwn_pio_txqueue {
uint16_t tq_size;
uint16_t tq_used;
uint16_t tq_free;
- uint8_t tq_stop;
uint8_t tq_index;
struct bwn_pio_txpkt tq_pkts[BWN_PIO_MAX_TXPACKETS];
TAILQ_HEAD(, bwn_pio_txpkt) tq_pktlist;
@@ -897,17 +896,18 @@ struct bwn_vap {
struct bwn_softc {
device_t sc_dev;
struct mtx sc_mtx;
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
unsigned sc_flags;
#define BWN_FLAG_ATTACHED (1 << 0)
#define BWN_FLAG_INVALID (1 << 1)
#define BWN_FLAG_NEED_BEACON_TP (1 << 2)
+#define BWN_FLAG_RUNNING (1 << 3)
unsigned sc_debug;
struct bwn_mac *sc_curmac;
TAILQ_HEAD(, bwn_mac) sc_maclist;
- uint8_t sc_macaddr[IEEE80211_ADDR_LEN];
uint8_t sc_bssid[IEEE80211_ADDR_LEN];
unsigned int sc_filters;
uint8_t sc_beacons[2];
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index 9c57aed..c30f31c 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/kthread.h>
+#include <sys/limits.h>
#include <net/if.h>
#include <net/if_var.h>
@@ -166,7 +167,6 @@ static void ndis_starttask (device_object *, void *);
static void ndis_resettask (device_object *, void *);
static void ndis_inputtask (device_object *, void *);
static int ndis_ioctl (struct ifnet *, u_long, caddr_t);
-static int ndis_ioctl_80211 (struct ifnet *, u_long, caddr_t);
static int ndis_newstate (struct ieee80211vap *, enum ieee80211_state,
int);
static int ndis_nettype_chan (uint32_t);
@@ -197,10 +197,15 @@ static int ndis_add_key (struct ieee80211vap *,
const struct ieee80211_key *, const u_int8_t []);
static int ndis_del_key (struct ieee80211vap *,
const struct ieee80211_key *);
-
static void ndis_setmulti (struct ndis_softc *);
static void ndis_map_sclist (void *, bus_dma_segment_t *,
int, bus_size_t, int);
+static int ndis_ifattach(struct ndis_softc *);
+
+static int ndis_80211attach(struct ndis_softc *);
+static int ndis_80211ioctl(struct ieee80211com *, u_long , void *);
+static int ndis_80211transmit(struct ieee80211com *, struct mbuf *);
+static void ndis_80211parent(struct ieee80211com *);
static int ndisdrv_loaded = 0;
@@ -536,16 +541,12 @@ ndis_nettype_mode(uint32_t type)
* setup and ethernet/BPF attach.
*/
int
-ndis_attach(dev)
- device_t dev;
+ndis_attach(device_t dev)
{
- u_char eaddr[ETHER_ADDR_LEN];
struct ndis_softc *sc;
driver_object *pdrv;
device_object *pdo;
- struct ifnet *ifp = NULL;
- int error = 0, len, mode;
- uint8_t bands = 0;
+ int error = 0, len;
int i;
sc = device_get_softc(dev);
@@ -559,6 +560,7 @@ ndis_attach(dev)
InitializeListHead(&sc->ndisusb_tasklist);
InitializeListHead(&sc->ndisusb_xferdonelist);
callout_init(&sc->ndis_stat_callout, 1);
+ mbufq_init(&sc->ndis_rxqueue, INT_MAX); /* XXXGL: sane maximum */
if (sc->ndis_iftype == PCMCIABus) {
error = ndis_alloc_amem(sc);
@@ -635,15 +637,8 @@ ndis_attach(dev)
}
/*
- * Get station address from the driver.
- */
- len = sizeof(eaddr);
- ndis_get_info(sc, OID_802_3_CURRENT_ADDRESS, &eaddr, &len);
-
- /*
* Figure out how big to make the TX buffer pool.
*/
-
len = sizeof(sc->ndis_maxpkts);
if (ndis_get_info(sc, OID_GEN_MAXIMUM_SEND_PACKETS,
&sc->ndis_maxpkts, &len)) {
@@ -696,95 +691,89 @@ ndis_attach(dev)
*/
for (i = 0; i < sc->ndis_oidcnt; i++)
if (sc->ndis_oids[i] == OID_802_11_CONFIGURATION) {
- sc->ndis_80211++;
+ sc->ndis_80211 = 1;
break;
}
if (sc->ndis_80211)
- ifp = if_alloc(IFT_IEEE80211);
+ error = ndis_80211attach(sc);
else
- ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- error = ENOSPC;
- goto fail;
+ error = ndis_ifattach(sc);
+
+fail:
+ if (error) {
+ ndis_detach(dev);
+ return (error);
}
- sc->ifp = ifp;
- ifp->if_softc = sc;
- /* Check for task offload support. */
- ndis_probe_offload(sc);
+ if (sc->ndis_iftype == PNPBus && ndisusb_halt == 0)
+ return (error);
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_ioctl = ndis_ioctl;
- ifp->if_start = ndis_start;
- ifp->if_init = ndis_init;
- ifp->if_baudrate = 10000000;
- IFQ_SET_MAXLEN(&ifp->if_snd, 50);
- ifp->if_snd.ifq_drv_maxlen = 25;
- IFQ_SET_READY(&ifp->if_snd);
- ifp->if_capenable = ifp->if_capabilities;
- ifp->if_hwassist = sc->ndis_hwassist;
+ DPRINTF(("attach done.\n"));
+ /* We're done talking to the NIC for now; halt it. */
+ ndis_halt_nic(sc);
+ DPRINTF(("halting done.\n"));
- /* Do media setup */
- if (sc->ndis_80211) {
- struct ieee80211com *ic = ifp->if_l2com;
- ndis_80211_rates_ex rates;
- struct ndis_80211_nettype_list *ntl;
- uint32_t arg;
- int r;
-
- callout_init(&sc->ndis_scan_callout, 1);
-
- ifp->if_ioctl = ndis_ioctl_80211;
- ic->ic_ifp = ifp;
- ic->ic_softc = sc;
- ic->ic_name = device_get_nameunit(dev);
- ic->ic_opmode = IEEE80211_M_STA;
- ic->ic_phytype = IEEE80211_T_DS;
- ic->ic_caps = IEEE80211_C_8023ENCAP |
- IEEE80211_C_STA | IEEE80211_C_IBSS;
- setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO);
- len = 0;
- r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED,
- NULL, &len);
- if (r != ENOSPC)
- goto nonettypes;
- ntl = malloc(len, M_DEVBUF, M_NOWAIT|M_ZERO);
- r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED,
- ntl, &len);
- if (r != 0) {
- free(ntl, M_DEVBUF);
- goto nonettypes;
- }
+ return (error);
+}
- for (i = 0; i < ntl->ntl_items; i++) {
- mode = ndis_nettype_mode(ntl->ntl_type[i]);
- if (mode) {
- setbit(ic->ic_modecaps, mode);
- setbit(&bands, mode);
- } else
- device_printf(dev, "Unknown nettype %d\n",
- ntl->ntl_type[i]);
- }
+static int
+ndis_80211attach(struct ndis_softc *sc)
+{
+ struct ieee80211com *ic = &sc->ndis_ic;
+ ndis_80211_rates_ex rates;
+ struct ndis_80211_nettype_list *ntl;
+ uint32_t arg;
+ int mode, i, r, len;
+ uint8_t bands = 0;
+
+ callout_init(&sc->ndis_scan_callout, 1);
+
+ ic->ic_softc = sc;
+ ic->ic_ioctl = ndis_80211ioctl;
+ ic->ic_name = device_get_nameunit(sc->ndis_dev);
+ ic->ic_opmode = IEEE80211_M_STA;
+ ic->ic_phytype = IEEE80211_T_DS;
+ ic->ic_caps = IEEE80211_C_8023ENCAP |
+ IEEE80211_C_STA | IEEE80211_C_IBSS;
+ setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO);
+ len = 0;
+ r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED, NULL, &len);
+ if (r != ENOSPC)
+ goto nonettypes;
+ ntl = malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
+ r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED, ntl, &len);
+ if (r != 0) {
free(ntl, M_DEVBUF);
+ goto nonettypes;
+ }
+
+ for (i = 0; i < ntl->ntl_items; i++) {
+ mode = ndis_nettype_mode(ntl->ntl_type[i]);
+ if (mode) {
+ setbit(ic->ic_modecaps, mode);
+ setbit(&bands, mode);
+ } else
+ device_printf(sc->ndis_dev, "Unknown nettype %d\n",
+ ntl->ntl_type[i]);
+ }
+ free(ntl, M_DEVBUF);
nonettypes:
- /* Default to 11b channels if the card did not supply any */
- if (bands == 0) {
- setbit(ic->ic_modecaps, IEEE80211_MODE_11B);
- setbit(&bands, IEEE80211_MODE_11B);
- }
- len = sizeof(rates);
- bzero((char *)&rates, len);
- r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES,
- (void *)rates, &len);
- if (r)
- device_printf(dev, "get rates failed: 0x%x\n", r);
- /*
- * Since the supported rates only up to 8 can be supported,
- * if this is not 802.11b we're just going to be faking it
- * all up to heck.
- */
+ /* Default to 11b channels if the card did not supply any */
+ if (bands == 0) {
+ setbit(ic->ic_modecaps, IEEE80211_MODE_11B);
+ setbit(&bands, IEEE80211_MODE_11B);
+ }
+ len = sizeof(rates);
+ bzero((char *)&rates, len);
+ r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES, (void *)rates, &len);
+ if (r != 0)
+ device_printf(sc->ndis_dev, "get rates failed: 0x%x\n", r);
+ /*
+ * Since the supported rates only up to 8 can be supported,
+ * if this is not 802.11b we're just going to be faking it
+ * all up to heck.
+ */
#define TESTSETRATE(x, y) \
do { \
@@ -804,174 +793,198 @@ nonettypes:
#define INCRATE(x) \
ic->ic_sup_rates[x].rs_nrates++
- ic->ic_curmode = IEEE80211_MODE_AUTO;
- if (isset(ic->ic_modecaps, IEEE80211_MODE_11A))
- ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates = 0;
- if (isset(ic->ic_modecaps, IEEE80211_MODE_11B))
- ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = 0;
- if (isset(ic->ic_modecaps, IEEE80211_MODE_11G))
- ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates = 0;
- for (i = 0; i < len; i++) {
- switch (rates[i] & IEEE80211_RATE_VAL) {
- case 2:
- case 4:
- case 11:
- case 10:
- case 22:
- if (isclr(ic->ic_modecaps, IEEE80211_MODE_11B)) {
- /* Lazy-init 802.11b. */
- setbit(ic->ic_modecaps,
- IEEE80211_MODE_11B);
- ic->ic_sup_rates[IEEE80211_MODE_11B].
- rs_nrates = 0;
- }
- SETRATE(IEEE80211_MODE_11B, rates[i]);
- INCRATE(IEEE80211_MODE_11B);
- break;
- default:
- if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) {
- SETRATE(IEEE80211_MODE_11A, rates[i]);
- INCRATE(IEEE80211_MODE_11A);
- }
- if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) {
- SETRATE(IEEE80211_MODE_11G, rates[i]);
- INCRATE(IEEE80211_MODE_11G);
- }
- break;
+ ic->ic_curmode = IEEE80211_MODE_AUTO;
+ if (isset(ic->ic_modecaps, IEEE80211_MODE_11A))
+ ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates = 0;
+ if (isset(ic->ic_modecaps, IEEE80211_MODE_11B))
+ ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = 0;
+ if (isset(ic->ic_modecaps, IEEE80211_MODE_11G))
+ ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates = 0;
+ for (i = 0; i < len; i++) {
+ switch (rates[i] & IEEE80211_RATE_VAL) {
+ case 2:
+ case 4:
+ case 11:
+ case 10:
+ case 22:
+ if (isclr(ic->ic_modecaps, IEEE80211_MODE_11B)) {
+ /* Lazy-init 802.11b. */
+ setbit(ic->ic_modecaps, IEEE80211_MODE_11B);
+ ic->ic_sup_rates[IEEE80211_MODE_11B].
+ rs_nrates = 0;
}
+ SETRATE(IEEE80211_MODE_11B, rates[i]);
+ INCRATE(IEEE80211_MODE_11B);
+ break;
+ default:
+ if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) {
+ SETRATE(IEEE80211_MODE_11A, rates[i]);
+ INCRATE(IEEE80211_MODE_11A);
+ }
+ if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) {
+ SETRATE(IEEE80211_MODE_11G, rates[i]);
+ INCRATE(IEEE80211_MODE_11G);
+ }
+ break;
}
+ }
+
+ /*
+ * If the hardware supports 802.11g, it most
+ * likely supports 802.11b and all of the
+ * 802.11b and 802.11g speeds, so maybe we can
+ * just cheat here. Just how in the heck do
+ * we detect turbo modes, though?
+ */
+ if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) {
+ TESTSETRATE(IEEE80211_MODE_11B, IEEE80211_RATE_BASIC|2);
+ TESTSETRATE(IEEE80211_MODE_11B, IEEE80211_RATE_BASIC|4);
+ TESTSETRATE(IEEE80211_MODE_11B, IEEE80211_RATE_BASIC|11);
+ TESTSETRATE(IEEE80211_MODE_11B, IEEE80211_RATE_BASIC|22);
+ }
+ if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) {
+ TESTSETRATE(IEEE80211_MODE_11G, 48);
+ TESTSETRATE(IEEE80211_MODE_11G, 72);
+ TESTSETRATE(IEEE80211_MODE_11G, 96);
+ TESTSETRATE(IEEE80211_MODE_11G, 108);
+ }
+ if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) {
+ TESTSETRATE(IEEE80211_MODE_11A, 48);
+ TESTSETRATE(IEEE80211_MODE_11A, 72);
+ TESTSETRATE(IEEE80211_MODE_11A, 96);
+ TESTSETRATE(IEEE80211_MODE_11A, 108);
+ }
- /*
- * If the hardware supports 802.11g, it most
- * likely supports 802.11b and all of the
- * 802.11b and 802.11g speeds, so maybe we can
- * just cheat here. Just how in the heck do
- * we detect turbo modes, though?
- */
- if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) {
- TESTSETRATE(IEEE80211_MODE_11B,
- IEEE80211_RATE_BASIC|2);
- TESTSETRATE(IEEE80211_MODE_11B,
- IEEE80211_RATE_BASIC|4);
- TESTSETRATE(IEEE80211_MODE_11B,
- IEEE80211_RATE_BASIC|11);
- TESTSETRATE(IEEE80211_MODE_11B,
- IEEE80211_RATE_BASIC|22);
- }
- if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) {
- TESTSETRATE(IEEE80211_MODE_11G, 48);
- TESTSETRATE(IEEE80211_MODE_11G, 72);
- TESTSETRATE(IEEE80211_MODE_11G, 96);
- TESTSETRATE(IEEE80211_MODE_11G, 108);
- }
- if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) {
- TESTSETRATE(IEEE80211_MODE_11A, 48);
- TESTSETRATE(IEEE80211_MODE_11A, 72);
- TESTSETRATE(IEEE80211_MODE_11A, 96);
- TESTSETRATE(IEEE80211_MODE_11A, 108);
- }
#undef SETRATE
#undef INCRATE
- ieee80211_init_channels(ic, NULL, &bands);
+#undef TESTSETRATE
- /*
- * To test for WPA support, we need to see if we can
- * set AUTHENTICATION_MODE to WPA and read it back
- * successfully.
- */
- i = sizeof(arg);
- arg = NDIS_80211_AUTHMODE_WPA;
- r = ndis_set_info(sc,
- OID_802_11_AUTHENTICATION_MODE, &arg, &i);
- if (r == 0) {
- r = ndis_get_info(sc,
- OID_802_11_AUTHENTICATION_MODE, &arg, &i);
- if (r == 0 && arg == NDIS_80211_AUTHMODE_WPA)
- ic->ic_caps |= IEEE80211_C_WPA;
- }
+ ieee80211_init_channels(ic, NULL, &bands);
- /*
- * To test for supported ciphers, we set each
- * available encryption type in descending order.
- * If ENC3 works, then we have WEP, TKIP and AES.
- * If only ENC2 works, then we have WEP and TKIP.
- * If only ENC1 works, then we have just WEP.
- */
- i = sizeof(arg);
- arg = NDIS_80211_WEPSTAT_ENC3ENABLED;
- r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
- if (r == 0) {
- ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
- | IEEE80211_CRYPTO_TKIP
- | IEEE80211_CRYPTO_AES_CCM;
- goto got_crypto;
- }
- arg = NDIS_80211_WEPSTAT_ENC2ENABLED;
- r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
- if (r == 0) {
- ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
- | IEEE80211_CRYPTO_TKIP;
- goto got_crypto;
- }
- arg = NDIS_80211_WEPSTAT_ENC1ENABLED;
- r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
- if (r == 0)
- ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP;
+ /*
+ * To test for WPA support, we need to see if we can
+ * set AUTHENTICATION_MODE to WPA and read it back
+ * successfully.
+ */
+ i = sizeof(arg);
+ arg = NDIS_80211_AUTHMODE_WPA;
+ r = ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i);
+ if (r == 0) {
+ r = ndis_get_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i);
+ if (r == 0 && arg == NDIS_80211_AUTHMODE_WPA)
+ ic->ic_caps |= IEEE80211_C_WPA;
+ }
+
+ /*
+ * To test for supported ciphers, we set each
+ * available encryption type in descending order.
+ * If ENC3 works, then we have WEP, TKIP and AES.
+ * If only ENC2 works, then we have WEP and TKIP.
+ * If only ENC1 works, then we have just WEP.
+ */
+ i = sizeof(arg);
+ arg = NDIS_80211_WEPSTAT_ENC3ENABLED;
+ r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
+ if (r == 0) {
+ ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
+ | IEEE80211_CRYPTO_TKIP
+ | IEEE80211_CRYPTO_AES_CCM;
+ goto got_crypto;
+ }
+ arg = NDIS_80211_WEPSTAT_ENC2ENABLED;
+ r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
+ if (r == 0) {
+ ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
+ | IEEE80211_CRYPTO_TKIP;
+ goto got_crypto;
+ }
+ arg = NDIS_80211_WEPSTAT_ENC1ENABLED;
+ r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
+ if (r == 0)
+ ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP;
got_crypto:
- i = sizeof(arg);
- r = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &i);
- if (r == 0)
- ic->ic_caps |= IEEE80211_C_PMGT;
-
- r = ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &i);
- if (r == 0)
- ic->ic_caps |= IEEE80211_C_TXPMGT;
-
- ieee80211_ifattach(ic, eaddr);
- ic->ic_raw_xmit = ndis_raw_xmit;
- ic->ic_scan_start = ndis_scan_start;
- ic->ic_scan_end = ndis_scan_end;
- ic->ic_set_channel = ndis_set_channel;
- ic->ic_scan_curchan = ndis_scan_curchan;
- ic->ic_scan_mindwell = ndis_scan_mindwell;
- ic->ic_bsschan = IEEE80211_CHAN_ANYC;
- //ic->ic_bss->ni_chan = ic->ic_bsschan;
- ic->ic_vap_create = ndis_vap_create;
- ic->ic_vap_delete = ndis_vap_delete;
- ic->ic_update_mcast = ndis_update_mcast;
- ic->ic_update_promisc = ndis_update_promisc;
-
- if (bootverbose)
- ieee80211_announce(ic);
+ i = sizeof(arg);
+ r = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &i);
+ if (r == 0)
+ ic->ic_caps |= IEEE80211_C_PMGT;
- } else {
- ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd,
- ndis_ifmedia_sts);
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
- ifmedia_add(&sc->ifmedia,
- IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
- ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO);
- ether_ifattach(ifp, eaddr);
- }
+ r = ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &i);
+ if (r == 0)
+ ic->ic_caps |= IEEE80211_C_TXPMGT;
-fail:
- if (error) {
- ndis_detach(dev);
- return (error);
- }
+ /*
+ * Get station address from the driver.
+ */
+ len = sizeof(ic->ic_macaddr);
+ ndis_get_info(sc, OID_802_3_CURRENT_ADDRESS, &ic->ic_macaddr, &len);
+
+ ieee80211_ifattach(ic);
+ ic->ic_raw_xmit = ndis_raw_xmit;
+ ic->ic_scan_start = ndis_scan_start;
+ ic->ic_scan_end = ndis_scan_end;
+ ic->ic_set_channel = ndis_set_channel;
+ ic->ic_scan_curchan = ndis_scan_curchan;
+ ic->ic_scan_mindwell = ndis_scan_mindwell;
+ ic->ic_bsschan = IEEE80211_CHAN_ANYC;
+ ic->ic_vap_create = ndis_vap_create;
+ ic->ic_vap_delete = ndis_vap_delete;
+ ic->ic_update_mcast = ndis_update_mcast;
+ ic->ic_update_promisc = ndis_update_promisc;
+ ic->ic_transmit = ndis_80211transmit;
+ ic->ic_parent = ndis_80211parent;
+
+ if (bootverbose)
+ ieee80211_announce(ic);
- if (sc->ndis_iftype == PNPBus && ndisusb_halt == 0)
- return (error);
+ return (0);
+}
- DPRINTF(("attach done.\n"));
- /* We're done talking to the NIC for now; halt it. */
- ndis_halt_nic(sc);
- DPRINTF(("halting done.\n"));
+static int
+ndis_ifattach(struct ndis_softc *sc)
+{
+ struct ifnet *ifp;
+ u_char eaddr[ETHER_ADDR_LEN];
+ int len;
- return (error);
+ ifp = if_alloc(IFT_ETHER);
+ if (ifp == NULL)
+ return (ENOSPC);
+ sc->ifp = ifp;
+ ifp->if_softc = sc;
+
+ /* Check for task offload support. */
+ ndis_probe_offload(sc);
+
+ /*
+ * Get station address from the driver.
+ */
+ len = sizeof(eaddr);
+ ndis_get_info(sc, OID_802_3_CURRENT_ADDRESS, eaddr, &len);
+
+ if_initname(ifp, device_get_name(sc->ndis_dev),
+ device_get_unit(sc->ndis_dev));
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_ioctl = ndis_ioctl;
+ ifp->if_start = ndis_start;
+ ifp->if_init = ndis_init;
+ ifp->if_baudrate = 10000000;
+ IFQ_SET_MAXLEN(&ifp->if_snd, 50);
+ ifp->if_snd.ifq_drv_maxlen = 25;
+ IFQ_SET_READY(&ifp->if_snd);
+ ifp->if_capenable = ifp->if_capabilities;
+ ifp->if_hwassist = sc->ndis_hwassist;
+
+ ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd,
+ ndis_ifmedia_sts);
+ ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
+ ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
+ ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
+ ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
+ ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
+ ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO);
+ ether_ifattach(ifp, eaddr);
+
+ return (0);
}
static struct ieee80211vap *
@@ -985,18 +998,16 @@ ndis_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return NULL;
- nvp = (struct ndis_vap *) malloc(sizeof(struct ndis_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (nvp == NULL)
- return NULL;
+ nvp = malloc(sizeof(struct ndis_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &nvp->vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
/* override with driver methods */
nvp->newstate = vap->iv_newstate;
vap->iv_newstate = ndis_newstate;
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ndis_media_status);
+ ieee80211_vap_attach(vap, ieee80211_media_change, ndis_media_status,
+ mac);
ic->ic_opmode = opmode;
/* install key handing routines */
vap->iv_key_set = ndis_add_key;
@@ -1009,8 +1020,7 @@ ndis_vap_delete(struct ieee80211vap *vap)
{
struct ndis_vap *nvp = NDIS_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct ndis_softc *sc = ifp->if_softc;
+ struct ndis_softc *sc = ic->ic_softc;
ndis_stop(sc);
callout_drain(&sc->ndis_scan_callout);
@@ -1026,28 +1036,27 @@ ndis_vap_delete(struct ieee80211vap *vap)
* allocated.
*/
int
-ndis_detach(dev)
- device_t dev;
+ndis_detach(device_t dev)
{
- struct ndis_softc *sc;
struct ifnet *ifp;
+ struct ndis_softc *sc;
driver_object *drv;
sc = device_get_softc(dev);
NDIS_LOCK(sc);
- ifp = sc->ifp;
+ if (!sc->ndis_80211)
+ ifp = sc->ifp;
+ else
+ ifp = NULL;
if (ifp != NULL)
ifp->if_flags &= ~IFF_UP;
-
if (device_is_attached(dev)) {
NDIS_UNLOCK(sc);
ndis_stop(sc);
- if (ifp != NULL) {
- if (sc->ndis_80211)
- ieee80211_ifdetach(ifp->if_l2com);
- else
- ether_ifdetach(ifp);
- }
+ if (sc->ndis_80211)
+ ieee80211_ifdetach(&sc->ndis_ic);
+ else if (ifp != NULL)
+ ether_ifdetach(ifp);
} else
NDIS_UNLOCK(sc);
@@ -1302,11 +1311,11 @@ ndis_rxeof_xfr(dpc, adapter, sysarg1, sysarg2)
IoFreeMdl(p->np_private.npp_head);
NdisFreePacket(p);
KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock);
- _IF_ENQUEUE(&sc->ndis_rxqueue, m);
+ mbufq_enqueue(&sc->ndis_rxqueue, m);
KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock);
IoQueueWorkItem(sc->ndis_inputitem,
(io_workitem_func)ndis_inputtask_wrap,
- WORKQUEUE_CRITICAL, ifp);
+ WORKQUEUE_CRITICAL, sc);
}
if (status == NDIS_STATUS_FAILURE)
@@ -1350,11 +1359,11 @@ ndis_rxeof_xfr_done(adapter, packet, status, len)
m->m_len = m->m_pkthdr.len;
m->m_pkthdr.rcvif = ifp;
KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock);
- _IF_ENQUEUE(&sc->ndis_rxqueue, m);
+ mbufq_enqueue(&sc->ndis_rxqueue, m);
KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock);
IoQueueWorkItem(sc->ndis_inputitem,
(io_workitem_func)ndis_inputtask_wrap,
- WORKQUEUE_CRITICAL, ifp);
+ WORKQUEUE_CRITICAL, sc);
}
/*
* A frame has been uploaded: pass the resulting mbuf chain up to
@@ -1399,7 +1408,7 @@ ndis_rxeof(adapter, packets, pktcnt)
* before we're completely ready to handle them. If we detect this,
* we need to return them to the miniport and ignore them.
*/
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!sc->ndis_running) {
for (i = 0; i < pktcnt; i++) {
p = packets[i];
if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS) {
@@ -1473,11 +1482,11 @@ ndis_rxeof(adapter, packets, pktcnt)
}
KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock);
- _IF_ENQUEUE(&sc->ndis_rxqueue, m0);
+ mbufq_enqueue(&sc->ndis_rxqueue, m0);
KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock);
IoQueueWorkItem(sc->ndis_inputitem,
(io_workitem_func)ndis_inputtask_wrap,
- WORKQUEUE_CRITICAL, ifp);
+ WORKQUEUE_CRITICAL, sc);
}
}
}
@@ -1489,34 +1498,29 @@ ndis_rxeof(adapter, packets, pktcnt)
* 'dispatch level' per-cpu sleep lock).
*/
static void
-ndis_inputtask(dobj, arg)
- device_object *dobj;
- void *arg;
+ndis_inputtask(device_object *dobj, void *arg)
{
ndis_miniport_block *block;
- struct ifnet *ifp;
- struct ndis_softc *sc;
+ struct ndis_softc *sc = arg;
struct mbuf *m;
- struct ieee80211com *ic;
- struct ieee80211vap *vap;
uint8_t irql;
- ifp = arg;
- sc = ifp->if_softc;
- ic = ifp->if_l2com;
- vap = TAILQ_FIRST(&ic->ic_vaps);
block = dobj->do_devext;
KeAcquireSpinLock(&sc->ndis_rxlock, &irql);
- while(1) {
- _IF_DEQUEUE(&sc->ndis_rxqueue, m);
- if (m == NULL)
- break;
+ while ((m = mbufq_dequeue(&sc->ndis_rxqueue)) != NULL) {
KeReleaseSpinLock(&sc->ndis_rxlock, irql);
- if ((sc->ndis_80211 != 0) && (vap != NULL))
- vap->iv_deliver_data(vap, vap->iv_bss, m);
- else
+ if ((sc->ndis_80211 != 0)) {
+ struct ieee80211com *ic = &sc->ndis_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+
+ if (vap != NULL)
+ vap->iv_deliver_data(vap, vap->iv_bss, m);
+ } else {
+ struct ifnet *ifp = sc->ifp;
+
(*ifp->if_input)(ifp, m);
+ }
KeAcquireSpinLock(&sc->ndis_rxlock, &irql);
}
KeReleaseSpinLock(&sc->ndis_rxlock, irql);
@@ -1676,20 +1680,12 @@ ndis_tick(xsc)
}
static void
-ndis_ticktask(d, xsc)
- device_object *d;
- void *xsc;
+ndis_ticktask(device_object *d, void *xsc)
{
- struct ndis_softc *sc;
- struct ieee80211com *ic;
- struct ieee80211vap *vap;
+ struct ndis_softc *sc = xsc;
ndis_checkforhang_handler hangfunc;
uint8_t rval;
- sc = xsc;
- ic = sc->ifp->if_l2com;
- vap = TAILQ_FIRST(&ic->ic_vaps);
-
NDIS_LOCK(sc);
if (!NDIS_INITIALIZED(sc)) {
NDIS_UNLOCK(sc);
@@ -1712,12 +1708,18 @@ ndis_ticktask(d, xsc)
if (sc->ndis_link == 0 &&
sc->ndis_sts == NDIS_STATUS_MEDIA_CONNECT) {
sc->ndis_link = 1;
- if ((sc->ndis_80211 != 0) && (vap != NULL)) {
- NDIS_UNLOCK(sc);
- ndis_getstate_80211(sc);
- ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
- NDIS_LOCK(sc);
- if_link_state_change(vap->iv_ifp, LINK_STATE_UP);
+ if (sc->ndis_80211 != 0) {
+ struct ieee80211com *ic = &sc->ndis_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+
+ if (vap != NULL) {
+ NDIS_UNLOCK(sc);
+ ndis_getstate_80211(sc);
+ ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
+ NDIS_LOCK(sc);
+ if_link_state_change(vap->iv_ifp,
+ LINK_STATE_UP);
+ }
} else
if_link_state_change(sc->ifp, LINK_STATE_UP);
}
@@ -1725,11 +1727,17 @@ ndis_ticktask(d, xsc)
if (sc->ndis_link == 1 &&
sc->ndis_sts == NDIS_STATUS_MEDIA_DISCONNECT) {
sc->ndis_link = 0;
- if ((sc->ndis_80211 != 0) && (vap != NULL)) {
- NDIS_UNLOCK(sc);
- ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
- NDIS_LOCK(sc);
- if_link_state_change(vap->iv_ifp, LINK_STATE_DOWN);
+ if (sc->ndis_80211 != 0) {
+ struct ieee80211com *ic = &sc->ndis_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+
+ if (vap != NULL) {
+ NDIS_UNLOCK(sc);
+ ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
+ NDIS_LOCK(sc);
+ if_link_state_change(vap->iv_ifp,
+ LINK_STATE_DOWN);
+ }
} else
if_link_state_change(sc->ifp, LINK_STATE_DOWN);
}
@@ -1939,13 +1947,103 @@ ndis_start(ifp)
return;
}
+static int
+ndis_80211transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct ndis_softc *sc = ic->ic_softc;
+ ndis_packet **p0 = NULL, *p = NULL;
+ int status;
+
+ NDIS_LOCK(sc);
+ if (!sc->ndis_link || !sc->ndis_running) {
+ NDIS_UNLOCK(sc);
+ return (ENXIO);
+ }
+
+ if (sc->ndis_txpending == 0) {
+ NDIS_UNLOCK(sc);
+ return (ENOBUFS);
+ }
+
+ p0 = &sc->ndis_txarray[sc->ndis_txidx];
+
+ NdisAllocatePacket(&status,
+ &sc->ndis_txarray[sc->ndis_txidx], sc->ndis_txpool);
+
+ if (status != NDIS_STATUS_SUCCESS) {
+ NDIS_UNLOCK(sc);
+ return (ENOBUFS);
+ }
+
+ if (ndis_mtop(m, &sc->ndis_txarray[sc->ndis_txidx])) {
+ NDIS_UNLOCK(sc);
+ return (ENOBUFS);
+ }
+
+ /*
+ * Save pointer to original mbuf
+ * so we can free it later.
+ */
+
+ p = sc->ndis_txarray[sc->ndis_txidx];
+ p->np_txidx = sc->ndis_txidx;
+ p->np_m0 = m;
+ p->np_oob.npo_status = NDIS_STATUS_PENDING;
+
+ /*
+ * Do scatter/gather processing, if driver requested it.
+ */
+ if (sc->ndis_sc) {
+ bus_dmamap_load_mbuf(sc->ndis_ttag,
+ sc->ndis_tmaps[sc->ndis_txidx], m,
+ ndis_map_sclist, &p->np_sclist, BUS_DMA_NOWAIT);
+ bus_dmamap_sync(sc->ndis_ttag,
+ sc->ndis_tmaps[sc->ndis_txidx],
+ BUS_DMASYNC_PREREAD);
+ p->np_ext.npe_info[ndis_sclist_info] = &p->np_sclist;
+ }
+
+ NDIS_INC(sc);
+ sc->ndis_txpending--;
+
+ /*
+ * Set a timeout in case the chip goes out to lunch.
+ */
+ sc->ndis_tx_timer = 5;
+ NDIS_UNLOCK(sc);
+
+ /*
+ * According to NDIS documentation, if a driver exports
+ * a MiniportSendPackets() routine, we prefer that over
+ * a MiniportSend() routine (which sends just a single
+ * packet).
+ */
+ if (sc->ndis_chars->nmc_sendmulti_func != NULL)
+ ndis_send_packets(sc, p0, 1);
+ else
+ ndis_send_packet(sc, p);
+
+ return (0);
+}
+
static void
-ndis_init(xsc)
- void *xsc;
+ndis_80211parent(struct ieee80211com *ic)
+{
+ struct ndis_softc *sc = ic->ic_softc;
+
+ /*NDIS_LOCK(sc);*/
+ if (ic->ic_nrunning > 0) {
+ if (!sc->ndis_running)
+ ndis_init(sc);
+ } else if (sc->ndis_running)
+ ndis_stop(sc);
+ /*NDIS_UNLOCK(sc);*/
+}
+
+static void
+ndis_init(void *xsc)
{
struct ndis_softc *sc = xsc;
- struct ifnet *ifp = sc->ifp;
- struct ieee80211com *ic = ifp->if_l2com;
int i, len, error;
/*
@@ -1971,17 +2069,21 @@ ndis_init(xsc)
}
}
- /* Init our MAC address */
-
/* Program the packet filter */
+ sc->ndis_filter = NDIS_PACKET_TYPE_DIRECTED |
+ NDIS_PACKET_TYPE_BROADCAST;
- sc->ndis_filter = NDIS_PACKET_TYPE_DIRECTED;
+ if (sc->ndis_80211) {
+ struct ieee80211com *ic = &sc->ndis_ic;
- if (ifp->if_flags & IFF_BROADCAST)
- sc->ndis_filter |= NDIS_PACKET_TYPE_BROADCAST;
+ if (ic->ic_promisc > 0)
+ sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS;
+ } else {
+ struct ifnet *ifp = sc->ifp;
- if (ifp->if_flags & IFF_PROMISC)
- sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS;
+ if (ifp->if_flags & IFF_PROMISC)
+ sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS;
+ }
len = sizeof(sc->ndis_filter);
@@ -1994,7 +2096,10 @@ ndis_init(xsc)
/*
* Set lookahead.
*/
- i = ifp->if_mtu;
+ if (sc->ndis_80211)
+ i = ETHERMTU;
+ else
+ i = sc->ifp->if_mtu;
len = sizeof(i);
ndis_set_info(sc, OID_GEN_CURRENT_LOOKAHEAD, &i, &len);
@@ -2012,10 +2117,12 @@ ndis_init(xsc)
sc->ndis_txpending = sc->ndis_maxpkts;
sc->ndis_link = 0;
- if_link_state_change(sc->ifp, LINK_STATE_UNKNOWN);
+ if (!sc->ndis_80211) {
+ if_link_state_change(sc->ifp, LINK_STATE_UNKNOWN);
+ sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ }
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
sc->ndis_tx_timer = 0;
/*
@@ -2029,11 +2136,12 @@ ndis_init(xsc)
sc->ndis_hang_timer = sc->ndis_block->nmb_checkforhangsecs;
callout_reset(&sc->ndis_stat_callout, hz, ndis_tick, sc);
+ sc->ndis_running = 1;
NDIS_UNLOCK(sc);
/* XXX force handling */
if (sc->ndis_80211)
- ieee80211_start_all(ic); /* start all vap's */
+ ieee80211_start_all(&sc->ndis_ic); /* start all vap's */
}
/*
@@ -2101,16 +2209,12 @@ ndis_ifmedia_sts(ifp, ifmr)
}
static int
-ndis_set_cipher(sc, cipher)
- struct ndis_softc *sc;
- int cipher;
+ndis_set_cipher(struct ndis_softc *sc, int cipher)
{
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->ndis_ic;
int rval = 0, len;
uint32_t arg, save;
- ic = sc->ifp->if_l2com;
-
len = sizeof(arg);
if (cipher == WPA_CSE_WEP40 || cipher == WPA_CSE_WEP104) {
@@ -2239,7 +2343,7 @@ static void
ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr)
{
struct ieee80211vap *vap = ifp->if_softc;
- struct ndis_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct ndis_softc *sc = vap->iv_ic->ic_softc;
uint32_t txrate;
int len;
@@ -2253,20 +2357,14 @@ ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr)
}
static void
-ndis_setstate_80211(sc)
- struct ndis_softc *sc;
+ndis_setstate_80211(struct ndis_softc *sc)
{
- struct ieee80211com *ic;
- struct ieee80211vap *vap;
+ struct ieee80211com *ic = &sc->ndis_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
ndis_80211_macaddr bssid;
ndis_80211_config config;
int rval = 0, len;
uint32_t arg;
- struct ifnet *ifp;
-
- ifp = sc->ifp;
- ic = ifp->if_l2com;
- vap = TAILQ_FIRST(&ic->ic_vaps);
if (!NDIS_INITIALIZED(sc)) {
DPRINTF(("%s: NDIS not initialized\n", __func__));
@@ -2371,7 +2469,7 @@ ndis_setstate_80211(sc)
/* Set the BSSID to our value so the driver doesn't associate */
len = IEEE80211_ADDR_LEN;
- bcopy(IF_LLADDR(ifp), bssid, len);
+ bcopy(vap->iv_myaddr, bssid, len);
DPRINTF(("Setting BSSID to %6D\n", (uint8_t *)&bssid, ":"));
rval = ndis_set_info(sc, OID_802_11_BSSID, &bssid, &len);
if (rval)
@@ -2380,22 +2478,14 @@ ndis_setstate_80211(sc)
}
static void
-ndis_auth_and_assoc(sc, vap)
- struct ndis_softc *sc;
- struct ieee80211vap *vap;
+ndis_auth_and_assoc(struct ndis_softc *sc, struct ieee80211vap *vap)
{
- struct ieee80211com *ic;
- struct ieee80211_node *ni;
+ struct ieee80211_node *ni = vap->iv_bss;
ndis_80211_ssid ssid;
ndis_80211_macaddr bssid;
ndis_80211_wep wep;
int i, rval = 0, len, error;
uint32_t arg;
- struct ifnet *ifp;
-
- ifp = sc->ifp;
- ic = ifp->if_l2com;
- ni = vap->iv_bss;
if (!NDIS_INITIALIZED(sc)) {
DPRINTF(("%s: NDIS not initialized\n", __func__));
@@ -2562,7 +2652,7 @@ ndis_auth_and_assoc(sc, vap)
vap->iv_opmode != IEEE80211_M_IBSS)
bcopy(ni->ni_bssid, bssid, len);
else
- bcopy(ifp->if_broadcastaddr, bssid, len);
+ bcopy(ieee80211broadcastaddr, bssid, len);
DPRINTF(("Setting BSSID to %6D\n", (uint8_t *)&bssid, ":"));
rval = ndis_set_info(sc, OID_802_11_BSSID, &bssid, &len);
@@ -2627,12 +2717,9 @@ ndis_get_bssid_list(sc, bl)
}
static int
-ndis_get_assoc(sc, assoc)
- struct ndis_softc *sc;
- ndis_wlan_bssid_ex **assoc;
+ndis_get_assoc(struct ndis_softc *sc, ndis_wlan_bssid_ex **assoc)
{
- struct ifnet *ifp = sc->ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->ndis_ic;
struct ieee80211vap *vap;
struct ieee80211_node *ni;
ndis_80211_bssid_list_ex *bl;
@@ -2679,22 +2766,15 @@ ndis_get_assoc(sc, assoc)
}
static void
-ndis_getstate_80211(sc)
- struct ndis_softc *sc;
+ndis_getstate_80211(struct ndis_softc *sc)
{
- struct ieee80211com *ic;
- struct ieee80211vap *vap;
- struct ieee80211_node *ni;
+ struct ieee80211com *ic = &sc->ndis_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ struct ieee80211_node *ni = vap->iv_bss;
ndis_wlan_bssid_ex *bs;
int rval, len, i = 0;
int chanflag;
uint32_t arg;
- struct ifnet *ifp;
-
- ifp = sc->ifp;
- ic = ifp->if_l2com;
- vap = TAILQ_FIRST(&ic->ic_vaps);
- ni = vap->iv_bss;
if (!NDIS_INITIALIZED(sc))
return;
@@ -2813,7 +2893,7 @@ ndis_ioctl(ifp, command, data)
switch (command) {
case SIOCSIFFLAGS:
if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
+ if (sc->ndis_running &&
ifp->if_flags & IFF_PROMISC &&
!(sc->ndis_if_flags & IFF_PROMISC)) {
sc->ndis_filter |=
@@ -2822,7 +2902,7 @@ ndis_ioctl(ifp, command, data)
error = ndis_set_info(sc,
OID_GEN_CURRENT_PACKET_FILTER,
&sc->ndis_filter, &i);
- } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
+ } else if (sc->ndis_running &&
!(ifp->if_flags & IFF_PROMISC) &&
sc->ndis_if_flags & IFF_PROMISC) {
sc->ndis_filter &=
@@ -2834,7 +2914,7 @@ ndis_ioctl(ifp, command, data)
} else
ndis_init(sc);
} else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->ndis_running)
ndis_stop(sc);
}
sc->ndis_if_flags = ifp->if_flags;
@@ -2868,101 +2948,48 @@ ndis_ioctl(ifp, command, data)
}
static int
-ndis_ioctl_80211(ifp, command, data)
- struct ifnet *ifp;
- u_long command;
- caddr_t data;
+ndis_80211ioctl(struct ieee80211com *ic, u_long cmd, void *data)
{
- struct ndis_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- struct ndis_oid_data oid;
- struct ndis_evt evt;
- void *oidbuf;
- int error = 0;
+ struct ndis_softc *sc = ic->ic_softc;
+ struct ifreq *ifr = data;
+ struct ndis_oid_data oid;
+ struct ndis_evt evt;
+ void *oidbuf = NULL;
+ int error = 0;
+
+ if ((error = priv_check(curthread, PRIV_DRIVER)) != 0)
+ return (error);
- switch (command) {
- case SIOCSIFFLAGS:
- /*NDIS_LOCK(sc);*/
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- ndis_init(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ndis_stop(sc);
- }
- sc->ndis_if_flags = ifp->if_flags;
- error = 0;
- /*NDIS_UNLOCK(sc);*/
- break;
+ switch (cmd) {
case SIOCGDRVSPEC:
- if ((error = priv_check(curthread, PRIV_DRIVER)))
- break;
- error = copyin(ifr->ifr_data, &oid, sizeof(oid));
+ case SIOCSDRVSPEC:
+ error = copyin(ifr->ifr_data, &oid, sizeof(oid));
if (error)
break;
- oidbuf = malloc(oid.len, M_TEMP, M_NOWAIT|M_ZERO);
- if (oidbuf == NULL) {
- error = ENOMEM;
- break;
- }
- error = copyin(ifr->ifr_data + sizeof(oid), oidbuf, oid.len);
- if (error) {
- free(oidbuf, M_TEMP);
- break;
- }
- error = ndis_get_info(sc, oid.oid, oidbuf, &oid.len);
- if (error) {
- free(oidbuf, M_TEMP);
- break;
- }
- error = copyout(&oid, ifr->ifr_data, sizeof(oid));
- if (error) {
- free(oidbuf, M_TEMP);
- break;
- }
- error = copyout(oidbuf, ifr->ifr_data + sizeof(oid), oid.len);
+ oidbuf = malloc(oid.len, M_TEMP, M_WAITOK | M_ZERO);
+ error = copyin(ifr->ifr_data + sizeof(oid), oidbuf, oid.len);
+ }
+
+ if (error) {
free(oidbuf, M_TEMP);
+ return (error);
+ }
+
+ switch (cmd) {
+ case SIOCGDRVSPEC:
+ error = ndis_get_info(sc, oid.oid, oidbuf, &oid.len);
break;
case SIOCSDRVSPEC:
- if ((error = priv_check(curthread, PRIV_DRIVER)))
- break;
- error = copyin(ifr->ifr_data, &oid, sizeof(oid));
- if (error)
- break;
- oidbuf = malloc(oid.len, M_TEMP, M_NOWAIT|M_ZERO);
- if (oidbuf == NULL) {
- error = ENOMEM;
- break;
- }
- error = copyin(ifr->ifr_data + sizeof(oid), oidbuf, oid.len);
- if (error) {
- free(oidbuf, M_TEMP);
- break;
- }
error = ndis_set_info(sc, oid.oid, oidbuf, &oid.len);
- if (error) {
- free(oidbuf, M_TEMP);
- break;
- }
- error = copyout(&oid, ifr->ifr_data, sizeof(oid));
- if (error) {
- free(oidbuf, M_TEMP);
- break;
- }
- error = copyout(oidbuf, ifr->ifr_data + sizeof(oid), oid.len);
- free(oidbuf, M_TEMP);
break;
case SIOCGPRIVATE_0:
- if ((error = priv_check(curthread, PRIV_DRIVER)))
- break;
NDIS_LOCK(sc);
if (sc->ndis_evt[sc->ndis_evtcidx].ne_sts == 0) {
error = ENOENT;
NDIS_UNLOCK(sc);
break;
}
- error = copyin(ifr->ifr_data, &evt, sizeof(evt));
+ error = copyin(ifr->ifr_data, &evt, sizeof(evt));
if (error) {
NDIS_UNLOCK(sc);
break;
@@ -2994,30 +3021,32 @@ ndis_ioctl_80211(ifp, command, data)
NDIS_EVTINC(sc->ndis_evtcidx);
NDIS_UNLOCK(sc);
break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, command);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, command, data);
- break;
default:
- error = EINVAL;
+ error = ENOTTY;
break;
}
+
+ switch (cmd) {
+ case SIOCGDRVSPEC:
+ case SIOCSDRVSPEC:
+ error = copyout(&oid, ifr->ifr_data, sizeof(oid));
+ if (error)
+ break;
+ error = copyout(oidbuf, ifr->ifr_data + sizeof(oid), oid.len);
+ }
+
+ free(oidbuf, M_TEMP);
+
return (error);
}
int
-ndis_del_key(vap, key)
- struct ieee80211vap *vap;
- const struct ieee80211_key *key;
+ndis_del_key(struct ieee80211vap *vap, const struct ieee80211_key *key)
{
- struct ndis_softc *sc;
+ struct ndis_softc *sc = vap->iv_ic->ic_softc;
ndis_80211_key rkey;
int len, error = 0;
- sc = vap->iv_ic->ic_ifp->if_softc;
-
bzero((char *)&rkey, sizeof(rkey));
len = sizeof(rkey);
@@ -3041,19 +3070,13 @@ ndis_del_key(vap, key)
* set after initial authentication with the AP.
*/
static int
-ndis_add_key(vap, key, mac)
- struct ieee80211vap *vap;
- const struct ieee80211_key *key;
- const uint8_t mac[IEEE80211_ADDR_LEN];
+ndis_add_key(struct ieee80211vap *vap, const struct ieee80211_key *key,
+ const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct ndis_softc *sc;
- struct ifnet *ifp;
+ struct ndis_softc *sc = vap->iv_ic->ic_softc;
ndis_80211_key rkey;
int len, error = 0;
- ifp = vap->iv_ic->ic_ifp;
- sc = ifp->if_softc;
-
switch (key->wk_cipher->ic_cipher) {
case IEEE80211_CIPHER_TKIP:
@@ -3077,7 +3100,7 @@ ndis_add_key(vap, key, mac)
rkey.nk_keyidx |= 1 << 31;
if (key->wk_flags & IEEE80211_KEY_GROUP) {
- bcopy(ifp->if_broadcastaddr,
+ bcopy(ieee80211broadcastaddr,
rkey.nk_bssid, IEEE80211_ADDR_LEN);
} else {
bcopy(vap->iv_bss->ni_bssid,
@@ -3138,19 +3161,18 @@ ndis_resettask(d, arg)
* RX and TX lists.
*/
static void
-ndis_stop(sc)
- struct ndis_softc *sc;
+ndis_stop(struct ndis_softc *sc)
{
- struct ifnet *ifp;
int i;
- ifp = sc->ifp;
callout_drain(&sc->ndis_stat_callout);
NDIS_LOCK(sc);
sc->ndis_tx_timer = 0;
sc->ndis_link = 0;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ if (!sc->ndis_80211)
+ sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->ndis_running = 0;
NDIS_UNLOCK(sc);
if (sc->ndis_iftype != PNPBus ||
@@ -3192,8 +3214,7 @@ ndis_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct ndis_vap *nvp = NDIS_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct ndis_softc *sc = ifp->if_softc;
+ struct ndis_softc *sc = ic->ic_softc;
enum ieee80211_state ostate;
DPRINTF(("%s: %s -> %s\n", __func__,
@@ -3239,8 +3260,8 @@ ndis_scan(void *arg)
static void
ndis_scan_results(struct ndis_softc *sc)
{
- struct ieee80211com *ic;
- struct ieee80211vap *vap;
+ struct ieee80211com *ic = &sc->ndis_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
ndis_80211_bssid_list_ex *bl;
ndis_wlan_bssid_ex *wb;
struct ieee80211_scanparams sp;
@@ -3252,8 +3273,6 @@ ndis_scan_results(struct ndis_softc *sc)
uint8_t rates[2+IEEE80211_RATE_MAXSIZE];
uint8_t *frm, *efrm;
- ic = sc->ifp->if_l2com;
- vap = TAILQ_FIRST(&ic->ic_vaps);
saved_chan = ic->ic_curchan;
noise = -96;
@@ -3329,8 +3348,7 @@ done:
static void
ndis_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct ndis_softc *sc = ifp->if_softc;
+ struct ndis_softc *sc = ic->ic_softc;
struct ieee80211vap *vap;
struct ieee80211_scan_state *ss;
ndis_80211_ssid ssid;
@@ -3391,7 +3409,7 @@ ndis_scan_mindwell(struct ieee80211_scan_state *ss)
static void
ndis_scan_end(struct ieee80211com *ic)
{
- struct ndis_softc *sc = ic->ic_ifp->if_softc;
+ struct ndis_softc *sc = ic->ic_softc;
ndis_scan_results(sc);
}
diff --git a/sys/dev/if_ndis/if_ndisvar.h b/sys/dev/if_ndis/if_ndisvar.h
index f98db0a..e3b1a39 100644
--- a/sys/dev/if_ndis/if_ndisvar.h
+++ b/sys/dev/if_ndis/if_ndisvar.h
@@ -152,8 +152,22 @@ struct ndisusb_task {
};
struct ndis_softc {
- struct ifnet *ifp;
- struct ifmedia ifmedia; /* media info */
+ u_int ndis_80211:1,
+ ndis_link:1,
+ ndis_running:1;
+ union {
+ struct { /* Ethernet */
+ struct ifnet *ifp;
+ struct ifmedia ifmedia;
+ int ndis_if_flags;
+ };
+ struct { /* Wireless */
+ struct ieee80211com ndis_ic;
+ struct callout ndis_scan_callout;
+ int (*ndis_newstate)(struct ieee80211com *,
+ enum ieee80211_state, int);
+ };
+ };
u_long ndis_hwassist;
uint32_t ndis_v4tx;
uint32_t ndis_v4rx;
@@ -180,7 +194,6 @@ struct ndis_softc {
ndis_miniport_block *ndis_block;
ndis_miniport_characteristics *ndis_chars;
interface_type ndis_type;
- struct callout ndis_scan_callout;
struct callout ndis_stat_callout;
int ndis_maxpkts;
ndis_oid *ndis_oids;
@@ -192,13 +205,9 @@ struct ndis_softc {
int ndis_sc;
ndis_cfg *ndis_regvals;
struct nch ndis_cfglist_head;
- int ndis_80211;
- int ndis_link;
uint32_t ndis_sts;
uint32_t ndis_filter;
- int ndis_if_flags;
int ndis_skip;
-
int ndis_devidx;
interface_type ndis_iftype;
driver_object *ndis_dobj;
@@ -217,11 +226,9 @@ struct ndis_softc {
struct ndis_evt ndis_evt[NDIS_EVENTS];
int ndis_evtpidx;
int ndis_evtcidx;
- struct ifqueue ndis_rxqueue;
+ struct mbufq ndis_rxqueue;
kspin_lock ndis_rxlock;
- int (*ndis_newstate)(struct ieee80211com *,
- enum ieee80211_state, int);
int ndis_tx_timer;
int ndis_hang_timer;
diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c
index d3eb85e..1ffd24c 100644
--- a/sys/dev/ipw/if_ipw.c
+++ b/sys/dev/ipw/if_ipw.c
@@ -127,14 +127,14 @@ static void ipw_intr(void *);
static void ipw_dma_map_addr(void *, bus_dma_segment_t *, int, int);
static const char * ipw_cmdname(int);
static int ipw_cmd(struct ipw_softc *, uint32_t, void *, uint32_t);
-static int ipw_tx_start(struct ifnet *, struct mbuf *,
+static int ipw_tx_start(struct ipw_softc *, struct mbuf *,
struct ieee80211_node *);
static int ipw_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void ipw_start(struct ifnet *);
-static void ipw_start_locked(struct ifnet *);
+static int ipw_transmit(struct ieee80211com *, struct mbuf *);
+static void ipw_start(struct ipw_softc *);
static void ipw_watchdog(void *);
-static int ipw_ioctl(struct ifnet *, u_long, caddr_t);
+static void ipw_parent(struct ieee80211com *);
static void ipw_stop_master(struct ipw_softc *);
static int ipw_enable(struct ipw_softc *);
static int ipw_disable(struct ipw_softc *);
@@ -220,18 +220,16 @@ static int
ipw_attach(device_t dev)
{
struct ipw_softc *sc = device_get_softc(dev);
- struct ifnet *ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_channel *c;
uint16_t val;
int error, i;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_dev = dev;
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
-
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
TASK_INIT(&sc->sc_init_task, 0, ipw_init_task, sc);
callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0);
@@ -268,24 +266,6 @@ ipw_attach(device_t dev)
goto fail2;
}
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(dev, "can not if_alloc()\n");
- goto fail3;
- }
- ic = ifp->if_l2com;
-
- ifp->if_softc = sc;
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = ipw_init;
- ifp->if_ioctl = ipw_ioctl;
- ifp->if_start = ipw_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_opmode = IEEE80211_M_STA;
@@ -303,14 +283,14 @@ ipw_attach(device_t dev)
/* read MAC address from EEPROM */
val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 0);
- macaddr[0] = val >> 8;
- macaddr[1] = val & 0xff;
+ ic->ic_macaddr[0] = val >> 8;
+ ic->ic_macaddr[1] = val & 0xff;
val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 1);
- macaddr[2] = val >> 8;
- macaddr[3] = val & 0xff;
+ ic->ic_macaddr[2] = val >> 8;
+ ic->ic_macaddr[3] = val & 0xff;
val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 2);
- macaddr[4] = val >> 8;
- macaddr[5] = val & 0xff;
+ ic->ic_macaddr[4] = val >> 8;
+ ic->ic_macaddr[5] = val & 0xff;
/* set supported .11b channels (read from EEPROM) */
if ((val = ipw_read_prom_word(sc, IPW_EEPROM_CHANNEL_LIST)) == 0)
@@ -329,16 +309,17 @@ ipw_attach(device_t dev)
if (!(ipw_read_prom_word(sc, IPW_EEPROM_RADIO) & 8))
sc->flags |= IPW_FLAG_HAS_RADIO_SWITCH;
- ieee80211_ifattach(ic, macaddr);
+ ieee80211_ifattach(ic);
ic->ic_scan_start = ipw_scan_start;
ic->ic_scan_end = ipw_scan_end;
ic->ic_set_channel = ipw_set_channel;
ic->ic_scan_curchan = ipw_scan_curchan;
ic->ic_scan_mindwell = ipw_scan_mindwell;
ic->ic_raw_xmit = ipw_raw_xmit;
-
ic->ic_vap_create = ipw_vap_create;
ic->ic_vap_delete = ipw_vap_delete;
+ ic->ic_transmit = ipw_transmit;
+ ic->ic_parent = ipw_parent;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -366,15 +347,13 @@ ipw_attach(device_t dev)
NULL, ipw_intr, sc, &sc->sc_ih);
if (error != 0) {
device_printf(dev, "could not set up interrupt\n");
- goto fail4;
+ goto fail3;
}
if (bootverbose)
ieee80211_announce(ic);
return 0;
-fail4:
- if_free(ifp);
fail3:
ipw_release(sc);
fail2:
@@ -391,8 +370,7 @@ static int
ipw_detach(device_t dev)
{
struct ipw_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
bus_teardown_intr(dev, sc->irq, sc->sc_ih);
@@ -402,6 +380,7 @@ ipw_detach(device_t dev)
ieee80211_ifdetach(ic);
callout_drain(&sc->sc_wdtimer);
+ mbufq_drain(&sc->sc_snd);
ipw_release(sc);
@@ -410,8 +389,6 @@ ipw_detach(device_t dev)
bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem),
sc->mem);
- if_free(ifp);
-
if (sc->sc_firmware != NULL) {
firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD);
sc->sc_firmware = NULL;
@@ -428,8 +405,7 @@ ipw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct ifnet *ifp = ic->ic_ifp;
- struct ipw_softc *sc = ifp->if_softc;
+ struct ipw_softc *sc = ic->ic_softc;
struct ipw_vap *ivp;
struct ieee80211vap *vap;
const struct firmware *fp;
@@ -487,19 +463,17 @@ ipw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
return NULL;
}
- ivp = (struct ipw_vap *) malloc(sizeof(struct ipw_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (ivp == NULL)
- return NULL;
+ ivp = malloc(sizeof(struct ipw_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &ivp->vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
/* override with driver methods */
ivp->newstate = vap->iv_newstate;
vap->iv_newstate = ipw_newstate;
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status);
+ ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status,
+ mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -827,7 +801,7 @@ static int
ipw_suspend(device_t dev)
{
struct ipw_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
ieee80211_suspend_all(ic);
return 0;
@@ -837,7 +811,7 @@ static int
ipw_resume(device_t dev)
{
struct ipw_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
pci_write_config(dev, 0x41, 0, 1);
@@ -866,7 +840,7 @@ ipw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
{
struct ieee80211vap *vap = ifp->if_softc;
struct ieee80211com *ic = vap->iv_ic;
- struct ipw_softc *sc = ic->ic_ifp->if_softc;
+ struct ipw_softc *sc = ic->ic_softc;
/* read current transmission rate from adapter */
vap->iv_bss->ni_txrate = ipw_cvtrate(
@@ -879,8 +853,7 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct ipw_vap *ivp = IPW_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct ipw_softc *sc = ifp->if_softc;
+ struct ipw_softc *sc = ic->ic_softc;
enum ieee80211_state ostate;
DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__,
@@ -1015,8 +988,7 @@ static void
ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
{
#define IEEESTATE(vap) ieee80211_state_name[vap->iv_state]
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t state;
@@ -1118,8 +1090,7 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
static void
ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
ic->ic_curchan = chan;
ieee80211_radiotap_chan_change(ic);
@@ -1132,8 +1103,7 @@ ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan)
static void
ipw_fix_channel(struct ipw_softc *sc, struct mbuf *m)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_channel *c;
struct ieee80211_frame *wh;
uint8_t subtype;
@@ -1178,8 +1148,7 @@ static void
ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
struct ipw_soft_bd *sbd, struct ipw_soft_buf *sbuf)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct mbuf *mnew, *m;
struct ieee80211_node *ni;
bus_addr_t physaddr;
@@ -1201,7 +1170,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
*/
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (mnew == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
@@ -1222,7 +1191,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
panic("%s: could not load old rx mbuf",
device_get_name(sc->sc_dev));
}
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
@@ -1233,9 +1202,6 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
m = sbuf->m;
sbuf->m = mnew;
sbd->bd->physaddr = htole32(physaddr);
-
- /* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = le32toh(status->len);
rssi = status->rssi + IPW_RSSI_TO_DBM;
@@ -1364,7 +1330,6 @@ ipw_release_sbd(struct ipw_softc *sc, struct ipw_soft_bd *sbd)
static void
ipw_tx_intr(struct ipw_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
struct ipw_soft_bd *sbd;
uint32_t r, i;
@@ -1375,10 +1340,6 @@ ipw_tx_intr(struct ipw_softc *sc)
for (i = (sc->txold + 1) % IPW_NTBD; i != r; i = (i + 1) % IPW_NTBD) {
sbd = &sc->stbd_list[i];
-
- if (sbd->type == IPW_SBD_TYPE_DATA)
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
ipw_release_sbd(sc, sbd);
sc->txfree++;
}
@@ -1386,15 +1347,13 @@ ipw_tx_intr(struct ipw_softc *sc)
/* remember what the firmware has processed */
sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ipw_start_locked(ifp);
+ ipw_start(sc);
}
static void
ipw_fatal_error_intr(struct ipw_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
device_printf(sc->sc_dev, "firmware error\n");
@@ -1579,10 +1538,9 @@ ipw_cmd(struct ipw_softc *sc, uint32_t type, void *data, uint32_t len)
}
static int
-ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
+ipw_tx_start(struct ipw_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
- struct ipw_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_frame *wh;
struct ipw_soft_bd *sbd;
@@ -1736,38 +1694,42 @@ ipw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
}
-static void
-ipw_start(struct ifnet *ifp)
+static int
+ipw_transmit(struct ieee80211com *ic, struct mbuf *m)
{
- struct ipw_softc *sc = ifp->if_softc;
+ struct ipw_softc *sc = ic->ic_softc;
+ int error;
IPW_LOCK(sc);
- ipw_start_locked(ifp);
+ if ((sc->flags & IPW_FLAG_RUNNING) == 0) {
+ IPW_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ IPW_UNLOCK(sc);
+ return (error);
+ }
+ ipw_start(sc);
IPW_UNLOCK(sc);
+ return (0);
}
static void
-ipw_start_locked(struct ifnet *ifp)
+ipw_start(struct ipw_softc *sc)
{
- struct ipw_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
IPW_LOCK_ASSERT(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->txfree < 1 + IPW_MAX_NSEG) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
+ while (sc->txfree < 1 + IPW_MAX_NSEG &&
+ (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
- if (ipw_tx_start(ifp, m, ni) != 0) {
+ if (ipw_tx_start(sc, m, ni) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
break;
}
/* start watchdog timer */
@@ -1779,15 +1741,14 @@ static void
ipw_watchdog(void *arg)
{
struct ipw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
IPW_LOCK_ASSERT(sc);
if (sc->sc_tx_timer > 0) {
if (--sc->sc_tx_timer == 0) {
- if_printf(ifp, "device timeout\n");
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ device_printf(sc->sc_dev, "device timeout\n");
+ counter_u64_add(ic->ic_oerrors, 1);
taskqueue_enqueue(taskqueue_swi, &sc->sc_init_task);
}
}
@@ -1803,45 +1764,27 @@ ipw_watchdog(void *arg)
}
}
}
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->flags & IPW_FLAG_RUNNING)
callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc);
}
-static int
-ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+ipw_parent(struct ieee80211com *ic)
{
- struct ipw_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
+ struct ipw_softc *sc = ic->ic_softc;
+ int startall = 0;
- switch (cmd) {
- case SIOCSIFFLAGS:
- IPW_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- ipw_init_locked(sc);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ipw_stop_locked(sc);
+ IPW_LOCK(sc);
+ if (ic->ic_nrunning > 0) {
+ if (!(sc->flags & IPW_FLAG_RUNNING)) {
+ ipw_init_locked(sc);
+ startall = 1;
}
- IPW_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
+ } else if (sc->flags & IPW_FLAG_RUNNING)
+ ipw_stop_locked(sc);
+ IPW_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
@@ -2057,8 +2000,7 @@ ipw_load_firmware(struct ipw_softc *sc, const char *fw, int size)
static int
ipw_setwepkeys(struct ipw_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ipw_wep_key wepkey;
struct ieee80211_key *wk;
@@ -2201,8 +2143,7 @@ done:
static int
ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t data;
int error;
@@ -2217,8 +2158,7 @@ ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan)
static void
ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap)
{
- struct ifnet *ifp = vap->iv_ic->ic_ifp;
- struct ipw_softc *sc = ifp->if_softc;
+ struct ipw_softc *sc = ic->ic_softc;
struct ieee80211_node *ni = vap->iv_bss;
struct ipw_security security;
uint32_t data;
@@ -2309,9 +2249,8 @@ done:
static void
ipw_disassoc(struct ieee80211com *ic, struct ieee80211vap *vap)
{
- struct ifnet *ifp = vap->iv_ic->ic_ifp;
struct ieee80211_node *ni = vap->iv_bss;
- struct ipw_softc *sc = ifp->if_softc;
+ struct ipw_softc *sc = ic->ic_softc;
IPW_LOCK(sc);
DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":"));
@@ -2345,22 +2284,20 @@ static void
ipw_init(void *priv)
{
struct ipw_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
IPW_LOCK(sc);
ipw_init_locked(sc);
IPW_UNLOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->flags & IPW_FLAG_RUNNING)
ieee80211_start_all(ic); /* start all vap's */
}
static void
ipw_init_locked(struct ipw_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
const struct firmware *fp;
const struct ipw_firmware_hdr *hdr;
@@ -2444,22 +2381,19 @@ ipw_init_locked(struct ipw_softc *sc)
}
callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
-
- sc->flags &=~ IPW_FLAG_INIT_LOCKED;
+ sc->flags |= IPW_FLAG_RUNNING;
+ sc->flags &= ~IPW_FLAG_INIT_LOCKED;
return;
fail:
ipw_stop_locked(sc);
- sc->flags &=~ IPW_FLAG_INIT_LOCKED;
+ sc->flags &= ~IPW_FLAG_INIT_LOCKED;
}
static int
ipw_config(struct ipw_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ipw_configuration config;
uint32_t data;
int error;
@@ -2504,7 +2438,7 @@ ipw_config(struct ipw_softc *sc)
IPW_CFG_PREAMBLE_AUTO | IPW_CFG_802_1x_ENABLE);
if (ic->ic_opmode == IEEE80211_M_IBSS)
config.flags |= htole32(IPW_CFG_IBSS_AUTO_START);
- if (ifp->if_flags & IFF_PROMISC)
+ if (ic->ic_promisc > 0)
config.flags |= htole32(IPW_CFG_PROMISCUOUS);
config.bss_chan = htole32(0x3fff); /* channels 1-14 */
config.ibss_chan = htole32(0x7ff); /* channels 1-11 */
@@ -2562,7 +2496,6 @@ ipw_stop(void *priv)
static void
ipw_stop_locked(struct ipw_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
int i;
IPW_LOCK_ASSERT(sc);
@@ -2579,7 +2512,7 @@ ipw_stop_locked(struct ipw_softc *sc)
ipw_release_sbd(sc, &sc->stbd_list[i]);
sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->flags &= ~IPW_FLAG_RUNNING;
}
static int
@@ -2677,8 +2610,7 @@ ipw_write_mem_1(struct ipw_softc *sc, bus_size_t offset, const uint8_t *datap,
static void
ipw_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct ipw_softc *sc = ifp->if_softc;
+ struct ipw_softc *sc = ic->ic_softc;
IPW_LOCK(sc);
ipw_scan(sc);
@@ -2688,8 +2620,7 @@ ipw_scan_start(struct ieee80211com *ic)
static void
ipw_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct ipw_softc *sc = ifp->if_softc;
+ struct ipw_softc *sc = ic->ic_softc;
IPW_LOCK(sc);
if (ic->ic_opmode == IEEE80211_M_MONITOR) {
@@ -2715,8 +2646,7 @@ ipw_scan_mindwell(struct ieee80211_scan_state *ss)
static void
ipw_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct ipw_softc *sc = ifp->if_softc;
+ struct ipw_softc *sc = ic->ic_softc;
IPW_LOCK(sc);
sc->flags &= ~IPW_FLAG_SCANNING;
diff --git a/sys/dev/ipw/if_ipwvar.h b/sys/dev/ipw/if_ipwvar.h
index cca050f..aa3ba5b 100644
--- a/sys/dev/ipw/if_ipwvar.h
+++ b/sys/dev/ipw/if_ipwvar.h
@@ -87,7 +87,8 @@ struct ipw_vap {
#define IPW_VAP(vap) ((struct ipw_vap *)(vap))
struct ipw_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct mtx sc_mtx;
@@ -104,6 +105,7 @@ struct ipw_softc {
#define IPW_FLAG_BUSY 0x0040
#define IPW_FLAG_ASSOCIATING 0x0080
#define IPW_FLAG_ASSOCIATED 0x0100
+#define IPW_FLAG_RUNNING 0x0200
struct resource *irq;
struct resource *mem;
diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c
index fecbe89..73631ea 100644
--- a/sys/dev/iwi/if_iwi.c
+++ b/sys/dev/iwi/if_iwi.c
@@ -166,14 +166,15 @@ static void iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *);
static void iwi_intr(void *);
static int iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t);
static void iwi_write_ibssnode(struct iwi_softc *, const u_int8_t [], int);
-static int iwi_tx_start(struct ifnet *, struct mbuf *,
+static int iwi_tx_start(struct iwi_softc *, struct mbuf *,
struct ieee80211_node *, int);
static int iwi_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void iwi_start_locked(struct ifnet *);
-static void iwi_start(struct ifnet *);
+static void iwi_start(struct iwi_softc *);
+static int iwi_transmit(struct ieee80211com *, struct mbuf *);
static void iwi_watchdog(void *);
-static int iwi_ioctl(struct ifnet *, u_long, caddr_t);
+static int iwi_ioctl(struct ieee80211com *, u_long, void *);
+static void iwi_parent(struct ieee80211com *);
static void iwi_stop_master(struct iwi_softc *);
static int iwi_reset(struct iwi_softc *);
static int iwi_load_ucode(struct iwi_softc *, const struct iwi_fw *);
@@ -269,23 +270,15 @@ static int
iwi_attach(device_t dev)
{
struct iwi_softc *sc = device_get_softc(dev);
- struct ifnet *ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t val;
int i, error;
uint8_t bands;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_dev = dev;
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(dev, "can not if_alloc()\n");
- return ENXIO;
- }
- ic = ifp->if_l2com;
-
IWI_LOCK_INIT(sc);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
sc->sc_unr = new_unrhdr(1, IWI_MAX_IBSSNODE-1, &sc->sc_mtx);
@@ -353,17 +346,6 @@ iwi_attach(device_t dev)
iwi_wme_init(sc);
- ifp->if_softc = sc;
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = iwi_init;
- ifp->if_ioctl = iwi_ioctl;
- ifp->if_start = iwi_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_opmode = IEEE80211_M_STA;
@@ -385,14 +367,14 @@ iwi_attach(device_t dev)
/* read MAC address from EEPROM */
val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0);
- macaddr[0] = val & 0xff;
- macaddr[1] = val >> 8;
+ ic->ic_macaddr[0] = val & 0xff;
+ ic->ic_macaddr[1] = val >> 8;
val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 1);
- macaddr[2] = val & 0xff;
- macaddr[3] = val >> 8;
+ ic->ic_macaddr[2] = val & 0xff;
+ ic->ic_macaddr[3] = val >> 8;
val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 2);
- macaddr[4] = val & 0xff;
- macaddr[5] = val >> 8;
+ ic->ic_macaddr[4] = val & 0xff;
+ ic->ic_macaddr[5] = val >> 8;
bands = 0;
setbit(&bands, IEEE80211_MODE_11B);
@@ -401,7 +383,7 @@ iwi_attach(device_t dev)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, macaddr);
+ ieee80211_ifattach(ic);
/* override default methods */
ic->ic_node_alloc = iwi_node_alloc;
sc->sc_node_free = ic->ic_node_free;
@@ -416,6 +398,9 @@ iwi_attach(device_t dev)
ic->ic_vap_create = iwi_vap_create;
ic->ic_vap_delete = iwi_vap_delete;
+ ic->ic_ioctl = iwi_ioctl;
+ ic->ic_transmit = iwi_transmit;
+ ic->ic_parent = iwi_parent;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -450,8 +435,7 @@ static int
iwi_detach(device_t dev)
{
struct iwi_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
bus_teardown_intr(dev, sc->irq, sc->sc_ih);
@@ -482,11 +466,10 @@ iwi_detach(device_t dev)
sc->mem);
delete_unrhdr(sc->sc_unr);
+ mbufq_drain(&sc->sc_snd);
IWI_LOCK_DESTROY(sc);
- if_free(ifp);
-
return 0;
}
@@ -496,8 +479,7 @@ iwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct ifnet *ifp = ic->ic_ifp;
- struct iwi_softc *sc = ifp->if_softc;
+ struct iwi_softc *sc = ic->ic_softc;
struct iwi_vap *ivp;
struct ieee80211vap *vap;
int i;
@@ -519,12 +501,9 @@ iwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (iwi_init_fw_dma(sc, i))
return NULL;
- ivp = (struct iwi_vap *) malloc(sizeof(struct iwi_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (ivp == NULL)
- return NULL;
+ ivp = malloc(sizeof(struct iwi_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &ivp->iwi_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
/* override the default, the setting comes from the linux driver */
vap->iv_bmissthreshold = 24;
/* override with driver methods */
@@ -532,7 +511,8 @@ iwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
vap->iv_newstate = iwi_newstate;
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, iwi_media_status);
+ ieee80211_vap_attach(vap, ieee80211_media_change, iwi_media_status,
+ mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -859,7 +839,7 @@ static int
iwi_suspend(device_t dev)
{
struct iwi_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
ieee80211_suspend_all(ic);
return 0;
@@ -869,7 +849,7 @@ static int
iwi_resume(device_t dev)
{
struct iwi_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
pci_write_config(dev, 0x41, 0, 1);
@@ -895,7 +875,7 @@ static void
iwi_node_free(struct ieee80211_node *ni)
{
struct ieee80211com *ic = ni->ni_ic;
- struct iwi_softc *sc = ic->ic_ifp->if_softc;
+ struct iwi_softc *sc = ic->ic_softc;
struct iwi_node *in = (struct iwi_node *)ni;
if (in->in_station != -1) {
@@ -939,7 +919,7 @@ iwi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
{
struct ieee80211vap *vap = ifp->if_softc;
struct ieee80211com *ic = vap->iv_ic;
- struct iwi_softc *sc = ic->ic_ifp->if_softc;
+ struct iwi_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
/* read current transmission rate from adapter */
@@ -955,8 +935,7 @@ iwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct iwi_vap *ivp = IWI_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct iwi_softc *sc = ifp->if_softc;
+ struct iwi_softc *sc = ic->ic_softc;
IWI_LOCK_DECL;
DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__,
@@ -1061,7 +1040,7 @@ iwi_wme_init(struct iwi_softc *sc)
static int
iwi_wme_setparams(struct iwi_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
const struct wmeParams *wmep;
int ac;
@@ -1095,7 +1074,7 @@ iwi_update_wme(void *arg, int npending)
static int
iwi_wme_update(struct ieee80211com *ic)
{
- struct iwi_softc *sc = ic->ic_ifp->if_softc;
+ struct iwi_softc *sc = ic->ic_softc;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
/*
@@ -1189,8 +1168,7 @@ iwi_read_prom_word(struct iwi_softc *sc, uint8_t addr)
static void
iwi_setcurchan(struct iwi_softc *sc, int chan)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
sc->curchan = chan;
ieee80211_radiotap_chan_change(ic);
@@ -1200,8 +1178,7 @@ static void
iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i,
struct iwi_frame *frame)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct mbuf *mnew, *m;
struct ieee80211_node *ni;
int type, error, framelen;
@@ -1237,7 +1214,7 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i,
*/
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (mnew == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
@@ -1258,7 +1235,7 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i,
panic("%s: could not load old rx mbuf",
device_get_name(sc->sc_dev));
}
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
@@ -1271,7 +1248,6 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i,
CSR_WRITE_4(sc, data->reg, data->physaddr);
/* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = sizeof (struct iwi_hdr) +
sizeof (struct iwi_frame) + framelen;
@@ -1410,8 +1386,7 @@ iwi_notif_link_quality(struct iwi_softc *sc, struct iwi_notif *notif)
static void
iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct iwi_notif_scan_channel *chan;
struct iwi_notif_scan_complete *scan;
@@ -1632,47 +1607,33 @@ iwi_rx_intr(struct iwi_softc *sc)
static void
iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq)
{
- struct ifnet *ifp = sc->sc_ifp;
struct iwi_tx_data *data;
uint32_t hw;
hw = CSR_READ_4(sc, txq->csr_ridx);
- for (; txq->next != hw;) {
+ while (txq->next != hw) {
data = &txq->data[txq->next];
-
+ DPRINTFN(15, ("tx done idx=%u\n", txq->next));
bus_dmamap_sync(txq->data_dmat, data->map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(txq->data_dmat, data->map);
- if (data->m->m_flags & M_TXCB)
- ieee80211_process_callback(data->ni, data->m, 0/*XXX*/);
- m_freem(data->m);
- data->m = NULL;
- ieee80211_free_node(data->ni);
+ ieee80211_tx_complete(data->ni, data->m, 0);
data->ni = NULL;
-
- DPRINTFN(15, ("tx done idx=%u\n", txq->next));
-
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
+ data->m = NULL;
txq->queued--;
txq->next = (txq->next + 1) % IWI_TX_RING_COUNT;
}
-
sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
if (sc->sc_softled)
iwi_led_event(sc, IWI_LED_TX);
-
- iwi_start_locked(ifp);
+ iwi_start(sc);
}
static void
iwi_fatal_error_intr(struct iwi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
device_printf(sc->sc_dev, "firmware error\n");
@@ -1688,10 +1649,8 @@ iwi_fatal_error_intr(struct iwi_softc *sc)
static void
iwi_radio_off_intr(struct iwi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- ieee80211_runtask(ic, &sc->sc_radiofftask);
+ ieee80211_runtask(&sc->sc_ic, &sc->sc_radiofftask);
}
static void
@@ -1806,10 +1765,9 @@ iwi_write_ibssnode(struct iwi_softc *sc,
}
static int
-iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni,
+iwi_tx_start(struct iwi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
int ac)
{
- struct iwi_softc *sc = ifp->if_softc;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
struct iwi_node *in = (struct iwi_node *)ni;
@@ -1852,9 +1810,10 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni,
in->in_station = alloc_unr(sc->sc_unr);
if (in->in_station == -1) {
/* h/w table is full */
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
m_freem(m0);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
return 0;
}
iwi_write_ibssnode(sc,
@@ -1980,141 +1939,139 @@ iwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
}
+static int
+iwi_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct iwi_softc *sc = ic->ic_softc;
+ int error;
+ IWI_LOCK_DECL;
+
+ IWI_LOCK(sc);
+ if (!sc->sc_running) {
+ IWI_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ IWI_UNLOCK(sc);
+ return (error);
+ }
+ iwi_start(sc);
+ IWI_UNLOCK(sc);
+ return (0);
+}
+
static void
-iwi_start_locked(struct ifnet *ifp)
+iwi_start(struct iwi_softc *sc)
{
- struct iwi_softc *sc = ifp->if_softc;
struct mbuf *m;
struct ieee80211_node *ni;
int ac;
IWI_LOCK_ASSERT(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ac = M_WME_GETAC(m);
if (sc->txq[ac].queued > IWI_TX_RING_COUNT - 8) {
/* there is no place left in this ring; tail drop */
/* XXX tail drop */
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ mbufq_prepend(&sc->sc_snd, m);
break;
}
-
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
- if (iwi_tx_start(ifp, m, ni, ac) != 0) {
+ if (iwi_tx_start(sc, m, ni, ac) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
break;
}
-
sc->sc_tx_timer = 5;
}
}
static void
-iwi_start(struct ifnet *ifp)
-{
- struct iwi_softc *sc = ifp->if_softc;
- IWI_LOCK_DECL;
-
- IWI_LOCK(sc);
- iwi_start_locked(ifp);
- IWI_UNLOCK(sc);
-}
-
-static void
iwi_watchdog(void *arg)
{
struct iwi_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
IWI_LOCK_ASSERT(sc);
if (sc->sc_tx_timer > 0) {
if (--sc->sc_tx_timer == 0) {
- if_printf(ifp, "device timeout\n");
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ device_printf(sc->sc_dev, "device timeout\n");
+ counter_u64_add(ic->ic_oerrors, 1);
ieee80211_runtask(ic, &sc->sc_restarttask);
}
}
if (sc->sc_state_timer > 0) {
if (--sc->sc_state_timer == 0) {
- if_printf(ifp, "firmware stuck in state %d, resetting\n",
+ device_printf(sc->sc_dev,
+ "firmware stuck in state %d, resetting\n",
sc->fw_state);
- if (sc->fw_state == IWI_FW_SCANNING) {
- struct ieee80211com *ic = ifp->if_l2com;
+ if (sc->fw_state == IWI_FW_SCANNING)
ieee80211_cancel_scan(TAILQ_FIRST(&ic->ic_vaps));
- }
ieee80211_runtask(ic, &sc->sc_restarttask);
sc->sc_state_timer = 3;
}
}
if (sc->sc_busy_timer > 0) {
if (--sc->sc_busy_timer == 0) {
- if_printf(ifp, "firmware command timeout, resetting\n");
+ device_printf(sc->sc_dev,
+ "firmware command timeout, resetting\n");
ieee80211_runtask(ic, &sc->sc_restarttask);
}
}
callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc);
}
+static void
+iwi_parent(struct ieee80211com *ic)
+{
+ struct iwi_softc *sc = ic->ic_softc;
+ int startall = 0;
+ IWI_LOCK_DECL;
+
+ IWI_LOCK(sc);
+ if (ic->ic_nrunning > 0) {
+ if (!sc->sc_running) {
+ iwi_init_locked(sc);
+ startall = 1;
+ }
+ } else if (sc->sc_running)
+ iwi_stop_locked(sc);
+ IWI_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
+}
+
static int
-iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+iwi_ioctl(struct ieee80211com *ic, u_long cmd, void *data)
{
- struct iwi_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
+ struct ifreq *ifr = data;
+ struct iwi_softc *sc = ic->ic_softc;
+ int error;
IWI_LOCK_DECL;
+ IWI_LOCK(sc);
switch (cmd) {
- case SIOCSIFFLAGS:
- IWI_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- iwi_init_locked(sc);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- iwi_stop_locked(sc);
- }
- IWI_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
case SIOCGIWISTATS:
- IWI_LOCK(sc);
/* XXX validate permissions/memory/etc? */
error = copyout(&sc->sc_linkqual, ifr->ifr_data,
sizeof(struct iwi_notif_link_quality));
- IWI_UNLOCK(sc);
break;
case SIOCZIWISTATS:
- IWI_LOCK(sc);
memset(&sc->sc_linkqual, 0,
sizeof(struct iwi_notif_link_quality));
- IWI_UNLOCK(sc);
error = 0;
break;
default:
- error = EINVAL;
+ error = ENOTTY;
break;
}
- return error;
+ IWI_UNLOCK(sc);
+
+ return (error);
}
static void
@@ -2593,8 +2550,7 @@ iwi_setwepkeys(struct iwi_softc *sc, struct ieee80211vap *vap)
static int
iwi_config(struct iwi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct iwi_configuration config;
struct iwi_rateset rs;
struct iwi_txpower power;
@@ -2603,8 +2559,8 @@ iwi_config(struct iwi_softc *sc)
IWI_LOCK_ASSERT(sc);
- DPRINTF(("Setting MAC address to %6D\n", IF_LLADDR(ifp), ":"));
- error = iwi_cmd(sc, IWI_CMD_SET_MAC_ADDRESS, IF_LLADDR(ifp),
+ DPRINTF(("Setting MAC address to %6D\n", ic->ic_macaddr, ":"));
+ error = iwi_cmd(sc, IWI_CMD_SET_MAC_ADDRESS, ic->ic_macaddr,
IEEE80211_ADDR_LEN);
if (error != 0)
return error;
@@ -2724,7 +2680,7 @@ iwi_monitor_scan(void *arg, int npending)
static int
iwi_scanchan(struct iwi_softc *sc, unsigned long maxdwell, int allchan)
{
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_channel *chan;
struct ieee80211_scan_state *ss;
struct iwi_scan_ext scan;
@@ -2741,7 +2697,6 @@ iwi_scanchan(struct iwi_softc *sc, unsigned long maxdwell, int allchan)
}
IWI_STATE_BEGIN(sc, IWI_FW_SCANNING);
- ic = sc->sc_ifp->if_l2com;
ss = ic->ic_scan;
memset(&scan, 0, sizeof scan);
@@ -3128,7 +3083,6 @@ error:
static void
iwi_init_locked(struct iwi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
struct iwi_rx_data *data;
int i;
@@ -3202,8 +3156,7 @@ iwi_init_locked(struct iwi_softc *sc)
}
callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_running = 1;
return;
fail:
IWI_STATE_END(sc, IWI_FW_LOADING);
@@ -3215,15 +3168,14 @@ static void
iwi_init(void *priv)
{
struct iwi_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
IWI_LOCK_DECL;
IWI_LOCK(sc);
iwi_init_locked(sc);
IWI_UNLOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_running)
ieee80211_start_all(ic);
}
@@ -3231,11 +3183,10 @@ static void
iwi_stop_locked(void *priv)
{
struct iwi_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
IWI_LOCK_ASSERT(sc);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_running = 0;
if (sc->sc_softled) {
callout_stop(&sc->sc_ledtimer);
@@ -3296,7 +3247,7 @@ static void
iwi_radio_on(void *arg, int pending)
{
struct iwi_softc *sc = arg;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
device_printf(sc->sc_dev, "radio turned on\n");
@@ -3317,10 +3268,7 @@ iwi_rfkill_poll(void *arg)
* it is enabled so we must poll for the latter.
*/
if (!iwi_getrfkill(sc)) {
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- ieee80211_runtask(ic, &sc->sc_radiontask);
+ ieee80211_runtask(&sc->sc_ic, &sc->sc_radiontask);
return;
}
callout_reset(&sc->sc_rftimer, 2*hz, iwi_rfkill_poll, sc);
@@ -3330,7 +3278,7 @@ static void
iwi_radio_off(void *arg, int pending)
{
struct iwi_softc *sc = arg;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
IWI_LOCK_DECL;
device_printf(sc->sc_dev, "radio turned off\n");
@@ -3594,8 +3542,8 @@ iwi_scan_start(struct ieee80211com *ic)
static void
iwi_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct iwi_softc *sc = ifp->if_softc;
+ struct iwi_softc *sc = ic->ic_softc;
+
if (sc->fw_state == IWI_FW_IDLE)
iwi_setcurchan(sc, ic->ic_curchan->ic_ieee);
}
@@ -3604,8 +3552,7 @@ static void
iwi_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
{
struct ieee80211vap *vap = ss->ss_vap;
- struct ifnet *ifp = vap->iv_ic->ic_ifp;
- struct iwi_softc *sc = ifp->if_softc;
+ struct iwi_softc *sc = vap->iv_ic->ic_softc;
IWI_LOCK_DECL;
IWI_LOCK(sc);
@@ -3623,8 +3570,7 @@ iwi_scan_mindwell(struct ieee80211_scan_state *ss)
static void
iwi_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct iwi_softc *sc = ifp->if_softc;
+ struct iwi_softc *sc = ic->ic_softc;
IWI_LOCK_DECL;
IWI_LOCK(sc);
diff --git a/sys/dev/iwi/if_iwivar.h b/sys/dev/iwi/if_iwivar.h
index b38bbd9..47848e1 100644
--- a/sys/dev/iwi/if_iwivar.h
+++ b/sys/dev/iwi/if_iwivar.h
@@ -125,11 +125,13 @@ struct iwi_vap {
#define IWI_VAP(vap) ((struct iwi_vap *)(vap))
struct iwi_softc {
- struct ifnet *sc_ifp;
- void (*sc_node_free)(struct ieee80211_node *);
+ struct mtx sc_mtx;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
- struct mtx sc_mtx;
+ void (*sc_node_free)(struct ieee80211_node *);
+
uint8_t sc_mcast[IEEE80211_ADDR_LEN];
struct unrhdr *sc_unr;
@@ -193,7 +195,8 @@ struct iwi_softc {
struct task sc_wmetask; /* set wme parameters */
struct task sc_monitortask;
- unsigned int sc_softled : 1, /* enable LED gpio status */
+ unsigned int sc_running : 1, /* initialized */
+ sc_softled : 1, /* enable LED gpio status */
sc_ledstate: 1, /* LED on/off state */
sc_blinking: 1; /* LED blink operation active */
u_int sc_nictype; /* NIC type from EEPROM */
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index 3cd5d7b..cfed420 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -235,10 +235,11 @@ static int iwn_tx_data_raw(struct iwn_softc *, struct mbuf *,
static void iwn_xmit_task(void *arg0, int pending);
static int iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void iwn_start(struct ifnet *);
-static void iwn_start_locked(struct ifnet *);
+static int iwn_transmit(struct ieee80211com *, struct mbuf *);
+static void iwn_start_locked(struct iwn_softc *);
static void iwn_watchdog(void *);
-static int iwn_ioctl(struct ifnet *, u_long, caddr_t);
+static int iwn_ioctl(struct ieee80211com *, u_long , void *);
+static void iwn_parent(struct ieee80211com *);
static int iwn_cmd(struct iwn_softc *, int, const void *, int, int);
static int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
int);
@@ -336,7 +337,7 @@ static void iwn_radio_on(void *, int);
static void iwn_radio_off(void *, int);
static void iwn_panicked(void *, int);
static void iwn_init_locked(struct iwn_softc *);
-static void iwn_init(void *);
+static void iwn_init(struct iwn_softc *);
static void iwn_stop_locked(struct iwn_softc *);
static void iwn_stop(struct iwn_softc *);
static void iwn_scan_start(struct ieee80211com *);
@@ -406,9 +407,7 @@ iwn_attach(device_t dev)
{
struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev);
struct ieee80211com *ic;
- struct ifnet *ifp;
int i, error, rid;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_dev = dev;
@@ -464,6 +463,7 @@ iwn_attach(device_t dev)
}
IWN_LOCK_INIT(sc);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
/* Read hardware revision and attach. */
sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> IWN_HW_REV_TYPE_SHIFT)
@@ -549,14 +549,7 @@ iwn_attach(device_t dev)
/* Clear pending interrupts. */
IWN_WRITE(sc, IWN_INT, 0xffffffff);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(dev, "can not allocate ifnet structure\n");
- goto fail;
- }
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
+ ic = &sc->sc_ic;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -581,7 +574,7 @@ iwn_attach(device_t dev)
;
/* Read MAC address, channels, etc from EEPROM. */
- if ((error = iwn_read_eeprom(sc, macaddr)) != 0) {
+ if ((error = iwn_read_eeprom(sc, ic->ic_macaddr)) != 0) {
device_printf(dev, "could not read EEPROM, error %d\n",
error);
goto fail;
@@ -599,7 +592,7 @@ iwn_attach(device_t dev)
if (bootverbose) {
device_printf(dev, "MIMO %dT%dR, %.4s, address %6D\n",
sc->ntxchains, sc->nrxchains, sc->eeprom_domain,
- macaddr, ":");
+ ic->ic_macaddr, ":");
}
if (sc->sc_flags & IWN_FLAG_HAS_11N) {
@@ -640,19 +633,12 @@ iwn_attach(device_t dev)
;
}
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_softc = sc;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = iwn_init;
- ifp->if_ioctl = iwn_ioctl;
- ifp->if_start = iwn_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ieee80211_ifattach(ic, macaddr);
+ ieee80211_ifattach(ic);
ic->ic_vap_create = iwn_vap_create;
+ ic->ic_ioctl = iwn_ioctl;
+ ic->ic_parent = iwn_parent;
ic->ic_vap_delete = iwn_vap_delete;
+ ic->ic_transmit = iwn_transmit;
ic->ic_raw_xmit = iwn_raw_xmit;
ic->ic_node_alloc = iwn_node_alloc;
sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start;
@@ -1293,10 +1279,9 @@ iwn5000_attach(struct iwn_softc *sc, uint16_t pid)
static void
iwn_radiotap_attach(struct iwn_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
- ieee80211_radiotap_attach(ic,
+ ieee80211_radiotap_attach(&sc->sc_ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
IWN_TX_RADIOTAP_PRESENT,
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
@@ -1326,21 +1311,14 @@ iwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
struct iwn_softc *sc = ic->ic_softc;
struct iwn_vap *ivp;
struct ieee80211vap *vap;
- uint8_t mac1[IEEE80211_ADDR_LEN];
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return NULL;
- IEEE80211_ADDR_COPY(mac1, mac);
-
- ivp = (struct iwn_vap *) malloc(sizeof(struct iwn_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (ivp == NULL)
- return NULL;
+ ivp = malloc(sizeof(struct iwn_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &ivp->iv_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac1);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
ivp->ctx = IWN_RXON_BSS_CTX;
- IEEE80211_ADDR_COPY(ivp->macaddr, mac1);
vap->iv_bmissthreshold = 10; /* override default */
/* Override with driver methods. */
ivp->iv_newstate = vap->iv_newstate;
@@ -1349,7 +1327,8 @@ iwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_init(vap);
/* Complete setup. */
- ieee80211_vap_attach(vap, iwn_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, iwn_media_change, ieee80211_media_status,
+ mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -1390,24 +1369,19 @@ static int
iwn_detach(device_t dev)
{
struct iwn_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
int qid;
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
- if (ifp != NULL) {
- ic = ifp->if_l2com;
-
+ if (sc->sc_ic.ic_softc != NULL) {
/* Free the mbuf queue and node references */
IWN_LOCK(sc);
iwn_xmit_queue_drain(sc);
IWN_UNLOCK(sc);
- ieee80211_draintask(ic, &sc->sc_reinit_task);
- ieee80211_draintask(ic, &sc->sc_radioon_task);
- ieee80211_draintask(ic, &sc->sc_radiooff_task);
-
+ ieee80211_draintask(&sc->sc_ic, &sc->sc_reinit_task);
+ ieee80211_draintask(&sc->sc_ic, &sc->sc_radioon_task);
+ ieee80211_draintask(&sc->sc_ic, &sc->sc_radiooff_task);
iwn_stop(sc);
taskqueue_drain_all(sc->sc_tq);
@@ -1415,9 +1389,11 @@ iwn_detach(device_t dev)
callout_drain(&sc->watchdog_to);
callout_drain(&sc->calib_to);
- ieee80211_ifdetach(ic);
+ ieee80211_ifdetach(&sc->sc_ic);
}
+ mbufq_drain(&sc->sc_snd);
+
/* Uninstall interrupt handler. */
if (sc->irq != NULL) {
bus_teardown_intr(dev, sc->irq, sc->sc_ih);
@@ -1440,9 +1416,6 @@ iwn_detach(device_t dev)
bus_release_resource(dev, SYS_RES_MEMORY,
rman_get_rid(sc->mem), sc->mem);
- if (ifp != NULL)
- if_free(ifp);
-
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n", __func__);
IWN_LOCK_DESTROY(sc);
return 0;
@@ -1461,9 +1434,8 @@ static int
iwn_suspend(device_t dev)
{
struct iwn_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
- ieee80211_suspend_all(ic);
+ ieee80211_suspend_all(&sc->sc_ic);
return 0;
}
@@ -1471,12 +1443,11 @@ static int
iwn_resume(device_t dev)
{
struct iwn_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
/* Clear device-specific "PCI retry timeout" register (41h). */
pci_write_config(dev, 0x41, 0, 1);
- ieee80211_resume_all(ic);
+ ieee80211_resume_all(&sc->sc_ic);
return 0;
}
@@ -2385,8 +2356,7 @@ iwn_eeprom_channel_flags(struct iwn_eeprom_chan *channel)
static void
iwn_read_eeprom_band(struct iwn_softc *sc, int n)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
const struct iwn_chan_band *band = &iwn_bands[n];
struct ieee80211_channel *c;
@@ -2445,8 +2415,7 @@ iwn_read_eeprom_band(struct iwn_softc *sc, int n)
static void
iwn_read_eeprom_ht40(struct iwn_softc *sc, int n)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
const struct iwn_chan_band *band = &iwn_bands[n];
struct ieee80211_channel *c, *cent, *extc;
@@ -2514,8 +2483,7 @@ iwn_read_eeprom_ht40(struct iwn_softc *sc, int n)
static void
iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
iwn_read_prom_data(sc, addr, &sc->eeprom_channels[n],
iwn_bands[n].nchan * sizeof (struct iwn_eeprom_chan));
@@ -2583,8 +2551,7 @@ static void
iwn_read_eeprom_enhinfo(struct iwn_softc *sc)
{
struct iwn_eeprom_enhinfo enhinfo[35];
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_channel *c;
uint16_t val, base;
int8_t maxpwr;
@@ -2967,8 +2934,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
struct iwn_rx_data *data)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct iwn_rx_ring *ring = &sc->rxq;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
@@ -3015,14 +2981,14 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
if ((flags & IWN_RX_NOERROR) != IWN_RX_NOERROR) {
DPRINTF(sc, IWN_DEBUG_RECV, "%s: RX flags error %x\n",
__func__, flags);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
/* Discard frames that are too short. */
if (len < sizeof (struct ieee80211_frame_ack)) {
DPRINTF(sc, IWN_DEBUG_RECV, "%s: frame too short: %d\n",
__func__, len);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
@@ -3030,7 +2996,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
if (m1 == NULL) {
DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n",
__func__);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
bus_dmamap_unload(ring->data_dmat, data->map);
@@ -3053,7 +3019,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
ring->desc[ring->cur] = htole32(paddr >> 8);
bus_dmamap_sync(ring->data_dmat, ring->desc_dma.map,
BUS_DMASYNC_PREWRITE);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
@@ -3065,7 +3031,6 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
BUS_DMASYNC_PREWRITE);
/* Finalize mbuf. */
- m->m_pkthdr.rcvif = ifp;
m->m_data = head;
m->m_pkthdr.len = m->m_len = len;
@@ -3159,7 +3124,6 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
struct iwn_rx_data *data)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
struct iwn_node *wn;
struct ieee80211_node *ni;
struct iwn_compressed_ba *ba = (struct iwn_compressed_ba *)(desc + 1);
@@ -3240,12 +3204,10 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
bitmap = (le64toh(ba->bitmap) >> shift) & wn->agg[tid].bitmap;
for (i = 0; bitmap; i++) {
if ((bitmap & 1) == 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
tx_err ++;
ieee80211_ratectl_tx_complete(ni->ni_vap, ni,
IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL);
} else {
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
tx_ok ++;
ieee80211_ratectl_tx_complete(ni->ni_vap, ni,
IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL);
@@ -3391,8 +3353,7 @@ iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
struct iwn_rx_data *data)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct iwn_calib_state *calib = &sc->calib;
struct iwn_stats *stats = (struct iwn_stats *)(desc + 1);
@@ -3565,7 +3526,6 @@ static void
iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
uint8_t status)
{
- struct ifnet *ifp = sc->sc_ifp;
struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
struct iwn_tx_data *data = &ring->data[desc->idx];
struct mbuf *m;
@@ -3586,15 +3546,12 @@ iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
/*
* Update rate control statistics for the node.
*/
- if (status & IWN_TX_FAIL) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if (status & IWN_TX_FAIL)
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL);
- } else {
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ else
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL);
- }
/*
* Channels marked for "radar" require traffic to be received
@@ -3620,11 +3577,8 @@ iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
sc->sc_tx_timer = 0;
if (--ring->queued < IWN_TX_RING_LOMARK) {
sc->qfullmsk &= ~(1 << ring->qid);
- if (sc->qfullmsk == 0 &&
- (ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- iwn_start_locked(ifp);
- }
+ if (sc->qfullmsk == 0)
+ iwn_start_locked(sc);
}
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__);
@@ -3669,7 +3623,6 @@ iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes,
int ackfailcnt, void *stat)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
struct iwn_tx_ring *ring = &sc->txq[qid];
struct iwn_tx_data *data;
struct mbuf *m;
@@ -3808,11 +3761,8 @@ iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes,
sc->sc_tx_timer = 0;
if (ring->queued < IWN_TX_RING_LOMARK) {
sc->qfullmsk &= ~(1 << ring->qid);
- if (sc->qfullmsk == 0 &&
- (ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- iwn_start_locked(ifp);
- }
+ if (sc->qfullmsk == 0)
+ iwn_start_locked(sc);
}
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__);
@@ -3826,8 +3776,7 @@ static void
iwn_notif_intr(struct iwn_softc *sc)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint16_t hw;
@@ -4021,8 +3970,7 @@ iwn_wakeup_intr(struct iwn_softc *sc)
static void
iwn_rftoggle_intr(struct iwn_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp = IWN_READ(sc, IWN_GP_CNTRL);
IWN_LOCK_ASSERT(sc);
@@ -4101,7 +4049,6 @@ static void
iwn_intr(void *arg)
{
struct iwn_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
uint32_t r1, r2, tmp;
IWN_LOCK(sc);
@@ -4194,7 +4141,7 @@ iwn_intr(void *arg)
done:
/* Re-enable interrupts. */
- if (ifp->if_flags & IFF_UP)
+ if (sc->sc_flags & IWN_FLAG_RUNNING)
IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
IWN_UNLOCK(sc);
@@ -4678,9 +4625,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
{
struct iwn_ops *ops = &sc->ops;
-// struct ifnet *ifp = sc->sc_ifp;
struct ieee80211vap *vap = ni->ni_vap;
-// struct ieee80211com *ic = ifp->if_l2com;
struct iwn_tx_cmd *cmd;
struct iwn_cmd_data *tx;
struct ieee80211_frame *wh;
@@ -4875,7 +4820,6 @@ static void
iwn_xmit_task(void *arg0, int pending)
{
struct iwn_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211_node *ni;
struct mbuf *m;
int error;
@@ -4907,8 +4851,9 @@ iwn_xmit_task(void *arg0, int pending)
error = iwn_tx_data(sc, m, ni);
if (error != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
}
@@ -4921,13 +4866,12 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct iwn_softc *sc = ifp->if_softc;
+ struct iwn_softc *sc = ic->ic_softc;
int error = 0;
DPRINTF(sc, IWN_DEBUG_XMIT | IWN_DEBUG_TRACE, "->%s begin\n", __func__);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ if ((sc->sc_flags & IWN_FLAG_RUNNING) == 0) {
ieee80211_free_node(ni);
m_freem(m);
return ENETDOWN;
@@ -4942,8 +4886,9 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (sc->sc_beacon_wait) {
if (iwn_xmit_queue_enqueue(sc, m) != 0) {
m_freem(m);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
IWN_UNLOCK(sc);
return (ENOBUFS);
}
@@ -4968,7 +4913,6 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (error != 0) {
/* NB: m is reclaimed on tx failure */
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
} else
sc->sc_tx_timer = 5;
@@ -4979,20 +4923,32 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return error;
}
-static void
-iwn_start(struct ifnet *ifp)
+static int
+iwn_transmit(struct ieee80211com *ic, struct mbuf *m)
{
- struct iwn_softc *sc = ifp->if_softc;
+ struct iwn_softc *sc;
+ int error;
+
+ sc = ic->ic_softc;
IWN_LOCK(sc);
- iwn_start_locked(ifp);
+ if ((sc->sc_flags & IWN_FLAG_RUNNING) == 0) {
+ IWN_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ IWN_UNLOCK(sc);
+ return (error);
+ }
+ iwn_start_locked(sc);
IWN_UNLOCK(sc);
+ return (0);
}
static void
-iwn_start_locked(struct ifnet *ifp)
+iwn_start_locked(struct iwn_softc *sc)
{
- struct iwn_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
@@ -5007,27 +4963,16 @@ iwn_start_locked(struct ifnet *ifp)
}
DPRINTF(sc, IWN_DEBUG_XMIT, "%s: called\n", __func__);
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
- (ifp->if_drv_flags & IFF_DRV_OACTIVE))
- return;
-
- for (;;) {
- if (sc->qfullmsk != 0) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while (sc->qfullmsk == 0 &&
+ (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
if (iwn_tx_data(sc, m, ni) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
} else
sc->sc_tx_timer = 5;
}
-
DPRINTF(sc, IWN_DEBUG_XMIT, "%s: done\n", __func__);
}
@@ -5035,12 +4980,11 @@ static void
iwn_watchdog(void *arg)
{
struct iwn_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
IWN_LOCK_ASSERT(sc);
- KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
+ KASSERT(sc->sc_flags & IWN_FLAG_RUNNING, ("not running"));
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
@@ -5055,41 +4999,13 @@ iwn_watchdog(void *arg)
}
static int
-iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+iwn_ioctl(struct ieee80211com *ic, u_long cmd, void *data)
{
- struct iwn_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0, stop = 0;
-
+ struct ifreq *ifr = data;
+ struct iwn_softc *sc = ic->ic_softc;
+ int error = 0;
+
switch (cmd) {
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- case SIOCSIFFLAGS:
- IWN_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- iwn_init_locked(sc);
- if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)
- startall = 1;
- else
- stop = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- iwn_stop_locked(sc);
- }
- IWN_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- else if (vap != NULL && stop)
- ieee80211_stop(vap);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
case SIOCGIWNSTATS:
IWN_LOCK(sc);
/* XXX validate permissions/memory/etc? */
@@ -5103,10 +5019,35 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
IWN_UNLOCK(sc);
break;
default:
- error = EINVAL;
+ error = ENOTTY;
break;
}
- return error;
+ return (error);
+}
+
+static void
+iwn_parent(struct ieee80211com *ic)
+{
+ struct iwn_softc *sc = ic->ic_softc;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ int startall = 0, stop = 0;
+
+ IWN_LOCK(sc);
+ if (ic->ic_nrunning > 0) {
+ if (!(sc->sc_flags & IWN_FLAG_RUNNING)) {
+ iwn_init_locked(sc);
+ if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)
+ startall = 1;
+ else
+ stop = 1;
+ }
+ } else if (sc->sc_flags & IWN_FLAG_RUNNING)
+ iwn_stop_locked(sc);
+ IWN_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
+ else if (vap != NULL && stop)
+ ieee80211_stop(vap);
}
/*
@@ -5340,8 +5281,7 @@ static int
iwn_add_broadcast_node(struct iwn_softc *sc, int async)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct iwn_node_info node;
struct iwn_cmd_link_quality linkq;
uint8_t txant;
@@ -5352,7 +5292,7 @@ iwn_add_broadcast_node(struct iwn_softc *sc, int async)
sc->rxon = &sc->rx_on[IWN_RXON_BSS_CTX];
memset(&node, 0, sizeof node);
- IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);
+ IEEE80211_ADDR_COPY(node.macaddr, ieee80211broadcastaddr);
node.id = sc->broadcast_id;
DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node\n", __func__);
if ((error = ops->add_node(sc, &node, async)) != 0)
@@ -5501,8 +5441,7 @@ iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni)
static void
iwn4965_power_calibration(struct iwn_softc *sc, int temp)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
@@ -5872,8 +5811,7 @@ iwn_collect_noise(struct iwn_softc *sc,
{
struct iwn_ops *ops = &sc->ops;
struct iwn_calib_state *calib = &sc->calib;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t val;
int i;
@@ -6506,9 +6444,8 @@ iwn5000_runtime_calib(struct iwn_softc *sc)
static uint32_t
iwn_get_rxon_ht_flags(struct iwn_softc *sc, struct ieee80211_channel *c)
{
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t htflags = 0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
if (! IEEE80211_IS_CHAN_HT(c))
return (0);
@@ -6535,8 +6472,9 @@ static int
iwn_config(struct iwn_softc *sc)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ const uint8_t *macaddr;
uint32_t txmask;
uint16_t rxchain;
int error;
@@ -6618,8 +6556,9 @@ iwn_config(struct iwn_softc *sc)
/* Set mode, channel, RX filter and enable RX. */
sc->rxon = &sc->rx_on[IWN_RXON_BSS_CTX];
memset(sc->rxon, 0, sizeof (struct iwn_rxon));
- IEEE80211_ADDR_COPY(sc->rxon->myaddr, IF_LLADDR(ifp));
- IEEE80211_ADDR_COPY(sc->rxon->wlap, IF_LLADDR(ifp));
+ macaddr = vap ? vap->iv_myaddr : ic->ic_macaddr;
+ IEEE80211_ADDR_COPY(sc->rxon->myaddr, macaddr);
+ IEEE80211_ADDR_COPY(sc->rxon->wlap, macaddr);
sc->rxon->chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
sc->rxon->flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
@@ -6732,7 +6671,7 @@ iwn_get_active_dwell_time(struct iwn_softc *sc,
static uint16_t
iwn_limit_dwell(struct iwn_softc *sc, uint16_t dwell_time)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = NULL;
int bintval = 0;
@@ -6780,8 +6719,7 @@ static int
iwn_scan(struct iwn_softc *sc, struct ieee80211vap *vap,
struct ieee80211_scan_state *ss, struct ieee80211_channel *c)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni = vap->iv_bss;
struct iwn_scan_hdr *hdr;
struct iwn_cmd_data *tx;
@@ -6919,9 +6857,9 @@ iwn_scan(struct iwn_softc *sc, struct ieee80211vap *vap,
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
IEEE80211_FC0_SUBTYPE_PROBE_REQ;
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
- IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
- IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(ifp));
- IEEE80211_ADDR_COPY(wh->i_addr3, ifp->if_broadcastaddr);
+ IEEE80211_ADDR_COPY(wh->i_addr1, vap->iv_ifp->if_broadcastaddr);
+ IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(vap->iv_ifp));
+ IEEE80211_ADDR_COPY(wh->i_addr3, vap->iv_ifp->if_broadcastaddr);
*(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */
*(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */
@@ -7040,8 +6978,7 @@ static int
iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni = vap->iv_bss;
int error;
@@ -7113,8 +7050,7 @@ static int
iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni = vap->iv_bss;
struct iwn_node_info node;
int error;
@@ -8685,8 +8621,7 @@ static void
iwn_radio_on(void *arg0, int pending)
{
struct iwn_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
@@ -8701,8 +8636,7 @@ static void
iwn_radio_off(void *arg0, int pending)
{
struct iwn_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
@@ -8722,8 +8656,7 @@ static void
iwn_panicked(void *arg0, int pending)
{
struct iwn_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
int error;
@@ -8751,7 +8684,7 @@ iwn_panicked(void *arg0, int pending)
}
/* Only run start once the NIC is in a useful state, like associated */
- iwn_start_locked(sc->sc_ifp);
+ iwn_start_locked(sc);
IWN_UNLOCK(sc);
}
@@ -8759,13 +8692,14 @@ iwn_panicked(void *arg0, int pending)
static void
iwn_init_locked(struct iwn_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
int error;
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
IWN_LOCK_ASSERT(sc);
+ sc->sc_flags |= IWN_FLAG_RUNNING;
+
if ((error = iwn_hw_prepare(sc)) != 0) {
device_printf(sc->sc_dev, "%s: hardware not ready, error %d\n",
__func__, error);
@@ -8813,38 +8747,33 @@ iwn_init_locked(struct iwn_softc *sc)
goto fail;
}
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
-
callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc);
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__);
return;
-fail: iwn_stop_locked(sc);
+fail:
+ sc->sc_flags &= ~IWN_FLAG_RUNNING;
+ iwn_stop_locked(sc);
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end in error\n",__func__);
}
static void
-iwn_init(void *arg)
+iwn_init(struct iwn_softc *sc)
{
- struct iwn_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
IWN_LOCK(sc);
iwn_init_locked(sc);
IWN_UNLOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic);
+ if (sc->sc_flags & IWN_FLAG_RUNNING)
+ ieee80211_start_all(&sc->sc_ic);
}
static void
iwn_stop_locked(struct iwn_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
IWN_LOCK_ASSERT(sc);
@@ -8852,7 +8781,7 @@ iwn_stop_locked(struct iwn_softc *sc)
sc->sc_tx_timer = 0;
callout_stop(&sc->watchdog_to);
callout_stop(&sc->calib_to);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_flags &= ~IWN_FLAG_RUNNING;
/* Power OFF hardware. */
iwn_hw_stop(sc);
@@ -8872,8 +8801,7 @@ iwn_stop(struct iwn_softc *sc)
static void
iwn_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct iwn_softc *sc = ifp->if_softc;
+ struct iwn_softc *sc = ic->ic_softc;
IWN_LOCK(sc);
/* make the link LED blink while we're scanning */
@@ -8887,8 +8815,7 @@ iwn_scan_start(struct ieee80211com *ic)
static void
iwn_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct iwn_softc *sc = ifp->if_softc;
+ struct iwn_softc *sc = ic->ic_softc;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
IWN_LOCK(sc);
@@ -8906,8 +8833,7 @@ static void
iwn_set_channel(struct ieee80211com *ic)
{
const struct ieee80211_channel *c = ic->ic_curchan;
- struct ifnet *ifp = ic->ic_ifp;
- struct iwn_softc *sc = ifp->if_softc;
+ struct iwn_softc *sc = ic->ic_softc;
int error;
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
@@ -8964,8 +8890,7 @@ static void
iwn_hw_reset(void *arg0, int pending)
{
struct iwn_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h
index 9366fc2..ed275bf 100644
--- a/sys/dev/iwn/if_iwnvar.h
+++ b/sys/dev/iwn/if_iwnvar.h
@@ -228,18 +228,16 @@ struct iwn_vap {
enum ieee80211_state, int);
int ctx;
int beacon_int;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
};
#define IWN_VAP(_vap) ((struct iwn_vap *)(_vap))
struct iwn_softc {
device_t sc_dev;
-
- struct ifnet *sc_ifp;
int sc_debug;
-
struct mtx sc_mtx;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
u_int sc_flags;
#define IWN_FLAG_HAS_OTPROM (1 << 1)
@@ -251,6 +249,7 @@ struct iwn_softc {
#define IWN_FLAG_ADV_BTCOEX (1 << 8)
#define IWN_FLAG_PAN_SUPPORT (1 << 9)
#define IWN_FLAG_BTCOEX (1 << 10)
+#define IWN_FLAG_RUNNING (1 << 11)
uint8_t hw_type;
/* subdevice_id used to adjust configuration */
@@ -320,7 +319,6 @@ struct iwn_softc {
struct iwn_calib_state calib;
int last_calib_ticks;
struct callout watchdog_to;
- struct callout ct_kill_exit_to;
struct iwn_fw_info fw;
struct iwn_calib_info calibcmd[IWN5000_PHY_CALIB_MAX_RESULT];
uint32_t errptr;
diff --git a/sys/dev/malo/if_malo.c b/sys/dev/malo/if_malo.c
index 7418379..2790fdc 100644
--- a/sys/dev/malo/if_malo.c
+++ b/sys/dev/malo/if_malo.c
@@ -102,13 +102,9 @@ enum {
(IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON))
#define IFF_DUMPPKTS_RECV(sc, wh) \
(((sc->malo_debug & MALO_DEBUG_RECV) && \
- ((sc->malo_debug & MALO_DEBUG_RECV_ALL) || !IS_BEACON(wh))) || \
- (sc->malo_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == \
- (IFF_DEBUG|IFF_LINK2))
+ ((sc->malo_debug & MALO_DEBUG_RECV_ALL) || !IS_BEACON(wh))))
#define IFF_DUMPPKTS_XMIT(sc) \
- ((sc->malo_debug & MALO_DEBUG_XMIT) || \
- (sc->malo_ifp->if_flags & (IFF_DEBUG | IFF_LINK2)) == \
- (IFF_DEBUG | IFF_LINK2))
+ (sc->malo_debug & MALO_DEBUG_XMIT)
#define DPRINTF(sc, m, fmt, ...) do { \
if (sc->malo_debug & (m)) \
printf(fmt, __VA_ARGS__); \
@@ -130,9 +126,10 @@ static int malo_dma_setup(struct malo_softc *);
static int malo_setup_hwdma(struct malo_softc *);
static void malo_txq_init(struct malo_softc *, struct malo_txq *, int);
static void malo_tx_cleanupq(struct malo_softc *, struct malo_txq *);
-static void malo_start(struct ifnet *);
+static void malo_parent(struct ieee80211com *);
+static int malo_transmit(struct ieee80211com *, struct mbuf *);
+static void malo_start(struct malo_softc *);
static void malo_watchdog(void *);
-static int malo_ioctl(struct ifnet *, u_long, caddr_t);
static void malo_updateslot(struct ieee80211com *);
static int malo_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void malo_scan_start(struct ieee80211com *);
@@ -143,7 +140,7 @@ static int malo_raw_xmit(struct ieee80211_node *, struct mbuf *,
static void malo_sysctlattach(struct malo_softc *);
static void malo_announce(struct malo_softc *);
static void malo_dma_cleanup(struct malo_softc *);
-static void malo_stop_locked(struct ifnet *, int);
+static void malo_stop(struct malo_softc *);
static int malo_chan_set(struct malo_softc *, struct ieee80211_channel *);
static int malo_mode_init(struct malo_softc *);
static void malo_tx_proc(void *, int);
@@ -173,30 +170,19 @@ malo_bar0_write4(struct malo_softc *sc, bus_size_t off, uint32_t val)
int
malo_attach(uint16_t devid, struct malo_softc *sc)
{
- int error;
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->malo_ic;
struct malo_hal *mh;
+ int error;
uint8_t bands;
- ifp = sc->malo_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->malo_dev, "can not if_alloc()\n");
- return ENOSPC;
- }
- ic = ifp->if_l2com;
-
MALO_LOCK_INIT(sc);
callout_init_mtx(&sc->malo_watchdog_timer, &sc->malo_mtx, 0);
-
- /* set these up early for if_printf use */
- if_initname(ifp, device_get_name(sc->malo_dev),
- device_get_unit(sc->malo_dev));
+ mbufq_init(&sc->malo_snd, ifqmaxlen);
mh = malo_hal_attach(sc->malo_dev, devid,
sc->malo_io1h, sc->malo_io1t, sc->malo_dmat);
if (mh == NULL) {
- if_printf(ifp, "unable to attach HAL\n");
+ device_printf(sc->malo_dev, "unable to attach HAL\n");
error = EIO;
goto bad;
}
@@ -209,13 +195,13 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
*/
error = malo_hal_fwload(mh, "malo8335-h", "malo8335-m");
if (error != 0) {
- if_printf(ifp, "unable to setup firmware\n");
+ device_printf(sc->malo_dev, "unable to setup firmware\n");
goto bad1;
}
/* XXX gethwspecs() extracts correct informations? not maybe! */
error = malo_hal_gethwspecs(mh, &sc->malo_hwspecs);
if (error != 0) {
- if_printf(ifp, "unable to fetch h/w specs\n");
+ device_printf(sc->malo_dev, "unable to fetch h/w specs\n");
goto bad1;
}
@@ -251,7 +237,8 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
*/
error = malo_dma_setup(sc);
if (error != 0) {
- if_printf(ifp, "failed to setup descriptors: %d\n", error);
+ device_printf(sc->malo_dev,
+ "failed to setup descriptors: %d\n", error);
goto bad1;
}
error = malo_setup_hwdma(sc); /* push to firmware */
@@ -261,21 +248,11 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
sc->malo_tq = taskqueue_create_fast("malo_taskq", M_NOWAIT,
taskqueue_thread_enqueue, &sc->malo_tq);
taskqueue_start_threads(&sc->malo_tq, 1, PI_NET,
- "%s taskq", ifp->if_xname);
+ "%s taskq", device_get_nameunit(sc->malo_dev));
TASK_INIT(&sc->malo_rxtask, 0, malo_rx_proc, sc);
TASK_INIT(&sc->malo_txtask, 0, malo_tx_proc, sc);
- ifp->if_softc = sc;
- ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
- ifp->if_start = malo_start;
- ifp->if_ioctl = malo_ioctl;
- ifp->if_init = malo_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;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(sc->malo_dev);
/* XXX not right but it's not used anywhere important */
@@ -290,6 +267,7 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
| IEEE80211_C_TXPMGT /* capable of txpow mgt */
| IEEE80211_C_WPA /* capable of WPA1+WPA2 */
;
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->malo_hwspecs.macaddr);
/*
* Transmit requires space in the packet for a special format transmit
@@ -301,16 +279,17 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
sizeof(struct ieee80211_frame);
/* call MI attach routine. */
- ieee80211_ifattach(ic, sc->malo_hwspecs.macaddr);
+ ieee80211_ifattach(ic);
/* override default methods */
ic->ic_vap_create = malo_vap_create;
ic->ic_vap_delete = malo_vap_delete;
ic->ic_raw_xmit = malo_raw_xmit;
ic->ic_updateslot = malo_updateslot;
-
ic->ic_scan_start = malo_scan_start;
ic->ic_scan_end = malo_scan_end;
ic->ic_set_channel = malo_set_channel;
+ ic->ic_parent = malo_parent;
+ ic->ic_transmit = malo_transmit;
sc->malo_invalid = 0; /* ready to go, enable int handling */
@@ -335,7 +314,6 @@ bad2:
bad1:
malo_hal_detach(mh);
bad:
- if_free(ifp);
sc->malo_invalid = 1;
return error;
@@ -347,12 +325,12 @@ malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct ifnet *ifp = ic->ic_ifp;
+ struct malo_softc *sc = ic->ic_softc;
struct malo_vap *mvp;
struct ieee80211vap *vap;
if (!TAILQ_EMPTY(&ic->ic_vaps)) {
- if_printf(ifp, "multiple vaps not supported\n");
+ device_printf(sc->malo_dev, "multiple vaps not supported\n");
return NULL;
}
switch (opmode) {
@@ -363,18 +341,13 @@ malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_MONITOR:
break;
default:
- if_printf(ifp, "%s mode not supported\n",
+ device_printf(sc->malo_dev, "%s mode not supported\n",
ieee80211_opmode_name[opmode]);
return NULL; /* unsupported */
}
- mvp = (struct malo_vap *) malloc(sizeof(struct malo_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (mvp == NULL) {
- if_printf(ifp, "cannot allocate vap state block\n");
- return NULL;
- }
+ mvp = malloc(sizeof(struct malo_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &mvp->malo_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
/* override state transition machine */
mvp->malo_newstate = vap->iv_newstate;
@@ -382,7 +355,7 @@ malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* complete setup */
ieee80211_vap_attach(vap,
- ieee80211_media_change, ieee80211_media_status);
+ ieee80211_media_change, ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -461,7 +434,6 @@ malo_desc_setup(struct malo_softc *sc, const char *name,
int nbuf, size_t bufsize, int ndesc, size_t descsize)
{
int error;
- struct ifnet *ifp = sc->malo_ifp;
uint8_t *ds;
DPRINTF(sc, MALO_DEBUG_RESET,
@@ -488,7 +460,8 @@ malo_desc_setup(struct malo_softc *sc, const char *name,
NULL, /* lockarg */
&dd->dd_dmat);
if (error != 0) {
- if_printf(ifp, "cannot allocate %s DMA tag\n", dd->dd_name);
+ device_printf(sc->malo_dev, "cannot allocate %s DMA tag\n",
+ dd->dd_name);
return error;
}
@@ -496,7 +469,8 @@ malo_desc_setup(struct malo_softc *sc, const char *name,
error = bus_dmamem_alloc(dd->dd_dmat, (void**) &dd->dd_desc,
BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dd->dd_dmamap);
if (error != 0) {
- if_printf(ifp, "unable to alloc memory for %u %s descriptors, "
+ device_printf(sc->malo_dev,
+ "unable to alloc memory for %u %s descriptors, "
"error %u\n", nbuf * ndesc, dd->dd_name, error);
goto fail1;
}
@@ -505,7 +479,8 @@ malo_desc_setup(struct malo_softc *sc, const char *name,
dd->dd_desc, dd->dd_desc_len,
malo_load_cb, &dd->dd_desc_paddr, BUS_DMA_NOWAIT);
if (error != 0) {
- if_printf(ifp, "unable to map %s descriptors, error %u\n",
+ device_printf(sc->malo_dev,
+ "unable to map %s descriptors, error %u\n",
dd->dd_name, error);
goto fail2;
}
@@ -532,7 +507,6 @@ fail1:
static int
malo_rxdma_setup(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
int error, bsize, i;
struct malo_rxbuf *bf;
struct malo_rxdesc *ds;
@@ -549,7 +523,8 @@ malo_rxdma_setup(struct malo_softc *sc)
bsize = malo_rxbuf * sizeof(struct malo_rxbuf);
bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO);
if (bf == NULL) {
- if_printf(ifp, "malloc of %u rx buffers failed\n", bsize);
+ device_printf(sc->malo_dev,
+ "malloc of %u rx buffers failed\n", bsize);
return error;
}
sc->malo_rxdma.dd_bufptr = bf;
@@ -562,8 +537,9 @@ malo_rxdma_setup(struct malo_softc *sc)
error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT,
&bf->bf_dmamap);
if (error != 0) {
- if_printf(ifp, "%s: unable to dmamap for rx buffer, "
- "error %d\n", __func__, error);
+ device_printf(sc->malo_dev,
+ "%s: unable to dmamap for rx buffer, error %d\n",
+ __func__, error);
return error;
}
/* NB: tail is intentional to preserve descriptor order */
@@ -575,7 +551,6 @@ malo_rxdma_setup(struct malo_softc *sc)
static int
malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq)
{
- struct ifnet *ifp = sc->malo_ifp;
int error, bsize, i;
struct malo_txbuf *bf;
struct malo_txdesc *ds;
@@ -590,7 +565,7 @@ malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq)
bsize = malo_txbuf * sizeof(struct malo_txbuf);
bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO);
if (bf == NULL) {
- if_printf(ifp, "malloc of %u tx buffers failed\n",
+ device_printf(sc->malo_dev, "malloc of %u tx buffers failed\n",
malo_txbuf);
return ENOMEM;
}
@@ -605,7 +580,8 @@ malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq)
error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT,
&bf->bf_dmamap);
if (error != 0) {
- if_printf(ifp, "unable to create dmamap for tx "
+ device_printf(sc->malo_dev,
+ "unable to create dmamap for tx "
"buffer %u, error %u\n", i, error);
return error;
}
@@ -1004,33 +980,19 @@ malo_tx_processq(struct malo_softc *sc, struct malo_txq *txq)
if (status & MALO_TXD_STATUS_FAILED_AGING)
sc->malo_stats.mst_tx_aging++;
}
- /*
- * Do any tx complete callback. Note this must
- * be done before releasing the node reference.
- * XXX no way to figure out if frame was ACK'd
- */
- if (bf->bf_m->m_flags & M_TXCB) {
- /* XXX strip fw len in case header inspected */
- m_adj(bf->bf_m, sizeof(uint16_t));
- ieee80211_process_callback(ni, bf->bf_m,
- (status & MALO_TXD_STATUS_OK) == 0);
- }
- /*
- * Reclaim reference to node.
- *
- * NB: the node may be reclaimed here if, for example
- * this is a DEAUTH message that was sent and the
- * node was timed out due to inactivity.
- */
- ieee80211_free_node(ni);
- }
+ /* XXX strip fw len in case header inspected */
+ m_adj(bf->bf_m, sizeof(uint16_t));
+ ieee80211_tx_complete(ni, bf->bf_m,
+ (status & MALO_TXD_STATUS_OK) == 0);
+ } else
+ m_freem(bf->bf_m);
+
ds->status = htole32(MALO_TXD_STATUS_IDLE);
ds->pktlen = htole32(0);
bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap);
- m_freem(bf->bf_m);
bf->bf_m = NULL;
bf->bf_node = NULL;
@@ -1049,23 +1011,23 @@ static void
malo_tx_proc(void *arg, int npending)
{
struct malo_softc *sc = arg;
- struct ifnet *ifp = sc->malo_ifp;
int i, nreaped;
/*
* Process each active queue.
*/
nreaped = 0;
+ MALO_LOCK(sc);
for (i = 0; i < MALO_NUM_TX_QUEUES; i++) {
if (!STAILQ_EMPTY(&sc->malo_txq[i].active))
nreaped += malo_tx_processq(sc, &sc->malo_txq[i]);
}
if (nreaped != 0) {
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
sc->malo_timer = 0;
- malo_start(ifp);
+ malo_start(sc);
}
+ MALO_UNLOCK(sc);
}
static int
@@ -1079,8 +1041,7 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni,
int error, ismcast, iswep;
int copyhdrlen, hdrlen, pktlen;
struct ieee80211_frame *wh;
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct malo_txdesc *ds;
struct malo_txrec *tr;
@@ -1225,7 +1186,7 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni,
ds->txpriority = txq->qnum;
break;
default:
- if_printf(ifp, "bogus frame type 0x%x (%s)\n",
+ device_printf(sc->malo_dev, "bogus frame type 0x%x (%s)\n",
wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
/* XXX statistic */
m_freem(m0);
@@ -1246,37 +1207,52 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni,
STAILQ_INSERT_TAIL(&txq->active, bf, bf_list);
MALO_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
sc->malo_timer = 5;
MALO_TXQ_UNLOCK(txq);
return 0;
#undef IEEE80211_DIR_DSTODS
}
+static int
+malo_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct malo_softc *sc = ic->ic_softc;
+ int error;
+
+ MALO_LOCK(sc);
+ if (!sc->malo_running) {
+ MALO_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->malo_snd, m);
+ if (error) {
+ MALO_UNLOCK(sc);
+ return (error);
+ }
+ malo_start(sc);
+ MALO_UNLOCK(sc);
+ return (0);
+}
+
static void
-malo_start(struct ifnet *ifp)
+malo_start(struct malo_softc *sc)
{
- struct malo_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct malo_txq *txq = &sc->malo_txq[0];
struct malo_txbuf *bf = NULL;
struct mbuf *m;
int nqueued = 0;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->malo_invalid)
+ MALO_LOCK_ASSERT(sc);
+
+ if (!sc->malo_running || sc->malo_invalid)
return;
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while ((m = mbufq_dequeue(&sc->malo_snd)) != NULL) {
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
bf = malo_getbuf(sc, txq);
if (bf == NULL) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
-
- /* XXX blocks other traffic */
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ mbufq_prepend(&sc->malo_snd, m);
sc->malo_stats.mst_tx_qstop++;
break;
}
@@ -1284,7 +1260,8 @@ malo_start(struct ifnet *ifp)
* Pass the frame to the h/w for transmission.
*/
if (malo_tx_start(sc, ni, bf, m)) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
if (bf != NULL) {
bf->bf_m = NULL;
bf->bf_node = NULL;
@@ -1328,21 +1305,18 @@ malo_start(struct ifnet *ifp)
static void
malo_watchdog(void *arg)
{
- struct malo_softc *sc;
- struct ifnet *ifp;
+ struct malo_softc *sc = arg;
- sc = arg;
callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
if (sc->malo_timer == 0 || --sc->malo_timer > 0)
return;
- ifp = sc->malo_ifp;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->malo_invalid) {
- if_printf(ifp, "watchdog timeout\n");
+ if (sc->malo_running && !sc->malo_invalid) {
+ device_printf(sc->malo_dev, "watchdog timeout\n");
/* XXX no way to reset h/w. now */
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->malo_ic.ic_oerrors, 1);
sc->malo_stats.mst_watchdog++;
}
}
@@ -1351,8 +1325,7 @@ static int
malo_hal_reset(struct malo_softc *sc)
{
static int first = 0;
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
struct malo_hal *mh = sc->malo_mh;
if (first == 0) {
@@ -1392,7 +1365,7 @@ malo_getrxmbuf(struct malo_softc *sc, struct malo_rxbuf *bf)
mtod(m, caddr_t), MJUMPAGESIZE,
malo_load_cb, &paddr, BUS_DMA_NOWAIT);
if (error != 0) {
- if_printf(sc->malo_ifp,
+ device_printf(sc->malo_dev,
"%s: bus_dmamap_load failed, error %d\n", __func__, error);
m_freem(m);
return NULL;
@@ -1483,26 +1456,23 @@ malo_startrecv(struct malo_softc *sc)
static void
malo_init_locked(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
struct malo_hal *mh = sc->malo_mh;
int error;
- DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags 0x%x\n",
- __func__, ifp->if_flags);
-
MALO_LOCK_ASSERT(sc);
/*
* Stop anything previously setup. This is safe whether this is
* the first time through or not.
*/
- malo_stop_locked(ifp, 0);
+ malo_stop(sc);
/*
* Push state to the firmware.
*/
if (!malo_hal_reset(sc)) {
- if_printf(ifp, "%s: unable to reset hardware\n", __func__);
+ device_printf(sc->malo_dev,
+ "%s: unable to reset hardware\n", __func__);
return;
}
@@ -1511,7 +1481,8 @@ malo_init_locked(struct malo_softc *sc)
*/
error = malo_startrecv(sc);
if (error != 0) {
- if_printf(ifp, "%s: unable to start recv logic, error %d\n",
+ device_printf(sc->malo_dev,
+ "%s: unable to start recv logic, error %d\n",
__func__, error);
return;
}
@@ -1528,7 +1499,7 @@ malo_init_locked(struct malo_softc *sc)
| MALO_A2HRIC_BIT_RADAR_DETECT
| MALO_A2HRIC_BIT_CHAN_SWITCH;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->malo_running = 1;
malo_hal_intrset(mh, sc->malo_imask);
callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
}
@@ -1537,18 +1508,13 @@ static void
malo_init(void *arg)
{
struct malo_softc *sc = (struct malo_softc *) arg;
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
- DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags 0x%x\n",
- __func__, ifp->if_flags);
-
MALO_LOCK(sc);
malo_init_locked(sc);
-
MALO_UNLOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->malo_running)
ieee80211_start_all(ic); /* start all vap's */
}
@@ -1558,9 +1524,8 @@ malo_init(void *arg)
static void
malo_setmcastfilter(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifmultiaddr *ifma;
+ struct ieee80211com *ic = &sc->malo_ic;
+ struct ieee80211vap *vap;
uint8_t macs[IEEE80211_ADDR_LEN * MALO_HAL_MCAST_MAX];
uint8_t *mp;
int nmc;
@@ -1568,26 +1533,32 @@ malo_setmcastfilter(struct malo_softc *sc)
mp = macs;
nmc = 0;
- if (ic->ic_opmode == IEEE80211_M_MONITOR ||
- (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)))
+ if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_allmulti > 0 ||
+ ic->ic_promisc > 0)
goto all;
-
- if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- if (nmc == MALO_HAL_MCAST_MAX) {
- ifp->if_flags |= IFF_ALLMULTI;
- if_maddr_runlock(ifp);
- goto all;
- }
- IEEE80211_ADDR_COPY(mp,
- LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ struct ifnet *ifp;
+ struct ifmultiaddr *ifma;
+
+ ifp = vap->iv_ifp;
+ if_maddr_rlock(ifp);
+ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+
+ if (nmc == MALO_HAL_MCAST_MAX) {
+ ifp->if_flags |= IFF_ALLMULTI;
+ if_maddr_runlock(ifp);
+ goto all;
+ }
+ IEEE80211_ADDR_COPY(mp,
+ LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
- mp += IEEE80211_ADDR_LEN, nmc++;
+ mp += IEEE80211_ADDR_LEN, nmc++;
+ }
+ if_maddr_runlock(ifp);
}
- if_maddr_runlock(ifp);
malo_hal_setmcast(sc->malo_mh, nmc, macs);
@@ -1602,8 +1573,7 @@ all:
static int
malo_mode_init(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
struct malo_hal *mh = sc->malo_mh;
/*
@@ -1612,7 +1582,7 @@ malo_mode_init(struct malo_softc *sc)
* identify internal requests (from the bridge)
* versus external requests such as for tcpdump.
*/
- malo_hal_setpromisc(mh, (ifp->if_flags & IFF_PROMISC) &&
+ malo_hal_setpromisc(mh, ic->ic_promisc > 0 &&
ic->ic_opmode != IEEE80211_M_HOSTAP);
malo_setmcastfilter(sc);
@@ -1641,8 +1611,7 @@ malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq)
MALO_TXQ_UNLOCK(txq);
#ifdef MALO_DEBUG
if (sc->malo_debug & MALO_DEBUG_RESET) {
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
const struct malo_txrec *tr =
mtod(bf->bf_m, const struct malo_txrec *);
malo_printtxbuf(bf, txq->qnum, ix);
@@ -1670,18 +1639,17 @@ malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq)
}
static void
-malo_stop_locked(struct ifnet *ifp, int disable)
+malo_stop(struct malo_softc *sc)
{
- struct malo_softc *sc = ifp->if_softc;
struct malo_hal *mh = sc->malo_mh;
int i;
- DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n",
- __func__, sc->malo_invalid, ifp->if_flags);
+ DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid %u running %u\n",
+ __func__, sc->malo_invalid, sc->malo_running);
MALO_LOCK_ASSERT(sc);
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ if (!sc->malo_running)
return;
/*
@@ -1693,10 +1661,10 @@ malo_stop_locked(struct ifnet *ifp, int disable)
* Note that some of this work is not possible if the hardware
* is gone (invalid).
*/
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ sc->malo_running = 0;
callout_stop(&sc->malo_watchdog_timer);
sc->malo_timer = 0;
- /* diable interrupt. */
+ /* disable interrupt. */
malo_hal_intrset(mh, 0);
/* turn off the radio. */
malo_hal_setradio(mh, 0, MHP_AUTO_PREAMBLE);
@@ -1706,57 +1674,38 @@ malo_stop_locked(struct ifnet *ifp, int disable)
malo_tx_draintxq(sc, &sc->malo_txq[i]);
}
-static int
-malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+malo_parent(struct ieee80211com *ic)
{
-#define MALO_IS_RUNNING(ifp) \
- ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
- struct malo_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
+ struct malo_softc *sc = ic->ic_softc;
+ int startall = 0;
MALO_LOCK(sc);
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (MALO_IS_RUNNING(ifp)) {
- /*
- * To avoid rescanning another access point,
- * do not call malo_init() here. Instead,
- * only reflect promisc mode settings.
- */
- malo_mode_init(sc);
- } else if (ifp->if_flags & IFF_UP) {
- /*
- * Beware of being called during attach/detach
- * to reset promiscuous mode. In that case we
- * will still be marked UP but not RUNNING.
- * However trying to re-init the interface
- * is the wrong thing to do as we've already
- * torn down much of our state. There's
- * probably a better way to deal with this.
- */
- if (!sc->malo_invalid) {
- malo_init_locked(sc);
- startall = 1;
- }
- } else
- malo_stop_locked(ifp, 1);
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- default:
- error = ether_ioctl(ifp, cmd, data);
- break;
- }
+ if (ic->ic_nrunning > 0) {
+ /*
+ * Beware of being called during attach/detach
+ * to reset promiscuous mode. In that case we
+ * will still be marked UP but not RUNNING.
+ * However trying to re-init the interface
+ * is the wrong thing to do as we've already
+ * torn down much of our state. There's
+ * probably a better way to deal with this.
+ */
+ if (!sc->malo_running && !sc->malo_invalid) {
+ malo_init(sc);
+ startall = 1;
+ }
+ /*
+ * To avoid rescanning another access point,
+ * do not call malo_init() here. Instead,
+ * only reflect promisc mode settings.
+ */
+ malo_mode_init(sc);
+ } else if (sc->malo_running)
+ malo_stop(sc);
MALO_UNLOCK(sc);
-
if (startall)
ieee80211_start_all(ic);
- return error;
-#undef MALO_IS_RUNNING
}
/*
@@ -1773,7 +1722,7 @@ malo_updateslot(struct ieee80211com *ic)
int error;
/* NB: can be called early; suppress needless cmds */
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if (!sc->malo_running)
return;
DPRINTF(sc, MALO_DEBUG_RESET,
@@ -1795,7 +1744,7 @@ static int
malo_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct ieee80211com *ic = vap->iv_ic;
- struct malo_softc *sc = ic->ic_ifp->if_softc;
+ struct malo_softc *sc = ic->ic_softc;
struct malo_hal *mh = sc->malo_mh;
int error;
@@ -1839,12 +1788,11 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct malo_softc *sc = ifp->if_softc;
+ struct malo_softc *sc = ic->ic_softc;
struct malo_txbuf *bf;
struct malo_txq *txq;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->malo_invalid) {
+ if (!sc->malo_running || sc->malo_invalid) {
ieee80211_free_node(ni);
m_freem(m);
return ENETDOWN;
@@ -1859,8 +1807,6 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
txq = &sc->malo_txq[0];
bf = malo_getbuf(sc, txq);
if (bf == NULL) {
- /* XXX blocks other traffic */
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
ieee80211_free_node(ni);
m_freem(m);
return ENOBUFS;
@@ -1870,7 +1816,6 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
* Pass the frame to the h/w for transmission.
*/
if (malo_tx_start(sc, ni, bf, m) != 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
bf->bf_m = NULL;
bf->bf_node = NULL;
MALO_TXQ_LOCK(txq);
@@ -1915,9 +1860,9 @@ malo_sysctlattach(struct malo_softc *sc)
static void
malo_announce(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
- if_printf(ifp, "versions [hw %d fw %d.%d.%d.%d] (regioncode %d)\n",
+ device_printf(sc->malo_dev,
+ "versions [hw %d fw %d.%d.%d.%d] (regioncode %d)\n",
sc->malo_hwspecs.hwversion,
(sc->malo_hwspecs.fw_releasenum >> 24) & 0xff,
(sc->malo_hwspecs.fw_releasenum >> 16) & 0xff,
@@ -1926,9 +1871,11 @@ malo_announce(struct malo_softc *sc)
sc->malo_hwspecs.regioncode);
if (bootverbose || malo_rxbuf != MALO_RXBUF)
- if_printf(ifp, "using %u rx buffers\n", malo_rxbuf);
+ device_printf(sc->malo_dev,
+ "using %u rx buffers\n", malo_rxbuf);
if (bootverbose || malo_txbuf != MALO_TXBUF)
- if_printf(ifp, "using %u tx buffers\n", malo_txbuf);
+ device_printf(sc->malo_dev,
+ "using %u tx buffers\n", malo_txbuf);
}
/*
@@ -1989,8 +1936,7 @@ malo_chan_set(struct malo_softc *sc, struct ieee80211_channel *chan)
static void
malo_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct malo_softc *sc = ifp->if_softc;
+ struct malo_softc *sc = ic->ic_softc;
DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__);
}
@@ -1998,8 +1944,7 @@ malo_scan_start(struct ieee80211com *ic)
static void
malo_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct malo_softc *sc = ifp->if_softc;
+ struct malo_softc *sc = ic->ic_softc;
DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__);
}
@@ -2007,8 +1952,7 @@ malo_scan_end(struct ieee80211com *ic)
static void
malo_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct malo_softc *sc = ifp->if_softc;
+ struct malo_softc *sc = ic->ic_softc;
(void) malo_chan_set(sc, ic->ic_curchan);
}
@@ -2020,8 +1964,7 @@ malo_rx_proc(void *arg, int npending)
((((const struct ieee80211_frame *)wh)->i_fc[1] & \
IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
struct malo_softc *sc = arg;
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
struct malo_rxbuf *bf;
struct malo_rxdesc *ds;
struct mbuf *m, *mnew;
@@ -2078,7 +2021,7 @@ malo_rx_proc(void *arg, int npending)
#endif
status = ds->status;
if (status & MALO_RXD_STATUS_DECRYPT_ERR_MASK) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto rx_next;
}
/*
@@ -2117,7 +2060,7 @@ malo_rx_proc(void *arg, int npending)
/* XXX don't need mbuf, just dma buffer */
mnew = malo_getrxmbuf(sc, bf);
if (mnew == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto rx_next;
}
/*
@@ -2128,7 +2071,6 @@ malo_rx_proc(void *arg, int npending)
bf->bf_m = mnew;
m->m_data += off - hdrlen;
m->m_pkthdr.len = m->m_len = pktlen;
- m->m_pkthdr.rcvif = ifp;
/*
* Piece 802.11 header together.
@@ -2158,8 +2100,6 @@ malo_rx_proc(void *arg, int npending)
len, ds->rate, rssi);
}
#endif
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
-
/* dispatch */
ni = ieee80211_find_rxnode(ic,
(struct ieee80211_frame_min *)wh);
@@ -2177,22 +2117,11 @@ rx_next:
malo_bar0_write4(sc, sc->malo_hwspecs.rxdesc_read, readptr);
sc->malo_rxnext = bf;
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
- malo_start(ifp);
+ if (mbufq_first(&sc->malo_snd) != NULL)
+ malo_start(sc);
#undef IEEE80211_DIR_DSTODS
}
-static void
-malo_stop(struct ifnet *ifp, int disable)
-{
- struct malo_softc *sc = ifp->if_softc;
-
- MALO_LOCK(sc);
- malo_stop_locked(ifp, disable);
- MALO_UNLOCK(sc);
-}
-
/*
* Reclaim all tx queue resources.
*/
@@ -2208,13 +2137,9 @@ malo_tx_cleanup(struct malo_softc *sc)
int
malo_detach(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
- DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n",
- __func__, ifp->if_flags);
-
- malo_stop(ifp, 1);
+ malo_stop(sc);
if (sc->malo_tq != NULL) {
taskqueue_drain(sc->malo_tq, &sc->malo_rxtask);
@@ -2240,8 +2165,7 @@ malo_detach(struct malo_softc *sc)
malo_dma_cleanup(sc);
malo_tx_cleanup(sc);
malo_hal_detach(sc->malo_mh);
- if_free(ifp);
-
+ mbufq_drain(&sc->malo_snd);
MALO_LOCK_DESTROY(sc);
return 0;
@@ -2250,28 +2174,21 @@ malo_detach(struct malo_softc *sc)
void
malo_shutdown(struct malo_softc *sc)
{
- malo_stop(sc->malo_ifp, 1);
+
+ malo_stop(sc);
}
void
malo_suspend(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
- DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n",
- __func__, ifp->if_flags);
-
- malo_stop(ifp, 1);
+ malo_stop(sc);
}
void
malo_resume(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
-
- DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n",
- __func__, ifp->if_flags);
- if (ifp->if_flags & IFF_UP)
+ if (sc->malo_ic.ic_nrunning > 0)
malo_init(sc);
}
diff --git a/sys/dev/malo/if_malo.h b/sys/dev/malo/if_malo.h
index bac290c..681e750 100644
--- a/sys/dev/malo/if_malo.h
+++ b/sys/dev/malo/if_malo.h
@@ -520,8 +520,9 @@ struct malo_vap {
#define MALO_VAP(vap) ((struct malo_vap *)(vap))
struct malo_softc {
+ struct ieee80211com malo_ic;
+ struct mbufq malo_snd;
device_t malo_dev;
- struct ifnet *malo_ifp; /* interface common */
struct mtx malo_mtx; /* master lock (recursive) */
struct taskqueue *malo_tq; /* private task queue */
@@ -531,9 +532,10 @@ struct malo_softc {
bus_space_handle_t malo_io1h; /* BAR 1 */
bus_space_tag_t malo_io1t;
- unsigned int malo_invalid : 1,/* disable hardware accesses */
- malo_recvsetup : 1, /* recv setup */
- malo_fixedrate: 1; /* use fixed tx rate */
+ unsigned int malo_invalid: 1,/* disable hardware accesses */
+ malo_recvsetup: 1, /* recv setup */
+ malo_fixedrate: 1, /* use fixed tx rate */
+ malo_running: 1;
struct malo_hal *malo_mh; /* h/w access layer */
struct malo_hal_hwspec malo_hwspecs; /* h/w capabilities */
diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c
index 0997500..42264ac 100644
--- a/sys/dev/mwl/if_mwl.c
+++ b/sys/dev/mwl/if_mwl.c
@@ -91,17 +91,17 @@ static struct ieee80211vap *mwl_vap_create(struct ieee80211com *,
static void mwl_vap_delete(struct ieee80211vap *);
static int mwl_setupdma(struct mwl_softc *);
static int mwl_hal_reset(struct mwl_softc *sc);
-static int mwl_init_locked(struct mwl_softc *);
-static void mwl_init(void *);
-static void mwl_stop_locked(struct ifnet *, int);
+static int mwl_init(struct mwl_softc *);
+static void mwl_parent(struct ieee80211com *);
static int mwl_reset(struct ieee80211vap *, u_long);
-static void mwl_stop(struct ifnet *, int);
-static void mwl_start(struct ifnet *);
+static void mwl_stop(struct mwl_softc *);
+static void mwl_start(struct mwl_softc *);
+static int mwl_transmit(struct ieee80211com *, struct mbuf *);
static int mwl_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static int mwl_media_change(struct ifnet *);
static void mwl_watchdog(void *);
-static int mwl_ioctl(struct ifnet *, u_long, caddr_t);
+static int mwl_ioctl(struct ieee80211com *, u_long, void *);
static void mwl_radar_proc(void *, int);
static void mwl_chanswitch_proc(void *, int);
static void mwl_bawatchdog_proc(void *, int);
@@ -229,12 +229,11 @@ enum {
((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK|IEEE80211_FC0_SUBTYPE_MASK)) == \
(IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON))
#define IFF_DUMPPKTS_RECV(sc, wh) \
- (((sc->sc_debug & MWL_DEBUG_RECV) && \
- ((sc->sc_debug & MWL_DEBUG_RECV_ALL) || !IS_BEACON(wh))) || \
- (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
+ ((sc->sc_debug & MWL_DEBUG_RECV) && \
+ ((sc->sc_debug & MWL_DEBUG_RECV_ALL) || !IS_BEACON(wh)))
#define IFF_DUMPPKTS_XMIT(sc) \
- ((sc->sc_debug & MWL_DEBUG_XMIT) || \
- (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
+ (sc->sc_debug & MWL_DEBUG_XMIT)
+
#define DPRINTF(sc, m, fmt, ...) do { \
if (sc->sc_debug & (m)) \
printf(fmt, __VA_ARGS__); \
@@ -246,16 +245,10 @@ enum {
static void mwl_printrxbuf(const struct mwl_rxbuf *bf, u_int ix);
static void mwl_printtxbuf(const struct mwl_txbuf *bf, u_int qnum, u_int ix);
#else
-#define IFF_DUMPPKTS_RECV(sc, wh) \
- ((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
-#define IFF_DUMPPKTS_XMIT(sc) \
- ((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
-#define DPRINTF(sc, m, fmt, ...) do { \
- (void) sc; \
-} while (0)
-#define KEYPRINTF(sc, k, mac) do { \
- (void) sc; \
-} while (0)
+#define IFF_DUMPPKTS_RECV(sc, wh) do {} while (0)
+#define IFF_DUMPPKTS_XMIT(sc) do {} while (0)
+#define DPRINTF(sc, m, fmt, ...) do {} while (0)
+#define KEYPRINTF(sc, k, mac) do {} while (0)
#endif
static MALLOC_DEFINE(M_MWLDEV, "mwldev", "mwl driver dma buffers");
@@ -293,34 +286,22 @@ WR4(struct mwl_softc *sc, bus_size_t off, uint32_t val)
int
mwl_attach(uint16_t devid, struct mwl_softc *sc)
{
- struct ifnet *ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
struct mwl_hal *mh;
int error = 0;
DPRINTF(sc, MWL_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "cannot if_alloc()\n");
- return ENOSPC;
- }
- ic = ifp->if_l2com;
-
/*
* Setup the RX free list lock early, so it can be consistently
* removed.
*/
MWL_RXFREE_INIT(sc);
- /* set these up early for if_printf use */
- if_initname(ifp, device_get_name(sc->sc_dev),
- device_get_unit(sc->sc_dev));
-
mh = mwl_hal_attach(sc->sc_dev, devid,
sc->sc_io1h, sc->sc_io1t, sc->sc_dmat);
if (mh == NULL) {
- if_printf(ifp, "unable to attach HAL\n");
+ device_printf(sc->sc_dev, "unable to attach HAL\n");
error = EIO;
goto bad;
}
@@ -331,12 +312,12 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc)
* needed so setting up the wrong mode isn't a big deal.
*/
if (mwl_hal_fwload(mh, NULL) != 0) {
- if_printf(ifp, "unable to setup builtin firmware\n");
+ device_printf(sc->sc_dev, "unable to setup builtin firmware\n");
error = EIO;
goto bad1;
}
if (mwl_hal_gethwspecs(mh, &sc->sc_hwspecs) != 0) {
- if_printf(ifp, "unable to fetch h/w specs\n");
+ device_printf(sc->sc_dev, "unable to fetch h/w specs\n");
error = EIO;
goto bad1;
}
@@ -356,7 +337,8 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc)
*/
error = mwl_dma_setup(sc);
if (error != 0) {
- if_printf(ifp, "failed to setup descriptors: %d\n", error);
+ device_printf(sc->sc_dev, "failed to setup descriptors: %d\n",
+ error);
goto bad1;
}
error = mwl_setupdma(sc); /* push to firmware */
@@ -365,11 +347,12 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc)
callout_init(&sc->sc_timer, 1);
callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
sc->sc_tq = taskqueue_create("mwl_taskq", M_NOWAIT,
taskqueue_thread_enqueue, &sc->sc_tq);
taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
- "%s taskq", ifp->if_xname);
+ "%s taskq", device_get_nameunit(sc->sc_dev));
TASK_INIT(&sc->sc_rxtask, 0, mwl_rx_proc, sc);
TASK_INIT(&sc->sc_radartask, 0, mwl_radar_proc, sc);
@@ -378,8 +361,9 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc)
/* NB: insure BK queue is the lowest priority h/w queue */
if (!mwl_tx_setup(sc, WME_AC_BK, MWL_WME_AC_BK)) {
- if_printf(ifp, "unable to setup xmit queue for %s traffic!\n",
- ieee80211_wme_acnames[WME_AC_BK]);
+ device_printf(sc->sc_dev,
+ "unable to setup xmit queue for %s traffic!\n",
+ ieee80211_wme_acnames[WME_AC_BK]);
error = EIO;
goto bad2;
}
@@ -403,16 +387,6 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc)
}
TASK_INIT(&sc->sc_txtask, 0, mwl_tx_proc, sc);
- ifp->if_softc = sc;
- ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
- ifp->if_start = mwl_start;
- ifp->if_ioctl = mwl_ioctl;
- ifp->if_init = mwl_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;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(sc->sc_dev);
/* XXX not right but it's not used anywhere important */
@@ -480,8 +454,10 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc)
ic->ic_headroom = sizeof(struct mwltxrec) -
sizeof(struct ieee80211_frame);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->sc_hwspecs.macAddr);
+
/* call MI attach routine. */
- ieee80211_ifattach(ic, sc->sc_hwspecs.macAddr);
+ ieee80211_ifattach(ic);
ic->ic_setregdomain = mwl_setregdomain;
ic->ic_getradiocaps = mwl_getradiocaps;
/* override default methods */
@@ -491,6 +467,9 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc)
ic->ic_update_mcast = mwl_update_mcast;
ic->ic_update_promisc = mwl_update_promisc;
ic->ic_wme.wme_update = mwl_wme_update;
+ ic->ic_transmit = mwl_transmit;
+ ic->ic_ioctl = mwl_ioctl;
+ ic->ic_parent = mwl_parent;
ic->ic_node_alloc = mwl_node_alloc;
sc->sc_node_cleanup = ic->ic_node_cleanup;
@@ -537,7 +516,6 @@ bad1:
mwl_hal_detach(mh);
bad:
MWL_RXFREE_DESTROY(sc);
- if_free(ifp);
sc->sc_invalid = 1;
return error;
}
@@ -545,13 +523,11 @@ bad:
int
mwl_detach(struct mwl_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n",
- __func__, ifp->if_flags);
+ struct ieee80211com *ic = &sc->sc_ic;
- mwl_stop(ifp, 1);
+ MWL_LOCK(sc);
+ mwl_stop(sc);
+ MWL_UNLOCK(sc);
/*
* NB: the order of these is important:
* o call the 802.11 layer before detaching the hal to
@@ -570,7 +546,7 @@ mwl_detach(struct mwl_softc *sc)
MWL_RXFREE_DESTROY(sc);
mwl_tx_cleanup(sc);
mwl_hal_detach(sc->sc_mh);
- if_free(ifp);
+ mbufq_drain(&sc->sc_snd);
return 0;
}
@@ -601,7 +577,7 @@ assign_address(struct mwl_softc *sc, uint8_t mac[IEEE80211_ADDR_LEN], int clone)
}
static void
-reclaim_address(struct mwl_softc *sc, uint8_t mac[IEEE80211_ADDR_LEN])
+reclaim_address(struct mwl_softc *sc, const uint8_t mac[IEEE80211_ADDR_LEN])
{
int i = mac[0] >> 2;
if (i != 0 || --sc->sc_nbssid0 == 0)
@@ -614,8 +590,7 @@ mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac0[IEEE80211_ADDR_LEN])
{
- struct ifnet *ifp = ic->ic_ifp;
- struct mwl_softc *sc = ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
struct mwl_hal *mh = sc->sc_mh;
struct ieee80211vap *vap, *apvap;
struct mwl_hal_vap *hvap;
@@ -661,17 +636,7 @@ mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
return NULL;
}
- mvp = (struct mwl_vap *) malloc(sizeof(struct mwl_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (mvp == NULL) {
- if (hvap != NULL) {
- mwl_hal_delvap(hvap);
- if ((flags & IEEE80211_CLONE_MACADDR) == 0)
- reclaim_address(sc, mac);
- }
- /* XXX msg */
- return NULL;
- }
+ mvp = malloc(sizeof(struct mwl_vap), M_80211_VAP, M_WAITOK | M_ZERO);
mvp->mv_hvap = hvap;
if (opmode == IEEE80211_M_WDS) {
/*
@@ -686,9 +651,7 @@ mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
KASSERT(mvp->mv_ap_hvap != NULL, ("no ap vap"));
}
vap = &mvp->mv_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
- if (hvap != NULL)
- IEEE80211_ADDR_COPY(vap->iv_myaddr, mac);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
/* override with driver methods */
mvp->mv_newstate = vap->iv_newstate;
vap->iv_newstate = mwl_newstate;
@@ -713,7 +676,8 @@ mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_4;
/* complete setup */
- ieee80211_vap_attach(vap, mwl_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, mwl_media_change, ieee80211_media_status,
+ mac);
switch (vap->iv_opmode) {
case IEEE80211_M_HOSTAP:
@@ -752,14 +716,13 @@ static void
mwl_vap_delete(struct ieee80211vap *vap)
{
struct mwl_vap *mvp = MWL_VAP(vap);
- struct ifnet *parent = vap->iv_ic->ic_ifp;
- struct mwl_softc *sc = parent->if_softc;
+ struct mwl_softc *sc = vap->iv_ic->ic_softc;
struct mwl_hal *mh = sc->sc_mh;
struct mwl_hal_vap *hvap = mvp->mv_hvap;
enum ieee80211_opmode opmode = vap->iv_opmode;
/* XXX disallow ap vap delete if WDS still present */
- if (parent->if_drv_flags & IFF_DRV_RUNNING) {
+ if (sc->sc_running) {
/* quiesce h/w while we remove the vap */
mwl_hal_intrset(mh, 0); /* disable interrupts */
}
@@ -786,31 +749,31 @@ mwl_vap_delete(struct ieee80211vap *vap)
}
mwl_cleartxq(sc, vap);
free(mvp, M_80211_VAP);
- if (parent->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_running)
mwl_hal_intrset(mh, sc->sc_imask);
}
void
mwl_suspend(struct mwl_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n",
- __func__, ifp->if_flags);
-
- mwl_stop(ifp, 1);
+ MWL_LOCK(sc);
+ mwl_stop(sc);
+ MWL_UNLOCK(sc);
}
void
mwl_resume(struct mwl_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
+ int error = EDOOFUS;
- DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n",
- __func__, ifp->if_flags);
+ MWL_LOCK(sc);
+ if (sc->sc_ic.ic_nrunning > 0)
+ error = mwl_init(sc);
+ MWL_UNLOCK(sc);
- if (ifp->if_flags & IFF_UP)
- mwl_init(sc);
+ if (error == 0)
+ ieee80211_start_all(&sc->sc_ic); /* start all vap's */
}
void
@@ -818,7 +781,9 @@ mwl_shutdown(void *arg)
{
struct mwl_softc *sc = arg;
- mwl_stop(sc->sc_ifp, 1);
+ MWL_LOCK(sc);
+ mwl_stop(sc);
+ MWL_UNLOCK(sc);
}
/*
@@ -884,8 +849,7 @@ static void
mwl_radar_proc(void *arg, int pending)
{
struct mwl_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
DPRINTF(sc, MWL_DEBUG_ANY, "%s: radar detected, pending %u\n",
__func__, pending);
@@ -902,8 +866,7 @@ static void
mwl_chanswitch_proc(void *arg, int pending)
{
struct mwl_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
DPRINTF(sc, MWL_DEBUG_ANY, "%s: channel switch notice, pending %u\n",
__func__, pending);
@@ -1031,8 +994,7 @@ mwl_setupdma(struct mwl_softc *sc)
static int
mwl_setcurchanrates(struct mwl_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
const struct ieee80211_rateset *rs;
MWL_HAL_TXRATE rates;
@@ -1145,8 +1107,7 @@ mwl_map2regioncode(const struct ieee80211_regdomain *rd)
static int
mwl_hal_reset(struct mwl_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct mwl_hal *mh = sc->sc_mh;
mwl_hal_setantenna(mh, WL_ANTENNATYPE_RX, sc->sc_rxantenna);
@@ -1168,28 +1129,24 @@ mwl_hal_reset(struct mwl_softc *sc)
}
static int
-mwl_init_locked(struct mwl_softc *sc)
+mwl_init(struct mwl_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
struct mwl_hal *mh = sc->sc_mh;
int error = 0;
- DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags 0x%x\n",
- __func__, ifp->if_flags);
-
MWL_LOCK_ASSERT(sc);
/*
* Stop anything previously setup. This is safe
* whether this is the first time through or not.
*/
- mwl_stop_locked(ifp, 0);
+ mwl_stop(sc);
/*
* Push vap-independent state to the firmware.
*/
if (!mwl_hal_reset(sc)) {
- if_printf(ifp, "unable to reset hardware\n");
+ device_printf(sc->sc_dev, "unable to reset hardware\n");
return EIO;
}
@@ -1198,7 +1155,7 @@ mwl_init_locked(struct mwl_softc *sc)
*/
error = mwl_startrecv(sc);
if (error != 0) {
- if_printf(ifp, "unable to start recv logic\n");
+ device_printf(sc->sc_dev, "unable to start recv logic\n");
return error;
}
@@ -1221,7 +1178,7 @@ mwl_init_locked(struct mwl_softc *sc)
| MACREQ_A2HRIC_BIT_TX_ACK
;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_running = 1;
mwl_hal_intrset(mh, sc->sc_imask);
callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc);
@@ -1229,54 +1186,21 @@ mwl_init_locked(struct mwl_softc *sc)
}
static void
-mwl_init(void *arg)
+mwl_stop(struct mwl_softc *sc)
{
- struct mwl_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- int error = 0;
-
- DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags 0x%x\n",
- __func__, ifp->if_flags);
-
- MWL_LOCK(sc);
- error = mwl_init_locked(sc);
- MWL_UNLOCK(sc);
-
- if (error == 0)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
-mwl_stop_locked(struct ifnet *ifp, int disable)
-{
- struct mwl_softc *sc = ifp->if_softc;
-
- DPRINTF(sc, MWL_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n",
- __func__, sc->sc_invalid, ifp->if_flags);
MWL_LOCK_ASSERT(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ if (sc->sc_running) {
/*
* Shutdown the hardware and driver.
*/
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ sc->sc_running = 0;
callout_stop(&sc->sc_watchdog);
sc->sc_tx_timer = 0;
mwl_draintxq(sc);
}
}
-static void
-mwl_stop(struct ifnet *ifp, int disable)
-{
- struct mwl_softc *sc = ifp->if_softc;
-
- MWL_LOCK(sc);
- mwl_stop_locked(ifp, disable);
- MWL_UNLOCK(sc);
-}
-
static int
mwl_reset_vap(struct ieee80211vap *vap, int state)
{
@@ -1319,8 +1243,7 @@ mwl_reset(struct ieee80211vap *vap, u_long cmd)
if (hvap != NULL) { /* WDS, MONITOR, etc. */
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct mwl_softc *sc = ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
struct mwl_hal *mh = sc->sc_mh;
/* XXX handle DWDS sta vap change */
@@ -1386,24 +1309,41 @@ mwl_puttxbuf_tail(struct mwl_txq *txq, struct mwl_txbuf *bf)
MWL_TXQ_UNLOCK(txq);
}
+static int
+mwl_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct mwl_softc *sc = ic->ic_softc;
+ int error;
+
+ MWL_LOCK(sc);
+ if (!sc->sc_running) {
+ MWL_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ MWL_UNLOCK(sc);
+ return (error);
+ }
+ mwl_start(sc);
+ MWL_UNLOCK(sc);
+ return (0);
+}
+
static void
-mwl_start(struct ifnet *ifp)
+mwl_start(struct mwl_softc *sc)
{
- struct mwl_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mwl_txbuf *bf;
struct mbuf *m;
struct mwl_txq *txq = NULL; /* XXX silence gcc */
int nqueued;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid)
+ MWL_LOCK_ASSERT(sc);
+ if (!sc->sc_running || sc->sc_invalid)
return;
nqueued = 0;
- for (;;) {
- bf = NULL;
- IFQ_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
/*
* Grab the node for the destination.
*/
@@ -1421,8 +1361,6 @@ mwl_start(struct ifnet *ifp)
ieee80211_free_node(ni);
#ifdef MWL_TX_NODROP
sc->sc_stats.mst_tx_qstop++;
- /* XXX blocks other traffic */
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
#else
DPRINTF(sc, MWL_DEBUG_XMIT,
@@ -1436,7 +1374,8 @@ mwl_start(struct ifnet *ifp)
* Pass the frame to the h/w for transmission.
*/
if (mwl_tx_start(sc, ni, bf, m)) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
mwl_puttxbuf_head(txq, bf);
ieee80211_free_node(ni);
continue;
@@ -1474,12 +1413,11 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct mwl_softc *sc = ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
struct mwl_txbuf *bf;
struct mwl_txq *txq;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) {
+ if (!sc->sc_running || sc->sc_invalid) {
ieee80211_free_node(ni);
m_freem(m);
return ENETDOWN;
@@ -1496,8 +1434,6 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
bf = mwl_gettxbuf(sc, txq);
if (bf == NULL) {
sc->sc_stats.mst_tx_qstop++;
- /* XXX blocks other traffic */
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
ieee80211_free_node(ni);
m_freem(m);
return ENOBUFS;
@@ -1506,7 +1442,6 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
* Pass the frame to the h/w for transmission.
*/
if (mwl_tx_start(sc, ni, bf, m)) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
mwl_puttxbuf_head(txq, bf);
ieee80211_free_node(ni);
@@ -1581,7 +1516,7 @@ static int
mwl_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
{
- struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = vap->iv_ic->ic_softc;
if (k->wk_keyix != IEEE80211_KEYIX_NONE ||
(k->wk_flags & IEEE80211_KEY_GROUP)) {
@@ -1609,7 +1544,7 @@ mwl_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
static int
mwl_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
{
- struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = vap->iv_ic->ic_softc;
struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
MWL_HAL_KEYVAL hk;
const uint8_t bcastaddr[IEEE80211_ADDR_LEN] =
@@ -1676,7 +1611,7 @@ mwl_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k,
#define IEEE80211_IS_STATICKEY(k) \
(((k)->wk_flags & (GRPXMIT|IEEE80211_KEY_RECV)) == \
(GRPXMIT|IEEE80211_KEY_RECV))
- struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = vap->iv_ic->ic_softc;
struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap;
const struct ieee80211_cipher *cip = k->wk_cipher;
const uint8_t *macaddr;
@@ -1791,7 +1726,6 @@ mwl_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k,
static void
mwl_setmcastfilter(struct mwl_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
#if 0
struct ether_multi *enm;
struct ether_multistep estep;
@@ -1815,17 +1749,13 @@ mwl_setmcastfilter(struct mwl_softc *sc)
}
ifp->if_flags &= ~IFF_ALLMULTI;
mwl_hal_setmcast(sc->sc_mh, nmc, macs);
-#else
- /* XXX no mcast filter support; we get everything */
- ifp->if_flags |= IFF_ALLMULTI;
#endif
}
static int
mwl_mode_init(struct mwl_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct mwl_hal *mh = sc->sc_mh;
/*
@@ -1834,7 +1764,7 @@ mwl_mode_init(struct mwl_softc *sc)
* identify internal requests (from the bridge)
* versus external requests such as for tcpdump.
*/
- mwl_hal_setpromisc(mh, (ifp->if_flags & IFF_PROMISC) &&
+ mwl_hal_setpromisc(mh, ic->ic_promisc > 0 &&
ic->ic_opmode != IEEE80211_M_HOSTAP);
mwl_setmcastfilter(sc);
@@ -1864,8 +1794,7 @@ mwl_update_promisc(struct ieee80211com *ic)
{
struct mwl_softc *sc = ic->ic_softc;
- mwl_hal_setpromisc(sc->sc_mh,
- (ic->ic_ifp->if_flags & IFF_PROMISC) != 0);
+ mwl_hal_setpromisc(sc->sc_mh, ic->ic_promisc > 0);
}
/*
@@ -1882,7 +1811,7 @@ mwl_updateslot(struct ieee80211com *ic)
int prot;
/* NB: can be called early; suppress needless cmds */
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if (!sc->sc_running)
return;
/*
@@ -2004,7 +1933,6 @@ mwl_desc_setup(struct mwl_softc *sc, const char *name,
struct mwl_descdma *dd,
int nbuf, size_t bufsize, int ndesc, size_t descsize)
{
- struct ifnet *ifp = sc->sc_ifp;
uint8_t *ds;
int error;
@@ -2032,7 +1960,7 @@ mwl_desc_setup(struct mwl_softc *sc, const char *name,
NULL, /* lockarg */
&dd->dd_dmat);
if (error != 0) {
- if_printf(ifp, "cannot allocate %s DMA tag\n", dd->dd_name);
+ device_printf(sc->sc_dev, "cannot allocate %s DMA tag\n", dd->dd_name);
return error;
}
@@ -2041,7 +1969,7 @@ mwl_desc_setup(struct mwl_softc *sc, const char *name,
BUS_DMA_NOWAIT | BUS_DMA_COHERENT,
&dd->dd_dmamap);
if (error != 0) {
- if_printf(ifp, "unable to alloc memory for %u %s descriptors, "
+ device_printf(sc->sc_dev, "unable to alloc memory for %u %s descriptors, "
"error %u\n", nbuf * ndesc, dd->dd_name, error);
goto fail1;
}
@@ -2051,7 +1979,7 @@ mwl_desc_setup(struct mwl_softc *sc, const char *name,
mwl_load_cb, &dd->dd_desc_paddr,
BUS_DMA_NOWAIT);
if (error != 0) {
- if_printf(ifp, "unable to map %s descriptors, error %u\n",
+ device_printf(sc->sc_dev, "unable to map %s descriptors, error %u\n",
dd->dd_name, error);
goto fail2;
}
@@ -2109,7 +2037,6 @@ mwl_txq_reset(struct mwl_softc *sc, struct mwl_txq *txq)
static int
mwl_txdma_setup(struct mwl_softc *sc, struct mwl_txq *txq)
{
- struct ifnet *ifp = sc->sc_ifp;
int error, bsize, i;
struct mwl_txbuf *bf;
struct mwl_txdesc *ds;
@@ -2124,7 +2051,7 @@ mwl_txdma_setup(struct mwl_softc *sc, struct mwl_txq *txq)
bsize = mwl_txbuf * sizeof(struct mwl_txbuf);
bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO);
if (bf == NULL) {
- if_printf(ifp, "malloc of %u tx buffers failed\n",
+ device_printf(sc->sc_dev, "malloc of %u tx buffers failed\n",
mwl_txbuf);
return ENOMEM;
}
@@ -2137,7 +2064,7 @@ mwl_txdma_setup(struct mwl_softc *sc, struct mwl_txq *txq)
error = bus_dmamap_create(sc->sc_dmat, BUS_DMA_NOWAIT,
&bf->bf_dmamap);
if (error != 0) {
- if_printf(ifp, "unable to create dmamap for tx "
+ device_printf(sc->sc_dev, "unable to create dmamap for tx "
"buffer %u, error %u\n", i, error);
return error;
}
@@ -2172,7 +2099,6 @@ mwl_txdma_cleanup(struct mwl_softc *sc, struct mwl_txq *txq)
static int
mwl_rxdma_setup(struct mwl_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
int error, jumbosize, bsize, i;
struct mwl_rxbuf *bf;
struct mwl_jumbo *rbuf;
@@ -2196,7 +2122,7 @@ mwl_rxdma_setup(struct mwl_softc *sc)
* us while frames are processed.
*/
if (mwl_rxbuf < 2*mwl_rxdesc) {
- if_printf(ifp,
+ device_printf(sc->sc_dev,
"too few rx dma buffers (%d); increasing to %d\n",
mwl_rxbuf, 2*mwl_rxdesc);
mwl_rxbuf = 2*mwl_rxdesc;
@@ -2217,7 +2143,7 @@ mwl_rxdma_setup(struct mwl_softc *sc)
NULL, /* lockarg */
&sc->sc_rxdmat);
if (error != 0) {
- if_printf(ifp, "could not create rx DMA tag\n");
+ device_printf(sc->sc_dev, "could not create rx DMA tag\n");
return error;
}
@@ -2225,7 +2151,7 @@ mwl_rxdma_setup(struct mwl_softc *sc)
BUS_DMA_NOWAIT | BUS_DMA_COHERENT,
&sc->sc_rxmap);
if (error != 0) {
- if_printf(ifp, "could not alloc %ju bytes of rx DMA memory\n",
+ device_printf(sc->sc_dev, "could not alloc %ju bytes of rx DMA memory\n",
(uintmax_t) sc->sc_rxmemsize);
return error;
}
@@ -2235,7 +2161,7 @@ mwl_rxdma_setup(struct mwl_softc *sc)
mwl_load_cb, &sc->sc_rxmem_paddr,
BUS_DMA_NOWAIT);
if (error != 0) {
- if_printf(ifp, "could not load rx DMA map\n");
+ device_printf(sc->sc_dev, "could not load rx DMA map\n");
return error;
}
@@ -2245,7 +2171,7 @@ mwl_rxdma_setup(struct mwl_softc *sc)
bsize = mwl_rxdesc * sizeof(struct mwl_rxbuf);
bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO);
if (bf == NULL) {
- if_printf(ifp, "malloc of %u rx buffers failed\n", bsize);
+ device_printf(sc->sc_dev, "malloc of %u rx buffers failed\n", bsize);
return error;
}
sc->sc_rxdma.dd_bufptr = bf;
@@ -2329,7 +2255,7 @@ static struct ieee80211_node *
mwl_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
{
struct ieee80211com *ic = vap->iv_ic;
- struct mwl_softc *sc = ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
const size_t space = sizeof(struct mwl_node);
struct mwl_node *mn;
@@ -2346,7 +2272,7 @@ static void
mwl_node_cleanup(struct ieee80211_node *ni)
{
struct ieee80211com *ic = ni->ni_ic;
- struct mwl_softc *sc = ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
struct mwl_node *mn = MWL_NODE(ni);
DPRINTF(sc, MWL_DEBUG_NODE, "%s: ni %p ic %p staid %d\n",
@@ -2441,7 +2367,7 @@ static void
mwl_node_drain(struct ieee80211_node *ni)
{
struct ieee80211com *ic = ni->ni_ic;
- struct mwl_softc *sc = ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
struct mwl_node *mn = MWL_NODE(ni);
DPRINTF(sc, MWL_DEBUG_NODE, "%s: ni %p vap %p staid %d\n",
@@ -2696,8 +2622,7 @@ mwl_rx_proc(void *arg, int npending)
#define IEEE80211_DIR_DSTODS(wh) \
((((const struct ieee80211_frame *)wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
struct mwl_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct mwl_rxbuf *bf;
struct mwl_rxdesc *ds;
struct mbuf *m;
@@ -2744,7 +2669,7 @@ mwl_rx_proc(void *arg, int npending)
#endif
status = ds->Status;
if (status & EAGLE_RXD_STATUS_DECRYPT_ERR_MASK) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
sc->sc_stats.mst_rx_crypto++;
/*
* NB: Check EAGLE_RXD_STATUS_GENERAL_DECRYPT_ERR
@@ -2840,7 +2765,6 @@ mwl_rx_proc(void *arg, int npending)
data, sc, 0, EXT_NET_DRV);
m->m_data += off - hdrlen;
m->m_pkthdr.len = m->m_len = pktlen;
- m->m_pkthdr.rcvif = ifp;
/* NB: dma buffer assumed read-only */
/*
@@ -2890,8 +2814,6 @@ mwl_rx_proc(void *arg, int npending)
ieee80211_dump_pkt(ic, mtod(m, caddr_t),
len, ds->Rate, rssi);
}
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
-
/* dispatch */
ni = ieee80211_find_rxnode(ic,
(const struct ieee80211_frame_min *) wh);
@@ -2918,11 +2840,10 @@ rx_next:
rx_stop:
sc->sc_rxnext = bf;
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd)) {
+ if (mbufq_first(&sc->sc_snd) != NULL) {
/* NB: kick fw; the tx thread may have been preempted */
mwl_hal_txstart(sc->sc_mh, 0);
- mwl_start(ifp);
+ mwl_start(sc);
}
#undef IEEE80211_DIR_DSTODS
}
@@ -2987,8 +2908,7 @@ static int
mwl_txq_update(struct mwl_softc *sc, int ac)
{
#define MWL_EXPONENT_TO_VALUE(v) ((1<<v)-1)
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct mwl_txq *txq = sc->sc_ac2q[ac];
struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
struct mwl_hal *mh = sc->sc_mh;
@@ -3016,7 +2936,7 @@ mwl_txq_update(struct mwl_softc *sc, int ac)
static int
mwl_wme_update(struct ieee80211com *ic)
{
- struct mwl_softc *sc = ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
return !mwl_txq_update(sc, WME_AC_BE) ||
!mwl_txq_update(sc, WME_AC_BK) ||
@@ -3173,8 +3093,7 @@ mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf *
{
#define IEEE80211_DIR_DSTODS(wh) \
((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
int error, iswep, ismcast;
int hdrlen, copyhdrlen, pktlen;
@@ -3391,7 +3310,7 @@ mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf *
ds->TxPriority = txq->qnum;
break;
default:
- if_printf(ifp, "bogus frame type 0x%x (%s)\n",
+ device_printf(sc->sc_dev, "bogus frame type 0x%x (%s)\n",
wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
sc->sc_stats.mst_tx_badframetype++;
m_freem(m0);
@@ -3408,7 +3327,6 @@ mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf *
STAILQ_INSERT_TAIL(&txq->active, bf, bf_list);
MWL_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
sc->sc_tx_timer = 5;
MWL_TXQ_UNLOCK(txq);
@@ -3434,8 +3352,7 @@ mwl_tx_processq(struct mwl_softc *sc, struct mwl_txq *txq)
{
#define EAGLE_TXD_STATUS_MCAST \
(EAGLE_TXD_STATUS_MULTICAST_TX | EAGLE_TXD_STATUS_BROADCAST_TX)
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct mwl_txbuf *bf;
struct mwl_txdesc *ds;
struct ieee80211_node *ni;
@@ -3497,32 +3414,18 @@ mwl_tx_processq(struct mwl_softc *sc, struct mwl_txq *txq)
if (bf->bf_m->m_flags & M_FF)
sc->sc_stats.mst_ff_txerr++;
}
- /*
- * Do any tx complete callback. Note this must
- * be done before releasing the node reference.
- * XXX no way to figure out if frame was ACK'd
- */
- if (bf->bf_m->m_flags & M_TXCB) {
+ if (bf->bf_m->m_flags & M_TXCB)
/* XXX strip fw len in case header inspected */
m_adj(bf->bf_m, sizeof(uint16_t));
- ieee80211_process_callback(ni, bf->bf_m,
- (status & EAGLE_TXD_STATUS_OK) == 0);
- }
- /*
- * Reclaim reference to node.
- *
- * NB: the node may be reclaimed here if, for example
- * this is a DEAUTH message that was sent and the
- * node was timed out due to inactivity.
- */
- ieee80211_free_node(ni);
- }
+ ieee80211_tx_complete(ni, bf->bf_m,
+ (status & EAGLE_TXD_STATUS_OK) == 0);
+ } else
+ m_freem(bf->bf_m);
ds->Status = htole32(EAGLE_TXD_STATUS_IDLE);
bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
- m_freem(bf->bf_m);
mwl_puttxbuf_tail(txq, bf);
}
@@ -3538,7 +3441,6 @@ static void
mwl_tx_proc(void *arg, int npending)
{
struct mwl_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
int nreaped;
/*
@@ -3555,12 +3457,11 @@ mwl_tx_proc(void *arg, int npending)
nreaped += mwl_tx_processq(sc, &sc->sc_txq[3]);
if (nreaped != 0) {
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
sc->sc_tx_timer = 0;
- if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
+ if (mbufq_first(&sc->sc_snd) != NULL) {
/* NB: kick fw; the tx thread may have been preempted */
mwl_hal_txstart(sc->sc_mh, 0);
- mwl_start(ifp);
+ mwl_start(sc);
}
}
}
@@ -3587,8 +3488,7 @@ mwl_tx_draintxq(struct mwl_softc *sc, struct mwl_txq *txq)
MWL_TXQ_UNLOCK(txq);
#ifdef MWL_DEBUG
if (sc->sc_debug & MWL_DEBUG_RESET) {
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
const struct mwltxrec *tr =
mtod(bf->bf_m, const struct mwltxrec *);
mwl_printtxbuf(bf, txq->qnum, ix);
@@ -3616,12 +3516,10 @@ mwl_tx_draintxq(struct mwl_softc *sc, struct mwl_txq *txq)
static void
mwl_draintxq(struct mwl_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
int i;
for (i = 0; i < MWL_NUM_TX_QUEUES; i++)
mwl_tx_draintxq(sc, &sc->sc_txq[i]);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
sc->sc_tx_timer = 0;
}
@@ -3671,7 +3569,7 @@ static int
mwl_recv_action(struct ieee80211_node *ni, const struct ieee80211_frame *wh,
const uint8_t *frm, const uint8_t *efrm)
{
- struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = ni->ni_ic->ic_softc;
const struct ieee80211_action *ia;
ia = (const struct ieee80211_action *) frm;
@@ -3692,7 +3590,7 @@ static int
mwl_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
int dialogtoken, int baparamset, int batimeout)
{
- struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = ni->ni_ic->ic_softc;
struct ieee80211vap *vap = ni->ni_vap;
struct mwl_node *mn = MWL_NODE(ni);
struct mwl_bastate *bas;
@@ -3764,7 +3662,7 @@ static int
mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
int code, int baparamset, int batimeout)
{
- struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = ni->ni_ic->ic_softc;
struct mwl_bastate *bas;
bas = tap->txa_private;
@@ -3830,7 +3728,7 @@ mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
static void
mwl_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
{
- struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = ni->ni_ic->ic_softc;
struct mwl_bastate *bas;
bas = tap->txa_private;
@@ -3923,8 +3821,7 @@ static int
mwl_chan_set(struct mwl_softc *sc, struct ieee80211_channel *chan)
{
struct mwl_hal *mh = sc->sc_mh;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
MWL_HAL_CHANNEL hchan;
int maxtxpow;
@@ -3980,8 +3877,7 @@ mwl_chan_set(struct mwl_softc *sc, struct ieee80211_channel *chan)
static void
mwl_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct mwl_softc *sc = ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
DPRINTF(sc, MWL_DEBUG_STATE, "%s\n", __func__);
}
@@ -3989,8 +3885,7 @@ mwl_scan_start(struct ieee80211com *ic)
static void
mwl_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct mwl_softc *sc = ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
DPRINTF(sc, MWL_DEBUG_STATE, "%s\n", __func__);
}
@@ -3998,8 +3893,7 @@ mwl_scan_end(struct ieee80211com *ic)
static void
mwl_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct mwl_softc *sc = ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
(void) mwl_chan_set(sc, ic->ic_curchan);
}
@@ -4014,7 +3908,7 @@ static void
mwl_startcsa(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
- struct mwl_softc *sc = ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
MWL_HAL_CHANNEL hchan;
if (sc->sc_csapending)
@@ -4215,8 +4109,7 @@ mwl_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
struct mwl_hal_vap *hvap = mvp->mv_hvap;
struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_node *ni = NULL;
- struct ifnet *ifp = ic->ic_ifp;
- struct mwl_softc *sc = ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
struct mwl_hal *mh = sc->sc_mh;
enum ieee80211_state ostate = vap->iv_state;
int error;
@@ -4398,7 +4291,7 @@ static void
mwl_newassoc(struct ieee80211_node *ni, int isnew)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = vap->iv_ic->ic_softc;
struct mwl_node *mn = MWL_NODE(ni);
MWL_HAL_PEERINFO pi;
uint16_t aid;
@@ -4454,7 +4347,7 @@ static int
mwl_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
int nchan, struct ieee80211_channel chans[])
{
- struct mwl_softc *sc = ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
struct mwl_hal *mh = sc->sc_mh;
const MWL_HAL_CHANNELINFO *ci;
int i;
@@ -4472,7 +4365,7 @@ mwl_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
IEEE80211_IS_CHAN_HT40(c) ?
MWL_CH_40_MHz_WIDTH : MWL_CH_20_MHz_WIDTH, &ci);
} else {
- if_printf(ic->ic_ifp,
+ device_printf(sc->sc_dev,
"%s: channel %u freq %u/0x%x not 2.4/5GHz\n",
__func__, c->ic_ieee, c->ic_freq, c->ic_flags);
return EINVAL;
@@ -4498,7 +4391,7 @@ mwl_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
goto next;
}
}
- if_printf(ic->ic_ifp,
+ device_printf(sc->sc_dev,
"%s: no cal data for channel %u ext %u freq %u/0x%x\n",
__func__, c->ic_ieee, c->ic_extieee,
c->ic_freq, c->ic_flags);
@@ -4654,7 +4547,7 @@ static void
mwl_getradiocaps(struct ieee80211com *ic,
int maxchans, int *nchans, struct ieee80211_channel chans[])
{
- struct mwl_softc *sc = ic->ic_ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
getchannels(sc, maxchans, nchans, chans);
}
@@ -4662,8 +4555,7 @@ mwl_getradiocaps(struct ieee80211com *ic,
static int
mwl_getchannels(struct mwl_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
/*
* Use the channel info from the hal to craft the
@@ -4768,25 +4660,24 @@ mwl_txq_dump(struct mwl_txq *txq)
static void
mwl_watchdog(void *arg)
{
- struct mwl_softc *sc;
- struct ifnet *ifp;
+ struct mwl_softc *sc = arg;
- sc = arg;
callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc);
if (sc->sc_tx_timer == 0 || --sc->sc_tx_timer > 0)
return;
- ifp = sc->sc_ifp;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->sc_invalid) {
+ if (sc->sc_running && !sc->sc_invalid) {
if (mwl_hal_setkeepalive(sc->sc_mh))
- if_printf(ifp, "transmit timeout (firmware hung?)\n");
+ device_printf(sc->sc_dev,
+ "transmit timeout (firmware hung?)\n");
else
- if_printf(ifp, "transmit timeout\n");
+ device_printf(sc->sc_dev,
+ "transmit timeout\n");
#if 0
- mwl_reset(ifp);
+ mwl_reset(sc);
mwl_txq_dump(&sc->sc_txq[0]);/*XXX*/
#endif
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
sc->sc_stats.mst_watchdog++;
}
}
@@ -4885,28 +4776,22 @@ mwl_ioctl_reset(struct mwl_softc *sc, struct mwl_diag *md)
}
#endif /* MWL_DIAGAPI */
-static int
-mwl_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+mwl_parent(struct ieee80211com *ic)
{
-#define IS_RUNNING(ifp) \
- ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
- struct mwl_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *)data;
- int error = 0, startall;
+ struct mwl_softc *sc = ic->ic_softc;
+ int startall = 0;
- switch (cmd) {
- case SIOCSIFFLAGS:
- MWL_LOCK(sc);
- startall = 0;
- if (IS_RUNNING(ifp)) {
+ MWL_LOCK(sc);
+ if (ic->ic_nrunning > 0) {
+ if (sc->sc_running) {
/*
* To avoid rescanning another access point,
* do not call mwl_init() here. Instead,
* only reflect promisc mode settings.
*/
mwl_mode_init(sc);
- } else if (ifp->if_flags & IFF_UP) {
+ } else {
/*
* Beware of being called during attach/detach
* to reset promiscuous mode. In that case we
@@ -4917,30 +4802,42 @@ mwl_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
* probably a better way to deal with this.
*/
if (!sc->sc_invalid) {
- mwl_init_locked(sc); /* XXX lose error */
+ mwl_init(sc); /* XXX lose error */
startall = 1;
}
- } else
- mwl_stop_locked(ifp, 1);
- MWL_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
+ }
+ } else
+ mwl_stop(sc);
+ MWL_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
+}
+
+static int
+mwl_ioctl(struct ieee80211com *ic, u_long cmd, void *data)
+{
+ struct mwl_softc *sc = ic->ic_softc;
+ struct ifreq *ifr = data;
+ int error = 0;
+
+ switch (cmd) {
case SIOCGMVSTATS:
mwl_hal_gethwstats(sc->sc_mh, &sc->sc_stats.hw_stats);
+#if 0
/* NB: embed these numbers to get a consistent view */
sc->sc_stats.mst_tx_packets =
ifp->if_get_counter(ifp, IFCOUNTER_OPACKETS);
sc->sc_stats.mst_rx_packets =
ifp->if_get_counter(ifp, IFCOUNTER_IPACKETS);
+#endif
/*
* NB: Drop the softc lock in case of a page fault;
* we'll accept any potential inconsisentcy in the
* statistics. The alternative is to copy the data
* to a local structure.
*/
- return copyout(&sc->sc_stats,
- ifr->ifr_data, sizeof (sc->sc_stats));
+ return (copyout(&sc->sc_stats,
+ ifr->ifr_data, sizeof (sc->sc_stats)));
#ifdef MWL_DIAGAPI
case SIOCGMVDIAG:
/* XXX check privs */
@@ -4952,18 +4849,11 @@ mwl_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
MWL_UNLOCK(sc);
break;
#endif /* MWL_DIAGAPI */
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
default:
- error = EINVAL;
+ error = ENOTTY;
break;
}
- return error;
-#undef IS_RUNNING
+ return (error);
}
#ifdef MWL_DEBUG
@@ -5003,9 +4893,8 @@ mwl_sysctlattach(struct mwl_softc *sc)
static void
mwl_announce(struct mwl_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- if_printf(ifp, "Rev A%d hardware, v%d.%d.%d.%d firmware (regioncode %d)\n",
+ device_printf(sc->sc_dev, "Rev A%d hardware, v%d.%d.%d.%d firmware (regioncode %d)\n",
sc->sc_hwspecs.hwVersion,
(sc->sc_hwspecs.fwReleaseNumber>>24) & 0xff,
(sc->sc_hwspecs.fwReleaseNumber>>16) & 0xff,
@@ -5018,20 +4907,20 @@ mwl_announce(struct mwl_softc *sc)
int i;
for (i = 0; i <= WME_AC_VO; i++) {
struct mwl_txq *txq = sc->sc_ac2q[i];
- if_printf(ifp, "Use hw queue %u for %s traffic\n",
+ device_printf(sc->sc_dev, "Use hw queue %u for %s traffic\n",
txq->qnum, ieee80211_wme_acnames[i]);
}
}
if (bootverbose || mwl_rxdesc != MWL_RXDESC)
- if_printf(ifp, "using %u rx descriptors\n", mwl_rxdesc);
+ device_printf(sc->sc_dev, "using %u rx descriptors\n", mwl_rxdesc);
if (bootverbose || mwl_rxbuf != MWL_RXBUF)
- if_printf(ifp, "using %u rx buffers\n", mwl_rxbuf);
+ device_printf(sc->sc_dev, "using %u rx buffers\n", mwl_rxbuf);
if (bootverbose || mwl_txbuf != MWL_TXBUF)
- if_printf(ifp, "using %u tx buffers\n", mwl_txbuf);
+ device_printf(sc->sc_dev, "using %u tx buffers\n", mwl_txbuf);
if (bootverbose && mwl_hal_ismbsscapable(sc->sc_mh))
- if_printf(ifp, "multi-bss support\n");
+ device_printf(sc->sc_dev, "multi-bss support\n");
#ifdef MWL_TX_NODROP
if (bootverbose)
- if_printf(ifp, "no tx drop\n");
+ device_printf(sc->sc_dev, "no tx drop\n");
#endif
}
diff --git a/sys/dev/mwl/if_mwl_pci.c b/sys/dev/mwl/if_mwl_pci.c
index ef7009c..d9da128 100644
--- a/sys/dev/mwl/if_mwl_pci.c
+++ b/sys/dev/mwl/if_mwl_pci.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/errno.h>
diff --git a/sys/dev/mwl/if_mwlvar.h b/sys/dev/mwl/if_mwlvar.h
index 7071ba0..4a4b338 100644
--- a/sys/dev/mwl/if_mwlvar.h
+++ b/sys/dev/mwl/if_mwlvar.h
@@ -244,7 +244,8 @@ struct mwl_vap {
#define MWL_VAP_CONST(vap) ((const struct mwl_vap *)(vap))
struct mwl_softc {
- struct ifnet *sc_ifp; /* interface common */
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
struct mwl_stats sc_stats; /* interface statistics */
int sc_debug;
device_t sc_dev;
@@ -257,7 +258,8 @@ struct mwl_softc {
struct taskqueue *sc_tq; /* private task queue */
struct callout sc_watchdog;
int sc_tx_timer;
- unsigned int sc_invalid : 1, /* disable hardware accesses */
+ unsigned int sc_running : 1,
+ sc_invalid : 1, /* disable hardware accesses */
sc_recvsetup:1, /* recv setup */
sc_csapending:1,/* 11h channel switch pending */
sc_radarena : 1,/* radar detection enabled */
diff --git a/sys/dev/ral/if_ral_pci.c b/sys/dev/ral/if_ral_pci.c
index 519b4ca..42ec034 100644
--- a/sys/dev/ral/if_ral_pci.c
+++ b/sys/dev/ral/if_ral_pci.c
@@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/rman.h>
diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c
index 29ce8cb..ea9c416 100644
--- a/sys/dev/ral/rt2560.c
+++ b/sys/dev/ral/rt2560.c
@@ -127,10 +127,10 @@ static int rt2560_tx_mgt(struct rt2560_softc *, struct mbuf *,
struct ieee80211_node *);
static int rt2560_tx_data(struct rt2560_softc *, struct mbuf *,
struct ieee80211_node *);
-static void rt2560_start_locked(struct ifnet *);
-static void rt2560_start(struct ifnet *);
+static int rt2560_transmit(struct ieee80211com *, struct mbuf *);
+static void rt2560_start(struct rt2560_softc *);
static void rt2560_watchdog(void *);
-static int rt2560_ioctl(struct ifnet *, u_long, caddr_t);
+static void rt2560_parent(struct ieee80211com *);
static void rt2560_bbp_write(struct rt2560_softc *, uint8_t,
uint8_t);
static uint8_t rt2560_bbp_read(struct rt2560_softc *, uint8_t);
@@ -149,7 +149,8 @@ static void rt2560_set_basicrates(struct rt2560_softc *,
const struct ieee80211_rateset *);
static void rt2560_update_led(struct rt2560_softc *, int, int);
static void rt2560_set_bssid(struct rt2560_softc *, const uint8_t *);
-static void rt2560_set_macaddr(struct rt2560_softc *, uint8_t *);
+static void rt2560_set_macaddr(struct rt2560_softc *,
+ const uint8_t *);
static void rt2560_get_macaddr(struct rt2560_softc *, uint8_t *);
static void rt2560_update_promisc(struct ieee80211com *);
static const char *rt2560_get_rf(int);
@@ -197,11 +198,9 @@ int
rt2560_attach(device_t dev, int id)
{
struct rt2560_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic;
- struct ifnet *ifp;
- int error;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t bands;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
+ int error;
sc->sc_dev = dev;
@@ -209,6 +208,7 @@ rt2560_attach(device_t dev, int id)
MTX_DEF | MTX_RECURSE);
callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
/* retrieve RT2560 rev. no */
sc->asic_rev = RAL_READ(sc, RT2560_CSR0);
@@ -252,27 +252,9 @@ rt2560_attach(device_t dev, int id)
goto fail5;
}
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto fail6;
- }
- ic = ifp->if_l2com;
-
/* retrieve MAC address */
- rt2560_get_macaddr(sc, macaddr);
-
- ifp->if_softc = sc;
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = rt2560_init;
- ifp->if_ioctl = rt2560_ioctl;
- ifp->if_start = rt2560_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
+ rt2560_get_macaddr(sc, ic->ic_macaddr);
+
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_opmode = IEEE80211_M_STA;
@@ -303,7 +285,7 @@ rt2560_attach(device_t dev, int id)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, macaddr);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = rt2560_raw_xmit;
ic->ic_updateslot = rt2560_update_slot;
ic->ic_update_promisc = rt2560_update_promisc;
@@ -313,6 +295,8 @@ rt2560_attach(device_t dev, int id)
ic->ic_vap_create = rt2560_vap_create;
ic->ic_vap_delete = rt2560_vap_delete;
+ ic->ic_parent = rt2560_parent;
+ ic->ic_transmit = rt2560_transmit;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -341,7 +325,6 @@ rt2560_attach(device_t dev, int id)
return 0;
-fail6: rt2560_free_rx_ring(sc, &sc->rxq);
fail5: rt2560_free_tx_ring(sc, &sc->bcnq);
fail4: rt2560_free_tx_ring(sc, &sc->prioq);
fail3: rt2560_free_tx_ring(sc, &sc->atimq);
@@ -355,12 +338,12 @@ int
rt2560_detach(void *xsc)
{
struct rt2560_softc *sc = xsc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
rt2560_stop(sc);
ieee80211_ifdetach(ic);
+ mbufq_drain(&sc->sc_snd);
rt2560_free_tx_ring(sc, &sc->txq);
rt2560_free_tx_ring(sc, &sc->atimq);
@@ -368,8 +351,6 @@ rt2560_detach(void *xsc)
rt2560_free_tx_ring(sc, &sc->bcnq);
rt2560_free_rx_ring(sc, &sc->rxq);
- if_free(ifp);
-
mtx_destroy(&sc->sc_mtx);
return 0;
@@ -381,7 +362,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct ifnet *ifp = ic->ic_ifp;
+ struct rt2560_softc *sc = ic->ic_softc;
struct rt2560_vap *rvp;
struct ieee80211vap *vap;
@@ -394,7 +375,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_MBSS:
/* XXXRP: TBD */
if (!TAILQ_EMPTY(&ic->ic_vaps)) {
- if_printf(ifp, "only 1 vap supported\n");
+ device_printf(sc->sc_dev, "only 1 vap supported\n");
return NULL;
}
if (opmode == IEEE80211_M_STA)
@@ -403,7 +384,8 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_WDS:
if (TAILQ_EMPTY(&ic->ic_vaps) ||
ic->ic_opmode != IEEE80211_M_HOSTAP) {
- if_printf(ifp, "wds only supported in ap mode\n");
+ device_printf(sc->sc_dev,
+ "wds only supported in ap mode\n");
return NULL;
}
/*
@@ -414,15 +396,12 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
flags &= ~IEEE80211_CLONE_BSSID;
break;
default:
- if_printf(ifp, "unknown opmode %d\n", opmode);
+ device_printf(sc->sc_dev, "unknown opmode %d\n", opmode);
return NULL;
}
- rvp = (struct rt2560_vap *) malloc(sizeof(struct rt2560_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (rvp == NULL)
- return NULL;
+ rvp = malloc(sizeof(struct rt2560_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &rvp->ral_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
/* override state transition machine */
rvp->ral_newstate = vap->iv_newstate;
@@ -431,7 +410,8 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_init(vap);
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, ieee80211_media_change,
+ ieee80211_media_status, mac);
if (TAILQ_FIRST(&ic->ic_vaps) == vap)
ic->ic_opmode = opmode;
return vap;
@@ -451,9 +431,8 @@ void
rt2560_resume(void *xsc)
{
struct rt2560_softc *sc = xsc;
- struct ifnet *ifp = sc->sc_ifp;
- if (ifp->if_flags & IFF_UP)
+ if (sc->sc_ic.ic_nrunning > 0)
rt2560_init(sc);
}
@@ -763,8 +742,7 @@ static int
rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct rt2560_vap *rvp = RT2560_VAP(vap);
- struct ifnet *ifp = vap->iv_ic->ic_ifp;
- struct rt2560_softc *sc = ifp->if_softc;
+ struct rt2560_softc *sc = vap->iv_ic->ic_softc;
int error;
if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) {
@@ -792,7 +770,8 @@ rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
vap->iv_opmode == IEEE80211_M_MBSS) {
m = ieee80211_beacon_alloc(ni, &rvp->ral_bo);
if (m == NULL) {
- if_printf(ifp, "could not allocate beacon\n");
+ device_printf(sc->sc_dev,
+ "could not allocate beacon\n");
return ENOBUFS;
}
ieee80211_ref_node(ni);
@@ -926,14 +905,13 @@ rt2560_encryption_intr(struct rt2560_softc *sc)
static void
rt2560_tx_intr(struct rt2560_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
struct rt2560_tx_desc *desc;
struct rt2560_tx_data *data;
struct mbuf *m;
- uint32_t flags;
- int retrycnt;
struct ieee80211vap *vap;
struct ieee80211_node *ni;
+ uint32_t flags;
+ int retrycnt, status;
bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map,
BUS_DMASYNC_POSTREAD);
@@ -961,7 +939,7 @@ rt2560_tx_intr(struct rt2560_softc *sc)
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_SUCCESS,
&retrycnt, NULL);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ status = 0;
break;
case RT2560_TX_SUCCESS_RETRY:
@@ -973,7 +951,7 @@ rt2560_tx_intr(struct rt2560_softc *sc)
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_SUCCESS,
&retrycnt, NULL);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ status = 0;
break;
case RT2560_TX_FAIL_RETRY:
@@ -985,7 +963,7 @@ rt2560_tx_intr(struct rt2560_softc *sc)
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_FAILURE,
&retrycnt, NULL);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ status = 1;
break;
case RT2560_TX_FAIL_INVALID:
@@ -993,16 +971,16 @@ rt2560_tx_intr(struct rt2560_softc *sc)
default:
device_printf(sc->sc_dev, "sending data frame failed "
"0x%08x\n", flags);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ status = 1;
}
bus_dmamap_sync(sc->txq.data_dmat, data->map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->txq.data_dmat, data->map);
- m_freem(m);
- data->m = NULL;
- ieee80211_free_node(data->ni);
+
+ ieee80211_tx_complete(ni, m, status);
data->ni = NULL;
+ data->m = NULL;
/* descriptor is no longer valid */
desc->flags &= ~htole32(RT2560_TX_VALID);
@@ -1019,19 +997,13 @@ rt2560_tx_intr(struct rt2560_softc *sc)
if (sc->prioq.queued == 0 && sc->txq.queued == 0)
sc->sc_tx_timer = 0;
- if (sc->txq.queued < RT2560_TX_RING_COUNT - 1) {
- sc->sc_flags &= ~RT2560_F_DATA_OACTIVE;
- if ((sc->sc_flags &
- (RT2560_F_DATA_OACTIVE | RT2560_F_PRIO_OACTIVE)) == 0)
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- rt2560_start_locked(ifp);
- }
+ if (sc->txq.queued < RT2560_TX_RING_COUNT - 1)
+ rt2560_start(sc);
}
static void
rt2560_prio_intr(struct rt2560_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
struct rt2560_tx_desc *desc;
struct rt2560_tx_data *data;
struct ieee80211_node *ni;
@@ -1103,13 +1075,8 @@ rt2560_prio_intr(struct rt2560_softc *sc)
if (sc->prioq.queued == 0 && sc->txq.queued == 0)
sc->sc_tx_timer = 0;
- if (sc->prioq.queued < RT2560_PRIO_RING_COUNT) {
- sc->sc_flags &= ~RT2560_F_PRIO_OACTIVE;
- if ((sc->sc_flags &
- (RT2560_F_DATA_OACTIVE | RT2560_F_PRIO_OACTIVE)) == 0)
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- rt2560_start_locked(ifp);
- }
+ if (sc->prioq.queued < RT2560_PRIO_RING_COUNT)
+ rt2560_start(sc);
}
/*
@@ -1119,8 +1086,7 @@ rt2560_prio_intr(struct rt2560_softc *sc)
static void
rt2560_decryption_intr(struct rt2560_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct rt2560_rx_desc *desc;
struct rt2560_rx_data *data;
bus_addr_t physaddr;
@@ -1146,13 +1112,13 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
break;
if (data->drop) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto skip;
}
if ((le32toh(desc->flags) & RT2560_RX_CIPHER_MASK) != 0 &&
(le32toh(desc->flags) & RT2560_RX_ICV_ERROR)) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto skip;
}
@@ -1165,7 +1131,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
*/
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (mnew == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto skip;
}
@@ -1188,7 +1154,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
panic("%s: could not load old rx mbuf",
device_get_name(sc->sc_dev));
}
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto skip;
}
@@ -1201,7 +1167,6 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
desc->physaddr = htole32(physaddr);
/* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len =
(le32toh(desc->flags) >> 16) & 0xfff;
@@ -1321,8 +1286,7 @@ rt2560_beacon_update(struct ieee80211vap *vap, int item)
static void
rt2560_beacon_expire(struct rt2560_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct rt2560_vap *rvp = RT2560_VAP(vap);
struct rt2560_tx_data *data;
@@ -1363,7 +1327,6 @@ void
rt2560_intr(void *arg)
{
struct rt2560_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
uint32_t r;
RAL_LOCK(sc);
@@ -1372,7 +1335,7 @@ rt2560_intr(void *arg)
RAL_WRITE(sc, RT2560_CSR8, 0xffffffff);
/* don't re-enable interrupts if we're shutting down */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & RT2560_F_RUNNING)) {
RAL_UNLOCK(sc);
return;
}
@@ -1440,8 +1403,7 @@ static void
rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc,
uint32_t flags, int len, int rate, int encrypt, bus_addr_t physaddr)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t plcp_length;
int remainder;
@@ -1916,55 +1878,57 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
return 0;
}
+static int
+rt2560_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct rt2560_softc *sc = ic->ic_softc;
+ int error;
+
+ RAL_LOCK(sc);
+ if ((sc->sc_flags & RT2560_F_RUNNING) == 0) {
+ RAL_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ RAL_UNLOCK(sc);
+ return (error);
+ }
+ rt2560_start(sc);
+ RAL_UNLOCK(sc);
+
+ return (0);
+}
+
static void
-rt2560_start_locked(struct ifnet *ifp)
+rt2560_start(struct rt2560_softc *sc)
{
- struct rt2560_softc *sc = ifp->if_softc;
- struct mbuf *m;
struct ieee80211_node *ni;
+ struct mbuf *m;
RAL_LOCK_ASSERT(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->txq.queued >= RT2560_TX_RING_COUNT - 1) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- sc->sc_flags |= RT2560_F_DATA_OACTIVE;
- break;
- }
+ while (sc->txq.queued < RT2560_TX_RING_COUNT - 1 &&
+ (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
if (rt2560_tx_data(sc, m, ni) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
break;
}
-
sc->sc_tx_timer = 5;
}
}
static void
-rt2560_start(struct ifnet *ifp)
-{
- struct rt2560_softc *sc = ifp->if_softc;
-
- RAL_LOCK(sc);
- rt2560_start_locked(ifp);
- RAL_UNLOCK(sc);
-}
-
-static void
rt2560_watchdog(void *arg)
{
struct rt2560_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
RAL_LOCK_ASSERT(sc);
- KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
+ KASSERT(sc->sc_flags & RT2560_F_RUNNING, ("not running"));
if (sc->sc_invalid) /* card ejected */
return;
@@ -1973,51 +1937,33 @@ rt2560_watchdog(void *arg)
rt2560_tx_intr(sc);
if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
- if_printf(ifp, "device timeout\n");
+ device_printf(sc->sc_dev, "device timeout\n");
rt2560_init_locked(sc);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
/* NB: callout is reset in rt2560_init() */
return;
}
callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc);
}
-static int
-rt2560_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+rt2560_parent(struct ieee80211com *ic)
{
- struct rt2560_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
+ struct rt2560_softc *sc = ic->ic_softc;
+ int startall = 0;
- switch (cmd) {
- case SIOCSIFFLAGS:
- RAL_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- rt2560_init_locked(sc);
- startall = 1;
- } else
- rt2560_update_promisc(ic);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rt2560_stop_locked(sc);
- }
- RAL_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
+ RAL_LOCK(sc);
+ if (ic->ic_nrunning > 0) {
+ if ((sc->sc_flags & RT2560_F_RUNNING) == 0) {
+ rt2560_init_locked(sc);
+ startall = 1;
+ } else
+ rt2560_update_promisc(ic);
+ } else if (sc->sc_flags & RT2560_F_RUNNING)
+ rt2560_stop_locked(sc);
+ RAL_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
@@ -2101,8 +2047,7 @@ rt2560_rf_write(struct rt2560_softc *sc, uint8_t reg, uint32_t val)
static void
rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t power, tmp;
u_int i, chan;
@@ -2201,8 +2146,7 @@ rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c)
static void
rt2560_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct rt2560_softc *sc = ifp->if_softc;
+ struct rt2560_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
rt2560_set_chan(sc, ic->ic_curchan);
@@ -2238,8 +2182,7 @@ rt2560_disable_rf_tune(struct rt2560_softc *sc)
static void
rt2560_enable_tsf_sync(struct rt2560_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint16_t logcwmin, preload;
uint32_t tmp;
@@ -2280,8 +2223,7 @@ rt2560_enable_tsf(struct rt2560_softc *sc)
static void
rt2560_update_plcp(struct rt2560_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
/* no short preamble for 1Mbps */
RAL_WRITE(sc, RT2560_PLCP1MCSR, 0x00700400);
@@ -2360,8 +2302,7 @@ rt2560_set_basicrates(struct rt2560_softc *sc,
const struct ieee80211_rateset *rs)
{
#define RV(r) ((r) & IEEE80211_RATE_VAL)
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t mask = 0;
uint8_t rate;
int i;
@@ -2406,7 +2347,7 @@ rt2560_set_bssid(struct rt2560_softc *sc, const uint8_t *bssid)
}
static void
-rt2560_set_macaddr(struct rt2560_softc *sc, uint8_t *addr)
+rt2560_set_macaddr(struct rt2560_softc *sc, const uint8_t *addr)
{
uint32_t tmp;
@@ -2444,13 +2385,13 @@ rt2560_update_promisc(struct ieee80211com *ic)
tmp = RAL_READ(sc, RT2560_RXCSR0);
tmp &= ~RT2560_DROP_NOT_TO_ME;
- if (!(ic->ic_ifp->if_flags & IFF_PROMISC))
+ if (ic->ic_promisc == 0)
tmp |= RT2560_DROP_NOT_TO_ME;
RAL_WRITE(sc, RT2560_RXCSR0, tmp);
DPRINTF(sc, "%s promiscuous mode\n",
- (ic->ic_ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
+ (ic->ic_promisc > 0) ? "entering" : "leaving");
}
static const char *
@@ -2516,19 +2457,17 @@ rt2560_read_config(struct rt2560_softc *sc)
static void
rt2560_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct rt2560_softc *sc = ifp->if_softc;
+ struct rt2560_softc *sc = ic->ic_softc;
/* abort TSF synchronization */
RAL_WRITE(sc, RT2560_CSR14, 0);
- rt2560_set_bssid(sc, ifp->if_broadcastaddr);
+ rt2560_set_bssid(sc, ieee80211broadcastaddr);
}
static void
rt2560_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct rt2560_softc *sc = ifp->if_softc;
+ struct rt2560_softc *sc = ic->ic_softc;
struct ieee80211vap *vap = ic->ic_scan->ss_vap;
rt2560_enable_tsf_sync(sc);
@@ -2622,8 +2561,8 @@ static void
rt2560_init_locked(struct rt2560_softc *sc)
{
#define N(a) (sizeof (a) / sizeof ((a)[0]))
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
int i;
@@ -2654,7 +2593,7 @@ rt2560_init_locked(struct rt2560_softc *sc)
for (i = 0; i < N(rt2560_def_mac); i++)
RAL_WRITE(sc, rt2560_def_mac[i].reg, rt2560_def_mac[i].val);
- rt2560_set_macaddr(sc, IF_LLADDR(ifp));
+ rt2560_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
/* set basic rate set (will be updated later) */
RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x153);
@@ -2684,7 +2623,7 @@ rt2560_init_locked(struct rt2560_softc *sc)
if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
ic->ic_opmode != IEEE80211_M_MBSS)
tmp |= RT2560_DROP_TODS;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (ic->ic_promisc == 0)
tmp |= RT2560_DROP_NOT_TO_ME;
}
RAL_WRITE(sc, RT2560_RXCSR0, tmp);
@@ -2699,8 +2638,7 @@ rt2560_init_locked(struct rt2560_softc *sc)
/* enable interrupts */
RAL_WRITE(sc, RT2560_CSR8, RT2560_INTR_MASK);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= RT2560_F_RUNNING;
callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc);
#undef N
@@ -2710,21 +2648,19 @@ static void
rt2560_init(void *priv)
{
struct rt2560_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
RAL_LOCK(sc);
rt2560_init_locked(sc);
RAL_UNLOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_flags & RT2560_F_RUNNING)
ieee80211_start_all(ic); /* start all vap's */
}
static void
rt2560_stop_locked(struct rt2560_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
volatile int *flags = &sc->sc_flags;
RAL_LOCK_ASSERT(sc);
@@ -2735,8 +2671,8 @@ rt2560_stop_locked(struct rt2560_softc *sc)
callout_stop(&sc->watchdog_ch);
sc->sc_tx_timer = 0;
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ if (sc->sc_flags & RT2560_F_RUNNING) {
+ sc->sc_flags &= ~RT2560_F_RUNNING;
/* abort Tx */
RAL_WRITE(sc, RT2560_TXCSR0, RT2560_ABORT_TX);
@@ -2758,7 +2694,6 @@ rt2560_stop_locked(struct rt2560_softc *sc)
rt2560_reset_tx_ring(sc, &sc->bcnq);
rt2560_reset_rx_ring(sc, &sc->rxq);
}
- sc->sc_flags &= ~(RT2560_F_PRIO_OACTIVE | RT2560_F_DATA_OACTIVE);
}
void
@@ -2776,29 +2711,24 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct rt2560_softc *sc = ifp->if_softc;
+ struct rt2560_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & RT2560_F_RUNNING)) {
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return ENETDOWN;
}
if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- sc->sc_flags |= RT2560_F_PRIO_OACTIVE;
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return ENOBUFS; /* XXX */
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
if (params == NULL) {
/*
* Legacy path; interpret frame contents to decide
@@ -2820,7 +2750,6 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
bad:
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
RAL_UNLOCK(sc);
return EIO; /* XXX */
diff --git a/sys/dev/ral/rt2560var.h b/sys/dev/ral/rt2560var.h
index b6a8d68..3a5fef9 100644
--- a/sys/dev/ral/rt2560var.h
+++ b/sys/dev/ral/rt2560var.h
@@ -105,13 +105,13 @@ struct rt2560_vap {
#define RT2560_VAP(vap) ((struct rt2560_vap *)(vap))
struct rt2560_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mtx sc_mtx;
+ struct mbufq sc_snd;
device_t sc_dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
- struct mtx sc_mtx;
-
struct callout watchdog_ch;
int sc_tx_timer;
@@ -152,8 +152,7 @@ struct rt2560_softc {
struct rt2560_tx_radiotap_header sc_txtap;
int sc_txtap_len;
#define RT2560_F_INPUT_RUNNING 0x1
-#define RT2560_F_PRIO_OACTIVE 0x2
-#define RT2560_F_DATA_OACTIVE 0x4
+#define RT2560_F_RUNNING 0x2
int sc_flags;
};
diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c
index 15a2364..c77d4f8 100644
--- a/sys/dev/ral/rt2661.c
+++ b/sys/dev/ral/rt2661.c
@@ -121,12 +121,12 @@ static int rt2661_tx_data(struct rt2661_softc *, struct mbuf *,
struct ieee80211_node *, int);
static int rt2661_tx_mgt(struct rt2661_softc *, struct mbuf *,
struct ieee80211_node *);
-static void rt2661_start_locked(struct ifnet *);
-static void rt2661_start(struct ifnet *);
+static int rt2661_transmit(struct ieee80211com *, struct mbuf *);
+static void rt2661_start(struct rt2661_softc *);
static int rt2661_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static void rt2661_watchdog(void *);
-static int rt2661_ioctl(struct ifnet *, u_long, caddr_t);
+static void rt2661_parent(struct ieee80211com *);
static void rt2661_bbp_write(struct rt2661_softc *, uint8_t,
uint8_t);
static uint8_t rt2661_bbp_read(struct rt2661_softc *, uint8_t);
@@ -197,27 +197,19 @@ int
rt2661_attach(device_t dev, int id)
{
struct rt2661_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t val;
int error, ac, ntries;
uint8_t bands;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_id = id;
sc->sc_dev = dev;
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- return ENOMEM;
- }
- ic = ifp->if_l2com;
-
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
/* wait for NIC to initialize */
for (ntries = 0; ntries < 1000; ntries++) {
@@ -233,7 +225,7 @@ rt2661_attach(device_t dev, int id)
}
/* retrieve RF rev. no and various other things from EEPROM */
- rt2661_read_eeprom(sc, macaddr);
+ rt2661_read_eeprom(sc, ic->ic_macaddr);
device_printf(dev, "MAC/BBP RT%X, RF %s\n", val,
rt2661_get_rf(sc->rf_rev));
@@ -263,17 +255,6 @@ rt2661_attach(device_t dev, int id)
goto fail3;
}
- ifp->if_softc = sc;
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = rt2661_init;
- ifp->if_ioctl = rt2661_ioctl;
- ifp->if_start = rt2661_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_opmode = IEEE80211_M_STA;
@@ -305,7 +286,7 @@ rt2661_attach(device_t dev, int id)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, macaddr);
+ ieee80211_ifattach(ic);
#if 0
ic->ic_wme.wme_update = rt2661_wme_update;
#endif
@@ -315,7 +296,8 @@ rt2661_attach(device_t dev, int id)
ic->ic_updateslot = rt2661_update_slot;
ic->ic_update_promisc = rt2661_update_promisc;
ic->ic_raw_xmit = rt2661_raw_xmit;
-
+ ic->ic_transmit = rt2661_transmit;
+ ic->ic_parent = rt2661_parent;
ic->ic_vap_create = rt2661_vap_create;
ic->ic_vap_delete = rt2661_vap_delete;
@@ -339,7 +321,6 @@ fail3: rt2661_free_tx_ring(sc, &sc->mgtq);
fail2: while (--ac >= 0)
rt2661_free_tx_ring(sc, &sc->txq[ac]);
fail1: mtx_destroy(&sc->sc_mtx);
- if_free(ifp);
return error;
}
@@ -347,14 +328,14 @@ int
rt2661_detach(void *xsc)
{
struct rt2661_softc *sc = xsc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
RAL_LOCK(sc);
rt2661_stop_locked(sc);
RAL_UNLOCK(sc);
ieee80211_ifdetach(ic);
+ mbufq_drain(&sc->sc_snd);
rt2661_free_tx_ring(sc, &sc->txq[0]);
rt2661_free_tx_ring(sc, &sc->txq[1]);
@@ -363,8 +344,6 @@ rt2661_detach(void *xsc)
rt2661_free_tx_ring(sc, &sc->mgtq);
rt2661_free_rx_ring(sc, &sc->rxq);
- if_free(ifp);
-
mtx_destroy(&sc->sc_mtx);
return 0;
@@ -376,7 +355,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct ifnet *ifp = ic->ic_ifp;
+ struct rt2661_softc *sc = ic->ic_softc;
struct rt2661_vap *rvp;
struct ieee80211vap *vap;
@@ -389,7 +368,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_MBSS:
/* XXXRP: TBD */
if (!TAILQ_EMPTY(&ic->ic_vaps)) {
- if_printf(ifp, "only 1 vap supported\n");
+ device_printf(sc->sc_dev, "only 1 vap supported\n");
return NULL;
}
if (opmode == IEEE80211_M_STA)
@@ -398,7 +377,8 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_WDS:
if (TAILQ_EMPTY(&ic->ic_vaps) ||
ic->ic_opmode != IEEE80211_M_HOSTAP) {
- if_printf(ifp, "wds only supported in ap mode\n");
+ device_printf(sc->sc_dev,
+ "wds only supported in ap mode\n");
return NULL;
}
/*
@@ -409,15 +389,12 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
flags &= ~IEEE80211_CLONE_BSSID;
break;
default:
- if_printf(ifp, "unknown opmode %d\n", opmode);
+ device_printf(sc->sc_dev, "unknown opmode %d\n", opmode);
return NULL;
}
- rvp = (struct rt2661_vap *) malloc(sizeof(struct rt2661_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (rvp == NULL)
- return NULL;
+ rvp = malloc(sizeof(struct rt2661_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &rvp->ral_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
/* override state transition machine */
rvp->ral_newstate = vap->iv_newstate;
@@ -428,7 +405,8 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_init(vap);
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, ieee80211_media_change,
+ ieee80211_media_status, mac);
if (TAILQ_FIRST(&ic->ic_vaps) == vap)
ic->ic_opmode = opmode;
return vap;
@@ -464,9 +442,8 @@ void
rt2661_resume(void *xsc)
{
struct rt2661_softc *sc = xsc;
- struct ifnet *ifp = sc->sc_ifp;
- if (ifp->if_flags & IFF_UP)
+ if (sc->sc_ic.ic_nrunning > 0)
rt2661_init(sc);
}
@@ -770,7 +747,7 @@ rt2661_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct rt2661_vap *rvp = RT2661_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct rt2661_softc *sc = ic->ic_ifp->if_softc;
+ struct rt2661_softc *sc = ic->ic_softc;
int error;
if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) {
@@ -869,11 +846,10 @@ rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t addr)
static void
rt2661_tx_intr(struct rt2661_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
struct rt2661_tx_ring *txq;
struct rt2661_tx_data *data;
uint32_t val;
- int qid, retrycnt;
+ int error, qid, retrycnt;
struct ieee80211vap *vap;
for (;;) {
@@ -911,7 +887,7 @@ rt2661_tx_intr(struct rt2661_softc *sc)
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_SUCCESS,
&retrycnt, NULL);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ error = 0;
break;
case RT2661_TX_RETRY_FAIL:
@@ -923,14 +899,14 @@ rt2661_tx_intr(struct rt2661_softc *sc)
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_FAILURE,
&retrycnt, NULL);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ error = 1;
break;
default:
/* other failure */
device_printf(sc->sc_dev,
"sending data frame failed 0x%08x\n", val);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ error = 1;
}
DPRINTFN(sc, 15, "tx done q=%d idx=%u\n", qid, txq->stat);
@@ -939,17 +915,12 @@ rt2661_tx_intr(struct rt2661_softc *sc)
if (++txq->stat >= txq->count) /* faster than % count */
txq->stat = 0;
- if (m->m_flags & M_TXCB)
- ieee80211_process_callback(ni, m,
- RT2661_TX_RESULT(val) != RT2661_TX_SUCCESS);
- m_freem(m);
- ieee80211_free_node(ni);
+ ieee80211_tx_complete(ni, m, error);
}
sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- rt2661_start_locked(ifp);
+ rt2661_start(sc);
}
static void
@@ -987,8 +958,7 @@ rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *txq)
static void
rt2661_rx_intr(struct rt2661_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct rt2661_rx_desc *desc;
struct rt2661_rx_data *data;
bus_addr_t physaddr;
@@ -1017,12 +987,12 @@ rt2661_rx_intr(struct rt2661_softc *sc)
*/
DPRINTFN(sc, 5, "PHY or CRC error flags 0x%08x\n",
le32toh(desc->flags));
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto skip;
}
if ((le32toh(desc->flags) & RT2661_RX_CIPHER_MASK) != 0) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto skip;
}
@@ -1035,7 +1005,7 @@ rt2661_rx_intr(struct rt2661_softc *sc)
*/
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (mnew == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto skip;
}
@@ -1058,7 +1028,7 @@ rt2661_rx_intr(struct rt2661_softc *sc)
panic("%s: could not load old rx mbuf",
device_get_name(sc->sc_dev));
}
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto skip;
}
@@ -1071,7 +1041,6 @@ rt2661_rx_intr(struct rt2661_softc *sc)
desc->physaddr = htole32(physaddr);
/* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len =
(le32toh(desc->flags) >> 16) & 0xfff;
@@ -1156,7 +1125,6 @@ void
rt2661_intr(void *arg)
{
struct rt2661_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
uint32_t r1, r2;
RAL_LOCK(sc);
@@ -1166,7 +1134,7 @@ rt2661_intr(void *arg)
RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
/* don't re-enable interrupts if we're shutting down */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & RAL_RUNNING)) {
RAL_UNLOCK(sc);
return;
}
@@ -1242,8 +1210,7 @@ rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc,
uint32_t flags, uint16_t xflags, int len, int rate,
const bus_dma_segment_t *segs, int nsegs, int ac)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t plcp_length;
int i, remainder;
@@ -1461,8 +1428,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
struct ieee80211_node *ni, int ac)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct rt2661_tx_ring *txq = &sc->txq[ac];
struct rt2661_tx_desc *desc;
struct rt2661_tx_data *data;
@@ -1604,10 +1570,31 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
return 0;
}
+static int
+rt2661_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct rt2661_softc *sc = ic->ic_softc;
+ int error;
+
+ RAL_LOCK(sc);
+ if ((sc->sc_flags & RAL_RUNNING) == 0) {
+ RAL_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ RAL_UNLOCK(sc);
+ return (error);
+ }
+ rt2661_start(sc);
+ RAL_UNLOCK(sc);
+
+ return (0);
+}
+
static void
-rt2661_start_locked(struct ifnet *ifp)
+rt2661_start(struct rt2661_softc *sc)
{
- struct rt2661_softc *sc = ifp->if_softc;
struct mbuf *m;
struct ieee80211_node *ni;
int ac;
@@ -1615,69 +1602,50 @@ rt2661_start_locked(struct ifnet *ifp)
RAL_LOCK_ASSERT(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) || sc->sc_invalid)
+ if (!(sc->sc_flags & RAL_RUNNING) || sc->sc_invalid)
return;
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
-
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ac = M_WME_GETAC(m);
if (sc->txq[ac].queued >= RT2661_TX_RING_COUNT - 1) {
/* there is no place left in this ring */
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ mbufq_prepend(&sc->sc_snd, m);
break;
}
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
if (rt2661_tx_data(sc, m, ni, ac) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
break;
}
-
sc->sc_tx_timer = 5;
}
}
-static void
-rt2661_start(struct ifnet *ifp)
-{
- struct rt2661_softc *sc = ifp->if_softc;
-
- RAL_LOCK(sc);
- rt2661_start_locked(ifp);
- RAL_UNLOCK(sc);
-}
-
static int
rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct rt2661_softc *sc = ifp->if_softc;
+ struct rt2661_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & RAL_RUNNING)) {
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return ENETDOWN;
}
if (sc->mgtq.queued >= RT2661_MGT_RING_COUNT) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return ENOBUFS; /* XXX */
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
/*
* Legacy path; interpret frame contents to decide
* precisely how to send the frame.
@@ -1691,7 +1659,6 @@ rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
bad:
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
RAL_UNLOCK(sc);
return EIO; /* XXX */
@@ -1701,61 +1668,42 @@ static void
rt2661_watchdog(void *arg)
{
struct rt2661_softc *sc = (struct rt2661_softc *)arg;
- struct ifnet *ifp = sc->sc_ifp;
RAL_LOCK_ASSERT(sc);
- KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
+ KASSERT(sc->sc_flags & RAL_RUNNING, ("not running"));
if (sc->sc_invalid) /* card ejected */
return;
if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
- if_printf(ifp, "device timeout\n");
+ device_printf(sc->sc_dev, "device timeout\n");
rt2661_init_locked(sc);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
/* NB: callout is reset in rt2661_init() */
return;
}
callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
}
-static int
-rt2661_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+rt2661_parent(struct ieee80211com *ic)
{
- struct rt2661_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
+ struct rt2661_softc *sc = ic->ic_softc;
+ int startall = 0;
- switch (cmd) {
- case SIOCSIFFLAGS:
- RAL_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- rt2661_init_locked(sc);
- startall = 1;
- } else
- rt2661_update_promisc(ic);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rt2661_stop_locked(sc);
- }
- RAL_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
+ RAL_LOCK(sc);
+ if (ic->ic_nrunning > 0) {
+ if ((sc->sc_flags & RAL_RUNNING) == 0) {
+ rt2661_init_locked(sc);
+ startall = 1;
+ } else
+ rt2661_update_promisc(ic);
+ } else if (sc->sc_flags & RAL_RUNNING)
+ rt2661_stop_locked(sc);
+ RAL_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
@@ -1879,8 +1827,7 @@ rt2661_select_antenna(struct rt2661_softc *sc)
static void
rt2661_enable_mrr(struct rt2661_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
tmp = RAL_READ(sc, RT2661_TXRX_CSR4);
@@ -1896,8 +1843,7 @@ rt2661_enable_mrr(struct rt2661_softc *sc)
static void
rt2661_set_txpreamble(struct rt2661_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
tmp = RAL_READ(sc, RT2661_TXRX_CSR4);
@@ -1914,8 +1860,7 @@ rt2661_set_basicrates(struct rt2661_softc *sc,
const struct ieee80211_rateset *rs)
{
#define RV(r) ((r) & IEEE80211_RATE_VAL)
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t mask = 0;
uint8_t rate;
int i;
@@ -1984,8 +1929,7 @@ rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c)
static void
rt2661_set_chan(struct rt2661_softc *sc, struct ieee80211_channel *c)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
const struct rfprog *rfprog;
uint8_t bbp3, bbp94 = RT2661_BBPR94_DEFAULT;
int8_t power;
@@ -2088,13 +2032,13 @@ rt2661_update_promisc(struct ieee80211com *ic)
tmp = RAL_READ(sc, RT2661_TXRX_CSR0);
tmp &= ~RT2661_DROP_NOT_TO_ME;
- if (!(ic->ic_ifp->if_flags & IFF_PROMISC))
+ if (ic->ic_promisc == 0)
tmp |= RT2661_DROP_NOT_TO_ME;
RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp);
DPRINTF(sc, "%s promiscuous mode\n",
- (ic->ic_ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
+ (ic->ic_promisc > 0) ? "entering" : "leaving");
}
/*
@@ -2103,7 +2047,7 @@ rt2661_update_promisc(struct ieee80211com *ic)
static int
rt2661_wme_update(struct ieee80211com *ic)
{
- struct rt2661_softc *sc = ic->ic_ifp->if_softc;
+ struct rt2661_softc *sc = ic->ic_softc;
const struct wmeParams *wmep;
wmep = ic->ic_wme.wme_chanParams.cap_wmeParams;
@@ -2301,8 +2245,8 @@ static void
rt2661_init_locked(struct rt2661_softc *sc)
{
#define N(a) (sizeof (a) / sizeof ((a)[0]))
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp, sta[3];
int i, error, ntries;
@@ -2311,7 +2255,7 @@ rt2661_init_locked(struct rt2661_softc *sc)
if ((sc->sc_flags & RAL_FW_LOADED) == 0) {
error = rt2661_load_microcode(sc);
if (error != 0) {
- if_printf(ifp,
+ device_printf(sc->sc_dev,
"%s: could not load 8051 microcode, error %d\n",
__func__, error);
return;
@@ -2364,7 +2308,7 @@ rt2661_init_locked(struct rt2661_softc *sc)
for (i = 0; i < N(rt2661_def_mac); i++)
RAL_WRITE(sc, rt2661_def_mac[i].reg, rt2661_def_mac[i].val);
- rt2661_set_macaddr(sc, IF_LLADDR(ifp));
+ rt2661_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
/* set host ready */
RAL_WRITE(sc, RT2661_MAC_CSR1, 3);
@@ -2403,7 +2347,7 @@ rt2661_init_locked(struct rt2661_softc *sc)
if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
ic->ic_opmode != IEEE80211_M_MBSS)
tmp |= RT2661_DROP_TODS;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (ic->ic_promisc == 0)
tmp |= RT2661_DROP_NOT_TO_ME;
}
@@ -2425,8 +2369,7 @@ rt2661_init_locked(struct rt2661_softc *sc)
/* kick Rx */
RAL_WRITE(sc, RT2661_RX_CNTL_CSR, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= RAL_RUNNING;
callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
#undef N
@@ -2436,23 +2379,21 @@ static void
rt2661_init(void *priv)
{
struct rt2661_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
RAL_LOCK(sc);
rt2661_init_locked(sc);
RAL_UNLOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_flags & RAL_RUNNING)
ieee80211_start_all(ic); /* start all vap's */
}
void
rt2661_stop_locked(struct rt2661_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- uint32_t tmp;
volatile int *flags = &sc->sc_flags;
+ uint32_t tmp;
while (*flags & RAL_INPUT_RUNNING)
msleep(sc, &sc->sc_mtx, 0, "ralrunning", hz/10);
@@ -2460,8 +2401,8 @@ rt2661_stop_locked(struct rt2661_softc *sc)
callout_stop(&sc->watchdog_ch);
sc->sc_tx_timer = 0;
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ if (sc->sc_flags & RAL_RUNNING) {
+ sc->sc_flags &= ~RAL_RUNNING;
/* abort Tx (for all 5 Tx rings) */
RAL_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16);
@@ -2505,7 +2446,6 @@ rt2661_stop(void *priv)
static int
rt2661_load_microcode(struct rt2661_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
const struct firmware *fp;
const char *imagename;
int ntries, error;
@@ -2517,7 +2457,7 @@ rt2661_load_microcode(struct rt2661_softc *sc)
case 0x0302: imagename = "rt2561fw"; break;
case 0x0401: imagename = "rt2661fw"; break;
default:
- if_printf(ifp, "%s: unexpected pci device id 0x%x, "
+ device_printf(sc->sc_dev, "%s: unexpected pci device id 0x%x, "
"don't know how to retrieve firmware\n",
__func__, sc->sc_id);
return EINVAL;
@@ -2526,7 +2466,8 @@ rt2661_load_microcode(struct rt2661_softc *sc)
fp = firmware_get(imagename);
RAL_LOCK(sc);
if (fp == NULL) {
- if_printf(ifp, "%s: unable to retrieve firmware image %s\n",
+ device_printf(sc->sc_dev,
+ "%s: unable to retrieve firmware image %s\n",
__func__, imagename);
return EINVAL;
}
@@ -2557,8 +2498,8 @@ rt2661_load_microcode(struct rt2661_softc *sc)
DELAY(100);
}
if (ntries == 500) {
- if_printf(ifp, "%s: timeout waiting for MCU to initialize\n",
- __func__);
+ device_printf(sc->sc_dev,
+ "%s: timeout waiting for MCU to initialize\n", __func__);
error = EIO;
} else
error = 0;
@@ -2726,8 +2667,7 @@ rt2661_prepare_beacon(struct rt2661_softc *sc, struct ieee80211vap *vap)
static void
rt2661_enable_tsf_sync(struct rt2661_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
@@ -2811,21 +2751,19 @@ rt2661_get_rssi(struct rt2661_softc *sc, uint8_t raw)
static void
rt2661_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct rt2661_softc *sc = ifp->if_softc;
+ struct rt2661_softc *sc = ic->ic_softc;
uint32_t tmp;
/* abort TSF synchronization */
tmp = RAL_READ(sc, RT2661_TXRX_CSR9);
RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0xffffff);
- rt2661_set_bssid(sc, ifp->if_broadcastaddr);
+ rt2661_set_bssid(sc, ieee80211broadcastaddr);
}
static void
rt2661_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct rt2661_softc *sc = ifp->if_softc;
+ struct rt2661_softc *sc = ic->ic_softc;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
rt2661_enable_tsf_sync(sc);
@@ -2836,8 +2774,7 @@ rt2661_scan_end(struct ieee80211com *ic)
static void
rt2661_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct rt2661_softc *sc = ifp->if_softc;
+ struct rt2661_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
rt2661_set_chan(sc, ic->ic_curchan);
diff --git a/sys/dev/ral/rt2661var.h b/sys/dev/ral/rt2661var.h
index 9927d13..7ea16f6 100644
--- a/sys/dev/ral/rt2661var.h
+++ b/sys/dev/ral/rt2661var.h
@@ -97,13 +97,13 @@ struct rt2661_vap {
#define RT2661_VAP(vap) ((struct rt2661_vap *)(vap))
struct rt2661_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mtx sc_mtx;
+ struct mbufq sc_snd;
device_t sc_dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
- struct mtx sc_mtx;
-
struct callout watchdog_ch;
int sc_tx_timer;
@@ -117,6 +117,7 @@ struct rt2661_softc {
int sc_flags;
#define RAL_FW_LOADED 0x1
#define RAL_INPUT_RUNNING 0x2
+#define RAL_RUNNING 0x4
int sc_id;
struct ieee80211_channel *sc_curchan;
diff --git a/sys/dev/ral/rt2860.c b/sys/dev/ral/rt2860.c
index 782fa1f..b3c737d 100644
--- a/sys/dev/ral/rt2860.c
+++ b/sys/dev/ral/rt2860.c
@@ -122,10 +122,10 @@ static int rt2860_raw_xmit(struct ieee80211_node *, struct mbuf *,
static int rt2860_tx_raw(struct rt2860_softc *, struct mbuf *,
struct ieee80211_node *,
const struct ieee80211_bpf_params *params);
-static void rt2860_start(struct ifnet *);
-static void rt2860_start_locked(struct ifnet *);
+static int rt2860_transmit(struct ieee80211com *, struct mbuf *);
+static void rt2860_start(struct rt2860_softc *);
static void rt2860_watchdog(void *);
-static int rt2860_ioctl(struct ifnet *, u_long, caddr_t);
+static void rt2860_parent(struct ieee80211com *);
static void rt2860_mcu_bbp_write(struct rt2860_softc *, uint8_t, uint8_t);
static uint8_t rt2860_mcu_bbp_read(struct rt2860_softc *, uint8_t);
static void rt2860_rf_write(struct rt2860_softc *, uint8_t, uint32_t);
@@ -156,7 +156,7 @@ static void rt2860_set_bssid(struct rt2860_softc *, const uint8_t *);
static void rt2860_set_macaddr(struct rt2860_softc *, const uint8_t *);
static void rt2860_update_promisc(struct ieee80211com *);
static void rt2860_updateslot(struct ieee80211com *);
-static void rt2860_updateprot(struct ifnet *);
+static void rt2860_updateprot(struct rt2860_softc *);
static int rt2860_updateedca(struct ieee80211com *);
#ifdef HW_CRYPTO
static int rt2860_set_key(struct ieee80211com *, struct ieee80211_node *,
@@ -230,27 +230,19 @@ int
rt2860_attach(device_t dev, int id)
{
struct rt2860_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
int error, ntries, qid;
uint8_t bands;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_dev = dev;
sc->sc_debug = 0;
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- return ENOMEM;
- }
- ic = ifp->if_l2com;
-
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
/* wait for NIC to initialize */
for (ntries = 0; ntries < 100; ntries++) {
@@ -273,11 +265,11 @@ rt2860_attach(device_t dev, int id)
sc->sc_flags |= RT2860_ADVANCED_PS;
/* retrieve RF rev. no and various other things from EEPROM */
- rt2860_read_eeprom(sc, macaddr);
+ rt2860_read_eeprom(sc, ic->ic_macaddr);
device_printf(sc->sc_dev, "MAC/BBP RT%X (rev 0x%04X), "
"RF %s (MIMO %dT%dR), address %6D\n",
sc->mac_ver, sc->mac_rev, rt2860_get_rf(sc->rf_rev),
- sc->ntxchains, sc->nrxchains, macaddr, ":");
+ sc->ntxchains, sc->nrxchains, ic->ic_macaddr, ":");
/*
* Allocate Tx (4 EDCAs + HCCA + Mgt) and Rx rings.
@@ -304,17 +296,6 @@ rt2860_attach(device_t dev, int id)
sc->mgtqid = (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) ?
WME_AC_VO : 5;
- ifp->if_softc = sc;
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = rt2860_init;
- ifp->if_ioctl = rt2860_ioctl;
- ifp->if_start = rt2860_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_opmode = IEEE80211_M_STA;
@@ -345,7 +326,7 @@ rt2860_attach(device_t dev, int id)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, macaddr);
+ ieee80211_ifattach(ic);
ic->ic_wme.wme_update = rt2860_updateedca;
ic->ic_scan_start = rt2860_scan_start;
@@ -357,7 +338,8 @@ rt2860_attach(device_t dev, int id)
sc->sc_node_free = ic->ic_node_free;
ic->ic_node_free = rt2860_node_free;
ic->ic_newassoc = rt2860_newassoc;
-
+ ic->ic_transmit = rt2860_transmit;
+ ic->ic_parent = rt2860_parent;
ic->ic_vap_create = rt2860_vap_create;
ic->ic_vap_delete = rt2860_vap_delete;
@@ -381,7 +363,6 @@ fail3: rt2860_free_rx_ring(sc, &sc->rxq);
fail2: while (--qid >= 0)
rt2860_free_tx_ring(sc, &sc->txq[qid]);
fail1: mtx_destroy(&sc->sc_mtx);
- if_free(ifp);
return error;
}
@@ -389,8 +370,7 @@ int
rt2860_detach(void *xsc)
{
struct rt2860_softc *sc = xsc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
int qid;
RAL_LOCK(sc);
@@ -398,14 +378,12 @@ rt2860_detach(void *xsc)
RAL_UNLOCK(sc);
ieee80211_ifdetach(ic);
-
+ mbufq_drain(&sc->sc_snd);
for (qid = 0; qid < 6; qid++)
rt2860_free_tx_ring(sc, &sc->txq[qid]);
rt2860_free_rx_ring(sc, &sc->rxq);
rt2860_free_tx_pool(sc);
- if_free(ifp);
-
mtx_destroy(&sc->sc_mtx);
return 0;
@@ -431,9 +409,8 @@ void
rt2860_resume(void *xsc)
{
struct rt2860_softc *sc = xsc;
- struct ifnet *ifp = sc->sc_ifp;
- if (ifp->if_flags & IFF_UP)
+ if (sc->sc_ic.ic_nrunning > 0)
rt2860_init(sc);
}
@@ -443,7 +420,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct ifnet *ifp = ic->ic_ifp;
+ struct rt2860_softc *sc = ic->ic_softc;
struct rt2860_vap *rvp;
struct ieee80211vap *vap;
@@ -456,7 +433,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_MBSS:
/* XXXRP: TBD */
if (!TAILQ_EMPTY(&ic->ic_vaps)) {
- if_printf(ifp, "only 1 vap supported\n");
+ device_printf(sc->sc_dev, "only 1 vap supported\n");
return NULL;
}
if (opmode == IEEE80211_M_STA)
@@ -465,7 +442,8 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_WDS:
if (TAILQ_EMPTY(&ic->ic_vaps) ||
ic->ic_opmode != IEEE80211_M_HOSTAP) {
- if_printf(ifp, "wds only supported in ap mode\n");
+ device_printf(sc->sc_dev,
+ "wds only supported in ap mode\n");
return NULL;
}
/*
@@ -476,14 +454,12 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
flags &= ~IEEE80211_CLONE_BSSID;
break;
default:
- if_printf(ifp, "unknown opmode %d\n", opmode);
+ device_printf(sc->sc_dev, "unknown opmode %d\n", opmode);
return NULL;
}
- rvp = malloc(sizeof(struct rt2860_vap), M_80211_VAP, M_NOWAIT | M_ZERO);
- if (rvp == NULL)
- return NULL;
+ rvp = malloc(sizeof(struct rt2860_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &rvp->ral_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
/* override state transition machine */
rvp->ral_newstate = vap->iv_newstate;
@@ -497,7 +473,8 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_init(vap);
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, ieee80211_media_change,
+ ieee80211_media_status, mac);
if (TAILQ_FIRST(&ic->ic_vaps) == vap)
ic->ic_opmode = opmode;
return vap;
@@ -829,7 +806,7 @@ rt2860_free_rx_ring(struct rt2860_softc *sc, struct rt2860_rx_ring *ring)
static void
rt2860_updatestats(struct rt2860_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
/*
* In IBSS or HostAP modes (when the hardware sends beacons), the
@@ -856,7 +833,7 @@ static void
rt2860_newassoc(struct ieee80211_node *ni, int isnew)
{
struct ieee80211com *ic = ni->ni_ic;
- struct rt2860_softc *sc = ic->ic_ifp->if_softc;
+ struct rt2860_softc *sc = ic->ic_softc;
uint8_t wcid;
wcid = IEEE80211_AID(ni->ni_associd);
@@ -875,7 +852,7 @@ static void
rt2860_node_free(struct ieee80211_node *ni)
{
struct ieee80211com *ic = ni->ni_ic;
- struct rt2860_softc *sc = ic->ic_ifp->if_softc;
+ struct rt2860_softc *sc = ic->ic_softc;
uint8_t wcid;
if (ni->ni_associd != 0) {
@@ -923,7 +900,7 @@ rt2860_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct rt2860_vap *rvp = RT2860_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct rt2860_softc *sc = ic->ic_ifp->if_softc;
+ struct rt2860_softc *sc = ic->ic_softc;
uint32_t tmp;
int error;
@@ -1101,7 +1078,6 @@ rt2860_intr_coherent(struct rt2860_softc *sc)
static void
rt2860_drain_stats_fifo(struct rt2860_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211_node *ni;
uint32_t stat;
int retrycnt;
@@ -1137,7 +1113,8 @@ rt2860_drain_stats_fifo(struct rt2860_softc *sc)
} else {
ieee80211_ratectl_tx_complete(ni->ni_vap, ni,
IEEE80211_RATECTL_TX_FAILURE, &retrycnt, NULL);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
}
}
}
@@ -1145,7 +1122,6 @@ rt2860_drain_stats_fifo(struct rt2860_softc *sc)
static void
rt2860_tx_intr(struct rt2860_softc *sc, int qid)
{
- struct ifnet *ifp = sc->sc_ifp;
struct rt2860_tx_ring *ring = &sc->txq[qid];
uint32_t hw;
@@ -1163,15 +1139,11 @@ rt2860_tx_intr(struct rt2860_softc *sc, int qid)
ieee80211_process_callback(data->ni, data->m,
0);
}
- m_freem(data->m);
- ieee80211_free_node(data->ni);
- data->m = NULL;
+ ieee80211_tx_complete(data->ni, data->m, 0);
data->ni = NULL;
-
+ data->m = NULL;
SLIST_INSERT_HEAD(&sc->data_pool, data, next);
ring->data[ring->next] = NULL;
-
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
}
ring->queued--;
ring->next = (ring->next + 1) % RT2860_TX_RING_COUNT;
@@ -1180,8 +1152,7 @@ rt2860_tx_intr(struct rt2860_softc *sc, int qid)
sc->sc_tx_timer = 0;
if (ring->queued < RT2860_TX_RING_COUNT)
sc->qfullmsk &= ~(1 << qid);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- rt2860_start_locked(ifp);
+ rt2860_start(sc);
}
/*
@@ -1206,8 +1177,7 @@ static void
rt2860_rx_intr(struct rt2860_softc *sc)
{
struct rt2860_rx_radiotap_header *tap;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct mbuf *m, *m1;
@@ -1234,7 +1204,7 @@ rt2860_rx_intr(struct rt2860_softc *sc)
if (__predict_false(rxd->flags &
htole32(RT2860_RX_CRCERR | RT2860_RX_ICVERR))) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto skip;
}
@@ -1243,14 +1213,14 @@ rt2860_rx_intr(struct rt2860_softc *sc)
/* report MIC failures to net80211 for TKIP */
ic->ic_stats.is_rx_locmicfail++;
ieee80211_michael_mic_failure(ic, 0/* XXX */);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto skip;
}
#endif
m1 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (__predict_false(m1 == NULL)) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto skip;
}
@@ -1274,7 +1244,7 @@ rt2860_rx_intr(struct rt2860_softc *sc)
}
/* physical address may have changed */
rxd->sdp0 = htole32(physaddr);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto skip;
}
@@ -1289,7 +1259,6 @@ rt2860_rx_intr(struct rt2860_softc *sc)
rxwi = mtod(m, struct rt2860_rxwi *);
/* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
m->m_data = (caddr_t)(rxwi + 1);
m->m_pkthdr.len = m->m_len = le16toh(rxwi->len) & 0xfff;
@@ -1399,7 +1368,7 @@ rt2860_tbtt_intr(struct rt2860_softc *sc)
#endif
/* check if protection mode has changed */
if ((sc->sc_ic_flags ^ ic->ic_flags) & IEEE80211_F_USEPROT) {
- rt2860_updateprot(ic);
+ rt2860_updateprot(sc);
sc->sc_ic_flags = ic->ic_flags;
}
#endif
@@ -1408,7 +1377,7 @@ rt2860_tbtt_intr(struct rt2860_softc *sc)
static void
rt2860_gp_intr(struct rt2860_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
DPRINTFN(2, ("GP timeout state=%d\n", vap->iv_state));
@@ -1480,8 +1449,7 @@ rt2860_intr(void *arg)
static int
rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct rt2860_tx_ring *ring;
struct rt2860_tx_data *data;
@@ -1725,14 +1693,13 @@ rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct rt2860_softc *sc = ifp->if_softc;
+ struct rt2860_softc *sc = ic->ic_softc;
int error;
RAL_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & RT2860_RUNNNING)) {
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
@@ -1754,7 +1721,6 @@ rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (error != 0) {
/* NB: m is reclaimed on tx failure */
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
sc->sc_tx_timer = 5;
RAL_UNLOCK(sc);
@@ -1765,8 +1731,7 @@ static int
rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m,
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct rt2860_tx_ring *ring;
struct rt2860_tx_data *data;
@@ -1973,41 +1938,46 @@ rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m,
return 0;
}
-static void
-rt2860_start(struct ifnet *ifp)
+static int
+rt2860_transmit(struct ieee80211com *ic, struct mbuf *m)
{
- struct rt2860_softc *sc = ifp->if_softc;
+ struct rt2860_softc *sc = ic->ic_softc;
+ int error;
RAL_LOCK(sc);
- rt2860_start_locked(ifp);
+ if ((sc->sc_flags & RT2860_RUNNNING) == 0) {
+ RAL_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ RAL_UNLOCK(sc);
+ return (error);
+ }
+ rt2860_start(sc);
RAL_UNLOCK(sc);
+
+ return (0);
}
static void
-rt2860_start_locked(struct ifnet *ifp)
+rt2860_start(struct rt2860_softc *sc)
{
- struct rt2860_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
RAL_LOCK_ASSERT(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
- (ifp->if_drv_flags & IFF_DRV_OACTIVE))
+ if ((sc->sc_flags & RT2860_RUNNNING) == 0)
return;
- for (;;) {
- if (SLIST_EMPTY(&sc->data_pool) || sc->qfullmsk != 0) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while (!SLIST_EMPTY(&sc->data_pool) && sc->qfullmsk == 0 &&
+ (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
if (rt2860_tx(sc, m, ni) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
continue;
}
sc->sc_tx_timer = 5;
@@ -2018,61 +1988,42 @@ static void
rt2860_watchdog(void *arg)
{
struct rt2860_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
RAL_LOCK_ASSERT(sc);
- KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
+ KASSERT(sc->sc_flags & RT2860_RUNNNING, ("not running"));
if (sc->sc_invalid) /* card ejected */
return;
if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
- if_printf(ifp, "device timeout\n");
+ device_printf(sc->sc_dev, "device timeout\n");
rt2860_stop_locked(sc);
rt2860_init_locked(sc);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
return;
}
callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc);
}
-static int
-rt2860_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+rt2860_parent(struct ieee80211com *ic)
{
- struct rt2860_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *)data;
- int error = 0, startall = 0;
+ struct rt2860_softc *sc = ic->ic_softc;
+ int startall = 0;
- switch (cmd) {
- case SIOCSIFFLAGS:
- RAL_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- rt2860_init_locked(sc);
- startall = 1;
- } else
- rt2860_update_promisc(ic);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rt2860_stop_locked(sc);
- }
- RAL_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCSIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
+ RAL_LOCK(sc);
+ if (ic->ic_nrunning> 0) {
+ if (!(sc->sc_flags & RT2860_RUNNNING)) {
+ rt2860_init_locked(sc);
+ startall = 1;
+ } else
+ rt2860_update_promisc(ic);
+ } else if (sc->sc_flags & RT2860_RUNNNING)
+ rt2860_stop_locked(sc);
+ RAL_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
/*
@@ -2295,8 +2246,7 @@ rt2860_enable_mrr(struct rt2860_softc *sc)
static void
rt2860_set_txpreamble(struct rt2860_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
tmp = RAL_READ(sc, RT2860_AUTO_RSP_CFG);
@@ -2311,8 +2261,7 @@ rt2860_set_basicrates(struct rt2860_softc *sc,
const struct ieee80211_rateset *rs)
{
#define RV(r) ((r) & IEEE80211_RATE_VAL)
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t mask = 0;
uint8_t rate;
int i;
@@ -2333,8 +2282,7 @@ rt2860_set_basicrates(struct rt2860_softc *sc,
static void
rt2860_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct rt2860_softc *sc = ifp->if_softc;
+ struct rt2860_softc *sc = ic->ic_softc;
uint32_t tmp;
tmp = RAL_READ(sc, RT2860_BCN_TIME_CFG);
@@ -2347,8 +2295,7 @@ rt2860_scan_start(struct ieee80211com *ic)
static void
rt2860_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct rt2860_softc *sc = ifp->if_softc;
+ struct rt2860_softc *sc = ic->ic_softc;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
if (vap->iv_state == IEEE80211_S_RUN) {
@@ -2360,8 +2307,7 @@ rt2860_scan_end(struct ieee80211com *ic)
static void
rt2860_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct rt2860_softc *sc = ifp->if_softc;
+ struct rt2860_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
rt2860_switch_chan(sc, ic->ic_curchan);
@@ -3113,10 +3059,9 @@ rt2860_updateslot(struct ieee80211com *ic)
}
static void
-rt2860_updateprot(struct ifnet *ifp)
+rt2860_updateprot(struct rt2860_softc *sc)
{
- struct rt2860_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL;
@@ -3145,7 +3090,7 @@ rt2860_update_promisc(struct ieee80211com *ic)
tmp = RAL_READ(sc, RT2860_RX_FILTR_CFG);
tmp &= ~RT2860_DROP_NOT_MYBSS;
- if (!(ic->ic_ifp->if_flags & IFF_PROMISC))
+ if (ic->ic_promisc == 0)
tmp |= RT2860_DROP_NOT_MYBSS;
RAL_WRITE(sc, RT2860_RX_FILTR_CFG, tmp);
}
@@ -3153,7 +3098,7 @@ rt2860_update_promisc(struct ieee80211com *ic)
static int
rt2860_updateedca(struct ieee80211com *ic)
{
- struct rt2860_softc *sc = ic->ic_ifp->if_softc;
+ struct rt2860_softc *sc = ic->ic_softc;
const struct wmeParams *wmep;
int aci;
@@ -3325,8 +3270,7 @@ rt2860_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
static int8_t
rt2860_rssi2dbm(struct rt2860_softc *sc, uint8_t rssi, uint8_t rxchain)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_channel *c = ic->ic_curchan;
int delta;
@@ -3801,8 +3745,7 @@ rt5390_bbp_init(struct rt2860_softc *sc)
static int
rt2860_txrx_enable(struct rt2860_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
int ntries;
@@ -3848,22 +3791,21 @@ static void
rt2860_init(void *arg)
{
struct rt2860_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
RAL_LOCK(sc);
rt2860_init_locked(sc);
RAL_UNLOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_flags & RT2860_RUNNNING)
ieee80211_start_all(ic);
}
static void
rt2860_init_locked(struct rt2860_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
uint8_t bbp1, bbp3;
int i, qid, ridx, ntries, error;
@@ -3899,7 +3841,7 @@ rt2860_init_locked(struct rt2860_softc *sc)
return;
}
- rt2860_set_macaddr(sc, IF_LLADDR(ifp));
+ rt2860_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
/* init Tx power for all Tx rates (from EEPROM) */
for (ridx = 0; ridx < 5; ridx++) {
@@ -4096,7 +4038,7 @@ rt2860_init_locked(struct rt2860_softc *sc)
RAL_WRITE(sc, RT2860_TX_RTS_CFG, tmp);
/* setup initial protection mode */
- rt2860_updateprot(ifp);
+ rt2860_updateprot(sc);
/* turn radio LED on */
rt2860_set_leds(sc, RT2860_LED_RADIO);
@@ -4115,8 +4057,7 @@ rt2860_init_locked(struct rt2860_softc *sc)
if (sc->sc_flags & RT2860_ADVANCED_PS)
rt2860_mcu_cmd(sc, RT2860_MCU_CMD_PSLEVEL, sc->pslevel, 0);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= RT2860_RUNNNING;
callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc);
}
@@ -4134,16 +4075,15 @@ rt2860_stop(void *arg)
static void
rt2860_stop_locked(struct rt2860_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
int qid;
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_flags & RT2860_RUNNNING)
rt2860_set_leds(sc, 0); /* turn all LEDs off */
callout_stop(&sc->watchdog_ch);
sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_flags &= ~RT2860_RUNNNING;
/* disable interrupts */
RAL_WRITE(sc, RT2860_INT_MASK, 0);
@@ -4294,8 +4234,7 @@ rt3090_set_rx_antenna(struct rt2860_softc *sc, int aux)
static void
rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
u_int chan, group;
chan = ieee80211_chan2ieee(ic, c);
@@ -4364,8 +4303,7 @@ rt2860_setup_beacon(struct rt2860_softc *sc, struct ieee80211vap *vap)
static void
rt2860_enable_tsf_sync(struct rt2860_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
diff --git a/sys/dev/ral/rt2860var.h b/sys/dev/ral/rt2860var.h
index 28a3d59..3779e5b 100644
--- a/sys/dev/ral/rt2860var.h
+++ b/sys/dev/ral/rt2860var.h
@@ -115,13 +115,13 @@ struct rt2860_vap {
#define RT2860_VAP(vap) ((struct rt2860_vap *)(vap))
struct rt2860_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
+ struct mtx sc_mtx;
device_t sc_dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
- struct mtx sc_mtx;
-
struct callout watchdog_ch;
int sc_invalid;
@@ -139,6 +139,7 @@ struct rt2860_softc {
#define RT2860_ENABLED (1 << 0)
#define RT2860_ADVANCED_PS (1 << 1)
#define RT2860_PCIE (1 << 2)
+#define RT2860_RUNNNING (1 << 3)
struct ieee80211_node *wcid2ni[RT2860_WCID_MAX];
diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c
index 89b8c00..463a9bd 100644
--- a/sys/dev/usb/wlan/if_rsu.c
+++ b/sys/dev/usb/wlan/if_rsu.c
@@ -187,15 +187,13 @@ static struct mbuf *
static void rsu_txeof(struct usb_xfer *, struct rsu_data *);
static int rsu_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void rsu_init(void *);
-static void rsu_init_locked(struct rsu_softc *);
+static void rsu_init(struct rsu_softc *);
static int rsu_tx_start(struct rsu_softc *, struct ieee80211_node *,
struct mbuf *, struct rsu_data *);
-static void rsu_start(struct ifnet *);
-static void rsu_start_locked(struct ifnet *);
-static int rsu_ioctl(struct ifnet *, u_long, caddr_t);
-static void rsu_stop(struct ifnet *, int);
-static void rsu_stop_locked(struct ifnet *, int);
+static int rsu_transmit(struct ieee80211com *, struct mbuf *);
+static void rsu_start(struct rsu_softc *);
+static void rsu_parent(struct ieee80211com *);
+static void rsu_stop(struct rsu_softc *);
static void rsu_ms_delay(struct rsu_softc *);
static device_method_t rsu_methods[] = {
@@ -285,8 +283,7 @@ rsu_attach(device_t self)
{
struct usb_attach_arg *uaa = device_get_ivars(self);
struct rsu_softc *sc = device_get_softc(self);
- struct ifnet *ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
int error;
uint8_t iface_index, bands;
@@ -298,6 +295,7 @@ rsu_attach(device_t self)
MTX_DEF);
TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_task, 0,
rsu_calib_task, sc);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
/* Allocate Tx/Rx buffers. */
error = rsu_alloc_rx_list(sc);
@@ -333,28 +331,9 @@ rsu_attach(device_t self)
device_printf(self, "could not read ROM\n");
goto fail_rom;
}
- IEEE80211_ADDR_COPY(sc->sc_bssid, &sc->rom[0x12]);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, &sc->rom[0x12]);
device_printf(self, "MAC/BB RTL8712 cut %d\n", sc->cut);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(self, "cannot allocate interface\n");
- goto fail_ifalloc;
- }
- ic = ifp->if_l2com;
- ifp->if_softc = sc;
- if_initname(ifp, "rsu", device_get_unit(self));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = rsu_init;
- ifp->if_ioctl = rsu_ioctl;
- ifp->if_start = rsu_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
- ifp->if_capabilities |= IFCAP_RXCSUM;
- ifp->if_capenable |= IFCAP_RXCSUM;
- ifp->if_hwassist = CSUM_TCP;
-
- ic->ic_ifp = ifp;
+
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* Not only, but not used. */
@@ -387,7 +366,7 @@ rsu_attach(device_t self)
setbit(&bands, IEEE80211_MODE_11G);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = rsu_raw_xmit;
ic->ic_scan_start = rsu_scan_start;
ic->ic_scan_end = rsu_scan_end;
@@ -395,6 +374,8 @@ rsu_attach(device_t self)
ic->ic_vap_create = rsu_vap_create;
ic->ic_vap_delete = rsu_vap_delete;
ic->ic_update_mcast = rsu_update_mcast;
+ ic->ic_parent = rsu_parent;
+ ic->ic_transmit = rsu_transmit;
ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr,
sizeof(sc->sc_txtap), RSU_TX_RADIOTAP_PRESENT,
@@ -406,7 +387,6 @@ rsu_attach(device_t self)
return (0);
-fail_ifalloc:
fail_rom:
usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER);
fail_usb:
@@ -418,10 +398,11 @@ static int
rsu_detach(device_t self)
{
struct rsu_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
- rsu_stop(ifp, 1);
+ RSU_LOCK(sc);
+ rsu_stop(sc);
+ RSU_UNLOCK(sc);
usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER);
ieee80211_ifdetach(ic);
@@ -431,7 +412,7 @@ rsu_detach(device_t self)
rsu_free_tx_list(sc);
rsu_free_rx_list(sc);
- if_free(ifp);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -471,14 +452,11 @@ rsu_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return (NULL);
- uvp = (struct rsu_vap *) malloc(sizeof(struct rsu_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return (NULL);
+ uvp = malloc(sizeof(struct rsu_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &uvp->vap;
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags, bssid, mac) != 0) {
+ flags, bssid) != 0) {
/* out of memory */
free(uvp, M_80211_VAP);
return (NULL);
@@ -490,7 +468,7 @@ rsu_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return (vap);
@@ -508,9 +486,8 @@ rsu_vap_delete(struct ieee80211vap *vap)
static void
rsu_scan_start(struct ieee80211com *ic)
{
+ struct rsu_softc *sc = ic->ic_softc;
int error;
- struct ifnet *ifp = ic->ic_ifp;
- struct rsu_softc *sc = ifp->if_softc;
/* Scanning is done by the firmware. */
RSU_LOCK(sc);
@@ -676,11 +653,8 @@ rsu_getbuf(struct rsu_softc *sc)
RSU_ASSERT_LOCKED(sc);
bf = _rsu_getbuf(sc);
- if (bf == NULL) {
- struct ifnet *ifp = sc->sc_ifp;
+ if (bf == NULL)
DPRINTF("stop queue\n");
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- }
return (bf);
}
@@ -935,7 +909,7 @@ rsu_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct rsu_vap *uvp = RSU_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct rsu_softc *sc = ic->ic_ifp->if_softc;
+ struct rsu_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
struct ieee80211_rateset *rs;
enum ieee80211_state ostate;
@@ -1033,29 +1007,27 @@ static int
rsu_site_survey(struct rsu_softc *sc, struct ieee80211vap *vap)
{
struct r92s_fw_cmd_sitesurvey cmd;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
memset(&cmd, 0, sizeof(cmd));
- if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->scan_pass == 1)
+ if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->sc_scan_pass == 1)
cmd.active = htole32(1);
cmd.limit = htole32(48);
- if (sc->scan_pass == 1 && vap->iv_des_nssid > 0) {
+ if (sc->sc_scan_pass == 1 && vap->iv_des_nssid > 0) {
/* Do a directed scan for second pass. */
cmd.ssidlen = htole32(vap->iv_des_ssid[0].len);
memcpy(cmd.ssid, vap->iv_des_ssid[0].ssid,
vap->iv_des_ssid[0].len);
}
- DPRINTF("sending site survey command, pass=%d\n", sc->scan_pass);
+ DPRINTF("sending site survey command, pass=%d\n", sc->sc_scan_pass);
return (rsu_fw_cmd(sc, R92S_CMD_SITE_SURVEY, &cmd, sizeof(cmd)));
}
static int
rsu_join_bss(struct rsu_softc *sc, struct ieee80211_node *ni)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ndis_wlan_bssid_ex *bss;
struct ndis_802_11_fixed_ies *fixed;
@@ -1133,8 +1105,7 @@ rsu_disconnect(struct rsu_softc *sc)
static void
rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_channel *c;
struct ndis_wlan_bssid_ex *bss;
@@ -1165,7 +1136,7 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
IEEE80211_FC0_SUBTYPE_BEACON;
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
USETW(wh->i_dur, 0);
- IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
+ IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr);
IEEE80211_ADDR_COPY(wh->i_addr2, bss->macaddr);
IEEE80211_ADDR_COPY(wh->i_addr3, bss->macaddr);
*(uint16_t *)wh->i_seq = 0;
@@ -1173,7 +1144,6 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
/* Finalize mbuf. */
m->m_pkthdr.len = m->m_len = pktlen;
- m->m_pkthdr.rcvif = ifp;
/* Fix the channel. */
c = ieee80211_find_channel_byieee(ic,
le32toh(bss->config.dsconfig),
@@ -1191,8 +1161,7 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
static void
rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni = vap->iv_bss;
struct r92s_event_join_bss *rsp;
@@ -1228,8 +1197,7 @@ rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len)
static void
rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
DPRINTFN(4, "Rx event code=%d len=%d\n", code, len);
@@ -1240,18 +1208,18 @@ rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len)
break;
case R92S_EVT_SURVEY_DONE:
DPRINTF("site survey pass %d done, found %d BSS\n",
- sc->scan_pass, le32toh(*(uint32_t *)buf));
+ sc->sc_scan_pass, le32toh(*(uint32_t *)buf));
if (vap->iv_state != IEEE80211_S_SCAN)
break; /* Ignore if not scanning. */
- if (sc->scan_pass == 0 && vap->iv_des_nssid != 0) {
+ if (sc->sc_scan_pass == 0 && vap->iv_des_nssid != 0) {
/* Schedule a directed scan for hidden APs. */
- sc->scan_pass = 1;
+ sc->sc_scan_pass = 1;
RSU_UNLOCK(sc);
ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
RSU_LOCK(sc);
break;
}
- sc->scan_pass = 0;
+ sc->sc_scan_pass = 0;
break;
case R92S_EVT_JOIN_BSS:
if (vap->iv_state == IEEE80211_S_AUTH)
@@ -1274,7 +1242,7 @@ XXX and disrupts the WLAN traffic. Disable for now.
DPRINTF("WPS PBC pushed.\n");
break;
case R92S_EVT_FWDBG:
- if (ifp->if_flags & IFF_DEBUG) {
+ if (vap->iv_ifp->if_flags & IFF_DEBUG) {
buf[60] = '\0';
printf("FWDBG: %s\n", (char *)buf);
}
@@ -1341,8 +1309,7 @@ rsu_get_rssi(struct rsu_softc *sc, int rate, void *physt)
static struct mbuf *
rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct r92s_rx_stat *stat;
uint32_t rxdw0, rxdw3;
@@ -1355,11 +1322,11 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi)
rxdw3 = le32toh(stat->rxdw3);
if (__predict_false(rxdw0 & R92S_RXDW0_CRCERR)) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return NULL;
}
if (__predict_false(pktlen < sizeof(*wh) || pktlen > MCLBYTES)) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return NULL;
}
@@ -1377,11 +1344,9 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi)
m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR);
if (__predict_false(m == NULL)) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return NULL;
}
- /* Finalize mbuf. */
- m->m_pkthdr.rcvif = ifp;
/* Hardware does Rx TCP checksum offload. */
if (rxdw3 & R92S_RXDW3_TCPCHKVALID) {
if (__predict_true(rxdw3 & R92S_RXDW3_TCPCHKRPT))
@@ -1479,6 +1444,7 @@ static struct mbuf *
rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi)
{
struct rsu_softc *sc = data->sc;
+ struct ieee80211com *ic = &sc->sc_ic;
struct r92s_rx_stat *stat;
int len;
@@ -1486,7 +1452,7 @@ rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi)
if (__predict_false(len < sizeof(*stat))) {
DPRINTF("xfer too short %d\n", len);
- if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
/* Determine if it is a firmware C2H event or an 802.11 frame. */
@@ -1503,8 +1469,7 @@ static void
rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct rsu_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct mbuf *m = NULL, *next;
@@ -1564,7 +1529,7 @@ tr_setup:
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
break;
@@ -1572,35 +1537,16 @@ tr_setup:
}
-
static void
rsu_txeof(struct usb_xfer *xfer, struct rsu_data *data)
{
- struct rsu_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
-
- RSU_ASSERT_LOCKED(sc);
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
if (data->m) {
- m = data->m;
- if (m->m_flags & M_TXCB) {
- /* XXX status? */
- ieee80211_process_callback(data->ni, m, 0);
- }
- m_freem(m);
+ /* XXX status? */
+ ieee80211_tx_complete(data->ni, data->m, 0);
data->m = NULL;
- }
- if (data->ni) {
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
static void
@@ -1608,7 +1554,7 @@ rsu_bulk_tx_callback_sub(struct usb_xfer *xfer, usb_error_t error,
uint8_t which)
{
struct rsu_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
struct rsu_data *data;
RSU_ASSERT_LOCKED(sc);
@@ -1643,7 +1589,7 @@ tr_setup:
rsu_txeof(xfer, data);
STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
}
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(ic->ic_oerrors, 1);
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
@@ -1669,8 +1615,7 @@ static int
rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni,
struct mbuf *m0, struct rsu_data *data)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_frame *wh;
struct ieee80211_key *k = NULL;
@@ -1772,82 +1717,75 @@ rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni,
return (0);
}
-static void
-rsu_start(struct ifnet *ifp)
+static int
+rsu_transmit(struct ieee80211com *ic, struct mbuf *m)
{
- struct rsu_softc *sc = ifp->if_softc;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
+ struct rsu_softc *sc = ic->ic_softc;
+ int error;
RSU_LOCK(sc);
- rsu_start_locked(ifp);
+ if (!sc->sc_running) {
+ RSU_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ RSU_UNLOCK(sc);
+ return (error);
+ }
+ rsu_start(sc);
RSU_UNLOCK(sc);
+
+ return (0);
}
static void
-rsu_start_locked(struct ifnet *ifp)
+rsu_start(struct rsu_softc *sc)
{
- struct rsu_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct rsu_data *bf;
struct mbuf *m;
RSU_ASSERT_LOCKED(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
+ bf = rsu_getbuf(sc);
+ if (bf == NULL) {
+ mbufq_prepend(&sc->sc_snd, m);
break;
+ }
+
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
m->m_pkthdr.rcvif = NULL;
- bf = rsu_getbuf(sc);
- if (bf == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
- m_freem(m);
- ieee80211_free_node(ni);
- } else if (rsu_tx_start(sc, ni, m, bf) != 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if (rsu_tx_start(sc, ni, m, bf) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
ieee80211_free_node(ni);
+ break;
}
}
}
-static int
-rsu_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+rsu_parent(struct ieee80211com *ic)
{
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- rsu_init(ifp->if_softc);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rsu_stop(ifp, 1);
+ struct rsu_softc *sc = ic->ic_softc;
+ int startall = 0;
+
+ RSU_LOCK(sc);
+ if (ic->ic_nrunning > 0) {
+ if (!sc->sc_running) {
+ rsu_init(sc);
+ startall = 1;
}
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
+ } else if (sc->sc_running)
+ rsu_stop(sc);
+ RSU_UNLOCK(sc);
- return (error);
+ if (startall)
+ ieee80211_start_all(ic);
}
/*
@@ -2296,12 +2234,11 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct rsu_softc *sc = ifp->if_softc;
+ struct rsu_softc *sc = ic->ic_softc;
struct rsu_data *bf;
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!sc->sc_running) {
m_freem(m);
ieee80211_free_node(ni);
return (ENETDOWN);
@@ -2314,10 +2251,8 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
RSU_UNLOCK(sc);
return (ENOBUFS);
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
if (rsu_tx_start(sc, ni, m, bf) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
RSU_UNLOCK(sc);
return (EIO);
@@ -2328,23 +2263,17 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
}
static void
-rsu_init(void *arg)
+rsu_init(struct rsu_softc *sc)
{
- struct rsu_softc *sc = arg;
-
- RSU_LOCK(sc);
- rsu_init_locked(arg);
- RSU_UNLOCK(sc);
-}
-
-static void
-rsu_init_locked(struct rsu_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ uint8_t macaddr[IEEE80211_ADDR_LEN];
struct r92s_set_pwr_mode cmd;
int error;
int i;
+ RSU_ASSERT_LOCKED(sc);
+
/* Init host async commands ring. */
sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0;
@@ -2384,14 +2313,14 @@ rsu_init_locked(struct rsu_softc *sc)
rsu_read_1(sc, 0xfe5c) | 0x80);
/* Set MAC address. */
- rsu_write_region_1(sc, R92S_MACID, IF_LLADDR(ifp),
- IEEE80211_ADDR_LEN);
+ IEEE80211_ADDR_COPY(macaddr, vap ? vap->iv_myaddr : ic->ic_macaddr);
+ rsu_write_region_1(sc, R92S_MACID, macaddr, IEEE80211_ADDR_LEN);
/* It really takes 1.5 seconds for the firmware to boot: */
usb_pause_mtx(&sc->sc_mtx, (3 * hz) / 2);
- DPRINTF("setting MAC address to %s\n", ether_sprintf(IF_LLADDR(ifp)));
- error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, IF_LLADDR(ifp),
+ DPRINTF("setting MAC address to %s\n", ether_sprintf(macaddr));
+ error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, macaddr,
IEEE80211_ADDR_LEN);
if (error != 0) {
device_printf(sc->sc_dev, "could not set MAC address\n");
@@ -2427,12 +2356,11 @@ rsu_init_locked(struct rsu_softc *sc)
/* Set default channel. */
ic->ic_bss->ni_chan = ic->ic_ibss_chan;
#endif
- sc->scan_pass = 0;
+ sc->sc_scan_pass = 0;
usbd_transfer_start(sc->sc_xfer[RSU_BULK_RX]);
/* We're ready to go. */
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_running = 1;
return;
fail:
/* Need to stop all failed transfers, if any */
@@ -2441,22 +2369,11 @@ fail:
}
static void
-rsu_stop(struct ifnet *ifp, int disable)
-{
- struct rsu_softc *sc = ifp->if_softc;
-
- RSU_LOCK(sc);
- rsu_stop_locked(ifp, disable);
- RSU_UNLOCK(sc);
-}
-
-static void
-rsu_stop_locked(struct ifnet *ifp, int disable __unused)
+rsu_stop(struct rsu_softc *sc)
{
- struct rsu_softc *sc = ifp->if_softc;
int i;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_running = 0;
sc->sc_calibrating = 0;
taskqueue_cancel_timeout(taskqueue_thread, &sc->calib_task, NULL);
diff --git a/sys/dev/usb/wlan/if_rsureg.h b/sys/dev/usb/wlan/if_rsureg.h
index db0751d..4e6cd88 100644
--- a/sys/dev/usb/wlan/if_rsureg.h
+++ b/sys/dev/usb/wlan/if_rsureg.h
@@ -726,7 +726,8 @@ struct rsu_vap {
#define RSU_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
struct rsu_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
int (*sc_newstate)(struct ieee80211com *,
@@ -736,17 +737,17 @@ struct rsu_softc {
const uint8_t *qid2idx;
struct mtx sc_mtx;
+ u_int sc_running:1,
+ sc_calibrating:1,
+ sc_scan_pass:1;
u_int cut;
- int scan_pass;
struct rsu_host_cmd_ring cmdq;
struct rsu_data sc_rx[RSU_RX_LIST_COUNT];
struct rsu_data sc_tx[RSU_TX_LIST_COUNT];
struct rsu_data *fwcmd_data;
uint8_t cmd_seq;
uint8_t rom[128];
- uint8_t sc_bssid[IEEE80211_ADDR_LEN];
struct usb_xfer *sc_xfer[RSU_N_TRANSFER];
- uint8_t sc_calibrating;
STAILQ_HEAD(, rsu_data) sc_rx_active;
STAILQ_HEAD(, rsu_data) sc_rx_inactive;
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
index d5142ea..6a558f6 100644
--- a/sys/dev/usb/wlan/if_rum.c
+++ b/sys/dev/usb/wlan/if_rum.c
@@ -175,8 +175,9 @@ static int rum_tx_raw(struct rum_softc *, struct mbuf *,
const struct ieee80211_bpf_params *);
static int rum_tx_data(struct rum_softc *, struct mbuf *,
struct ieee80211_node *);
-static void rum_start(struct ifnet *);
-static int rum_ioctl(struct ifnet *, u_long, caddr_t);
+static int rum_transmit(struct ieee80211com *, struct mbuf *);
+static void rum_start(struct rum_softc *);
+static void rum_parent(struct ieee80211com *);
static void rum_eeprom_read(struct rum_softc *, uint16_t, void *,
int);
static uint32_t rum_read(struct rum_softc *, uint16_t);
@@ -198,7 +199,7 @@ static void rum_set_chan(struct rum_softc *,
struct ieee80211_channel *);
static void rum_enable_tsf_sync(struct rum_softc *);
static void rum_enable_tsf(struct rum_softc *);
-static void rum_update_slot(struct ifnet *);
+static void rum_update_slot(struct rum_softc *);
static void rum_set_bssid(struct rum_softc *, const uint8_t *);
static void rum_set_macaddr(struct rum_softc *, const uint8_t *);
static void rum_update_mcast(struct ieee80211com *);
@@ -207,8 +208,7 @@ static void rum_setpromisc(struct rum_softc *);
static const char *rum_get_rf(int);
static void rum_read_eeprom(struct rum_softc *);
static int rum_bbp_init(struct rum_softc *);
-static void rum_init_locked(struct rum_softc *);
-static void rum_init(void *);
+static void rum_init(struct rum_softc *);
static void rum_stop(struct rum_softc *);
static void rum_load_microcode(struct rum_softc *, const uint8_t *,
size_t);
@@ -425,8 +425,7 @@ rum_attach(device_t self)
{
struct usb_attach_arg *uaa = device_get_ivars(self);
struct rum_softc *sc = device_get_softc(self);
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t iface_index, bands;
uint32_t tmp;
int error, ntries;
@@ -437,6 +436,7 @@ rum_attach(device_t self)
mtx_init(&sc->sc_mtx, device_get_nameunit(self),
MTX_NETWORK_LOCK, MTX_DEF);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
iface_index = RT2573_IFACE_INDEX;
error = usbd_transfer_setup(uaa->device, &iface_index,
@@ -470,24 +470,6 @@ rum_attach(device_t self)
rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode));
RUM_UNLOCK(sc);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto detach;
- }
- ic = ifp->if_l2com;
-
- ifp->if_softc = sc;
- if_initname(ifp, "rum", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = rum_init;
- ifp->if_ioctl = rum_ioctl;
- ifp->if_start = rum_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -512,13 +494,14 @@ rum_attach(device_t self)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_update_promisc = rum_update_promisc;
ic->ic_raw_xmit = rum_raw_xmit;
ic->ic_scan_start = rum_scan_start;
ic->ic_scan_end = rum_scan_end;
ic->ic_set_channel = rum_set_channel;
-
+ ic->ic_transmit = rum_transmit;
+ ic->ic_parent = rum_parent;
ic->ic_vap_create = rum_vap_create;
ic->ic_vap_delete = rum_vap_delete;
ic->ic_update_mcast = rum_update_mcast;
@@ -543,8 +526,6 @@ static int
rum_detach(device_t self)
{
struct rum_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
/* Prevent further ioctls */
RUM_LOCK(sc);
@@ -559,11 +540,9 @@ rum_detach(device_t self)
rum_unsetup_tx_list(sc);
RUM_UNLOCK(sc);
- if (ifp) {
- ic = ifp->if_l2com;
- ieee80211_ifdetach(ic);
- if_free(ifp);
- }
+ if (sc->sc_ic.ic_softc == sc)
+ ieee80211_ifdetach(&sc->sc_ic);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
}
@@ -595,21 +574,18 @@ rum_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct rum_softc *sc = ic->ic_ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
struct rum_vap *rvp;
struct ieee80211vap *vap;
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return NULL;
- rvp = (struct rum_vap *) malloc(sizeof(struct rum_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (rvp == NULL)
- return NULL;
+ rvp = malloc(sizeof(struct rum_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &rvp->vap;
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(rvp, M_80211_VAP);
return (NULL);
@@ -624,7 +600,8 @@ rum_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_init(vap);
ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, ieee80211_media_change,
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -648,13 +625,8 @@ rum_tx_free(struct rum_tx_data *data, int txerr)
struct rum_softc *sc = data->sc;
if (data->m != NULL) {
- if (data->m->m_flags & M_TXCB)
- ieee80211_process_callback(data->ni, data->m,
- txerr ? ETIMEDOUT : 0);
- m_freem(data->m);
+ ieee80211_tx_complete(data->ni, data->m, txerr);
data->m = NULL;
-
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
@@ -711,7 +683,7 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct rum_vap *rvp = RUM_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct rum_softc *sc = ic->ic_ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
const struct ieee80211_txparam *tp;
enum ieee80211_state ostate;
struct ieee80211_node *ni;
@@ -745,12 +717,12 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
ieee80211_free_node(ni);
return (-1);
}
- rum_update_slot(ic->ic_ifp);
+ rum_update_slot(sc);
rum_enable_mrr(sc);
rum_set_txpreamble(sc);
rum_set_basicrates(sc);
- IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
- rum_set_bssid(sc, sc->sc_bssid);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid);
+ rum_set_bssid(sc, ic->ic_macaddr);
}
if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
@@ -780,7 +752,6 @@ static void
rum_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct rum_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211vap *vap;
struct rum_tx_data *data;
struct mbuf *m;
@@ -799,9 +770,6 @@ rum_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
rum_tx_free(data, 0);
usbd_xfer_set_priv(xfer, NULL);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
/* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
@@ -844,16 +812,14 @@ tr_setup:
usbd_transfer_submit(xfer);
}
- RUM_UNLOCK(sc);
- rum_start(ifp);
- RUM_LOCK(sc);
+ rum_start(sc);
break;
default: /* Error */
DPRINTFN(11, "transfer error, %s\n",
usbd_errstr(error));
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
data = usbd_xfer_get_priv(xfer);
if (data != NULL) {
rum_tx_free(data, error);
@@ -880,8 +846,7 @@ static void
rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct rum_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
struct mbuf *m = NULL;
struct usb_page_cache *pc;
@@ -899,7 +864,7 @@ rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
if (len < (int)(RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN)) {
DPRINTF("%s: xfer too short %d\n",
device_get_nameunit(sc->sc_dev), len);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
@@ -916,21 +881,20 @@ rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
* filled RUM_TXRX_CSR2:
*/
DPRINTFN(5, "PHY or CRC error\n");
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (m == NULL) {
DPRINTF("could not allocate mbuf\n");
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
usbd_copy_out(pc, RT2573_RX_DESC_SIZE,
mtod(m, uint8_t *), len);
/* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
if (ieee80211_radiotap_active(ic)) {
@@ -968,10 +932,8 @@ tr_setup:
(void) ieee80211_input_all(ic, m, rssi,
RT2573_NOISE_FLOOR);
}
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
- rum_start(ifp);
RUM_LOCK(sc);
+ rum_start(sc);
return;
default: /* Error */
@@ -1011,8 +973,7 @@ static void
rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
uint32_t flags, uint16_t xflags, int len, int rate)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t plcp_length;
int remainder;
@@ -1109,8 +1070,7 @@ static int
rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct rum_tx_data *data;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
@@ -1221,8 +1181,7 @@ static int
rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct rum_tx_data *data;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
@@ -1299,80 +1258,73 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
return 0;
}
+static int
+rum_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct rum_softc *sc = ic->ic_softc;
+ int error;
+
+ RUM_LOCK(sc);
+ if (!sc->sc_running) {
+ RUM_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ RUM_UNLOCK(sc);
+ return (error);
+ }
+ rum_start(sc);
+ RUM_UNLOCK(sc);
+
+ return (0);
+}
+
static void
-rum_start(struct ifnet *ifp)
+rum_start(struct rum_softc *sc)
{
- struct rum_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
- RUM_LOCK(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- RUM_UNLOCK(sc);
+ RUM_LOCK_ASSERT(sc, MA_OWNED);
+
+ if (!sc->sc_running)
return;
- }
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->tx_nfree < RUM_TX_MINFREE) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
+
+ while (sc->tx_nfree >= RUM_TX_MINFREE &&
+ (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
if (rum_tx_data(sc, m, ni) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
break;
}
}
- RUM_UNLOCK(sc);
}
-static int
-rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+rum_parent(struct ieee80211com *ic)
{
- struct rum_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error;
+ struct rum_softc *sc = ic->ic_softc;
int startall = 0;
RUM_LOCK(sc);
- error = sc->sc_detached ? ENXIO : 0;
- RUM_UNLOCK(sc);
- if (error)
- return (error);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- RUM_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- rum_init_locked(sc);
- startall = 1;
- } else
- rum_setpromisc(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rum_stop(sc);
- }
+ if (sc->sc_detached) {
RUM_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
+ return;
}
- return error;
+ if (ic->ic_nrunning > 0) {
+ if (!sc->sc_running) {
+ rum_init(sc);
+ startall = 1;
+ } else
+ rum_setpromisc(sc);
+ } else if (sc->sc_running)
+ rum_stop(sc);
+ RUM_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
@@ -1572,8 +1524,7 @@ rum_select_antenna(struct rum_softc *sc)
static void
rum_enable_mrr(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
tmp = rum_read(sc, RT2573_TXRX_CSR4);
@@ -1589,8 +1540,7 @@ rum_enable_mrr(struct rum_softc *sc)
static void
rum_set_txpreamble(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
tmp = rum_read(sc, RT2573_TXRX_CSR4);
@@ -1605,8 +1555,7 @@ rum_set_txpreamble(struct rum_softc *sc)
static void
rum_set_basicrates(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
/* update basic rate set */
if (ic->ic_curmode == IEEE80211_MODE_11B) {
@@ -1671,8 +1620,7 @@ rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
static void
rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
const struct rfprog *rfprog;
uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT;
int8_t power;
@@ -1748,8 +1696,7 @@ rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
static void
rum_enable_tsf_sync(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
@@ -1784,10 +1731,9 @@ rum_enable_tsf(struct rum_softc *sc)
}
static void
-rum_update_slot(struct ifnet *ifp)
+rum_update_slot(struct rum_softc *sc)
{
- struct rum_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t slottime;
uint32_t tmp;
@@ -1827,18 +1773,17 @@ rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
static void
rum_setpromisc(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
tmp = rum_read(sc, RT2573_TXRX_CSR0);
tmp &= ~RT2573_DROP_NOT_TO_ME;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (sc->sc_ic.ic_promisc == 0)
tmp |= RT2573_DROP_NOT_TO_ME;
rum_write(sc, RT2573_TXRX_CSR0, tmp);
- DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
+ DPRINTF("%s promiscuous mode\n", sc->sc_ic.ic_promisc > 0 ?
"entering" : "leaving");
}
@@ -1847,10 +1792,11 @@ rum_update_promisc(struct ieee80211com *ic)
{
struct rum_softc *sc = ic->ic_softc;
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
RUM_LOCK(sc);
+ if (!sc->sc_running) {
+ RUM_UNLOCK(sc);
+ return;
+ }
rum_setpromisc(sc);
RUM_UNLOCK(sc);
}
@@ -1887,7 +1833,7 @@ rum_read_eeprom(struct rum_softc *sc)
#endif
/* read MAC address */
- rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_bssid, 6);
+ rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_ic.ic_macaddr, 6);
rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2);
val = le16toh(val);
@@ -1994,10 +1940,10 @@ rum_bbp_init(struct rum_softc *sc)
}
static void
-rum_init_locked(struct rum_softc *sc)
+rum_init(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
usb_error_t error;
int i, ntries;
@@ -2039,7 +1985,7 @@ rum_init_locked(struct rum_softc *sc)
/* clear STA registers */
rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
- rum_set_macaddr(sc, IF_LLADDR(ifp));
+ rum_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
/* initialize ASIC */
rum_write(sc, RT2573_MAC_CSR1, 4);
@@ -2058,13 +2004,12 @@ rum_init_locked(struct rum_softc *sc)
RT2573_DROP_ACKCTS;
if (ic->ic_opmode != IEEE80211_M_HOSTAP)
tmp |= RT2573_DROP_TODS;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (ic->ic_promisc == 0)
tmp |= RT2573_DROP_NOT_TO_ME;
}
rum_write(sc, RT2573_TXRX_CSR0, tmp);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_running = 1;
usbd_xfer_set_stall(sc->sc_xfer[RUM_BULK_WR]);
usbd_transfer_start(sc->sc_xfer[RUM_BULK_RD]);
return;
@@ -2074,29 +2019,13 @@ fail: rum_stop(sc);
}
static void
-rum_init(void *priv)
-{
- struct rum_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- RUM_LOCK(sc);
- rum_init_locked(sc);
- RUM_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
rum_stop(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
RUM_LOCK_ASSERT(sc, MA_OWNED);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_running = 0;
RUM_UNLOCK(sc);
@@ -2188,27 +2117,23 @@ static int
rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
- struct ifnet *ifp = ni->ni_ic->ic_ifp;
- struct rum_softc *sc = ifp->if_softc;
+ struct rum_softc *sc = ni->ni_ic->ic_softc;
RUM_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!sc->sc_running) {
RUM_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return ENETDOWN;
}
if (sc->tx_nfree < RUM_TX_MINFREE) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
RUM_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return EIO;
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
if (params == NULL) {
/*
* Legacy path; interpret frame contents to decide
@@ -2228,7 +2153,6 @@ rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
bad:
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
RUM_UNLOCK(sc);
ieee80211_free_node(ni);
return EIO;
@@ -2262,8 +2186,7 @@ rum_ratectl_task(void *arg, int pending)
struct rum_vap *rvp = arg;
struct ieee80211vap *vap = &rvp->vap;
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct rum_softc *sc = ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
int ok, fail;
int sum, retrycnt;
@@ -2283,7 +2206,8 @@ rum_ratectl_task(void *arg, int pending)
(void) ieee80211_ratectl_rate(ni, NULL, 0);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, fail); /* count TX retry-fail as Tx errors */
+ /* count TX retry-fail as Tx errors */
+ if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, fail);
usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp);
RUM_UNLOCK(sc);
@@ -2292,15 +2216,14 @@ rum_ratectl_task(void *arg, int pending)
static void
rum_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct rum_softc *sc = ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
uint32_t tmp;
RUM_LOCK(sc);
/* abort TSF synchronization */
tmp = rum_read(sc, RT2573_TXRX_CSR9);
rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
- rum_set_bssid(sc, ifp->if_broadcastaddr);
+ rum_set_bssid(sc, ieee80211broadcastaddr);
RUM_UNLOCK(sc);
}
@@ -2308,11 +2231,11 @@ rum_scan_start(struct ieee80211com *ic)
static void
rum_scan_end(struct ieee80211com *ic)
{
- struct rum_softc *sc = ic->ic_ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
RUM_LOCK(sc);
rum_enable_tsf_sync(sc);
- rum_set_bssid(sc, sc->sc_bssid);
+ rum_set_bssid(sc, ic->ic_macaddr);
RUM_UNLOCK(sc);
}
@@ -2320,7 +2243,7 @@ rum_scan_end(struct ieee80211com *ic)
static void
rum_set_channel(struct ieee80211com *ic)
{
- struct rum_softc *sc = ic->ic_ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
RUM_LOCK(sc);
rum_set_chan(sc, ic->ic_curchan);
@@ -2330,8 +2253,7 @@ rum_set_channel(struct ieee80211com *ic)
static int
rum_get_rssi(struct rum_softc *sc, uint8_t raw)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
int lna, agc, rssi;
lna = (raw >> 5) & 0x3;
diff --git a/sys/dev/usb/wlan/if_rumvar.h b/sys/dev/usb/wlan/if_rumvar.h
index 17944aa..35da6d3 100644
--- a/sys/dev/usb/wlan/if_rumvar.h
+++ b/sys/dev/usb/wlan/if_rumvar.h
@@ -85,7 +85,8 @@ enum {
};
struct rum_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
@@ -105,8 +106,8 @@ struct rum_softc {
uint32_t sta[6];
uint32_t rf_regs[4];
uint8_t txpow[44];
- uint8_t sc_bssid[6];
- uint8_t sc_detached;
+ u_int sc_detached:1,
+ sc_running:1;
struct {
uint8_t val;
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index ac14178..193b9ad 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -410,8 +410,9 @@ static int run_tx_param(struct run_softc *, struct mbuf *,
const struct ieee80211_bpf_params *);
static int run_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void run_start(struct ifnet *);
-static int run_ioctl(struct ifnet *, u_long, caddr_t);
+static int run_transmit(struct ieee80211com *, struct mbuf *);
+static void run_start(struct run_softc *);
+static void run_parent(struct ieee80211com *);
static void run_iq_calib(struct run_softc *, u_int);
static void run_set_agc(struct run_softc *, uint8_t);
static void run_select_chan_group(struct run_softc *, int);
@@ -457,7 +458,6 @@ static void run_rt3593_rf_setup(struct run_softc *);
static void run_rt5390_rf_setup(struct run_softc *);
static int run_txrx_enable(struct run_softc *);
static void run_adjust_freq_offset(struct run_softc *);
-static void run_init(void *);
static void run_init_locked(struct run_softc *);
static void run_stop(void *);
static void run_delay(struct run_softc *, u_int);
@@ -702,8 +702,7 @@ run_attach(device_t self)
{
struct run_softc *sc = device_get_softc(self);
struct usb_attach_arg *uaa = device_get_ivars(self);
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t ver;
int ntries, error;
uint8_t iface_index, bands;
@@ -716,6 +715,7 @@ run_attach(device_t self)
mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev),
MTX_NETWORK_LOCK, MTX_DEF);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
iface_index = RT2860_IFACE_INDEX;
@@ -754,28 +754,10 @@ run_attach(device_t self)
device_printf(sc->sc_dev,
"MAC/BBP RT%04X (rev 0x%04X), RF %s (MIMO %dT%dR), address %s\n",
sc->mac_ver, sc->mac_rev, run_get_rf(sc->rf_rev),
- sc->ntxchains, sc->nrxchains, ether_sprintf(sc->sc_bssid));
+ sc->ntxchains, sc->nrxchains, ether_sprintf(ic->ic_macaddr));
RUN_UNLOCK(sc);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto detach;
- }
- ic = ifp->if_l2com;
-
- ifp->if_softc = sc;
- if_initname(ifp, "run", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = run_init;
- ifp->if_ioctl = run_ioctl;
- ifp->if_start = run_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -812,7 +794,7 @@ run_attach(device_t self)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_scan_start = run_scan_start;
ic->ic_scan_end = run_scan_end;
@@ -824,9 +806,10 @@ run_attach(device_t self)
ic->ic_wme.wme_update = run_wme_update;
ic->ic_raw_xmit = run_raw_xmit;
ic->ic_update_promisc = run_update_promisc;
-
ic->ic_vap_create = run_vap_create;
ic->ic_vap_delete = run_vap_delete;
+ ic->ic_transmit = run_transmit;
+ ic->ic_parent = run_parent;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -852,8 +835,7 @@ static int
run_detach(device_t self)
{
struct run_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
int i;
RUN_LOCK(sc);
@@ -872,16 +854,15 @@ run_detach(device_t self)
run_unsetup_tx_list(sc, &sc->sc_epq[i]);
RUN_UNLOCK(sc);
- if (ifp) {
- ic = ifp->if_l2com;
+ if (sc->sc_ic.ic_softc == sc) {
/* drain tasks */
usb_callout_drain(&sc->ratectl_ch);
ieee80211_draintask(ic, &sc->cmdq_task);
ieee80211_draintask(ic, &sc->ratectl_task);
ieee80211_ifdetach(ic);
- if_free(ifp);
}
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -893,14 +874,13 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct ifnet *ifp = ic->ic_ifp;
- struct run_softc *sc = ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct run_vap *rvp;
struct ieee80211vap *vap;
int i;
if (sc->rvp_cnt >= RUN_VAP_MAX) {
- if_printf(ifp, "number of VAPs maxed out\n");
+ device_printf(sc->sc_dev, "number of VAPs maxed out\n");
return (NULL);
}
@@ -926,23 +906,21 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
break;
}
if (vap == NULL) {
- if_printf(ifp, "wds only supported in ap mode\n");
+ device_printf(sc->sc_dev,
+ "wds only supported in ap mode\n");
return (NULL);
}
break;
default:
- if_printf(ifp, "unknown opmode %d\n", opmode);
+ device_printf(sc->sc_dev, "unknown opmode %d\n", opmode);
return (NULL);
}
- rvp = (struct run_vap *) malloc(sizeof(struct run_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (rvp == NULL)
- return (NULL);
+ rvp = malloc(sizeof(struct run_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &rvp->vap;
- if (ieee80211_vap_setup(ic, vap, name, unit,
- opmode, flags, bssid, mac) != 0) {
+ if (ieee80211_vap_setup(ic, vap, name, unit, opmode, flags,
+ bssid) != 0) {
/* out of memory */
free(rvp, M_80211_VAP);
return (NULL);
@@ -969,7 +947,8 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
- ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status,
+ mac);
/* make sure id is always unique */
for (i = 0; i < RUN_VAP_MAX; i++) {
@@ -995,7 +974,6 @@ static void
run_vap_delete(struct ieee80211vap *vap)
{
struct run_vap *rvp = RUN_VAP(vap);
- struct ifnet *ifp;
struct ieee80211com *ic;
struct run_softc *sc;
uint8_t rvp_id;
@@ -1004,9 +982,7 @@ run_vap_delete(struct ieee80211vap *vap)
return;
ic = vap->iv_ic;
- ifp = ic->ic_ifp;
-
- sc = ifp->if_softc;
+ sc = ic->ic_softc;
RUN_LOCK(sc);
@@ -1740,6 +1716,7 @@ run_get_txpower(struct run_softc *sc)
static int
run_read_eeprom(struct run_softc *sc)
{
+ struct ieee80211com *ic = &sc->sc_ic;
int8_t delta_2ghz, delta_5ghz;
uint32_t tmp;
uint16_t val;
@@ -1760,14 +1737,14 @@ run_read_eeprom(struct run_softc *sc)
/* read MAC address */
run_srom_read(sc, RT2860_EEPROM_MAC01, &val);
- sc->sc_bssid[0] = val & 0xff;
- sc->sc_bssid[1] = val >> 8;
+ ic->ic_macaddr[0] = val & 0xff;
+ ic->ic_macaddr[1] = val >> 8;
run_srom_read(sc, RT2860_EEPROM_MAC23, &val);
- sc->sc_bssid[2] = val & 0xff;
- sc->sc_bssid[3] = val >> 8;
+ ic->ic_macaddr[2] = val & 0xff;
+ ic->ic_macaddr[3] = val >> 8;
run_srom_read(sc, RT2860_EEPROM_MAC45, &val);
- sc->sc_bssid[4] = val & 0xff;
- sc->sc_bssid[5] = val >> 8;
+ ic->ic_macaddr[4] = val & 0xff;
+ ic->ic_macaddr[5] = val >> 8;
if (sc->mac_ver < 0x3593) {
/* read vender BBP settings */
@@ -2002,7 +1979,7 @@ run_media_change(struct ifnet *ifp)
struct ieee80211vap *vap = ifp->if_softc;
struct ieee80211com *ic = vap->iv_ic;
const struct ieee80211_txparam *tp;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
uint8_t rate, ridx;
int error;
@@ -2033,7 +2010,7 @@ run_media_change(struct ifnet *ifp)
#if 0
if ((ifp->if_flags & IFF_UP) &&
- (ifp->if_drv_flags & IFF_DRV_RUNNING)){
+ (ifp->if_drv_flags & RUN_RUNNING)){
run_init_locked(sc);
}
#endif
@@ -2048,7 +2025,7 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
const struct ieee80211_txparam *tp;
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct run_vap *rvp = RUN_VAP(vap);
enum ieee80211_state ostate;
uint32_t sta[3];
@@ -2144,7 +2121,7 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
run_set_txpreamble(sc);
run_set_basicrates(sc);
ni = ieee80211_ref_node(vap->iv_bss);
- IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid);
run_set_bssid(sc, ni->ni_bssid);
ieee80211_free_node(ni);
run_enable_tsf_sync(sc);
@@ -2181,7 +2158,7 @@ static void
run_wme_update_cb(void *arg)
{
struct ieee80211com *ic = arg;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct ieee80211_wme_state *wmesp = &ic->ic_wme;
int aci, error = 0;
@@ -2234,7 +2211,7 @@ err:
static int
run_wme_update(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
/* sometime called wothout lock */
if (mtx_owned(&ic->ic_comlock.mtx)) {
@@ -2277,7 +2254,7 @@ run_key_set_cb(void *arg)
struct ieee80211vap *vap = cmdq->arg1;
struct ieee80211_key *k = cmdq->k;
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
uint32_t attr;
uint16_t base, associd;
@@ -2399,7 +2376,7 @@ run_key_set(struct ieee80211vap *vap, struct ieee80211_key *k,
const uint8_t mac[IEEE80211_ADDR_LEN])
{
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
uint32_t i;
i = RUN_CMDQ_GET(&sc->cmdq_store);
@@ -2467,7 +2444,7 @@ static int
run_key_delete(struct ieee80211vap *vap, struct ieee80211_key *k)
{
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct ieee80211_key *k0;
uint32_t i;
@@ -2498,7 +2475,7 @@ run_ratectl_to(void *arg)
struct run_softc *sc = arg;
/* do it in a process context, so it can go sleep */
- ieee80211_runtask(sc->sc_ifp->if_l2com, &sc->ratectl_task);
+ ieee80211_runtask(&sc->sc_ic, &sc->ratectl_task);
/* next timeout will be rescheduled in the callback task */
}
@@ -2507,7 +2484,7 @@ static void
run_ratectl_cb(void *arg, int pending)
{
struct run_softc *sc = arg;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
if (vap == NULL)
@@ -2540,7 +2517,6 @@ static void
run_drain_fifo(void *arg)
{
struct run_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
uint32_t stat;
uint16_t (*wstat)[3];
uint8_t wcid, mcs, pid;
@@ -2577,7 +2553,7 @@ run_drain_fifo(void *arg)
if (stat & RT2860_TXQ_OK)
(*wstat)[RUN_SUCCESS]++;
else
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
/*
* Check if there were retries, ie if the Tx success rate is
* different from the requested rate. Note that it works only
@@ -2600,8 +2576,6 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
{
struct run_softc *sc = arg;
struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
struct run_node *rn = (void *)ni;
union run_stats sta[2];
uint16_t (*wstat)[3];
@@ -2623,7 +2597,8 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
goto fail;
/* count failed TX as errors */
- if_inc_counter(ifp, IFCOUNTER_OERRORS, le16toh(sta[0].error.fail));
+ if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS,
+ le16toh(sta[0].error.fail));
retrycnt = le16toh(sta[1].tx.retry);
success = le16toh(sta[1].tx.success);
@@ -2661,7 +2636,7 @@ run_newassoc_cb(void *arg)
{
struct run_cmdq *cmdq = arg;
struct ieee80211_node *ni = cmdq->arg1;
- struct run_softc *sc = ni->ni_vap->iv_ic->ic_ifp->if_softc;
+ struct run_softc *sc = ni->ni_vap->iv_ic->ic_softc;
uint8_t wcid = cmdq->wcid;
RUN_LOCK_ASSERT(sc, MA_OWNED);
@@ -2679,7 +2654,7 @@ run_newassoc(struct ieee80211_node *ni, int isnew)
struct ieee80211_rateset *rs = &ni->ni_rates;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
uint8_t rate;
uint8_t ridx;
uint8_t wcid;
@@ -2769,8 +2744,7 @@ run_maxrssi_chain(struct run_softc *sc, const struct rt2860_rxwi *rxwi)
static void
run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct rt2870_rxd *rxd;
@@ -2789,7 +2763,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
rxwisize += sizeof(uint32_t);
if (__predict_false(len > dmalen)) {
m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
DPRINTF("bad RXWI length %u > %u\n", len, dmalen);
return;
}
@@ -2799,7 +2773,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
if (__predict_false(flags & (RT2860_RX_CRCERR | RT2860_RX_ICVERR))) {
m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
DPRINTF("%s error.\n", (flags & RT2860_RX_CRCERR)?"CRC":"ICV");
return;
}
@@ -2828,7 +2802,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
ieee80211_notify_michael_failure(ni->ni_vap, wh,
rxwi->keyidx);
m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
DPRINTF("MIC error. Someone is lying.\n");
return;
}
@@ -2837,7 +2811,6 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
rssi = rxwi->rssi[ant];
nf = run_rssi2dbm(sc, rssi, ant);
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = len;
if (ni != NULL) {
@@ -2890,7 +2863,7 @@ static void
run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct run_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
struct mbuf *m = NULL;
struct mbuf *m0;
uint32_t dmalen;
@@ -2928,7 +2901,7 @@ tr_setup:
}
if (sc->rx_m == NULL) {
DPRINTF("could not allocate mbuf - idle with stall\n");
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
usbd_xfer_set_stall(xfer);
usbd_xfer_set_frames(xfer, 0);
} else {
@@ -2948,12 +2921,9 @@ tr_setup:
if (error != USB_ERR_CANCELLED) {
/* try to clear stall first */
usbd_xfer_set_stall(xfer);
-
if (error == USB_ERR_TIMEOUT)
device_printf(sc->sc_dev, "device timeout\n");
-
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
-
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
if (sc->rx_m != NULL) {
@@ -3001,7 +2971,7 @@ tr_setup:
m0 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (__predict_false(m0 == NULL)) {
DPRINTF("could not allocate mbuf\n");
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
break;
}
m_copydata(m, 4 /* skip 32-bit DMA-len header */,
@@ -3048,8 +3018,7 @@ static void
run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index)
{
struct run_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct run_tx_data *data;
struct ieee80211vap *vap = NULL;
struct usb_page_cache *pc;
@@ -3067,14 +3036,9 @@ run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index)
"bytes @ index %d\n", actlen, index);
data = usbd_xfer_get_priv(xfer);
-
run_tx_free(pq, data, 0);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
usbd_xfer_set_priv(xfer, NULL);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
/* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
@@ -3091,11 +3055,7 @@ tr_setup:
size + 3 + 8) > RUN_MAX_TXSZ) {
DPRINTF("data overflow, %u bytes\n",
m->m_pkthdr.len);
-
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
-
run_tx_free(pq, data, 1);
-
goto tr_setup;
}
@@ -3132,12 +3092,8 @@ tr_setup:
usbd_xfer_set_frame_len(xfer, 0, size);
usbd_xfer_set_priv(xfer, data);
-
usbd_transfer_submit(xfer);
-
- RUN_UNLOCK(sc);
- run_start(ifp);
- RUN_LOCK(sc);
+ run_start(sc);
break;
@@ -3147,14 +3103,13 @@ tr_setup:
data = usbd_xfer_get_priv(xfer);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
-
if (data != NULL) {
if(data->ni != NULL)
vap = data->ni->ni_vap;
run_tx_free(pq, data, error);
usbd_xfer_set_priv(xfer, NULL);
}
+
if (vap == NULL)
vap = TAILQ_FIRST(&ic->ic_vaps);
@@ -3220,7 +3175,7 @@ static void
run_set_tx_desc(struct run_softc *sc, struct run_tx_data *data)
{
struct mbuf *m = data->m;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = data->ni->ni_vap;
struct ieee80211_frame *wh;
struct rt2870_txd *txd;
@@ -3283,7 +3238,7 @@ run_set_tx_desc(struct run_softc *sc, struct run_tx_data *data)
static int
run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_frame *wh;
struct ieee80211_channel *chan;
@@ -3451,8 +3406,7 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
static int
run_tx_mgt(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct run_node *rn = (void *)ni;
struct run_tx_data *data;
struct ieee80211_frame *wh;
@@ -3483,11 +3437,9 @@ run_tx_mgt(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
USETW(wh->i_dur, dur);
}
- if (sc->sc_epq[0].tx_nfree == 0) {
+ if (sc->sc_epq[0].tx_nfree == 0)
/* let caller free mbuf */
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
return (EIO);
- }
data = STAILQ_FIRST(&sc->sc_epq[0].tx_fh);
STAILQ_REMOVE_HEAD(&sc->sc_epq[0].tx_fh, next);
sc->sc_epq[0].tx_nfree--;
@@ -3555,11 +3507,9 @@ run_sendprot(struct run_softc *sc,
wflags = RT2860_TX_FRAG;
/* check that there are free slots before allocating the mbuf */
- if (sc->sc_epq[0].tx_nfree == 0) {
+ if (sc->sc_epq[0].tx_nfree == 0)
/* let caller free mbuf */
- sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE;
return (ENOBUFS);
- }
if (prot == IEEE80211_PROT_RTSCTS) {
/* NB: CTS is the same size as an ACK */
@@ -3570,7 +3520,7 @@ run_sendprot(struct run_softc *sc,
mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
}
if (mprot == NULL) {
- if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
DPRINTF("could not allocate mbuf\n");
return (ENOBUFS);
}
@@ -3652,7 +3602,6 @@ run_tx_param(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
if (sc->sc_epq[0].tx_nfree == 0) {
/* let caller free mbuf */
- sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE;
DPRINTF("sending raw frame, but tx ring is full\n");
return (EIO);
}
@@ -3691,36 +3640,31 @@ static int
run_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
- struct ifnet *ifp = ni->ni_ic->ic_ifp;
- struct run_softc *sc = ifp->if_softc;
+ struct run_softc *sc = ni->ni_ic->ic_softc;
int error = 0;
RUN_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- error = ENETDOWN;
+ if (!(sc->sc_flags & RUN_RUNNING)) {
+ error = ENETDOWN;
goto done;
}
if (params == NULL) {
/* tx mgt packet */
if ((error = run_tx_mgt(sc, m, ni)) != 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
DPRINTF("mgt tx failed\n");
goto done;
}
} else {
/* tx raw packet with param */
if ((error = run_tx_param(sc, m, ni, params)) != 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
DPRINTF("tx with param failed\n");
goto done;
}
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
done:
RUN_UNLOCK(sc);
@@ -3733,83 +3677,71 @@ done:
return (error);
}
+static int
+run_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct run_softc *sc = ic->ic_softc;
+ int error;
+
+ RUN_LOCK(sc);
+ if ((sc->sc_flags & RUN_RUNNING) == 0) {
+ RUN_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ RUN_UNLOCK(sc);
+ return (error);
+ }
+ run_start(sc);
+ RUN_UNLOCK(sc);
+
+ return (0);
+}
+
static void
-run_start(struct ifnet *ifp)
+run_start(struct run_softc *sc)
{
- struct run_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
- RUN_LOCK(sc);
+ RUN_LOCK_ASSERT(sc, MA_OWNED);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- RUN_UNLOCK(sc);
+ if ((sc->sc_flags & RUN_RUNNING) == 0)
return;
- }
-
- for (;;) {
- /* send data frames */
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
if (run_tx(sc, m, ni) != 0) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ mbufq_prepend(&sc->sc_snd, m);
break;
}
}
-
- RUN_UNLOCK(sc);
}
-static int
-run_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+run_parent(struct ieee80211com *ic)
{
- struct run_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
+ struct run_softc *sc = ic->ic_softc;
int startall = 0;
- int error;
RUN_LOCK(sc);
- error = sc->sc_detached ? ENXIO : 0;
- RUN_UNLOCK(sc);
- if (error)
- return (error);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- RUN_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)){
- startall = 1;
- run_init_locked(sc);
- } else
- run_update_promisc_locked(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- (ic->ic_nrunning == 0 || sc->rvp_cnt <= 1)) {
- run_stop(sc);
- }
- }
+ if (sc->sc_detached) {
RUN_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
+ return;
}
- return (error);
+ if (ic->ic_nrunning > 0) {
+ if (!(sc->sc_flags & RUN_RUNNING)) {
+ startall = 1;
+ run_init_locked(sc);
+ } else
+ run_update_promisc_locked(sc);
+ } else if ((sc->sc_flags & RUN_RUNNING) && sc->rvp_cnt <= 1)
+ run_stop(sc);
+ RUN_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
@@ -4796,7 +4728,7 @@ run_set_rx_antenna(struct run_softc *sc, int aux)
static int
run_set_chan(struct run_softc *sc, struct ieee80211_channel *c)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
u_int chan, group;
chan = ieee80211_chan2ieee(ic, c);
@@ -4841,7 +4773,7 @@ run_set_chan(struct run_softc *sc, struct ieee80211_channel *c)
static void
run_set_channel(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
RUN_LOCK(sc);
run_set_chan(sc, ic->ic_curchan);
@@ -4853,7 +4785,7 @@ run_set_channel(struct ieee80211com *ic)
static void
run_scan_start(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
uint32_t tmp;
RUN_LOCK(sc);
@@ -4863,7 +4795,7 @@ run_scan_start(struct ieee80211com *ic)
run_write(sc, RT2860_BCN_TIME_CFG,
tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN |
RT2860_TBTT_TIMER_EN));
- run_set_bssid(sc, sc->sc_ifp->if_broadcastaddr);
+ run_set_bssid(sc, ieee80211broadcastaddr);
RUN_UNLOCK(sc);
@@ -4873,13 +4805,13 @@ run_scan_start(struct ieee80211com *ic)
static void
run_scan_end(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
RUN_LOCK(sc);
run_enable_tsf_sync(sc);
/* XXX keep local copy */
- run_set_bssid(sc, sc->sc_bssid);
+ run_set_bssid(sc, ic->ic_macaddr);
RUN_UNLOCK(sc);
@@ -4894,7 +4826,7 @@ static void
run_update_beacon(struct ieee80211vap *vap, int item)
{
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct run_vap *rvp = RUN_VAP(vap);
int mcast = 0;
uint32_t i;
@@ -4939,7 +4871,7 @@ run_update_beacon_cb(void *arg)
struct ieee80211vap *vap = arg;
struct run_vap *rvp = RUN_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct rt2860_txwi txwi;
struct mbuf *m;
uint16_t txwisize;
@@ -4987,7 +4919,7 @@ run_update_beacon_cb(void *arg)
static void
run_updateprot(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
uint32_t i;
i = RUN_CMDQ_GET(&sc->cmdq_store);
@@ -5001,7 +4933,7 @@ static void
run_updateprot_cb(void *arg)
{
struct ieee80211com *ic = arg;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
uint32_t tmp;
tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL;
@@ -5025,7 +4957,7 @@ static void
run_usb_timeout_cb(void *arg)
{
struct ieee80211vap *vap = arg;
- struct run_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct run_softc *sc = vap->iv_ic->ic_softc;
RUN_LOCK_ASSERT(sc, MA_OWNED);
@@ -5071,12 +5003,12 @@ run_update_promisc_locked(struct run_softc *sc)
run_read(sc, RT2860_RX_FILTR_CFG, &tmp);
tmp |= RT2860_DROP_UC_NOME;
- if (sc->sc_ifp->if_flags & IFF_PROMISC)
+ if (sc->sc_ic.ic_promisc > 0)
tmp &= ~RT2860_DROP_UC_NOME;
run_write(sc, RT2860_RX_FILTR_CFG, tmp);
- DPRINTF("%s promiscuous mode\n", (sc->sc_ifp->if_flags & IFF_PROMISC) ?
+ DPRINTF("%s promiscuous mode\n", (sc->sc_ic.ic_promisc > 0) ?
"entering" : "leaving");
}
@@ -5085,7 +5017,7 @@ run_update_promisc(struct ieee80211com *ic)
{
struct run_softc *sc = ic->ic_softc;
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((sc->sc_flags & RUN_RUNNING) == 0)
return;
RUN_LOCK(sc);
@@ -5096,7 +5028,7 @@ run_update_promisc(struct ieee80211com *ic)
static void
run_enable_tsf_sync(struct run_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
@@ -5161,7 +5093,7 @@ run_enable_mrr(struct run_softc *sc)
static void
run_set_txpreamble(struct run_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
run_read(sc, RT2860_AUTO_RSP_CFG, &tmp);
@@ -5175,7 +5107,7 @@ run_set_txpreamble(struct run_softc *sc)
static void
run_set_basicrates(struct run_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
/* set basic rates mask */
if (ic->ic_curmode == IEEE80211_MODE_11B)
@@ -5220,7 +5152,7 @@ run_updateslot(struct ieee80211com *ic)
i = RUN_CMDQ_GET(&sc->cmdq_store);
DPRINTF("cmdq_store=%d\n", i);
sc->cmdq[i].func = run_updateslot_cb;
- sc->cmdq[i].arg0 = ic->ic_ifp;
+ sc->cmdq[i].arg0 = ic;
ieee80211_runtask(ic, &sc->cmdq_task);
return;
@@ -5230,9 +5162,8 @@ run_updateslot(struct ieee80211com *ic)
static void
run_updateslot_cb(void *arg)
{
- struct ifnet *ifp = arg;
- struct run_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = arg;
+ struct run_softc *sc = ic->ic_softc;
uint32_t tmp;
run_read(sc, RT2860_BKOFF_SLOT_CFG, &tmp);
@@ -5244,15 +5175,12 @@ run_updateslot_cb(void *arg)
static void
run_update_mcast(struct ieee80211com *ic)
{
-
- /* h/w filter supports getting everything or nothing */
- ic->ic_ifp->if_flags |= IFF_ALLMULTI;
}
static int8_t
run_rssi2dbm(struct run_softc *sc, uint8_t rssi, uint8_t rxchain)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_channel *c = ic->ic_curchan;
int delta;
@@ -5902,7 +5830,7 @@ run_rt5390_rf_setup(struct run_softc *sc)
static int
run_txrx_enable(struct run_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
int error, ntries;
@@ -5962,8 +5890,8 @@ run_adjust_freq_offset(struct run_softc *sc)
static void
run_init_locked(struct run_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
uint8_t bbp1, bbp3;
int i;
@@ -5993,7 +5921,7 @@ run_init_locked(struct run_softc *sc)
for (i = 0; i != RUN_EP_QUEUES; i++)
run_setup_tx_list(sc, &sc->sc_epq[i]);
- run_set_macaddr(sc, IF_LLADDR(ifp));
+ run_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
for (ntries = 0; ntries < 100; ntries++) {
if (run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp) != 0)
@@ -6166,8 +6094,7 @@ run_init_locked(struct run_softc *sc)
/* turn radio LED on */
run_set_leds(sc, RT2860_LED_RADIO);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= RUN_RUNNING;
sc->cmdq_run = RUN_CMDQ_GO;
for (i = 0; i != RUN_N_XFER; i++)
@@ -6185,35 +6112,19 @@ fail:
}
static void
-run_init(void *arg)
-{
- struct run_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- RUN_LOCK(sc);
- run_init_locked(sc);
- RUN_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic);
-}
-
-static void
run_stop(void *arg)
{
struct run_softc *sc = (struct run_softc *)arg;
- struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
int i;
int ntries;
RUN_LOCK_ASSERT(sc, MA_OWNED);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_flags & RUN_RUNNING)
run_set_leds(sc, 0); /* turn all LEDs off */
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_flags &= ~RUN_RUNNING;
sc->ratectl_run = RUN_RATECTL_OFF;
sc->cmdq_run = sc->cmdq_key_set;
diff --git a/sys/dev/usb/wlan/if_runvar.h b/sys/dev/usb/wlan/if_runvar.h
index ad0fc30..b8cb12f 100644
--- a/sys/dev/usb/wlan/if_runvar.h
+++ b/sys/dev/usb/wlan/if_runvar.h
@@ -151,13 +151,16 @@ struct run_endpoint_queue {
};
struct run_softc {
+ struct mtx sc_mtx;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
- struct ifnet *sc_ifp;
int sc_need_fwload;
int sc_flags;
#define RUN_FLAG_FWLOAD_NEEDED 0x01
+#define RUN_RUNNING 0x02
uint16_t wcid_stats[RT2870_WCID_MAX + 1][3];
#define RUN_TXCNT 0
@@ -203,10 +206,6 @@ struct run_softc {
uint32_t txpow40mhz_2ghz[5];
uint32_t txpow40mhz_5ghz[5];
- uint8_t sc_bssid[6];
-
- struct mtx sc_mtx;
-
struct run_endpoint_queue sc_epq[RUN_EP_QUEUES];
struct task ratectl_task;
diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c
index fca9e39..04e09204 100644
--- a/sys/dev/usb/wlan/if_uath.c
+++ b/sys/dev/usb/wlan/if_uath.c
@@ -279,12 +279,11 @@ static int uath_alloc_rx_data_list(struct uath_softc *);
static int uath_alloc_tx_data_list(struct uath_softc *);
static void uath_free_rx_data_list(struct uath_softc *);
static void uath_free_tx_data_list(struct uath_softc *);
-static int uath_init_locked(void *);
-static void uath_init(void *);
-static void uath_stop_locked(struct ifnet *);
-static void uath_stop(struct ifnet *);
-static int uath_ioctl(struct ifnet *, u_long, caddr_t);
-static void uath_start(struct ifnet *);
+static int uath_init(struct uath_softc *);
+static void uath_stop(struct uath_softc *);
+static void uath_parent(struct ieee80211com *);
+static int uath_transmit(struct ieee80211com *, struct mbuf *);
+static void uath_start(struct uath_softc *);
static int uath_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static void uath_scan_start(struct ieee80211com *);
@@ -336,11 +335,9 @@ uath_attach(device_t dev)
{
struct uath_softc *sc = device_get_softc(dev);
struct usb_attach_arg *uaa = device_get_ivars(dev);
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t bands, iface_index = UATH_IFACE_INDEX; /* XXX */
usb_error_t error;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_dev = dev;
sc->sc_udev = uaa->device;
@@ -356,6 +353,7 @@ uath_attach(device_t dev)
MTX_DEF);
callout_init(&sc->stat_ch, 0);
callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
uath_usbconfig, UATH_N_XFERS, sc, &sc->sc_mtx);
@@ -387,31 +385,24 @@ uath_attach(device_t dev)
error = uath_host_available(sc);
if (error != 0) {
device_printf(sc->sc_dev, "could not initialize adapter\n");
- goto fail3;
+ goto fail2;
}
error = uath_get_devcap(sc);
if (error != 0) {
device_printf(sc->sc_dev,
"could not get device capabilities\n");
- goto fail3;
+ goto fail2;
}
UATH_UNLOCK(sc);
/* Create device sysctl node. */
uath_sysctl_node(sc);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not allocate ifnet\n");
- error = ENXIO;
- goto fail2;
- }
-
UATH_LOCK(sc);
- error = uath_get_devstatus(sc, macaddr);
+ error = uath_get_devstatus(sc, ic->ic_macaddr);
if (error != 0) {
device_printf(sc->sc_dev, "could not get device status\n");
- goto fail4;
+ goto fail2;
}
/*
@@ -420,28 +411,15 @@ uath_attach(device_t dev)
error = uath_alloc_rx_data_list(sc);
if (error != 0) {
device_printf(sc->sc_dev, "could not allocate Rx data list\n");
- goto fail4;
+ goto fail2;
}
error = uath_alloc_tx_data_list(sc);
if (error != 0) {
device_printf(sc->sc_dev, "could not allocate Tx data list\n");
- goto fail4;
+ goto fail2;
}
UATH_UNLOCK(sc);
- ifp->if_softc = sc;
- if_initname(ifp, "uath", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = uath_init;
- ifp->if_ioctl = uath_ioctl;
- ifp->if_start = uath_start;
- /* XXX UATH_TX_DATA_LIST_COUNT */
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -469,16 +447,17 @@ uath_attach(device_t dev)
/* XXX turbo */
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, macaddr);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = uath_raw_xmit;
ic->ic_scan_start = uath_scan_start;
ic->ic_scan_end = uath_scan_end;
ic->ic_set_channel = uath_set_channel;
-
ic->ic_vap_create = uath_vap_create;
ic->ic_vap_delete = uath_vap_delete;
ic->ic_update_mcast = uath_update_mcast;
ic->ic_update_promisc = uath_update_promisc;
+ ic->ic_transmit = uath_transmit;
+ ic->ic_parent = uath_parent;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -491,9 +470,8 @@ uath_attach(device_t dev)
return (0);
-fail4: if_free(ifp);
-fail3: UATH_UNLOCK(sc);
-fail2: uath_free_cmd_list(sc, sc->sc_cmd);
+fail2: UATH_UNLOCK(sc);
+ uath_free_cmd_list(sc, sc->sc_cmd);
fail1: usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS);
fail:
return (error);
@@ -503,8 +481,7 @@ static int
uath_detach(device_t dev)
{
struct uath_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
unsigned int x;
/*
@@ -525,9 +502,9 @@ uath_detach(device_t dev)
STAILQ_INIT(&sc->sc_cmd_pending);
STAILQ_INIT(&sc->sc_cmd_waiting);
STAILQ_INIT(&sc->sc_cmd_inactive);
- UATH_UNLOCK(sc);
- uath_stop(ifp);
+ uath_stop(sc);
+ UATH_UNLOCK(sc);
callout_drain(&sc->stat_ch);
callout_drain(&sc->watchdog_ch);
@@ -547,7 +524,7 @@ uath_detach(device_t dev)
usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS);
ieee80211_ifdetach(ic);
- if_free(ifp);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
}
@@ -1067,15 +1044,12 @@ uath_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return (NULL);
- uvp = (struct uath_vap *) malloc(sizeof(struct uath_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return (NULL);
+ uvp = malloc(sizeof(struct uath_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &uvp->vap;
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(uvp, M_80211_VAP);
return (NULL);
@@ -1087,7 +1061,7 @@ uath_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return (vap);
}
@@ -1102,18 +1076,17 @@ uath_vap_delete(struct ieee80211vap *vap)
}
static int
-uath_init_locked(void *arg)
+uath_init(struct uath_softc *sc)
{
- struct uath_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t val;
int error;
UATH_ASSERT_LOCKED(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- uath_stop_locked(ifp);
+ if (sc->sc_flags & UATH_FLAG_INITDONE)
+ uath_stop(sc);
/* reset variables */
sc->sc_intrx_nextnum = sc->sc_msgid = 0;
@@ -1122,7 +1095,8 @@ uath_init_locked(void *arg)
uath_cmd_write(sc, WDCMSG_BIND, &val, sizeof val, 0);
/* set MAC address */
- uath_config_multi(sc, CFG_MAC_ADDR, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
+ uath_config_multi(sc, CFG_MAC_ADDR,
+ vap ? vap->iv_myaddr : ic->ic_macaddr, IEEE80211_ADDR_LEN);
/* XXX honor net80211 state */
uath_config(sc, CFG_RATE_CONTROL_ENABLE, 0x00000001);
@@ -1171,8 +1145,6 @@ uath_init_locked(void *arg)
UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON,
UATH_FILTER_OP_SET);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
sc->sc_flags |= UATH_FLAG_INITDONE;
callout_reset(&sc->watchdog_ch, hz, uath_watchdog, sc);
@@ -1180,28 +1152,16 @@ uath_init_locked(void *arg)
return (0);
fail:
- uath_stop_locked(ifp);
+ uath_stop(sc);
return (error);
}
static void
-uath_init(void *arg)
-{
- struct uath_softc *sc = arg;
-
- UATH_LOCK(sc);
- (void)uath_init_locked(sc);
- UATH_UNLOCK(sc);
-}
-
-static void
-uath_stop_locked(struct ifnet *ifp)
+uath_stop(struct uath_softc *sc)
{
- struct uath_softc *sc = ifp->if_softc;
UATH_ASSERT_LOCKED(sc);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
sc->sc_flags &= ~UATH_FLAG_INITDONE;
callout_stop(&sc->stat_ch);
@@ -1217,16 +1177,6 @@ uath_stop_locked(struct ifnet *ifp)
uath_cmd_write(sc, WDCMSG_TARGET_STOP, NULL, 0, 0);
}
-static void
-uath_stop(struct ifnet *ifp)
-{
- struct uath_softc *sc = ifp->if_softc;
-
- UATH_LOCK(sc);
- uath_stop_locked(ifp);
- UATH_UNLOCK(sc);
-}
-
static int
uath_config(struct uath_softc *sc, uint32_t reg, uint32_t val)
{
@@ -1329,13 +1279,13 @@ static void
uath_watchdog(void *arg)
{
struct uath_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
if (sc->sc_tx_timer > 0) {
if (--sc->sc_tx_timer == 0) {
device_printf(sc->sc_dev, "device timeout\n");
- /*uath_init(ifp); XXX needs a process context! */
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ /*uath_init(sc); XXX needs a process context! */
+ counter_u64_add(ic->ic_oerrors, 1);
return;
}
callout_reset(&sc->watchdog_ch, hz, uath_watchdog, sc);
@@ -1450,12 +1400,8 @@ uath_getbuf(struct uath_softc *sc)
UATH_ASSERT_LOCKED(sc);
bf = _uath_getbuf(sc);
- if (bf == NULL) {
- struct ifnet *ifp = sc->sc_ifp;
-
+ if (bf == NULL)
DPRINTF(sc, UATH_DEBUG_XMIT, "%s: stop queue\n", __func__);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- }
return (bf);
}
@@ -1474,8 +1420,7 @@ static int
uath_set_chan(struct uath_softc *sc, struct ieee80211_channel *c)
{
#ifdef UATH_DEBUG
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
#endif
struct uath_cmd_reset reset;
@@ -1554,47 +1499,28 @@ uath_wme_init(struct uath_softc *sc)
return (error);
}
-static int
-uath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+uath_parent(struct ieee80211com *ic)
{
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- struct uath_softc *sc = ifp->if_softc;
- int error;
+ struct uath_softc *sc = ic->ic_softc;
int startall = 0;
UATH_LOCK(sc);
- error = (sc->sc_flags & UATH_FLAG_INVALID) ? ENXIO : 0;
- UATH_UNLOCK(sc);
- if (error)
- return (error);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- uath_init(ifp->if_softc);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- uath_stop(ifp);
- }
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
+ if (sc->sc_flags & UATH_FLAG_INVALID) {
+ UATH_UNLOCK(sc);
+ return;
}
- return (error);
+ if (ic->ic_nrunning > 0) {
+ if (!(sc->sc_flags & UATH_FLAG_INITDONE)) {
+ uath_init(sc);
+ startall = 1;
+ }
+ } else if (sc->sc_flags & UATH_FLAG_INITDONE)
+ uath_stop(sc);
+ UATH_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static int
@@ -1763,31 +1689,49 @@ uath_freetx(struct mbuf *m)
} while ((m = next) != NULL);
}
+static int
+uath_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct uath_softc *sc = ic->ic_softc;
+ int error;
+
+ UATH_LOCK(sc);
+ if ((sc->sc_flags & UATH_FLAG_INITDONE) == 0) {
+ UATH_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ UATH_UNLOCK(sc);
+ return (error);
+ }
+ uath_start(sc);
+ UATH_UNLOCK(sc);
+
+ return (0);
+}
+
static void
-uath_start(struct ifnet *ifp)
+uath_start(struct uath_softc *sc)
{
struct uath_data *bf;
- struct uath_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m, *next;
uath_datahead frags;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
+ UATH_ASSERT_LOCKED(sc);
+
+ if ((sc->sc_flags & UATH_FLAG_INITDONE) == 0 ||
(sc->sc_flags & UATH_FLAG_INVALID))
return;
- UATH_LOCK(sc);
- for (;;) {
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
bf = uath_getbuf(sc);
- if (bf == NULL)
- break;
-
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL) {
- STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
- UATH_STAT_INC(sc, st_tx_inactive);
+ if (bf == NULL) {
+ mbufq_prepend(&sc->sc_snd, m);
break;
}
+
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
m->m_pkthdr.rcvif = NULL;
@@ -1816,7 +1760,8 @@ uath_start(struct ifnet *ifp)
next = m->m_nextpkt;
if (uath_tx_start(sc, m, ni, bf) != 0) {
bad:
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
reclaim:
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
UATH_STAT_INC(sc, st_tx_inactive);
@@ -1847,7 +1792,6 @@ uath_start(struct ifnet *ifp)
sc->sc_tx_timer = 5;
}
- UATH_UNLOCK(sc);
}
static int
@@ -1855,19 +1799,19 @@ uath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
struct uath_data *bf;
- struct uath_softc *sc = ifp->if_softc;
+ struct uath_softc *sc = ic->ic_softc;
+ UATH_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
if ((sc->sc_flags & UATH_FLAG_INVALID) ||
- !(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ !(sc->sc_flags & UATH_FLAG_INITDONE)) {
m_freem(m);
ieee80211_free_node(ni);
+ UATH_UNLOCK(sc);
return (ENETDOWN);
}
- UATH_LOCK(sc);
/* grab a TX buffer */
bf = uath_getbuf(sc);
if (bf == NULL) {
@@ -1880,7 +1824,6 @@ uath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
sc->sc_seqnum = 0;
if (uath_tx_start(sc, m, ni, bf) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
UATH_STAT_INC(sc, st_tx_inactive);
UATH_UNLOCK(sc);
@@ -1907,12 +1850,11 @@ uath_scan_end(struct ieee80211com *ic)
static void
uath_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct uath_softc *sc = ifp->if_softc;
+ struct uath_softc *sc = ic->ic_softc;
UATH_LOCK(sc);
if ((sc->sc_flags & UATH_FLAG_INVALID) ||
- (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ (sc->sc_flags & UATH_FLAG_INITDONE) == 0) {
UATH_UNLOCK(sc);
return;
}
@@ -1933,7 +1875,7 @@ uath_update_mcast(struct ieee80211com *ic)
UATH_LOCK(sc);
if ((sc->sc_flags & UATH_FLAG_INVALID) ||
- (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ (sc->sc_flags & UATH_FLAG_INITDONE) == 0) {
UATH_UNLOCK(sc);
return;
}
@@ -1953,7 +1895,7 @@ uath_update_promisc(struct ieee80211com *ic)
UATH_LOCK(sc);
if ((sc->sc_flags & UATH_FLAG_INVALID) ||
- (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ (sc->sc_flags & UATH_FLAG_INITDONE) == 0) {
UATH_UNLOCK(sc);
return;
}
@@ -1970,7 +1912,7 @@ static int
uath_create_connection(struct uath_softc *sc, uint32_t connid)
{
const struct ieee80211_rateset *rs;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni;
struct uath_cmd_create_connection create;
@@ -2021,7 +1963,7 @@ uath_set_rates(struct uath_softc *sc, const struct ieee80211_rateset *rs)
static int
uath_write_associd(struct uath_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni;
struct uath_cmd_set_associd associd;
@@ -2075,7 +2017,7 @@ uath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
int error;
struct ieee80211_node *ni;
struct ieee80211com *ic = vap->iv_ic;
- struct uath_softc *sc = ic->ic_ifp->if_softc;
+ struct uath_softc *sc = ic->ic_softc;
struct uath_vap *uvp = UATH_VAP(vap);
DPRINTF(sc, UATH_DEBUG_STATE,
@@ -2542,8 +2484,7 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
struct uath_rx_desc **pdesc)
{
struct uath_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct uath_chunk *chunk;
struct uath_rx_desc *desc;
struct mbuf *m = data->m, *mnew, *mp;
@@ -2555,14 +2496,14 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
if (actlen < (int)UATH_MIN_RXBUFSZ) {
DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
"%s: wrong xfer size (len=%d)\n", __func__, actlen);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
chunk = (struct uath_chunk *)data->buf;
if (chunk->seqnum == 0 && chunk->flags == 0 && chunk->length == 0) {
device_printf(sc->sc_dev, "%s: strange response\n", __func__);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
UATH_RESET_INTRX(sc);
return (NULL);
}
@@ -2595,7 +2536,7 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
if ((sc->sc_intrx_len + sizeof(struct uath_rx_desc) +
chunklen) > UATH_MAX_INTRX_SIZE) {
UATH_STAT_INC(sc, st_invalidlen);
- if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
if (sc->sc_intrx_head != NULL)
m_freem(sc->sc_intrx_head);
UATH_RESET_INTRX(sc);
@@ -2620,7 +2561,7 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
if (mnew == NULL) {
DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
"%s: can't get new mbuf, drop frame\n", __func__);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
if (sc->sc_intrx_head != NULL)
m_freem(sc->sc_intrx_head);
UATH_RESET_INTRX(sc);
@@ -2661,7 +2602,7 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
"%s: bad descriptor (len=%d)\n", __func__,
be32toh(desc->len));
- if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
UATH_STAT_INC(sc, st_toobigrxpkt);
if (sc->sc_intrx_head != NULL)
m_freem(sc->sc_intrx_head);
@@ -2673,13 +2614,11 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
/* finalize mbuf */
if (sc->sc_intrx_head == NULL) {
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len =
be32toh(desc->framelen) - UATH_RX_DUMMYSIZE;
m->m_data += sizeof(struct uath_chunk);
} else {
mp = sc->sc_intrx_head;
- mp->m_pkthdr.rcvif = ifp;
mp->m_flags |= M_PKTHDR;
mp->m_pkthdr.len = sc->sc_intrx_len;
m = mp;
@@ -2705,7 +2644,6 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
tap->wr_antnoise = -95;
}
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
UATH_RESET_INTRX(sc);
return (m);
@@ -2715,8 +2653,7 @@ static void
uath_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct uath_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct mbuf *m = NULL;
@@ -2776,10 +2713,8 @@ setup:
m = NULL;
desc = NULL;
}
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
- uath_start(ifp);
UATH_LOCK(sc);
+ uath_start(sc);
break;
default:
/* needs it to the inactive queue due to a error. */
@@ -2792,7 +2727,7 @@ setup:
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto setup;
}
break;
@@ -2803,40 +2738,22 @@ static void
uath_data_txeof(struct usb_xfer *xfer, struct uath_data *data)
{
struct uath_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
UATH_ASSERT_LOCKED(sc);
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
if (data->m) {
- m = data->m;
- if (m->m_flags & M_TXCB &&
- (sc->sc_flags & UATH_FLAG_INVALID) == 0) {
- /* XXX status? */
- ieee80211_process_callback(data->ni, m, 0);
- }
- m_freem(m);
+ /* XXX status? */
+ ieee80211_tx_complete(data->ni, data->m, 0);
data->m = NULL;
- }
- if (data->ni) {
- if ((sc->sc_flags & UATH_FLAG_INVALID) == 0)
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
sc->sc_tx_timer = 0;
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
static void
uath_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct uath_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct uath_data *data;
UATH_ASSERT_LOCKED(sc);
@@ -2868,19 +2785,18 @@ setup:
usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
usbd_transfer_submit(xfer);
- UATH_UNLOCK(sc);
- uath_start(ifp);
- UATH_LOCK(sc);
+ uath_start(sc);
break;
default:
data = STAILQ_FIRST(&sc->sc_tx_active);
if (data == NULL)
goto setup;
if (data->ni != NULL) {
+ if_inc_counter(data->ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
if ((sc->sc_flags & UATH_FLAG_INVALID) == 0)
ieee80211_free_node(data->ni);
data->ni = NULL;
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
diff --git a/sys/dev/usb/wlan/if_uathvar.h b/sys/dev/usb/wlan/if_uathvar.h
index fae3604..56b5ba3 100644
--- a/sys/dev/usb/wlan/if_uathvar.h
+++ b/sys/dev/usb/wlan/if_uathvar.h
@@ -183,7 +183,8 @@ struct uath_vap {
#define UATH_VAP(vap) ((struct uath_vap *)(vap))
struct uath_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
void *sc_cmd_dma_buf;
diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c
index a2e493e..b882fe3 100644
--- a/sys/dev/usb/wlan/if_upgt.c
+++ b/sys/dev/usb/wlan/if_upgt.c
@@ -128,10 +128,10 @@ static void upgt_eeprom_parse_freq4(struct upgt_softc *, uint8_t *, int);
static void upgt_eeprom_parse_freq6(struct upgt_softc *, uint8_t *, int);
static uint32_t upgt_chksum_le(const uint32_t *, size_t);
static void upgt_tx_done(struct upgt_softc *, uint8_t *);
-static void upgt_init(void *);
-static void upgt_init_locked(struct upgt_softc *);
-static int upgt_ioctl(struct ifnet *, u_long, caddr_t);
-static void upgt_start(struct ifnet *);
+static void upgt_init(struct upgt_softc *);
+static void upgt_parent(struct ieee80211com *);
+static int upgt_transmit(struct ieee80211com *, struct mbuf *);
+static void upgt_start(struct upgt_softc *);
static int upgt_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static void upgt_scan_start(struct ieee80211com *);
@@ -240,12 +240,11 @@ upgt_match(device_t dev)
static int
upgt_attach(device_t dev)
{
- int error;
- struct ieee80211com *ic;
- struct ifnet *ifp;
struct upgt_softc *sc = device_get_softc(dev);
+ struct ieee80211com *ic = &sc->sc_ic;
struct usb_attach_arg *uaa = device_get_ivars(dev);
uint8_t bands, iface_index = UPGT_IFACE_INDEX;
+ int error;
sc->sc_dev = dev;
sc->sc_udev = uaa->device;
@@ -258,6 +257,7 @@ upgt_attach(device_t dev)
MTX_DEF);
callout_init(&sc->sc_led_ch, 0);
callout_init(&sc->sc_watchdog_ch, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
upgt_config, UPGT_N_XFERS, sc, &sc->sc_mtx);
@@ -280,26 +280,20 @@ upgt_attach(device_t dev)
if (error)
goto fail3;
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(dev, "can not if_alloc()\n");
- goto fail4;
- }
-
/* Initialize the device. */
error = upgt_device_reset(sc);
if (error)
- goto fail5;
+ goto fail4;
/* Verify the firmware. */
error = upgt_fw_verify(sc);
if (error)
- goto fail5;
+ goto fail4;
/* Calculate device memory space. */
if (sc->sc_memaddr_frame_start == 0 || sc->sc_memaddr_frame_end == 0) {
device_printf(dev,
"could not find memory space addresses on FW\n");
error = EIO;
- goto fail5;
+ goto fail4;
}
sc->sc_memaddr_frame_end -= UPGT_MEMSIZE_RX + 1;
sc->sc_memaddr_rx_start = sc->sc_memaddr_frame_end + 1;
@@ -316,31 +310,19 @@ upgt_attach(device_t dev)
/* Load the firmware. */
error = upgt_fw_load(sc);
if (error)
- goto fail5;
+ goto fail4;
/* Read the whole EEPROM content and parse it. */
error = upgt_eeprom_read(sc);
if (error)
- goto fail5;
+ goto fail4;
error = upgt_eeprom_parse(sc);
if (error)
- goto fail5;
+ goto fail4;
/* all works related with the device have done here. */
upgt_abort_xfers(sc);
- /* Setup the 802.11 device. */
- ifp->if_softc = sc;
- if_initname(ifp, "upgt", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = upgt_init;
- ifp->if_ioctl = upgt_ioctl;
- ifp->if_start = upgt_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -360,15 +342,16 @@ upgt_attach(device_t dev)
setbit(&bands, IEEE80211_MODE_11G);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_myaddr);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = upgt_raw_xmit;
ic->ic_scan_start = upgt_scan_start;
ic->ic_scan_end = upgt_scan_end;
ic->ic_set_channel = upgt_set_channel;
-
ic->ic_vap_create = upgt_vap_create;
ic->ic_vap_delete = upgt_vap_delete;
ic->ic_update_mcast = upgt_update_mcast;
+ ic->ic_transmit = upgt_transmit;
+ ic->ic_parent = upgt_parent;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -383,7 +366,6 @@ upgt_attach(device_t dev)
return (0);
-fail5: if_free(ifp);
fail4: upgt_free_rx(sc);
fail3: upgt_free_tx(sc);
fail2: usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS);
@@ -395,30 +377,13 @@ fail1: mtx_destroy(&sc->sc_mtx);
static void
upgt_txeof(struct usb_xfer *xfer, struct upgt_data *data)
{
- struct upgt_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
-
- UPGT_ASSERT_LOCKED(sc);
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
if (data->m) {
- m = data->m;
- if (m->m_flags & M_TXCB) {
- /* XXX status? */
- ieee80211_process_callback(data->ni, m, 0);
- }
- m_freem(m);
+ /* XXX status? */
+ ieee80211_tx_complete(data->ni, data->m, 0);
data->m = NULL;
- }
- if (data->ni) {
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
}
static void
@@ -462,77 +427,43 @@ upgt_get_stats(struct upgt_softc *sc)
upgt_bulk_tx(sc, data_cmd);
}
-static int
-upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+upgt_parent(struct ieee80211com *ic)
{
- struct upgt_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error;
+ struct upgt_softc *sc = ic->ic_softc;
int startall = 0;
UPGT_LOCK(sc);
- error = (sc->sc_flags & UPGT_FLAG_DETACHED) ? ENXIO : 0;
- UPGT_UNLOCK(sc);
- if (error)
- return (error);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if ((ifp->if_flags ^ sc->sc_if_flags) &
- (IFF_ALLMULTI | IFF_PROMISC))
- upgt_set_multi(sc);
- } else {
- upgt_init(sc);
- startall = 1;
- }
+ if (sc->sc_flags & UPGT_FLAG_DETACHED) {
+ UPGT_UNLOCK(sc);
+ return;
+ }
+ if (ic->ic_nrunning > 0) {
+ if (sc->sc_flags & UPGT_FLAG_INITDONE) {
+ if (ic->ic_allmulti > 0 || ic->ic_promisc > 0)
+ upgt_set_multi(sc);
} else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- upgt_stop(sc);
+ upgt_init(sc);
+ startall = 1;
}
- sc->sc_if_flags = ifp->if_flags;
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
+ } else if (sc->sc_flags & UPGT_FLAG_INITDONE)
+ upgt_stop(sc);
+ UPGT_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
-upgt_stop_locked(struct upgt_softc *sc)
+upgt_stop(struct upgt_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
UPGT_ASSERT_LOCKED(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_flags & UPGT_FLAG_INITDONE)
upgt_set_macfilter(sc, IEEE80211_S_INIT);
upgt_abort_xfers_locked(sc);
-}
-
-static void
-upgt_stop(struct upgt_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
-
- UPGT_LOCK(sc);
- upgt_stop_locked(sc);
- UPGT_UNLOCK(sc);
-
/* device down */
sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
sc->sc_flags &= ~UPGT_FLAG_INITDONE;
}
@@ -624,36 +555,18 @@ upgt_set_led_blink(void *arg)
}
static void
-upgt_init(void *priv)
-{
- struct upgt_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- UPGT_LOCK(sc);
- upgt_init_locked(sc);
- UPGT_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
-upgt_init_locked(struct upgt_softc *sc)
+upgt_init(struct upgt_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
UPGT_ASSERT_LOCKED(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- upgt_stop_locked(sc);
+ if (sc->sc_flags & UPGT_FLAG_INITDONE)
+ upgt_stop(sc);
usbd_transfer_start(sc->sc_xfer[UPGT_BULK_RX]);
(void)upgt_set_macfilter(sc, IEEE80211_S_SCAN);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
sc->sc_flags |= UPGT_FLAG_INITDONE;
callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc);
@@ -662,14 +575,12 @@ upgt_init_locked(struct upgt_softc *sc)
static int
upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni;
struct upgt_data *data_cmd;
struct upgt_lmac_mem *mem;
struct upgt_lmac_filter *filter;
- uint8_t broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
UPGT_ASSERT_LOCKED(sc);
@@ -709,10 +620,11 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
case IEEE80211_S_SCAN:
DPRINTF(sc, UPGT_DEBUG_STATE,
"set MAC filter to SCAN (bssid %s)\n",
- ether_sprintf(broadcast));
+ ether_sprintf(ieee80211broadcastaddr));
filter->type = htole16(UPGT_FILTER_TYPE_NONE);
- IEEE80211_ADDR_COPY(filter->dst, sc->sc_myaddr);
- IEEE80211_ADDR_COPY(filter->src, broadcast);
+ IEEE80211_ADDR_COPY(filter->dst,
+ vap ? vap->iv_myaddr : ic->ic_macaddr);
+ IEEE80211_ADDR_COPY(filter->src, ieee80211broadcastaddr);
filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1);
filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2);
@@ -724,7 +636,8 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
/* XXX monitor mode isn't tested yet. */
if (vap->iv_opmode == IEEE80211_M_MONITOR) {
filter->type = htole16(UPGT_FILTER_TYPE_MONITOR);
- IEEE80211_ADDR_COPY(filter->dst, sc->sc_myaddr);
+ IEEE80211_ADDR_COPY(filter->dst,
+ vap ? vap->iv_myaddr : ic->ic_macaddr);
IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid);
filter->unknown1 = htole16(UPGT_FILTER_MONITOR_UNKNOWN1);
filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
@@ -736,7 +649,8 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
"set MAC filter to RUN (bssid %s)\n",
ether_sprintf(ni->ni_bssid));
filter->type = htole16(UPGT_FILTER_TYPE_STA);
- IEEE80211_ADDR_COPY(filter->dst, sc->sc_myaddr);
+ IEEE80211_ADDR_COPY(filter->dst,
+ vap ? vap->iv_myaddr : ic->ic_macaddr);
IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid);
filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1);
filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
@@ -765,8 +679,7 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
static void
upgt_setup_rates(struct ieee80211vap *vap, struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct upgt_softc *sc = ifp->if_softc;
+ struct upgt_softc *sc = ic->ic_softc;
const struct ieee80211_txparam *tp;
/*
@@ -813,39 +726,48 @@ upgt_setup_rates(struct ieee80211vap *vap, struct ieee80211com *ic)
static void
upgt_set_multi(void *arg)
{
- struct upgt_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- if (!(ifp->if_flags & IFF_UP))
- return;
+ /* XXX don't know how to set a device. Lack of docs. */
+}
- /*
- * XXX don't know how to set a device. Lack of docs. Just try to set
- * IFF_ALLMULTI flag here.
- */
- ifp->if_flags |= IFF_ALLMULTI;
+static int
+upgt_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct upgt_softc *sc = ic->ic_softc;
+ int error;
+
+ UPGT_LOCK(sc);
+ if ((sc->sc_flags & UPGT_FLAG_INITDONE) == 0) {
+ UPGT_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ UPGT_UNLOCK(sc);
+ return (error);
+ }
+ upgt_start(sc);
+ UPGT_UNLOCK(sc);
+
+ return (0);
}
static void
-upgt_start(struct ifnet *ifp)
+upgt_start(struct upgt_softc *sc)
{
- struct upgt_softc *sc = ifp->if_softc;
struct upgt_data *data_tx;
struct ieee80211_node *ni;
struct mbuf *m;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
+ UPGT_ASSERT_LOCKED(sc);
- UPGT_LOCK(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ if ((sc->sc_flags & UPGT_FLAG_INITDONE) == 0)
+ return;
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
data_tx = upgt_gettxbuf(sc);
if (data_tx == NULL) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
+ mbufq_prepend(&sc->sc_snd, m);
break;
}
@@ -853,15 +775,15 @@ upgt_start(struct ifnet *ifp)
m->m_pkthdr.rcvif = NULL;
if (upgt_tx_start(sc, m, ni, data_tx) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next);
UPGT_STAT_INC(sc, st_tx_inactive);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
continue;
}
sc->sc_tx_timer = 5;
}
- UPGT_UNLOCK(sc);
}
static int
@@ -869,18 +791,18 @@ upgt_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct upgt_softc *sc = ifp->if_softc;
+ struct upgt_softc *sc = ic->ic_softc;
struct upgt_data *data_tx = NULL;
+ UPGT_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & UPGT_FLAG_INITDONE)) {
m_freem(m);
ieee80211_free_node(ni);
+ UPGT_UNLOCK(sc);
return ENETDOWN;
}
- UPGT_LOCK(sc);
data_tx = upgt_gettxbuf(sc);
if (data_tx == NULL) {
ieee80211_free_node(ni);
@@ -893,7 +815,6 @@ upgt_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next);
UPGT_STAT_INC(sc, st_tx_inactive);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
UPGT_UNLOCK(sc);
return (EIO);
}
@@ -907,13 +828,13 @@ static void
upgt_watchdog(void *arg)
{
struct upgt_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
if (sc->sc_tx_timer > 0) {
if (--sc->sc_tx_timer == 0) {
device_printf(sc->sc_dev, "watchdog timeout\n");
- /* upgt_init(ifp); XXX needs a process context ? */
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ /* upgt_init(sc); XXX needs a process context ? */
+ counter_u64_add(ic->ic_oerrors, 1);
return;
}
callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc);
@@ -950,7 +871,7 @@ upgt_scan_end(struct ieee80211com *ic)
static void
upgt_set_channel(struct ieee80211com *ic)
{
- struct upgt_softc *sc = ic->ic_ifp->if_softc;
+ struct upgt_softc *sc = ic->ic_softc;
UPGT_LOCK(sc);
upgt_set_chan(sc, ic->ic_curchan);
@@ -960,8 +881,7 @@ upgt_set_channel(struct ieee80211com *ic)
static void
upgt_set_chan(struct upgt_softc *sc, struct ieee80211_channel *c)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct upgt_data *data_cmd;
struct upgt_lmac_mem *mem;
struct upgt_lmac_channel *chan;
@@ -1044,7 +964,7 @@ upgt_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(uvp, M_80211_VAP);
return (NULL);
@@ -1059,7 +979,7 @@ upgt_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -1069,7 +989,7 @@ upgt_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct upgt_vap *uvp = UPGT_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct upgt_softc *sc = ic->ic_ifp->if_softc;
+ struct upgt_softc *sc = ic->ic_softc;
/* do it in a process context */
sc->sc_state = nstate;
@@ -1125,6 +1045,7 @@ upgt_update_mcast(struct ieee80211com *ic)
static int
upgt_eeprom_parse(struct upgt_softc *sc)
{
+ struct ieee80211com *ic = &sc->sc_ic;
struct upgt_eeprom_header *eeprom_header;
struct upgt_eeprom_option *eeprom_option;
uint16_t option_len;
@@ -1169,7 +1090,8 @@ upgt_eeprom_parse(struct upgt_softc *sc)
DPRINTF(sc, UPGT_DEBUG_FW,
"EEPROM mac len=%d\n", option_len);
- IEEE80211_ADDR_COPY(sc->sc_myaddr, eeprom_option->data);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr,
+ eeprom_option->data);
break;
case UPGT_EEPROM_TYPE_HWRX:
DPRINTF(sc, UPGT_DEBUG_FW,
@@ -1518,8 +1440,7 @@ upgt_chksum_le(const uint32_t *buf, size_t size)
static struct mbuf *
upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct upgt_lmac_rx_desc *rxdesc;
struct mbuf *m;
@@ -1527,7 +1448,7 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
* don't pass packets to the ieee80211 framework if the driver isn't
* RUNNING.
*/
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ if (!(sc->sc_flags & UPGT_FLAG_INITDONE))
return (NULL);
/* access RX packet descriptor */
@@ -1545,7 +1466,6 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
memcpy(mtod(m, char *), rxdesc->data, pkglen);
/* trim FCS */
m->m_len = m->m_pkthdr.len = pkglen - IEEE80211_CRC_LEN;
- m->m_pkthdr.rcvif = ifp;
if (ieee80211_radiotap_active(ic)) {
struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap;
@@ -1554,7 +1474,6 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate);
tap->wr_antsignal = rxdesc->rssi;
}
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
DPRINTF(sc, UPGT_DEBUG_RX_PROC, "%s: RX done\n", __func__);
*rssi = rxdesc->rssi;
@@ -1564,8 +1483,7 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
static uint8_t
upgt_rx_rate(struct upgt_softc *sc, const int rate)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
static const uint8_t cck_upgt2rate[4] = { 2, 4, 11, 22 };
static const uint8_t ofdm_upgt2rate[12] =
{ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
@@ -1584,7 +1502,6 @@ upgt_rx_rate(struct upgt_softc *sc, const int rate)
static void
upgt_tx_done(struct upgt_softc *sc, uint8_t *data)
{
- struct ifnet *ifp = sc->sc_ifp;
struct upgt_lmac_tx_done_desc *desc;
int i, freed = 0;
@@ -1613,10 +1530,9 @@ upgt_tx_done(struct upgt_softc *sc, uint8_t *data)
}
if (freed != 0) {
- sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
UPGT_UNLOCK(sc);
- upgt_start(ifp);
+ sc->sc_tx_timer = 0;
+ upgt_start(sc);
UPGT_LOCK(sc);
}
}
@@ -2022,8 +1938,7 @@ static int
upgt_detach(device_t dev)
{
struct upgt_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
unsigned int x;
/*
@@ -2039,9 +1954,9 @@ upgt_detach(device_t dev)
STAILQ_INIT(&sc->sc_rx_active);
STAILQ_INIT(&sc->sc_rx_inactive);
- UPGT_UNLOCK(sc);
upgt_stop(sc);
+ UPGT_UNLOCK(sc);
callout_drain(&sc->sc_led_ch);
callout_drain(&sc->sc_watchdog_ch);
@@ -2060,7 +1975,7 @@ upgt_detach(device_t dev)
usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS);
ieee80211_ifdetach(ic);
- if_free(ifp);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -2168,12 +2083,8 @@ upgt_getbuf(struct upgt_softc *sc)
UPGT_ASSERT_LOCKED(sc);
bf = _upgt_getbuf(sc);
- if (bf == NULL) {
- struct ifnet *ifp = sc->sc_ifp;
-
+ if (bf == NULL)
DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: stop queue\n", __func__);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- }
return (bf);
}
@@ -2191,14 +2102,10 @@ upgt_gettxbuf(struct upgt_softc *sc)
bf->addr = upgt_mem_alloc(sc);
if (bf->addr == 0) {
- struct ifnet *ifp = sc->sc_ifp;
-
DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: no free prism memory!\n",
__func__);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
UPGT_STAT_INC(sc, st_tx_inactive);
- if (!(ifp->if_drv_flags & IFF_DRV_OACTIVE))
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
return (NULL);
}
return (bf);
@@ -2212,7 +2119,6 @@ upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
int error = 0, len;
struct ieee80211_frame *wh;
struct ieee80211_key *k;
- struct ifnet *ifp = sc->sc_ifp;
struct upgt_lmac_mem *mem;
struct upgt_lmac_tx_desc *txdesc;
@@ -2295,7 +2201,7 @@ done:
* will stall. It's strange, but it works, so we keep reading
* the statistics here. *shrug*
*/
- if (!(ifp->if_get_counter(ifp, IFCOUNTER_OPACKETS) %
+ if (!(vap->iv_ifp->if_get_counter(vap->iv_ifp, IFCOUNTER_OPACKETS) %
UPGT_TX_STAT_INTERVAL))
upgt_get_stats(sc);
@@ -2306,8 +2212,7 @@ static void
upgt_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct upgt_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct mbuf *m = NULL;
@@ -2355,10 +2260,8 @@ setup:
(void) ieee80211_input_all(ic, m, rssi, nf);
m = NULL;
}
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
- upgt_start(ifp);
UPGT_LOCK(sc);
+ upgt_start(sc);
break;
default:
/* needs it to the inactive queue due to a error. */
@@ -2369,7 +2272,7 @@ setup:
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto setup;
}
break;
@@ -2380,7 +2283,6 @@ static void
upgt_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct upgt_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct upgt_data *data;
UPGT_ASSERT_LOCKED(sc);
@@ -2410,18 +2312,17 @@ setup:
usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
usbd_transfer_submit(xfer);
- UPGT_UNLOCK(sc);
- upgt_start(ifp);
- UPGT_LOCK(sc);
+ upgt_start(sc);
break;
default:
data = STAILQ_FIRST(&sc->sc_tx_active);
if (data == NULL)
goto setup;
if (data->ni != NULL) {
+ if_inc_counter(data->ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(data->ni);
data->ni = NULL;
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
diff --git a/sys/dev/usb/wlan/if_upgtvar.h b/sys/dev/usb/wlan/if_upgtvar.h
index c50276b..3dcd335 100644
--- a/sys/dev/usb/wlan/if_upgtvar.h
+++ b/sys/dev/usb/wlan/if_upgtvar.h
@@ -418,8 +418,9 @@ struct upgt_vap {
#define UPGT_VAP(vap) ((struct upgt_vap *)(vap))
struct upgt_softc {
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
- struct ifnet *sc_ifp;
struct usb_device *sc_udev;
void *sc_rx_dma_buf;
void *sc_tx_dma_buf;
@@ -429,11 +430,8 @@ struct upgt_softc {
#define UPGT_FLAG_FWLOADED (1 << 0)
#define UPGT_FLAG_INITDONE (1 << 1)
#define UPGT_FLAG_DETACHED (1 << 2)
- int sc_if_flags;
int sc_debug;
- uint8_t sc_myaddr[IEEE80211_ADDR_LEN];
-
enum ieee80211_state sc_state;
int sc_arg;
int sc_led_blink;
diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c
index 79a5be0..e8224ba 100644
--- a/sys/dev/usb/wlan/if_ural.c
+++ b/sys/dev/usb/wlan/if_ural.c
@@ -149,8 +149,9 @@ static int ural_tx_mgt(struct ural_softc *, struct mbuf *,
struct ieee80211_node *);
static int ural_tx_data(struct ural_softc *, struct mbuf *,
struct ieee80211_node *);
-static void ural_start(struct ifnet *);
-static int ural_ioctl(struct ifnet *, u_long, caddr_t);
+static int ural_transmit(struct ieee80211com *, struct mbuf *);
+static void ural_start(struct ural_softc *);
+static void ural_parent(struct ieee80211com *);
static void ural_set_testmode(struct ural_softc *);
static void ural_eeprom_read(struct ural_softc *, uint16_t, void *,
int);
@@ -171,12 +172,12 @@ static void ural_set_chan(struct ural_softc *,
static void ural_disable_rf_tune(struct ural_softc *);
static void ural_enable_tsf_sync(struct ural_softc *);
static void ural_enable_tsf(struct ural_softc *);
-static void ural_update_slot(struct ifnet *);
+static void ural_update_slot(struct ural_softc *);
static void ural_set_txpreamble(struct ural_softc *);
static void ural_set_basicrates(struct ural_softc *,
const struct ieee80211_channel *);
static void ural_set_bssid(struct ural_softc *, const uint8_t *);
-static void ural_set_macaddr(struct ural_softc *, uint8_t *);
+static void ural_set_macaddr(struct ural_softc *, const uint8_t *);
static void ural_update_promisc(struct ieee80211com *);
static void ural_setpromisc(struct ural_softc *);
static const char *ural_get_rf(int);
@@ -184,8 +185,7 @@ static void ural_read_eeprom(struct ural_softc *);
static int ural_bbp_init(struct ural_softc *);
static void ural_set_txantenna(struct ural_softc *, int);
static void ural_set_rxantenna(struct ural_softc *, int);
-static void ural_init_locked(struct ural_softc *);
-static void ural_init(void *);
+static void ural_init(struct ural_softc *);
static void ural_stop(struct ural_softc *);
static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
@@ -422,8 +422,7 @@ ural_attach(device_t self)
{
struct usb_attach_arg *uaa = device_get_ivars(self);
struct ural_softc *sc = device_get_softc(self);
- struct ifnet *ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t iface_index, bands;
int error;
@@ -433,6 +432,7 @@ ural_attach(device_t self)
mtx_init(&sc->sc_mtx, device_get_nameunit(self),
MTX_NETWORK_LOCK, MTX_DEF);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
iface_index = RAL_IFACE_INDEX;
error = usbd_transfer_setup(uaa->device,
@@ -455,24 +455,6 @@ ural_attach(device_t self)
device_printf(self, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n",
sc->asic_rev, ural_get_rf(sc->rf_rev));
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto detach;
- }
- ic = ifp->if_l2com;
-
- ifp->if_softc = sc;
- if_initname(ifp, "ural", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = ural_init;
- ifp->if_ioctl = ural_ioctl;
- ifp->if_start = ural_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -497,13 +479,14 @@ ural_attach(device_t self)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_update_promisc = ural_update_promisc;
ic->ic_raw_xmit = ural_raw_xmit;
ic->ic_scan_start = ural_scan_start;
ic->ic_scan_end = ural_scan_end;
ic->ic_set_channel = ural_set_channel;
-
+ ic->ic_parent = ural_parent;
+ ic->ic_transmit = ural_transmit;
ic->ic_vap_create = ural_vap_create;
ic->ic_vap_delete = ural_vap_delete;
@@ -527,8 +510,7 @@ static int
ural_detach(device_t self)
{
struct ural_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
/* prevent further ioctls */
RAL_LOCK(sc);
@@ -543,11 +525,9 @@ ural_detach(device_t self)
ural_unsetup_tx_list(sc);
RAL_UNLOCK(sc);
- if (ifp) {
- ic = ifp->if_l2com;
+ if (ic->ic_softc == sc)
ieee80211_ifdetach(ic);
- if_free(ifp);
- }
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -580,7 +560,7 @@ ural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct ural_softc *sc = ic->ic_ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
struct ural_vap *uvp;
struct ieee80211vap *vap;
@@ -594,7 +574,7 @@ ural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(uvp, M_80211_VAP);
return (NULL);
@@ -610,7 +590,8 @@ ural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, ieee80211_media_change,
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -634,13 +615,8 @@ ural_tx_free(struct ural_tx_data *data, int txerr)
struct ural_softc *sc = data->sc;
if (data->m != NULL) {
- if (data->m->m_flags & M_TXCB)
- ieee80211_process_callback(data->ni, data->m,
- txerr ? ETIMEDOUT : 0);
- m_freem(data->m);
+ ieee80211_tx_complete(data->ni, data->m, txerr);
data->m = NULL;
-
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
@@ -697,7 +673,7 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct ural_vap *uvp = URAL_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct ural_softc *sc = ic->ic_ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
const struct ieee80211_txparam *tp;
struct ieee80211_node *ni;
struct mbuf *m;
@@ -731,11 +707,11 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
ieee80211_free_node(ni);
return (-1);
}
- ural_update_slot(ic->ic_ifp);
+ ural_update_slot(sc);
ural_set_txpreamble(sc);
ural_set_basicrates(sc, ic->ic_bsschan);
- IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
- ural_set_bssid(sc, sc->sc_bssid);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid);
+ ural_set_bssid(sc, ic->ic_macaddr);
}
if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
@@ -789,7 +765,6 @@ static void
ural_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct ural_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211vap *vap;
struct ural_tx_data *data;
struct mbuf *m;
@@ -807,9 +782,6 @@ ural_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
ural_tx_free(data, 0);
usbd_xfer_set_priv(xfer, NULL);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
/* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
@@ -852,16 +824,13 @@ tr_setup:
usbd_transfer_submit(xfer);
}
- RAL_UNLOCK(sc);
- ural_start(ifp);
- RAL_LOCK(sc);
+ ural_start(sc);
break;
default: /* Error */
DPRINTFN(11, "transfer error, %s\n",
usbd_errstr(error));
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
data = usbd_xfer_get_priv(xfer);
if (data != NULL) {
ural_tx_free(data, error);
@@ -883,8 +852,7 @@ static void
ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct ural_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
struct mbuf *m = NULL;
struct usb_page_cache *pc;
@@ -902,7 +870,7 @@ ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
if (len < (int)(RAL_RX_DESC_SIZE + IEEE80211_MIN_LEN)) {
DPRINTF("%s: xfer too short %d\n",
device_get_nameunit(sc->sc_dev), len);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
@@ -921,20 +889,19 @@ ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
* filled RAL_TXRX_CSR2:
*/
DPRINTFN(5, "PHY or CRC error\n");
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (m == NULL) {
DPRINTF("could not allocate mbuf\n");
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
usbd_copy_out(pc, 0, mtod(m, uint8_t *), len);
/* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
if (ieee80211_radiotap_active(ic)) {
@@ -973,10 +940,8 @@ tr_setup:
} else
(void) ieee80211_input_all(ic, m, rssi, nf);
}
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
- ural_start(ifp);
RAL_LOCK(sc);
+ ural_start(sc);
return;
default: /* Error */
@@ -1016,8 +981,7 @@ static void
ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc,
uint32_t flags, int len, int rate)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t plcp_length;
int remainder;
@@ -1066,12 +1030,10 @@ ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
const struct ieee80211_txparam *tp;
struct ural_tx_data *data;
if (sc->tx_nfree == 0) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
m_freem(m0);
ieee80211_free_node(ni);
return (EIO);
@@ -1348,78 +1310,73 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
return 0;
}
+static int
+ural_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct ural_softc *sc = ic->ic_softc;
+ int error;
+
+ RAL_LOCK(sc);
+ if (!sc->sc_running) {
+ RAL_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ RAL_UNLOCK(sc);
+ return (error);
+ }
+ ural_start(sc);
+ RAL_UNLOCK(sc);
+
+ return (0);
+}
+
static void
-ural_start(struct ifnet *ifp)
+ural_start(struct ural_softc *sc)
{
- struct ural_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
- RAL_LOCK(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- RAL_UNLOCK(sc);
+ RAL_LOCK_ASSERT(sc, MA_OWNED);
+
+ if (sc->sc_running == 0)
return;
- }
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->tx_nfree < RAL_TX_MINFREE) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
+
+ while (sc->tx_nfree >= RAL_TX_MINFREE &&
+ (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
if (ural_tx_data(sc, m, ni) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
break;
}
}
- RAL_UNLOCK(sc);
}
-static int
-ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+ural_parent(struct ieee80211com *ic)
{
- struct ural_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error;
+ struct ural_softc *sc = ic->ic_softc;
int startall = 0;
RAL_LOCK(sc);
- error = sc->sc_detached ? ENXIO : 0;
- RAL_UNLOCK(sc);
- if (error)
- return (error);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- RAL_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- ural_init_locked(sc);
- startall = 1;
- } else
- ural_setpromisc(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ural_stop(sc);
- }
+ if (sc->sc_detached) {
RAL_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- default:
- error = ether_ioctl(ifp, cmd, data);
- break;
+ return;
}
- return error;
+ if (ic->ic_nrunning > 0) {
+ if (sc->sc_running == 0) {
+ ural_init(sc);
+ startall = 1;
+ } else
+ ural_setpromisc(sc);
+ } else if (sc->sc_running)
+ ural_stop(sc);
+ RAL_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
@@ -1614,23 +1571,22 @@ ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val)
static void
ural_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct ural_softc *sc = ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
ural_write(sc, RAL_TXRX_CSR19, 0);
- ural_set_bssid(sc, ifp->if_broadcastaddr);
+ ural_set_bssid(sc, ieee80211broadcastaddr);
RAL_UNLOCK(sc);
}
static void
ural_scan_end(struct ieee80211com *ic)
{
- struct ural_softc *sc = ic->ic_ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
ural_enable_tsf_sync(sc);
- ural_set_bssid(sc, sc->sc_bssid);
+ ural_set_bssid(sc, ic->ic_macaddr);
RAL_UNLOCK(sc);
}
@@ -1638,7 +1594,7 @@ ural_scan_end(struct ieee80211com *ic)
static void
ural_set_channel(struct ieee80211com *ic)
{
- struct ural_softc *sc = ic->ic_ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
ural_set_chan(sc, ic->ic_curchan);
@@ -1648,8 +1604,7 @@ ural_set_channel(struct ieee80211com *ic)
static void
ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t power, tmp;
int i, chan;
@@ -1780,8 +1735,7 @@ ural_disable_rf_tune(struct ural_softc *sc)
static void
ural_enable_tsf_sync(struct ural_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint16_t logcwmin, preload, tmp;
@@ -1817,10 +1771,9 @@ ural_enable_tsf(struct ural_softc *sc)
#define RAL_RXTX_TURNAROUND 5 /* us */
static void
-ural_update_slot(struct ifnet *ifp)
+ural_update_slot(struct ural_softc *sc)
{
- struct ural_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t slottime, sifs, eifs;
slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
@@ -1845,8 +1798,7 @@ ural_update_slot(struct ifnet *ifp)
static void
ural_set_txpreamble(struct ural_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t tmp;
tmp = ural_read(sc, RAL_TXRX_CSR10);
@@ -1893,7 +1845,7 @@ ural_set_bssid(struct ural_softc *sc, const uint8_t *bssid)
}
static void
-ural_set_macaddr(struct ural_softc *sc, uint8_t *addr)
+ural_set_macaddr(struct ural_softc *sc, const uint8_t *addr)
{
uint16_t tmp;
@@ -1912,18 +1864,17 @@ ural_set_macaddr(struct ural_softc *sc, uint8_t *addr)
static void
ural_setpromisc(struct ural_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
tmp = ural_read(sc, RAL_TXRX_CSR2);
tmp &= ~RAL_DROP_NOT_TO_ME;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (sc->sc_ic.ic_promisc == 0)
tmp |= RAL_DROP_NOT_TO_ME;
ural_write(sc, RAL_TXRX_CSR2, tmp);
- DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
+ DPRINTF("%s promiscuous mode\n", sc->sc_ic.ic_promisc ?
"entering" : "leaving");
}
@@ -1932,11 +1883,9 @@ ural_update_promisc(struct ieee80211com *ic)
{
struct ural_softc *sc = ic->ic_softc;
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
RAL_LOCK(sc);
- ural_setpromisc(sc);
+ if (sc->sc_running)
+ ural_setpromisc(sc);
RAL_UNLOCK(sc);
}
@@ -1958,6 +1907,7 @@ ural_get_rf(int rev)
static void
ural_read_eeprom(struct ural_softc *sc)
{
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t val;
ural_eeprom_read(sc, RAL_EEPROM_CONFIG0, &val, 2);
@@ -1970,7 +1920,7 @@ ural_read_eeprom(struct ural_softc *sc)
sc->nb_ant = val & 0x3;
/* read MAC address */
- ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, sc->sc_bssid, 6);
+ ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, ic->ic_macaddr, 6);
/* read default values for BBP registers */
ural_eeprom_read(sc, RAL_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
@@ -2064,11 +2014,11 @@ ural_set_rxantenna(struct ural_softc *sc, int antenna)
}
static void
-ural_init_locked(struct ural_softc *sc)
+ural_init(struct ural_softc *sc)
{
#define N(a) ((int)(sizeof (a) / sizeof ((a)[0])))
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint16_t tmp;
int i, ntries;
@@ -2115,7 +2065,7 @@ ural_init_locked(struct ural_softc *sc)
ural_set_txantenna(sc, sc->tx_ant);
ural_set_rxantenna(sc, sc->rx_ant);
- ural_set_macaddr(sc, IF_LLADDR(ifp));
+ ural_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
/*
* Allocate Tx and Rx xfer queues.
@@ -2128,13 +2078,12 @@ ural_init_locked(struct ural_softc *sc)
tmp |= RAL_DROP_CTL | RAL_DROP_BAD_VERSION;
if (ic->ic_opmode != IEEE80211_M_HOSTAP)
tmp |= RAL_DROP_TODS;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (ic->ic_promisc == 0)
tmp |= RAL_DROP_NOT_TO_ME;
}
ural_write(sc, RAL_TXRX_CSR2, tmp);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_running = 1;
usbd_xfer_set_stall(sc->sc_xfer[URAL_BULK_WR]);
usbd_transfer_start(sc->sc_xfer[URAL_BULK_RD]);
return;
@@ -2144,28 +2093,12 @@ fail: ural_stop(sc);
}
static void
-ural_init(void *priv)
-{
- struct ural_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- RAL_LOCK(sc);
- ural_init_locked(sc);
- RAL_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
ural_stop(struct ural_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
RAL_LOCK_ASSERT(sc, MA_OWNED);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_running = 0;
/*
* Drain all the transfers, if not already drained:
@@ -2193,27 +2126,23 @@ ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct ural_softc *sc = ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!sc->sc_running) {
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return ENETDOWN;
}
if (sc->tx_nfree < RAL_TX_MINFREE) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return EIO;
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
if (params == NULL) {
/*
* Legacy path; interpret frame contents to decide
@@ -2232,7 +2161,6 @@ ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
RAL_UNLOCK(sc);
return 0;
bad:
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
RAL_UNLOCK(sc);
ieee80211_free_node(ni);
return EIO; /* XXX */
@@ -2266,8 +2194,7 @@ ural_ratectl_task(void *arg, int pending)
struct ural_vap *uvp = arg;
struct ieee80211vap *vap = &uvp->vap;
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct ural_softc *sc = ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
int ok, fail;
int sum, retrycnt;
@@ -2286,7 +2213,8 @@ ural_ratectl_task(void *arg, int pending)
ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt);
(void) ieee80211_ratectl_rate(ni, NULL, 0);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, fail); /* count TX retry-fail as Tx errors */
+ /* count TX retry-fail as Tx errors */
+ if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, fail);
usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp);
RAL_UNLOCK(sc);
diff --git a/sys/dev/usb/wlan/if_uralvar.h b/sys/dev/usb/wlan/if_uralvar.h
index c62b0e4..f40f71d 100644
--- a/sys/dev/usb/wlan/if_uralvar.h
+++ b/sys/dev/usb/wlan/if_uralvar.h
@@ -89,7 +89,8 @@ enum {
};
struct ural_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
@@ -109,8 +110,8 @@ struct ural_softc {
uint16_t sta[11];
uint32_t rf_regs[4];
uint8_t txpow[14];
- uint8_t sc_bssid[6];
- uint8_t sc_detached;
+ u_int sc_detached:1,
+ sc_running:1;
struct {
uint8_t val;
diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c
index f8b77d4..f0d2674 100644
--- a/sys/dev/usb/wlan/if_urtw.c
+++ b/sys/dev/usb/wlan/if_urtw.c
@@ -651,11 +651,11 @@ static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
int, const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN]);
static void urtw_vap_delete(struct ieee80211vap *);
-static void urtw_init(void *);
-static void urtw_stop(struct ifnet *);
-static void urtw_stop_locked(struct ifnet *);
-static int urtw_ioctl(struct ifnet *, u_long, caddr_t);
-static void urtw_start(struct ifnet *);
+static void urtw_init(struct urtw_softc *);
+static void urtw_stop(struct urtw_softc *);
+static void urtw_parent(struct ieee80211com *);
+static int urtw_transmit(struct ieee80211com *, struct mbuf *);
+static void urtw_start(struct urtw_softc *);
static int urtw_alloc_rx_data_list(struct urtw_softc *);
static int urtw_alloc_tx_data_list(struct urtw_softc *);
static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
@@ -784,8 +784,7 @@ urtw_attach(device_t dev)
int ret = ENXIO;
struct urtw_softc *sc = device_get_softc(dev);
struct usb_attach_arg *uaa = device_get_ivars(dev);
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t bands, iface_index = URTW_IFACE_INDEX; /* XXX */
uint16_t n_setup;
uint32_t data;
@@ -807,6 +806,7 @@ urtw_attach(device_t dev)
TASK_INIT(&sc->sc_led_task, 0, urtw_ledtask, sc);
TASK_INIT(&sc->sc_updateslot_task, 0, urtw_updateslottask, sc);
callout_init(&sc->sc_watchdog_ch, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
if (sc->sc_flags & URTW_RTL8187B) {
setup_start = urtw_8187b_usbconfig;
@@ -861,26 +861,6 @@ urtw_attach(device_t dev)
sc->sc_currate = 3;
sc->sc_preamble_mode = urtw_preamble_mode;
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not allocate ifnet\n");
- ret = ENOMEM;
- goto fail1;
- }
-
- ifp->if_softc = sc;
- if_initname(ifp, "urtw", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = urtw_init;
- ifp->if_ioctl = urtw_ioctl;
- ifp->if_start = urtw_start;
- /* XXX URTW_TX_DATA_LIST_COUNT */
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -901,7 +881,7 @@ urtw_attach(device_t dev)
setbit(&bands, IEEE80211_MODE_11G);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = urtw_raw_xmit;
ic->ic_scan_start = urtw_scan_start;
ic->ic_scan_end = urtw_scan_end;
@@ -910,6 +890,8 @@ urtw_attach(device_t dev)
ic->ic_vap_create = urtw_vap_create;
ic->ic_vap_delete = urtw_vap_delete;
ic->ic_update_mcast = urtw_update_mcast;
+ ic->ic_parent = urtw_parent;
+ ic->ic_transmit = urtw_transmit;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -923,8 +905,9 @@ urtw_attach(device_t dev)
ieee80211_announce(ic);
return (0);
-fail: URTW_UNLOCK(sc);
-fail1: usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
+fail:
+ URTW_UNLOCK(sc);
+ usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
fail0:
return (ret);
@@ -934,18 +917,16 @@ static int
urtw_detach(device_t dev)
{
struct urtw_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
unsigned int x;
unsigned int n_xfers;
/* Prevent further ioctls */
URTW_LOCK(sc);
sc->sc_flags |= URTW_DETACHED;
+ urtw_stop(sc);
URTW_UNLOCK(sc);
- urtw_stop(ifp);
-
ieee80211_draintask(ic, &sc->sc_updateslot_task);
ieee80211_draintask(ic, &sc->sc_led_task);
@@ -979,7 +960,7 @@ urtw_detach(device_t dev)
usbd_transfer_unsetup(sc->sc_xfer, n_xfers);
ieee80211_ifdetach(ic);
- if_free(ifp);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
}
@@ -1032,15 +1013,12 @@ urtw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return (NULL);
- uvp = (struct urtw_vap *) malloc(sizeof(struct urtw_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return (NULL);
+ uvp = malloc(sizeof(struct urtw_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &uvp->vap;
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(uvp, M_80211_VAP);
return (NULL);
@@ -1052,7 +1030,7 @@ urtw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return (vap);
}
@@ -1067,15 +1045,15 @@ urtw_vap_delete(struct ieee80211vap *vap)
}
static void
-urtw_init_locked(void *arg)
+urtw_init(struct urtw_softc *sc)
{
- int ret;
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
usb_error_t error;
+ int ret;
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- urtw_stop_locked(ifp);
+ URTW_ASSERT_LOCKED(sc);
+
+ if (sc->sc_flags & URTW_RUNNING)
+ urtw_stop(sc);
error = (sc->sc_flags & URTW_RTL8187B) ? urtw_adapter_start_b(sc) :
urtw_adapter_start(sc);
@@ -1105,24 +1083,13 @@ urtw_init_locked(void *arg)
if (sc->sc_flags & URTW_RTL8187B)
usbd_transfer_start(sc->sc_xfer[URTW_8187B_BULK_TX_STATUS]);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= URTW_RUNNING;
callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
fail:
return;
}
-static void
-urtw_init(void *arg)
-{
- struct urtw_softc *sc = arg;
-
- URTW_LOCK(sc);
- urtw_init_locked(arg);
- URTW_UNLOCK(sc);
-}
-
static usb_error_t
urtw_adapter_start_b(struct urtw_softc *sc)
{
@@ -1215,6 +1182,7 @@ fail:
static usb_error_t
urtw_adapter_start(struct urtw_softc *sc)
{
+ struct ieee80211com *ic = &sc->sc_ic;
usb_error_t error;
error = urtw_reset(sc);
@@ -1234,8 +1202,8 @@ urtw_adapter_start(struct urtw_softc *sc)
if (error)
goto fail;
/* applying MAC address again. */
- urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
- urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
+ urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]);
+ urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff);
error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
if (error)
goto fail;
@@ -1338,13 +1306,14 @@ urtw_do_request(struct urtw_softc *sc,
}
static void
-urtw_stop_locked(struct ifnet *ifp)
+urtw_stop(struct urtw_softc *sc)
{
- struct urtw_softc *sc = ifp->if_softc;
uint8_t data8;
usb_error_t error;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ URTW_ASSERT_LOCKED(sc);
+
+ sc->sc_flags &= ~URTW_RUNNING;
error = urtw_intr_disable(sc);
if (error)
@@ -1377,16 +1346,6 @@ fail:
}
static void
-urtw_stop(struct ifnet *ifp)
-{
- struct urtw_softc *sc = ifp->if_softc;
-
- URTW_LOCK(sc);
- urtw_stop_locked(ifp);
- URTW_UNLOCK(sc);
-}
-
-static void
urtw_abort_xfers(struct urtw_softc *sc)
{
int i, max;
@@ -1401,72 +1360,71 @@ urtw_abort_xfers(struct urtw_softc *sc)
usbd_transfer_stop(sc->sc_xfer[i]);
}
-static int
-urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+urtw_parent(struct ieee80211com *ic)
{
- struct urtw_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error;
+ struct urtw_softc *sc = ic->ic_softc;
int startall = 0;
URTW_LOCK(sc);
- error = (sc->sc_flags & URTW_DETACHED) ? ENXIO : 0;
- URTW_UNLOCK(sc);
- if (error)
- return (error);
+ if (sc->sc_flags & URTW_DETACHED) {
+ URTW_UNLOCK(sc);
+ return;
+ }
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if ((ifp->if_flags ^ sc->sc_if_flags) &
- (IFF_ALLMULTI | IFF_PROMISC))
- urtw_set_multi(sc);
- } else {
- urtw_init(ifp->if_softc);
- startall = 1;
- }
+ if (ic->ic_nrunning > 0) {
+ if (sc->sc_flags & URTW_RUNNING) {
+ if (ic->ic_promisc > 0 || ic->ic_allmulti > 0)
+ urtw_set_multi(sc);
} else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- urtw_stop(ifp);
+ urtw_init(sc);
+ startall = 1;
}
- sc->sc_if_flags = ifp->if_flags;
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
+ } else if (sc->sc_flags & URTW_RUNNING)
+ urtw_stop(sc);
+ URTW_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
+}
+
+static int
+urtw_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct urtw_softc *sc = ic->ic_softc;
+ int error;
+
+ URTW_LOCK(sc);
+ if ((sc->sc_flags & URTW_RUNNING) == 0) {
+ URTW_UNLOCK(sc);
+ return (ENXIO);
}
- return (error);
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ URTW_UNLOCK(sc);
+ return (error);
+ }
+ urtw_start(sc);
+ URTW_UNLOCK(sc);
+
+ return (0);
}
static void
-urtw_start(struct ifnet *ifp)
+urtw_start(struct urtw_softc *sc)
{
struct urtw_data *bf;
- struct urtw_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ URTW_ASSERT_LOCKED(sc);
+
+ if ((sc->sc_flags & URTW_RUNNING) == 0)
return;
- URTW_LOCK(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
bf = urtw_getbuf(sc);
if (bf == NULL) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
+ mbufq_prepend(&sc->sc_snd, m);
break;
}
@@ -1474,7 +1432,8 @@ urtw_start(struct ifnet *ifp)
m->m_pkthdr.rcvif = NULL;
if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_NORMAL) != 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
ieee80211_free_node(ni);
break;
@@ -1483,7 +1442,6 @@ urtw_start(struct ifnet *ifp)
sc->sc_txtimer = 5;
callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
}
- URTW_UNLOCK(sc);
}
static int
@@ -1565,12 +1523,11 @@ urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
+ struct urtw_softc *sc = ic->ic_softc;
struct urtw_data *bf;
- struct urtw_softc *sc = ifp->if_softc;
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & URTW_RUNNING)) {
m_freem(m);
ieee80211_free_node(ni);
return ENETDOWN;
@@ -1584,10 +1541,8 @@ urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return (ENOBUFS); /* XXX */
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
URTW_UNLOCK(sc);
return (EIO);
@@ -1615,8 +1570,7 @@ urtw_scan_end(struct ieee80211com *ic)
static void
urtw_set_channel(struct ieee80211com *ic)
{
- struct urtw_softc *sc = ic->ic_ifp->if_softc;
- struct ifnet *ifp = sc->sc_ifp;
+ struct urtw_softc *sc = ic->ic_softc;
uint32_t data, orig;
usb_error_t error;
@@ -1626,7 +1580,7 @@ urtw_set_channel(struct ieee80211com *ic)
* initialization would be failed if setting a channel is called before
* the init have done.
*/
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ if (!(sc->sc_flags & URTW_RUNNING))
return;
if (sc->sc_curchan != NULL && sc->sc_curchan == ic->ic_curchan)
@@ -1673,11 +1627,10 @@ static int
urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
struct urtw_data *data, int prior)
{
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
struct ieee80211_key *k;
const struct ieee80211_txparam *tp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = {
sc->sc_xfer[URTW_8187B_BULK_TX_BE],
@@ -1862,7 +1815,7 @@ static int
urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct ieee80211com *ic = vap->iv_ic;
- struct urtw_softc *sc = ic->ic_ifp->if_softc;
+ struct urtw_softc *sc = ic->ic_softc;
struct urtw_vap *uvp = URTW_VAP(vap);
struct ieee80211_node *ni;
usb_error_t error = 0;
@@ -1915,12 +1868,11 @@ static void
urtw_watchdog(void *arg)
{
struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
if (sc->sc_txtimer > 0) {
if (--sc->sc_txtimer == 0) {
device_printf(sc->sc_dev, "device timeout\n");
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
return;
}
callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
@@ -1930,17 +1882,7 @@ urtw_watchdog(void *arg)
static void
urtw_set_multi(void *arg)
{
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
-
- if (!(ifp->if_flags & IFF_UP))
- return;
-
- /*
- * XXX don't know how to set a device. Lack of docs. Just try to set
- * IFF_ALLMULTI flag here.
- */
- ifp->if_flags |= IFF_ALLMULTI;
+ /* XXX don't know how to set a device. Lack of docs. */
}
static usb_error_t
@@ -2002,8 +1944,7 @@ urtw_rtl2rate(uint32_t rate)
static usb_error_t
urtw_update_msr(struct urtw_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t data;
usb_error_t error;
@@ -2144,24 +2085,25 @@ urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
static usb_error_t
urtw_get_macaddr(struct urtw_softc *sc)
{
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t data;
usb_error_t error;
error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
if (error != 0)
goto fail;
- sc->sc_bssid[0] = data & 0xff;
- sc->sc_bssid[1] = (data & 0xff00) >> 8;
+ ic->ic_macaddr[0] = data & 0xff;
+ ic->ic_macaddr[1] = (data & 0xff00) >> 8;
error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
if (error != 0)
goto fail;
- sc->sc_bssid[2] = data & 0xff;
- sc->sc_bssid[3] = (data & 0xff00) >> 8;
+ ic->ic_macaddr[2] = data & 0xff;
+ ic->ic_macaddr[3] = (data & 0xff00) >> 8;
error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
if (error != 0)
goto fail;
- sc->sc_bssid[4] = data & 0xff;
- sc->sc_bssid[5] = (data & 0xff00) >> 8;
+ ic->ic_macaddr[4] = data & 0xff;
+ ic->ic_macaddr[5] = (data & 0xff00) >> 8;
fail:
return (error);
}
@@ -3233,7 +3175,7 @@ fail:
static usb_error_t
urtw_8225v2b_rf_init(struct urtw_softc *sc)
{
-#define N(a) ((int)(sizeof(a) / sizeof((a)[0])))
+ struct ieee80211com *ic = &sc->sc_ic;
int i;
uint8_t data8;
usb_error_t error;
@@ -3281,8 +3223,8 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc)
urtw_write8_m(sc, URTW_CONFIG1, data8);
/* applying MAC address again. */
- urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
- urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
+ urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]);
+ urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff);
error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
if (error)
@@ -3293,7 +3235,7 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc)
/*
* MAC configuration
*/
- for (i = 0; i < N(urtw_8225v2b_rf_part1); i++)
+ for (i = 0; i < nitems(urtw_8225v2b_rf_part1); i++)
urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg,
urtw_8225v2b_rf_part1[i].val);
urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50);
@@ -3326,7 +3268,7 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc)
urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff);
usb_pause_mtx(&sc->sc_mtx, 1100);
- for (i = 0; i < N(urtw_8225v2b_rf_part0); i++) {
+ for (i = 0; i < nitems(urtw_8225v2b_rf_part0); i++) {
urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg,
urtw_8225v2b_rf_part0[i].val);
usb_pause_mtx(&sc->sc_mtx, 1);
@@ -3372,7 +3314,7 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc)
}
urtw_8187_write_phy_ofdm(sc, 0x80, 0x10);
- for (i = 0; i < N(urtw_8225v2b_rf_part2); i++)
+ for (i = 0; i < nitems(urtw_8225v2b_rf_part2); i++)
urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val);
urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c);
@@ -3787,8 +3729,7 @@ static void
urtw_led_ch(void *arg)
{
struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
ieee80211_runtask(ic, &sc->sc_led_task);
}
@@ -3935,8 +3876,7 @@ fail:
static usb_error_t
urtw_rx_setconf(struct urtw_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t data;
usb_error_t error;
@@ -3961,7 +3901,7 @@ urtw_rx_setconf(struct urtw_softc *sc)
data = data | URTW_RX_FILTER_CRCERR;
if (ic->ic_opmode == IEEE80211_M_MONITOR ||
- (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
+ ic->ic_promisc > 0 || ic->ic_allmulti > 0) {
data = data | URTW_RX_FILTER_ALLMAC;
} else {
data = data | URTW_RX_FILTER_NICMAC;
@@ -3988,14 +3928,13 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
struct ieee80211_frame *wh;
struct mbuf *m, *mnew;
struct urtw_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t noise = 0, rate;
usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
if (actlen < (int)URTW_MIN_RXBUFSZ) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
@@ -4006,7 +3945,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
(actlen - (sizeof(struct urtw_8187b_rxhdr))));
flen = le32toh(rx->flag) & 0xfff;
if (flen > actlen) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
@@ -4020,7 +3959,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
(actlen - (sizeof(struct urtw_8187l_rxhdr))));
flen = le32toh(rx->flag) & 0xfff;
if (flen > actlen) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
@@ -4032,7 +3971,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (mnew == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
@@ -4041,7 +3980,6 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
data->buf = mtod(mnew, uint8_t *);
/* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN;
if (ieee80211_radiotap_active(ic)) {
@@ -4067,8 +4005,7 @@ static void
urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct urtw_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct mbuf *m = NULL;
@@ -4129,7 +4066,7 @@ setup:
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto setup;
}
break;
@@ -4143,7 +4080,7 @@ static void
urtw_txstatus_eof(struct usb_xfer *xfer)
{
struct urtw_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
int actlen, type, pktretry, seq;
uint64_t val;
@@ -4158,7 +4095,7 @@ urtw_txstatus_eof(struct usb_xfer *xfer)
pktretry = val & 0xff;
seq = (val >> 16) & 0xff;
if (pktretry == URTW_TX_MAXRETRY)
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(ic->ic_oerrors, 1);
DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n",
pktretry, seq);
}
@@ -4168,7 +4105,7 @@ static void
urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct urtw_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
void *dma_buf = usbd_xfer_get_frame_buffer(xfer, 0);
URTW_ASSERT_LOCKED(sc);
@@ -4186,7 +4123,7 @@ setup:
default:
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto setup;
}
break;
@@ -4197,38 +4134,22 @@ static void
urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data)
{
struct urtw_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
URTW_ASSERT_LOCKED(sc);
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
if (data->m) {
- m = data->m;
- if (m->m_flags & M_TXCB) {
- /* XXX status? */
- ieee80211_process_callback(data->ni, m, 0);
- }
- m_freem(m);
+ /* XXX status? */
+ ieee80211_tx_complete(data->ni, data->m, 0);
data->m = NULL;
- }
- if (data->ni) {
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
sc->sc_txtimer = 0;
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
static void
urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct urtw_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct urtw_data *data;
URTW_ASSERT_LOCKED(sc);
@@ -4256,18 +4177,17 @@ setup:
usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
usbd_transfer_submit(xfer);
- URTW_UNLOCK(sc);
- urtw_start(ifp);
- URTW_LOCK(sc);
+ urtw_start(sc);
break;
default:
data = STAILQ_FIRST(&sc->sc_tx_active);
if (data == NULL)
goto setup;
if (data->ni != NULL) {
+ if_inc_counter(data->ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(data->ni);
data->ni = NULL;
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
@@ -4301,12 +4221,8 @@ urtw_getbuf(struct urtw_softc *sc)
URTW_ASSERT_LOCKED(sc);
bf = _urtw_getbuf(sc);
- if (bf == NULL) {
- struct ifnet *ifp = sc->sc_ifp;
-
+ if (bf == NULL)
DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- }
return (bf);
}
@@ -4378,14 +4294,14 @@ static void
urtw_updateslottask(void *arg, int pending)
{
struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
int error;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
URTW_LOCK(sc);
+ if ((sc->sc_flags & URTW_RUNNING) == 0) {
+ URTW_UNLOCK(sc);
+ return;
+ }
if (sc->sc_flags & URTW_RTL8187B) {
urtw_write8_m(sc, URTW_SIFS, 0x22);
if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c
index 6b712b3..457a885 100644
--- a/sys/dev/usb/wlan/if_urtwn.c
+++ b/sys/dev/usb/wlan/if_urtwn.c
@@ -169,8 +169,8 @@ static device_detach_t urtwn_detach;
static usb_callback_t urtwn_bulk_tx_callback;
static usb_callback_t urtwn_bulk_rx_callback;
-static usb_error_t urtwn_do_request(struct urtwn_softc *sc,
- struct usb_device_request *req, void *data);
+static usb_error_t urtwn_do_request(struct urtwn_softc *,
+ struct usb_device_request *, void *);
static struct ieee80211vap *urtwn_vap_create(struct ieee80211com *,
const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
const uint8_t [IEEE80211_ADDR_LEN],
@@ -228,10 +228,9 @@ static int8_t urtwn_r88e_get_rssi(struct urtwn_softc *, int, void *);
static int urtwn_tx_start(struct urtwn_softc *,
struct ieee80211_node *, struct mbuf *,
struct urtwn_data *);
-static void urtwn_start(struct ifnet *);
-static void urtwn_start_locked(struct ifnet *,
- struct urtwn_softc *);
-static int urtwn_ioctl(struct ifnet *, u_long, caddr_t);
+static int urtwn_transmit(struct ieee80211com *, struct mbuf *);
+static void urtwn_start(struct urtwn_softc *);
+static void urtwn_parent(struct ieee80211com *);
static int urtwn_r92c_power_on(struct urtwn_softc *);
static int urtwn_r88e_power_on(struct urtwn_softc *);
static int urtwn_llt_init(struct urtwn_softc *);
@@ -269,10 +268,8 @@ static void urtwn_set_chan(struct urtwn_softc *,
static void urtwn_update_mcast(struct ieee80211com *);
static void urtwn_iq_calib(struct urtwn_softc *);
static void urtwn_lc_calib(struct urtwn_softc *);
-static void urtwn_init(void *);
-static void urtwn_init_locked(void *);
-static void urtwn_stop(struct ifnet *);
-static void urtwn_stop_locked(struct ifnet *);
+static void urtwn_init(struct urtwn_softc *);
+static void urtwn_stop(struct urtwn_softc *);
static void urtwn_abort_xfers(struct urtwn_softc *);
static int urtwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
@@ -368,8 +365,7 @@ urtwn_attach(device_t self)
{
struct usb_attach_arg *uaa = device_get_ivars(self);
struct urtwn_softc *sc = device_get_softc(self);
- struct ifnet *ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t iface_index, bands;
int error;
@@ -382,6 +378,7 @@ urtwn_attach(device_t self)
mtx_init(&sc->sc_mtx, device_get_nameunit(self),
MTX_NETWORK_LOCK, MTX_DEF);
callout_init(&sc->sc_watchdog_ch, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
iface_index = URTWN_IFACE_INDEX;
error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
@@ -424,24 +421,6 @@ urtwn_attach(device_t self)
URTWN_UNLOCK(sc);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto detach;
- }
- ic = ifp->if_l2com;
-
- ifp->if_softc = sc;
- if_initname(ifp, "urtwn", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = urtwn_init;
- ifp->if_ioctl = urtwn_ioctl;
- ifp->if_start = urtwn_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -462,12 +441,13 @@ urtwn_attach(device_t self)
setbit(&bands, IEEE80211_MODE_11G);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = urtwn_raw_xmit;
ic->ic_scan_start = urtwn_scan_start;
ic->ic_scan_end = urtwn_scan_end;
ic->ic_set_channel = urtwn_set_channel;
-
+ ic->ic_transmit = urtwn_transmit;
+ ic->ic_parent = urtwn_parent;
ic->ic_vap_create = urtwn_vap_create;
ic->ic_vap_delete = urtwn_vap_delete;
ic->ic_update_mcast = urtwn_update_mcast;
@@ -491,17 +471,15 @@ static int
urtwn_detach(device_t self)
{
struct urtwn_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
unsigned int x;
/* Prevent further ioctls. */
URTWN_LOCK(sc);
sc->sc_flags |= URTWN_DETACHED;
+ urtwn_stop(sc);
URTWN_UNLOCK(sc);
- urtwn_stop(ifp);
-
callout_drain(&sc->sc_watchdog_ch);
/* Prevent further allocations from RX/TX data lists. */
@@ -527,8 +505,7 @@ urtwn_detach(device_t self)
/* stop all USB transfers */
usbd_transfer_unsetup(sc->sc_xfer, URTWN_N_TRANSFER);
ieee80211_ifdetach(ic);
-
- if_free(ifp);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -599,15 +576,12 @@ urtwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return (NULL);
- uvp = (struct urtwn_vap *) malloc(sizeof(struct urtwn_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return (NULL);
+ uvp = malloc(sizeof(struct urtwn_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &uvp->vap;
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(uvp, M_80211_VAP);
return (NULL);
@@ -619,7 +593,7 @@ urtwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return (vap);
}
@@ -636,8 +610,7 @@ urtwn_vap_delete(struct ieee80211vap *vap)
static struct mbuf *
urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct mbuf *m;
struct r92c_rx_stat *stat;
@@ -650,7 +623,7 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
* don't pass packets to the ieee80211 framework if the driver isn't
* RUNNING.
*/
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ if (!(sc->sc_flags & URTWN_RUNNING))
return (NULL);
stat = (struct r92c_rx_stat *)buf;
@@ -662,11 +635,11 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
* This should not happen since we setup our Rx filter
* to not receive these frames.
*/
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
if (pktlen < sizeof(*wh) || pktlen > MCLBYTES) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
@@ -695,7 +668,6 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
}
/* Finalize mbuf. */
- m->m_pkthdr.rcvif = ifp;
wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz);
memcpy(mtod(m, uint8_t *), wh, pktlen);
m->m_pkthdr.len = m->m_len = pktlen;
@@ -741,7 +713,7 @@ urtwn_rxeof(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi,
int8_t *nf)
{
struct urtwn_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
struct r92c_rx_stat *stat;
struct mbuf *m, *m0 = NULL, *prevm = NULL;
uint32_t rxdw0;
@@ -751,7 +723,7 @@ urtwn_rxeof(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi,
usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
if (len < sizeof(*stat)) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
@@ -802,8 +774,7 @@ static void
urtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct urtwn_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct mbuf *m = NULL, *next;
@@ -866,7 +837,7 @@ tr_setup:
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
break;
@@ -877,38 +848,19 @@ static void
urtwn_txeof(struct usb_xfer *xfer, struct urtwn_data *data)
{
struct urtwn_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
URTWN_ASSERT_LOCKED(sc);
-
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
- if (data->m) {
- m = data->m;
- if (m->m_flags & M_TXCB) {
- /* XXX status? */
- ieee80211_process_callback(data->ni, m, 0);
- }
- m_freem(m);
- data->m = NULL;
- }
- if (data->ni) {
- ieee80211_free_node(data->ni);
- data->ni = NULL;
- }
+ /* XXX status? */
+ ieee80211_tx_complete(data->ni, data->m, 0);
+ data->ni = NULL;
+ data->m = NULL;
sc->sc_txtimer = 0;
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
static void
urtwn_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct urtwn_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct urtwn_data *data;
URTWN_ASSERT_LOCKED(sc);
@@ -933,16 +885,17 @@ tr_setup:
STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
usbd_transfer_submit(xfer);
- urtwn_start_locked(ifp, sc);
+ urtwn_start(sc);
break;
default:
data = STAILQ_FIRST(&sc->sc_tx_active);
if (data == NULL)
goto tr_setup;
if (data->ni != NULL) {
+ if_inc_counter(data->ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(data->ni);
data->ni = NULL;
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
@@ -975,11 +928,8 @@ urtwn_getbuf(struct urtwn_softc *sc)
URTWN_ASSERT_LOCKED(sc);
bf = _urtwn_getbuf(sc);
- if (bf == NULL) {
- struct ifnet *ifp = sc->sc_ifp;
+ if (bf == NULL)
DPRINTF("%s: stop queue\n", __func__);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- }
return (bf);
}
@@ -1302,7 +1252,7 @@ urtwn_read_rom(struct urtwn_softc *sc)
sc->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY);
DPRINTF("regulatory type=%d\n", sc->regulatory);
- IEEE80211_ADDR_COPY(sc->sc_bssid, rom->macaddr);
+ IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr);
sc->sc_rf_write = urtwn_r92c_rf_write;
sc->sc_power_on = urtwn_r92c_power_on;
@@ -1363,7 +1313,7 @@ urtwn_r88e_read_rom(struct urtwn_softc *sc)
if (sc->ofdm_tx_pwr_diff & 0x08)
sc->ofdm_tx_pwr_diff |= 0xf0;
sc->regulatory = MS(sc->r88e_rom[0xc1], R92C_ROM_RF1_REGULATORY);
- IEEE80211_ADDR_COPY(sc->sc_bssid, &sc->r88e_rom[0xd7]);
+ IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, &sc->r88e_rom[0xd7]);
sc->sc_rf_write = urtwn_r88e_rf_write;
sc->sc_power_on = urtwn_r88e_power_on;
@@ -1378,7 +1328,7 @@ urtwn_ra_init(struct urtwn_softc *sc)
{
static const uint8_t map[] =
{ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni;
struct ieee80211_rateset *rs;
@@ -1455,8 +1405,7 @@ urtwn_ra_init(struct urtwn_softc *sc)
void
urtwn_tsf_sync_enable(struct urtwn_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni = vap->iv_bss;
@@ -1513,7 +1462,7 @@ urtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct urtwn_vap *uvp = URTWN_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct urtwn_softc *sc = ic->ic_ifp->if_softc;
+ struct urtwn_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
enum ieee80211_state ostate;
uint32_t reg;
@@ -1669,12 +1618,11 @@ static void
urtwn_watchdog(void *arg)
{
struct urtwn_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
if (sc->sc_txtimer > 0) {
if (--sc->sc_txtimer == 0) {
device_printf(sc->sc_dev, "device timeout\n");
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
return;
}
callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
@@ -1800,10 +1748,9 @@ static int
urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni,
struct mbuf *m0, struct urtwn_data *data)
{
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211_frame *wh;
struct ieee80211_key *k;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct usb_xfer *xfer;
struct r92c_tx_desc *txd;
@@ -1942,89 +1889,78 @@ urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni,
return (0);
}
-static void
-urtwn_start(struct ifnet *ifp)
+static int
+urtwn_transmit(struct ieee80211com *ic, struct mbuf *m)
{
- struct urtwn_softc *sc = ifp->if_softc;
+ struct urtwn_softc *sc = ic->ic_softc;
+ int error;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
URTWN_LOCK(sc);
- urtwn_start_locked(ifp, sc);
+ if ((sc->sc_flags & URTWN_RUNNING) == 0) {
+ URTWN_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ URTWN_UNLOCK(sc);
+ return (error);
+ }
+ urtwn_start(sc);
URTWN_UNLOCK(sc);
+
+ return (0);
}
static void
-urtwn_start_locked(struct ifnet *ifp, struct urtwn_softc *sc)
+urtwn_start(struct urtwn_softc *sc)
{
struct ieee80211_node *ni;
struct mbuf *m;
struct urtwn_data *bf;
URTWN_ASSERT_LOCKED(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
bf = urtwn_getbuf(sc);
if (bf == NULL) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
+ mbufq_prepend(&sc->sc_snd, m);
break;
}
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
m->m_pkthdr.rcvif = NULL;
-
if (urtwn_tx_start(sc, ni, m, bf) != 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
ieee80211_free_node(ni);
break;
}
-
sc->sc_txtimer = 5;
callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
}
}
-static int
-urtwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+urtwn_parent(struct ieee80211com *ic)
{
- struct urtwn_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
+ struct urtwn_softc *sc = ic->ic_softc;
+ int startall = 0;
URTWN_LOCK(sc);
- error = (sc->sc_flags & URTWN_DETACHED) ? ENXIO : 0;
+ if (sc->sc_flags & URTWN_DETACHED) {
+ URTWN_UNLOCK(sc);
+ return;
+ }
+ if (ic->ic_nrunning > 0) {
+ if ((sc->sc_flags & URTWN_RUNNING) == 0) {
+ urtwn_init(sc);
+ startall = 1;
+ }
+ } else if (sc->sc_flags & URTWN_RUNNING)
+ urtwn_stop(sc);
URTWN_UNLOCK(sc);
- if (error != 0)
- return (error);
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- urtwn_init(ifp->if_softc);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- urtwn_stop(ifp);
- }
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return (error);
+ if (startall)
+ ieee80211_start_all(ic);
}
static int
@@ -2938,7 +2874,7 @@ urtwn_get_txpower(struct urtwn_softc *sc, int chain,
struct ieee80211_channel *c, struct ieee80211_channel *extc,
uint16_t power[URTWN_RIDX_COUNT])
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct r92c_rom *rom = &sc->rom;
uint16_t cckpow, ofdmpow, htpow, diff, max;
const struct urtwn_txpwr *base;
@@ -3037,7 +2973,7 @@ urtwn_r88e_get_txpower(struct urtwn_softc *sc, int chain,
struct ieee80211_channel *c, struct ieee80211_channel *extc,
uint16_t power[URTWN_RIDX_COUNT])
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t cckpow, ofdmpow, bw20pow, htpow;
const struct urtwn_r88e_txpwr *base;
int ridx, chan, group;
@@ -3134,7 +3070,7 @@ urtwn_scan_end(struct ieee80211com *ic)
static void
urtwn_set_channel(struct ieee80211com *ic)
{
- struct urtwn_softc *sc = ic->ic_ifp->if_softc;
+ struct urtwn_softc *sc = ic->ic_softc;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
URTWN_LOCK(sc);
@@ -3156,7 +3092,7 @@ static void
urtwn_set_chan(struct urtwn_softc *sc, struct ieee80211_channel *c,
struct ieee80211_channel *extc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t reg;
u_int chan;
int i;
@@ -3287,17 +3223,18 @@ urtwn_lc_calib(struct urtwn_softc *sc)
}
static void
-urtwn_init_locked(void *arg)
+urtwn_init(struct urtwn_softc *sc)
{
- struct urtwn_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ uint8_t macaddr[IEEE80211_ADDR_LEN];
uint32_t reg;
int error;
URTWN_ASSERT_LOCKED(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- urtwn_stop_locked(ifp);
+ if (sc->sc_flags & URTWN_RUNNING)
+ urtwn_stop(sc);
/* Init firmware commands ring. */
sc->fwcur = 0;
@@ -3340,8 +3277,8 @@ urtwn_init_locked(void *arg)
}
/* Set MAC address. */
- urtwn_write_region_1(sc, R92C_MACID, IF_LLADDR(ifp),
- IEEE80211_ADDR_LEN);
+ IEEE80211_ADDR_COPY(macaddr, vap ? vap->iv_myaddr : ic->ic_macaddr);
+ urtwn_write_region_1(sc, R92C_MACID, macaddr, IEEE80211_ADDR_LEN);
/* Set initial network type. */
reg = urtwn_read_4(sc, R92C_CR);
@@ -3465,8 +3402,7 @@ urtwn_init_locked(void *arg)
usbd_transfer_start(sc->sc_xfer[URTWN_BULK_RX]);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= URTWN_RUNNING;
callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
fail:
@@ -3474,39 +3410,16 @@ fail:
}
static void
-urtwn_init(void *arg)
-{
- struct urtwn_softc *sc = arg;
-
- URTWN_LOCK(sc);
- urtwn_init_locked(arg);
- URTWN_UNLOCK(sc);
-}
-
-static void
-urtwn_stop_locked(struct ifnet *ifp)
+urtwn_stop(struct urtwn_softc *sc)
{
- struct urtwn_softc *sc = ifp->if_softc;
URTWN_ASSERT_LOCKED(sc);
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
+ sc->sc_flags &= ~URTWN_RUNNING;
callout_stop(&sc->sc_watchdog_ch);
urtwn_abort_xfers(sc);
}
static void
-urtwn_stop(struct ifnet *ifp)
-{
- struct urtwn_softc *sc = ifp->if_softc;
-
- URTWN_LOCK(sc);
- urtwn_stop_locked(ifp);
- URTWN_UNLOCK(sc);
-}
-
-static void
urtwn_abort_xfers(struct urtwn_softc *sc)
{
int i;
@@ -3523,12 +3436,11 @@ urtwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct urtwn_softc *sc = ifp->if_softc;
+ struct urtwn_softc *sc = ic->ic_softc;
struct urtwn_data *bf;
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & URTWN_RUNNING)) {
m_freem(m);
ieee80211_free_node(ni);
return (ENETDOWN);
@@ -3542,10 +3454,8 @@ urtwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return (ENOBUFS);
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
if (urtwn_tx_start(sc, ni, m, bf) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
URTWN_UNLOCK(sc);
return (EIO);
diff --git a/sys/dev/usb/wlan/if_urtwnreg.h b/sys/dev/usb/wlan/if_urtwnreg.h
index 2bbec7a..0ca9db7 100644
--- a/sys/dev/usb/wlan/if_urtwnreg.h
+++ b/sys/dev/usb/wlan/if_urtwnreg.h
@@ -1172,7 +1172,8 @@ enum {
#define URTWN_EP_QUEUES URTWN_BULK_RX
struct urtwn_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
@@ -1180,6 +1181,7 @@ struct urtwn_softc {
u_int sc_flags;
#define URTWN_FLAG_CCK_HIPWR 0x01
#define URTWN_DETACHED 0x02
+#define URTWN_RUNNING 0x04
u_int chip;
#define URTWN_CHIP_92C 0x01
@@ -1224,7 +1226,6 @@ struct urtwn_softc {
uint8_t ht40_tx_pwr[5];
int8_t bw20_tx_pwr_diff;
int8_t ofdm_tx_pwr_diff;
- uint8_t sc_bssid[IEEE80211_ADDR_LEN];
struct callout sc_watchdog_ch;
struct mtx sc_mtx;
diff --git a/sys/dev/usb/wlan/if_urtwvar.h b/sys/dev/usb/wlan/if_urtwvar.h
index e99cbf4..a423214 100644
--- a/sys/dev/usb/wlan/if_urtwvar.h
+++ b/sys/dev/usb/wlan/if_urtwvar.h
@@ -93,14 +93,14 @@ struct urtw_vap {
#define URTW_VAP(vap) ((struct urtw_vap *)(vap))
struct urtw_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
struct mtx sc_mtx;
void *sc_tx_dma_buf;
int sc_debug;
- int sc_if_flags;
int sc_flags;
#define URTW_INIT_ONCE (1 << 1)
#define URTW_RTL8187B (1 << 2)
@@ -108,13 +108,13 @@ struct urtw_softc {
#define URTW_RTL8187B_REV_D (1 << 4)
#define URTW_RTL8187B_REV_E (1 << 5)
#define URTW_DETACHED (1 << 6)
+#define URTW_RUNNING (1 << 7)
enum ieee80211_state sc_state;
int sc_epromtype;
#define URTW_EEPROM_93C46 0
#define URTW_EEPROM_93C56 1
uint8_t sc_crcmon;
- uint8_t sc_bssid[IEEE80211_ADDR_LEN];
struct ieee80211_channel *sc_curchan;
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index 8f9035e..4c1c778 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -154,12 +154,12 @@ static int zyd_set_beacon_interval(struct zyd_softc *, int);
static void zyd_rx_data(struct usb_xfer *, int, uint16_t);
static int zyd_tx_start(struct zyd_softc *, struct mbuf *,
struct ieee80211_node *);
-static void zyd_start(struct ifnet *);
+static int zyd_transmit(struct ieee80211com *, struct mbuf *);
+static void zyd_start(struct zyd_softc *);
static int zyd_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static int zyd_ioctl(struct ifnet *, u_long, caddr_t);
+static void zyd_parent(struct ieee80211com *);
static void zyd_init_locked(struct zyd_softc *);
-static void zyd_init(void *);
static void zyd_stop(struct zyd_softc *);
static int zyd_loadfirmware(struct zyd_softc *);
static void zyd_scan_start(struct ieee80211com *);
@@ -333,8 +333,7 @@ zyd_attach(device_t dev)
{
struct usb_attach_arg *uaa = device_get_ivars(dev);
struct zyd_softc *sc = device_get_softc(dev);
- struct ifnet *ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t iface_index, bands;
int error;
@@ -353,6 +352,7 @@ zyd_attach(device_t dev)
mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev),
MTX_NETWORK_LOCK, MTX_DEF);
STAILQ_INIT(&sc->sc_rqh);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
iface_index = ZYD_IFACE_INDEX;
error = usbd_transfer_setup(uaa->device,
@@ -372,22 +372,6 @@ zyd_attach(device_t dev)
}
ZYD_UNLOCK(sc);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto detach;
- }
- ifp->if_softc = sc;
- if_initname(ifp, "zyd", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = zyd_init;
- ifp->if_ioctl = zyd_ioctl;
- ifp->if_start = zyd_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -408,16 +392,17 @@ zyd_attach(device_t dev)
setbit(&bands, IEEE80211_MODE_11G);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = zyd_raw_xmit;
ic->ic_scan_start = zyd_scan_start;
ic->ic_scan_end = zyd_scan_end;
ic->ic_set_channel = zyd_set_channel;
-
ic->ic_vap_create = zyd_vap_create;
ic->ic_vap_delete = zyd_vap_delete;
ic->ic_update_mcast = zyd_update_mcast;
ic->ic_update_promisc = zyd_update_mcast;
+ ic->ic_parent = zyd_parent;
+ ic->ic_transmit = zyd_transmit;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -439,8 +424,7 @@ static int
zyd_detach(device_t dev)
{
struct zyd_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
unsigned int x;
/*
@@ -465,11 +449,9 @@ zyd_detach(device_t dev)
/* free USB transfers and some data buffers */
usbd_transfer_unsetup(sc->sc_xfer, ZYD_N_TRANSFER);
- if (ifp) {
- ic = ifp->if_l2com;
+ if (ic->ic_softc == sc)
ieee80211_ifdetach(ic);
- if_free(ifp);
- }
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -486,15 +468,12 @@ zyd_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return (NULL);
- zvp = (struct zyd_vap *) malloc(sizeof(struct zyd_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (zvp == NULL)
- return (NULL);
+ zvp = malloc(sizeof(struct zyd_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &zvp->vap;
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(zvp, M_80211_VAP);
return (NULL);
@@ -509,7 +488,7 @@ zyd_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return (vap);
}
@@ -530,13 +509,8 @@ zyd_tx_free(struct zyd_tx_data *data, int txerr)
struct zyd_softc *sc = data->sc;
if (data->m != NULL) {
- if (data->m->m_flags & M_TXCB)
- ieee80211_process_callback(data->ni, data->m,
- txerr ? ETIMEDOUT : 0);
- m_freem(data->m);
+ ieee80211_tx_complete(data->ni, data->m, txerr);
data->m = NULL;
-
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
@@ -593,7 +567,7 @@ zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct zyd_vap *zvp = ZYD_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
+ struct zyd_softc *sc = ic->ic_softc;
int error;
DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__,
@@ -618,8 +592,8 @@ zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/* make data LED blink upon Tx */
zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1);
- IEEE80211_ADDR_COPY(sc->sc_bssid, vap->iv_bss->ni_bssid);
- zyd_set_bssid(sc, sc->sc_bssid);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, vap->iv_bss->ni_bssid);
+ zyd_set_bssid(sc, ic->ic_macaddr);
break;
default:
break;
@@ -637,8 +611,7 @@ static void
zyd_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct zyd_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni;
struct zyd_cmd *cmd = &sc->sc_ibuf;
@@ -681,7 +654,9 @@ zyd_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
ieee80211_free_node(ni);
}
if (le16toh(retry->count) & 0x100)
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); /* too many retries */
+ /* too many retries */
+ if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS,
+ 1);
break;
}
case ZYD_NOTIF_IORD:
@@ -1243,8 +1218,7 @@ zyd_al2230_bandedge6(struct zyd_rf *rf, struct ieee80211_channel *c)
#define N(a) ((int)(sizeof(a) / sizeof((a)[0])))
int error = 0, i;
struct zyd_softc *sc = rf->rf_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6;
int chan = ieee80211_chan2ieee(ic, c);
@@ -1932,7 +1906,7 @@ zyd_get_macaddr(struct zyd_softc *sc)
USETW(req.wIndex, 0);
USETW(req.wLength, IEEE80211_ADDR_LEN);
- error = zyd_do_request(sc, &req, sc->sc_bssid);
+ error = zyd_do_request(sc, &req, sc->sc_ic.ic_macaddr);
if (error != 0) {
device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
usbd_errstr(error));
@@ -2004,36 +1978,41 @@ fail:
static void
zyd_set_multi(struct zyd_softc *sc)
{
- int error;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifmultiaddr *ifma;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t low, high;
- uint8_t v;
+ int error;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0)
return;
low = 0x00000000;
high = 0x80000000;
- if (ic->ic_opmode == IEEE80211_M_MONITOR ||
- (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
+ if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_allmulti > 0 ||
+ ic->ic_promisc > 0) {
low = 0xffffffff;
high = 0xffffffff;
} else {
- if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- v = ((uint8_t *)LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr))[5] >> 2;
- if (v < 32)
- low |= 1 << v;
- else
- high |= 1 << (v - 32);
+ struct ieee80211vap *vap;
+ struct ifnet *ifp;
+ struct ifmultiaddr *ifma;
+ uint8_t v;
+
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ ifp = vap->iv_ifp;
+ if_maddr_rlock(ifp);
+ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+ v = ((uint8_t *)LLADDR((struct sockaddr_dl *)
+ ifma->ifma_addr))[5] >> 2;
+ if (v < 32)
+ low |= 1 << v;
+ else
+ high |= 1 << (v - 32);
+ }
+ if_maddr_runlock(ifp);
}
- if_maddr_runlock(ifp);
}
/* reprogram multicast global hash table */
@@ -2050,9 +2029,6 @@ zyd_update_mcast(struct ieee80211com *ic)
{
struct zyd_softc *sc = ic->ic_softc;
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
ZYD_LOCK(sc);
zyd_set_multi(sc);
ZYD_UNLOCK(sc);
@@ -2061,8 +2037,7 @@ zyd_update_mcast(struct ieee80211com *ic)
static int
zyd_set_rxfilter(struct zyd_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t rxfilter;
switch (ic->ic_opmode) {
@@ -2087,8 +2062,7 @@ static void
zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c)
{
int error;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct zyd_rf *rf = &sc->sc_rf;
uint32_t tmp;
int chan;
@@ -2179,8 +2153,7 @@ static void
zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len)
{
struct zyd_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct zyd_plcphdr plcp;
struct zyd_rx_stat stat;
struct usb_page_cache *pc;
@@ -2190,7 +2163,7 @@ zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len)
if (len < ZYD_MIN_FRAGSZ) {
DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too short (length=%d)\n",
device_get_nameunit(sc->sc_dev), len);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
pc = usbd_xfer_get_frame(xfer, 0);
@@ -2201,7 +2174,7 @@ zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len)
DPRINTF(sc, ZYD_DEBUG_RECV,
"%s: RX status indicated error (%x)\n",
device_get_nameunit(sc->sc_dev), stat.flags);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
@@ -2213,7 +2186,7 @@ zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len)
if (rlen > (int)MCLBYTES) {
DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too long (length=%d)\n",
device_get_nameunit(sc->sc_dev), rlen);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
} else if (rlen > (int)MHLEN)
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
@@ -2222,10 +2195,9 @@ zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len)
if (m == NULL) {
DPRINTF(sc, ZYD_DEBUG_RECV, "%s: could not allocate rx mbuf\n",
device_get_nameunit(sc->sc_dev));
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = rlen;
usbd_copy_out(pc, offset + sizeof(plcp), mtod(m, uint8_t *), rlen);
@@ -2255,8 +2227,7 @@ static void
zyd_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct zyd_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
struct zyd_rx_desc desc;
struct mbuf *m;
@@ -2328,10 +2299,8 @@ tr_setup:
} else
(void)ieee80211_input_all(ic, m, rssi, nf);
}
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
- zyd_start(ifp);
ZYD_LOCK(sc);
+ zyd_start(sc);
break;
default: /* Error */
@@ -2386,7 +2355,6 @@ static void
zyd_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct zyd_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211vap *vap;
struct zyd_tx_data *data;
struct mbuf *m;
@@ -2405,9 +2373,6 @@ zyd_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
zyd_tx_free(data, 0);
usbd_xfer_set_priv(xfer, NULL);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
/* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
@@ -2440,16 +2405,14 @@ tr_setup:
usbd_xfer_set_priv(xfer, data);
usbd_transfer_submit(xfer);
}
- ZYD_UNLOCK(sc);
- zyd_start(ifp);
- ZYD_LOCK(sc);
+ zyd_start(sc);
break;
default: /* Error */
DPRINTF(sc, ZYD_DEBUG_ANY, "transfer error, %s\n",
usbd_errstr(error));
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
data = usbd_xfer_get_priv(xfer);
usbd_xfer_set_priv(xfer, NULL);
if (data != NULL)
@@ -2590,31 +2553,45 @@ zyd_tx_start(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
return (0);
}
+static int
+zyd_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct zyd_softc *sc = ic->ic_softc;
+ int error;
+
+ ZYD_LOCK(sc);
+ if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0) {
+ ZYD_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ ZYD_UNLOCK(sc);
+ return (error);
+ }
+ zyd_start(sc);
+ ZYD_UNLOCK(sc);
+
+ return (0);
+}
+
static void
-zyd_start(struct ifnet *ifp)
+zyd_start(struct zyd_softc *sc)
{
- struct zyd_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
- ZYD_LOCK(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->tx_nfree == 0) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
+ ZYD_LOCK_ASSERT(sc, MA_LOCKED);
+
+ while (sc->tx_nfree > 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
if (zyd_tx_start(sc, m, ni) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
break;
}
}
- ZYD_UNLOCK(sc);
}
static int
@@ -2622,19 +2599,17 @@ zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct zyd_softc *sc = ifp->if_softc;
+ struct zyd_softc *sc = ic->ic_softc;
ZYD_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & ZYD_FLAG_RUNNING)) {
ZYD_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return (ENETDOWN);
}
if (sc->tx_nfree == 0) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
ZYD_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
@@ -2648,7 +2623,6 @@ zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
*/
if (zyd_tx_start(sc, m, ni) != 0) {
ZYD_UNLOCK(sc);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
return (EIO);
}
@@ -2656,56 +2630,35 @@ zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return (0);
}
-static int
-zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+zyd_parent(struct ieee80211com *ic)
{
- struct zyd_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error;
+ struct zyd_softc *sc = ic->ic_softc;
int startall = 0;
ZYD_LOCK(sc);
- error = (sc->sc_flags & ZYD_FLAG_DETACHED) ? ENXIO : 0;
- ZYD_UNLOCK(sc);
- if (error)
- return (error);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- ZYD_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- zyd_init_locked(sc);
- startall = 1;
- } else
- zyd_set_multi(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- zyd_stop(sc);
- }
+ if (sc->sc_flags & ZYD_FLAG_DETACHED) {
ZYD_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
+ return;
}
- return (error);
+ if (ic->ic_nrunning > 0) {
+ if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0) {
+ zyd_init_locked(sc);
+ startall = 1;
+ } else
+ zyd_set_multi(sc);
+ } else if (sc->sc_flags & ZYD_FLAG_RUNNING)
+ zyd_stop(sc);
+ ZYD_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
zyd_init_locked(struct zyd_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct usb_config_descriptor *cd;
int error;
uint32_t val;
@@ -2757,12 +2710,12 @@ zyd_init_locked(struct zyd_softc *sc)
sc->sc_flags |= ZYD_FLAG_INITONCE;
}
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_flags & ZYD_FLAG_RUNNING)
zyd_stop(sc);
DPRINTF(sc, ZYD_DEBUG_INIT, "setting MAC address to %6D\n",
- IF_LLADDR(ifp), ":");
- error = zyd_set_macaddr(sc, IF_LLADDR(ifp));
+ vap ? vap->iv_myaddr : ic->ic_macaddr, ":");
+ error = zyd_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
if (error != 0)
return;
@@ -2798,8 +2751,7 @@ zyd_init_locked(struct zyd_softc *sc)
/* enable interrupts */
zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= ZYD_FLAG_RUNNING;
usbd_xfer_set_stall(sc->sc_xfer[ZYD_BULK_WR]);
usbd_transfer_start(sc->sc_xfer[ZYD_BULK_RD]);
usbd_transfer_start(sc->sc_xfer[ZYD_INTR_RD]);
@@ -2811,29 +2763,13 @@ fail: zyd_stop(sc);
}
static void
-zyd_init(void *priv)
-{
- struct zyd_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- ZYD_LOCK(sc);
- zyd_init_locked(sc);
- ZYD_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
zyd_stop(struct zyd_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
int error;
ZYD_LOCK_ASSERT(sc, MA_OWNED);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_flags &= ~ZYD_FLAG_RUNNING;
/*
* Drain all the transfers, if not already drained:
@@ -2925,30 +2861,29 @@ zyd_loadfirmware(struct zyd_softc *sc)
static void
zyd_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct zyd_softc *sc = ifp->if_softc;
+ struct zyd_softc *sc = ic->ic_softc;
ZYD_LOCK(sc);
/* want broadcast address while scanning */
- zyd_set_bssid(sc, ifp->if_broadcastaddr);
+ zyd_set_bssid(sc, ieee80211broadcastaddr);
ZYD_UNLOCK(sc);
}
static void
zyd_scan_end(struct ieee80211com *ic)
{
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
+ struct zyd_softc *sc = ic->ic_softc;
ZYD_LOCK(sc);
/* restore previous bssid */
- zyd_set_bssid(sc, sc->sc_bssid);
+ zyd_set_bssid(sc, ic->ic_macaddr);
ZYD_UNLOCK(sc);
}
static void
zyd_set_channel(struct ieee80211com *ic)
{
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
+ struct zyd_softc *sc = ic->ic_softc;
ZYD_LOCK(sc);
zyd_set_chan(sc, ic->ic_curchan);
diff --git a/sys/dev/usb/wlan/if_zydreg.h b/sys/dev/usb/wlan/if_zydreg.h
index 05d94e3..ec61d06 100644
--- a/sys/dev/usb/wlan/if_zydreg.h
+++ b/sys/dev/usb/wlan/if_zydreg.h
@@ -1249,7 +1249,8 @@ enum {
};
struct zyd_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
@@ -1260,13 +1261,13 @@ struct zyd_softc {
#define ZYD_FLAG_INITONCE (1 << 1)
#define ZYD_FLAG_INITDONE (1 << 2)
#define ZYD_FLAG_DETACHED (1 << 3)
+#define ZYD_FLAG_RUNNING (1 << 4)
struct zyd_rf sc_rf;
STAILQ_HEAD(, zyd_rq) sc_rtx;
STAILQ_HEAD(, zyd_rq) sc_rqh;
- uint8_t sc_bssid[IEEE80211_ADDR_LEN];
uint16_t sc_fwbase;
uint8_t sc_regdomain;
uint8_t sc_macrev;
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index b316d46..f8af231 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -116,11 +116,9 @@ static struct ieee80211vap *wi_vap_create(struct ieee80211com *,
const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN]);
static void wi_vap_delete(struct ieee80211vap *vap);
-static void wi_stop_locked(struct wi_softc *sc, int disable);
-static void wi_start_locked(struct ifnet *);
-static void wi_start(struct ifnet *);
-static int wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr,
- struct mbuf *m0);
+static int wi_transmit(struct ieee80211com *, struct mbuf *);
+static void wi_start(struct wi_softc *);
+static int wi_start_tx(struct wi_softc *, struct wi_frame *, struct mbuf *);
static int wi_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static int wi_newstate_sta(struct ieee80211vap *, enum ieee80211_state, int);
@@ -131,10 +129,8 @@ static void wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
int rssi, int nf);
static int wi_reset(struct wi_softc *);
static void wi_watchdog(void *);
-static int wi_ioctl(struct ifnet *, u_long, caddr_t);
+static void wi_parent(struct ieee80211com *);
static void wi_media_status(struct ifnet *, struct ifmediareq *);
-static uint64_t wi_get_counter(struct ifnet *, ift_counter);
-
static void wi_rx_intr(struct wi_softc *);
static void wi_tx_intr(struct wi_softc *);
static void wi_tx_ex_intr(struct wi_softc *);
@@ -153,10 +149,10 @@ static int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int);
static int wi_cmd(struct wi_softc *, int, int, int, int);
static int wi_seek_bap(struct wi_softc *, int, int);
static int wi_read_bap(struct wi_softc *, int, int, void *, int);
-static int wi_write_bap(struct wi_softc *, int, int, void *, int);
+static int wi_write_bap(struct wi_softc *, int, int, const void *, int);
static int wi_mwrite_bap(struct wi_softc *, int, int, struct mbuf *, int);
static int wi_read_rid(struct wi_softc *, int, void *, int *);
-static int wi_write_rid(struct wi_softc *, int, void *, int);
+static int wi_write_rid(struct wi_softc *, int, const void *, int);
static int wi_write_appie(struct wi_softc *, int, const struct ieee80211_appie *);
static void wi_scan_start(struct ieee80211com *);
@@ -237,8 +233,7 @@ int
wi_attach(device_t dev)
{
struct wi_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
int i, nrates, buflen;
u_int16_t val;
u_int8_t ratebuf[2 + IEEE80211_RATE_SIZE];
@@ -249,15 +244,6 @@ wi_attach(device_t dev)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
int error;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
-
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(dev, "can not if_alloc\n");
- wi_free(dev);
- return ENOSPC;
- }
- ic = ifp->if_l2com;
sc->sc_firmware_type = WI_NOTYPE;
sc->wi_cmd_count = 500;
@@ -309,6 +295,7 @@ wi_attach(device_t dev)
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
/*
* Read the station address.
@@ -317,12 +304,13 @@ wi_attach(device_t dev)
* the probe to fail.
*/
buflen = IEEE80211_ADDR_LEN;
- error = wi_read_rid(sc, WI_RID_MAC_NODE, macaddr, &buflen);
+ error = wi_read_rid(sc, WI_RID_MAC_NODE, &ic->ic_macaddr, &buflen);
if (error != 0) {
buflen = IEEE80211_ADDR_LEN;
- error = wi_read_rid(sc, WI_RID_MAC_NODE, macaddr, &buflen);
+ error = wi_read_rid(sc, WI_RID_MAC_NODE, &ic->ic_macaddr,
+ &buflen);
}
- if (error || IEEE80211_ADDR_EQ(macaddr, empty_macaddr)) {
+ if (error || IEEE80211_ADDR_EQ(&ic->ic_macaddr, empty_macaddr)) {
if (error != 0)
device_printf(dev, "mac read failed %d\n", error);
else {
@@ -333,18 +321,6 @@ wi_attach(device_t dev)
return (error);
}
- ifp->if_softc = sc;
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_ioctl = wi_ioctl;
- ifp->if_start = wi_start;
- ifp->if_init = wi_init;
- ifp->if_get_counter = wi_get_counter;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_DS;
@@ -458,16 +434,17 @@ wi_attach(device_t dev)
sc->sc_portnum = WI_DEFAULT_PORT;
- ieee80211_ifattach(ic, macaddr);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = wi_raw_xmit;
ic->ic_scan_start = wi_scan_start;
ic->ic_scan_end = wi_scan_end;
ic->ic_set_channel = wi_set_channel;
-
ic->ic_vap_create = wi_vap_create;
ic->ic_vap_delete = wi_vap_delete;
ic->ic_update_mcast = wi_update_mcast;
ic->ic_update_promisc = wi_update_promisc;
+ ic->ic_transmit = wi_transmit;
+ ic->ic_parent = wi_parent;
ieee80211_radiotap_attach(ic,
&sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
@@ -483,7 +460,6 @@ wi_attach(device_t dev)
if (error) {
device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
ieee80211_ifdetach(ic);
- if_free(sc->sc_ifp);
wi_free(dev);
return error;
}
@@ -495,21 +471,20 @@ int
wi_detach(device_t dev)
{
struct wi_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
WI_LOCK(sc);
/* check if device was removed */
sc->wi_gone |= !bus_child_present(dev);
- wi_stop_locked(sc, 0);
+ wi_stop(sc, 0);
WI_UNLOCK(sc);
ieee80211_ifdetach(ic);
bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
- if_free(sc->sc_ifp);
wi_free(dev);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
}
@@ -520,19 +495,16 @@ wi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct wi_softc *sc = ic->ic_ifp->if_softc;
+ struct wi_softc *sc = ic->ic_softc;
struct wi_vap *wvp;
struct ieee80211vap *vap;
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return NULL;
- wvp = (struct wi_vap *) malloc(sizeof(struct wi_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (wvp == NULL)
- return NULL;
+ wvp = malloc(sizeof(struct wi_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &wvp->wv_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
vap->iv_max_aid = WI_MAX_AID;
@@ -566,7 +538,7 @@ wi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
}
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, wi_media_status);
+ ieee80211_vap_attach(vap, ieee80211_media_change, wi_media_status, mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -585,7 +557,9 @@ wi_shutdown(device_t dev)
{
struct wi_softc *sc = device_get_softc(dev);
+ WI_LOCK(sc);
wi_stop(sc, 1);
+ WI_UNLOCK(sc);
return (0);
}
@@ -593,12 +567,12 @@ void
wi_intr(void *arg)
{
struct wi_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
u_int16_t status;
WI_LOCK(sc);
- if (sc->wi_gone || !sc->sc_enabled || (ifp->if_flags & IFF_UP) == 0) {
+ if (sc->wi_gone || !sc->sc_enabled ||
+ (sc->sc_flags & WI_FLAGS_RUNNING) == 0) {
CSR_WRITE_2(sc, WI_INT_EN, 0);
CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
WI_UNLOCK(sc);
@@ -617,9 +591,8 @@ wi_intr(void *arg)
wi_tx_ex_intr(sc);
if (status & WI_EV_INFO)
wi_info_intr(sc);
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- wi_start_locked(ifp);
+ if (mbufq_first(&sc->sc_snd) != NULL)
+ wi_start(sc);
/* Re-enable interrupts. */
CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
@@ -642,7 +615,7 @@ wi_enable(struct wi_softc *sc)
static int
wi_setup_locked(struct wi_softc *sc, int porttype, int mode,
- uint8_t mac[IEEE80211_ADDR_LEN])
+ const uint8_t mac[IEEE80211_ADDR_LEN])
{
int i;
@@ -676,26 +649,25 @@ wi_setup_locked(struct wi_softc *sc, int porttype, int mode,
return 0;
}
-static void
-wi_init_locked(struct wi_softc *sc)
+void
+wi_init(struct wi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
int wasenabled;
WI_LOCK_ASSERT(sc);
wasenabled = sc->sc_enabled;
if (wasenabled)
- wi_stop_locked(sc, 1);
+ wi_stop(sc, 1);
- if (wi_setup_locked(sc, sc->sc_porttype, 3, IF_LLADDR(ifp)) != 0) {
- if_printf(ifp, "interface not running\n");
- wi_stop_locked(sc, 1);
+ if (wi_setup_locked(sc, sc->sc_porttype, 3,
+ sc->sc_ic.ic_macaddr) != 0) {
+ device_printf(sc->sc_dev, "interface not running\n");
+ wi_stop(sc, 1);
return;
}
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ sc->sc_flags |= WI_FLAGS_RUNNING;
callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc);
@@ -703,24 +675,8 @@ wi_init_locked(struct wi_softc *sc)
}
void
-wi_init(void *arg)
-{
- struct wi_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- WI_LOCK(sc);
- wi_init_locked(sc);
- WI_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
-wi_stop_locked(struct wi_softc *sc, int disable)
+wi_stop(struct wi_softc *sc, int disable)
{
- struct ifnet *ifp = sc->sc_ifp;
WI_LOCK_ASSERT(sc);
@@ -736,22 +692,13 @@ wi_stop_locked(struct wi_softc *sc, int disable)
sc->sc_tx_timer = 0;
sc->sc_false_syns = 0;
- ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING);
-}
-
-void
-wi_stop(struct wi_softc *sc, int disable)
-{
- WI_LOCK(sc);
- wi_stop_locked(sc, disable);
- WI_UNLOCK(sc);
+ sc->sc_flags &= ~WI_FLAGS_RUNNING;
}
static void
wi_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct wi_softc *sc = ifp->if_softc;
+ struct wi_softc *sc = ic->ic_softc;
DPRINTF(("%s: channel %d, %sscanning\n", __func__,
ieee80211_chan2ieee(ic, ic->ic_curchan),
@@ -766,8 +713,7 @@ wi_set_channel(struct ieee80211com *ic)
static void
wi_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct wi_softc *sc = ifp->if_softc;
+ struct wi_softc *sc = ic->ic_softc;
struct ieee80211_scan_state *ss = ic->ic_scan;
DPRINTF(("%s\n", __func__));
@@ -790,8 +736,7 @@ wi_scan_start(struct ieee80211com *ic)
static void
wi_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct wi_softc *sc = ifp->if_softc;
+ struct wi_softc *sc = ic->ic_softc;
DPRINTF(("%s: restore port type %d\n", __func__, sc->sc_porttype));
@@ -824,9 +769,8 @@ static int
wi_newstate_sta(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211_node *bss;
- struct wi_softc *sc = ifp->if_softc;
+ struct wi_softc *sc = ic->ic_softc;
DPRINTF(("%s: %s -> %s\n", __func__,
ieee80211_state_name[vap->iv_state],
@@ -894,9 +838,8 @@ static int
wi_newstate_hostap(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211_node *bss;
- struct wi_softc *sc = ifp->if_softc;
+ struct wi_softc *sc = ic->ic_softc;
int error;
DPRINTF(("%s: %s -> %s\n", __func__,
@@ -953,10 +896,30 @@ wi_newstate_hostap(struct ieee80211vap *vap, enum ieee80211_state nstate, int ar
return error;
}
+static int
+wi_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct wi_softc *sc = ic->ic_softc;
+ int error;
+
+ WI_LOCK(sc);
+ if ((sc->sc_flags & WI_FLAGS_RUNNING) == 0) {
+ WI_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ WI_UNLOCK(sc);
+ return (error);
+ }
+ wi_start(sc);
+ WI_UNLOCK(sc);
+ return (0);
+}
+
static void
-wi_start_locked(struct ifnet *ifp)
+wi_start(struct wi_softc *sc)
{
- struct wi_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct ieee80211_frame *wh;
struct mbuf *m0;
@@ -972,15 +935,8 @@ wi_start_locked(struct ifnet *ifp)
memset(&frmhdr, 0, sizeof(frmhdr));
cur = sc->sc_txnext;
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
- if (m0 == NULL)
- break;
- if (sc->sc_txd[cur].d_len != 0) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m0);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
+ while (sc->sc_txd[cur].d_len == 0 &&
+ (m0 = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *) m0->m_pkthdr.rcvif;
/* reconstruct 802.3 header */
@@ -1029,28 +985,16 @@ wi_start_locked(struct ifnet *ifp)
m_adj(m0, sizeof(struct ieee80211_frame));
frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len);
ieee80211_free_node(ni);
- if (wi_start_tx(ifp, &frmhdr, m0))
+ if (wi_start_tx(sc, &frmhdr, m0))
continue;
sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf;
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
}
}
-static void
-wi_start(struct ifnet *ifp)
-{
- struct wi_softc *sc = ifp->if_softc;
-
- WI_LOCK(sc);
- wi_start_locked(ifp);
- WI_UNLOCK(sc);
-}
-
static int
-wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr, struct mbuf *m0)
+wi_start_tx(struct wi_softc *sc, struct wi_frame *frmhdr, struct mbuf *m0)
{
- struct wi_softc *sc = ifp->if_softc;
int cur = sc->sc_txnext;
int fid, off, error;
@@ -1060,13 +1004,13 @@ wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr, struct mbuf *m0)
|| wi_mwrite_bap(sc, fid, off, m0, m0->m_pkthdr.len) != 0;
m_freem(m0);
if (error) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
return -1;
}
sc->sc_txd[cur].d_len = off;
if (sc->sc_txcur == cur) {
if (wi_cmd(sc, WI_CMD_TX | WI_RECLAIM, fid, 0, 0)) {
- if_printf(ifp, "xmit failed\n");
+ device_printf(sc->sc_dev, "xmit failed\n");
sc->sc_txd[cur].d_len = 0;
return -1;
}
@@ -1080,9 +1024,8 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211vap *vap = ni->ni_vap;
- struct wi_softc *sc = ifp->if_softc;
+ struct wi_softc *sc = ic->ic_softc;
struct ieee80211_key *k;
struct ieee80211_frame *wh;
struct wi_frame frmhdr;
@@ -1098,7 +1041,6 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
memset(&frmhdr, 0, sizeof(frmhdr));
cur = sc->sc_txnext;
if (sc->sc_txd[cur].d_len != 0) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
rc = ENOBUFS;
goto out;
}
@@ -1129,7 +1071,7 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
(caddr_t)&frmhdr.wi_whdr);
m_adj(m0, sizeof(struct ieee80211_frame));
frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len);
- if (wi_start_tx(ifp, &frmhdr, m0) < 0) {
+ if (wi_start_tx(sc, &frmhdr, m0) < 0) {
m0 = NULL;
rc = EIO;
goto out;
@@ -1160,7 +1102,7 @@ wi_reset(struct wi_softc *sc)
}
sc->sc_reset = 1;
if (i == WI_INIT_TRIES) {
- if_printf(sc->sc_ifp, "reset failed\n");
+ device_printf(sc->sc_dev, "reset failed\n");
return error;
}
@@ -1178,7 +1120,6 @@ static void
wi_watchdog(void *arg)
{
struct wi_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
WI_LOCK_ASSERT(sc);
@@ -1186,65 +1127,52 @@ wi_watchdog(void *arg)
return;
if (sc->sc_tx_timer && --sc->sc_tx_timer == 0) {
- if_printf(ifp, "device timeout\n");
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- wi_init_locked(ifp->if_softc);
+ device_printf(sc->sc_dev, "device timeout\n");
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
+ wi_init(sc);
return;
}
callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc);
}
-static int
-wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+wi_parent(struct ieee80211com *ic)
{
- struct wi_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
+ struct wi_softc *sc = ic->ic_softc;
+ int startall = 0;
- switch (cmd) {
- case SIOCSIFFLAGS:
- WI_LOCK(sc);
- /*
- * Can't do promisc and hostap at the same time. If all that's
- * changing is the promisc flag, try to short-circuit a call to
- * wi_init() by just setting PROMISC in the hardware.
- */
- if (ifp->if_flags & IFF_UP) {
- if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
- ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if ((ifp->if_flags ^ sc->sc_if_flags) & IFF_PROMISC) {
- wi_write_val(sc, WI_RID_PROMISC,
- (ifp->if_flags & IFF_PROMISC) != 0);
- } else {
- wi_init_locked(sc);
- startall = 1;
- }
+ WI_LOCK(sc);
+ /*
+ * Can't do promisc and hostap at the same time. If all that's
+ * changing is the promisc flag, try to short-circuit a call to
+ * wi_init() by just setting PROMISC in the hardware.
+ */
+ if (ic->ic_nrunning > 0) {
+ if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
+ sc->sc_flags & WI_FLAGS_RUNNING) {
+ if (ic->ic_promisc > 0 &&
+ (sc->sc_flags & WI_FLAGS_PROMISC) == 0) {
+ wi_write_val(sc, WI_RID_PROMISC, 1);
+ sc->sc_flags |= WI_FLAGS_PROMISC;
+ } else if (ic->ic_promisc == 0 &&
+ (sc->sc_flags & WI_FLAGS_PROMISC) != 0) {
+ wi_write_val(sc, WI_RID_PROMISC, 0);
+ sc->sc_flags &= ~WI_FLAGS_PROMISC;
} else {
- wi_init_locked(sc);
+ wi_init(sc);
startall = 1;
}
} else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- wi_stop_locked(sc, 1);
- sc->wi_gone = 0;
+ wi_init(sc);
+ startall = 1;
}
- sc->sc_if_flags = ifp->if_flags;
- WI_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
+ } else if (sc->sc_flags & WI_FLAGS_RUNNING) {
+ wi_stop(sc, 1);
+ sc->wi_gone = 0;
}
- return error;
+ WI_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
@@ -1252,7 +1180,7 @@ wi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
{
struct ieee80211vap *vap = ifp->if_softc;
struct ieee80211com *ic = vap->iv_ic;
- struct wi_softc *sc = ic->ic_ifp->if_softc;
+ struct wi_softc *sc = ic->ic_softc;
u_int16_t val;
int rate, len;
@@ -1280,8 +1208,7 @@ wi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
static void
wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN])
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni = vap->iv_bss;
@@ -1295,7 +1222,7 @@ wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN])
* indicator of the firmware's BSSID. Damp spurious
* change-of-BSSID indications.
*/
- if ((ifp->if_flags & IFF_PROMISC) != 0 &&
+ if (ic->ic_promisc > 0 &&
!ppsratecheck(&sc->sc_last_syn, &sc->sc_false_syns,
WI_MAX_FALSE_SYNS))
return;
@@ -1316,8 +1243,7 @@ wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN])
static __noinline void
wi_rx_intr(struct wi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct wi_frame frmhdr;
struct mbuf *m;
struct ieee80211_frame *wh;
@@ -1332,7 +1258,7 @@ wi_rx_intr(struct wi_softc *sc)
/* First read in the frame header */
if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) {
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
DPRINTF(("wi_rx_intr: read fid %x failed\n", fid));
return;
}
@@ -1343,7 +1269,7 @@ wi_rx_intr(struct wi_softc *sc)
status = le16toh(frmhdr.wi_status);
if (status & WI_STAT_ERRSTAT) {
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status));
return;
}
@@ -1358,7 +1284,7 @@ wi_rx_intr(struct wi_softc *sc)
if (off + len > MCLBYTES) {
if (ic->ic_opmode != IEEE80211_M_MONITOR) {
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
DPRINTF(("wi_rx_intr: oversized packet\n"));
return;
} else
@@ -1371,7 +1297,7 @@ wi_rx_intr(struct wi_softc *sc)
m = m_gethdr(M_NOWAIT, MT_DATA);
if (m == NULL) {
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
DPRINTF(("wi_rx_intr: MGET failed\n"));
return;
}
@@ -1380,7 +1306,6 @@ wi_rx_intr(struct wi_softc *sc)
wi_read_bap(sc, fid, sizeof(frmhdr),
m->m_data + sizeof(struct ieee80211_frame), len);
m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + len;
- m->m_pkthdr.rcvif = ifp;
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
@@ -1425,7 +1350,6 @@ wi_rx_intr(struct wi_softc *sc)
static __noinline void
wi_tx_ex_intr(struct wi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
struct wi_frame frmhdr;
int fid;
@@ -1440,7 +1364,7 @@ wi_tx_ex_intr(struct wi_softc *sc)
*/
if ((status & WI_TXSTAT_DISCONNECT) == 0) {
if (ppsratecheck(&lasttxerror, &curtxeps, wi_txerate)) {
- if_printf(ifp, "tx failed");
+ device_printf(sc->sc_dev, "tx failed");
if (status & WI_TXSTAT_RET_ERR)
printf(", retry limit exceeded");
if (status & WI_TXSTAT_AGED_ERR)
@@ -1455,7 +1379,7 @@ wi_tx_ex_intr(struct wi_softc *sc)
printf(", status=0x%x", status);
printf("\n");
}
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
} else
DPRINTF(("port disconnected\n"));
} else
@@ -1466,7 +1390,6 @@ wi_tx_ex_intr(struct wi_softc *sc)
static __noinline void
wi_tx_intr(struct wi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
int fid, cur;
if (sc->wi_gone)
@@ -1477,19 +1400,17 @@ wi_tx_intr(struct wi_softc *sc)
cur = sc->sc_txcur;
if (sc->sc_txd[cur].d_fid != fid) {
- if_printf(ifp, "bad alloc %x != %x, cur %d nxt %d\n",
+ device_printf(sc->sc_dev, "bad alloc %x != %x, cur %d nxt %d\n",
fid, sc->sc_txd[cur].d_fid, cur, sc->sc_txnext);
return;
}
sc->sc_tx_timer = 0;
sc->sc_txd[cur].d_len = 0;
sc->sc_txcur = cur = (cur + 1) % sc->sc_ntxbuf;
- if (sc->sc_txd[cur].d_len == 0)
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- else {
+ if (sc->sc_txd[cur].d_len != 0) {
if (wi_cmd(sc, WI_CMD_TX | WI_RECLAIM, sc->sc_txd[cur].d_fid,
0, 0)) {
- if_printf(ifp, "xmit failed\n");
+ device_printf(sc->sc_dev, "xmit failed\n");
sc->sc_txd[cur].d_len = 0;
} else {
sc->sc_tx_timer = 5;
@@ -1500,7 +1421,7 @@ wi_tx_intr(struct wi_softc *sc)
static __noinline void
wi_info_intr(struct wi_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
int i, fid, len, off;
u_int16_t ltbuf[2];
@@ -1574,32 +1495,15 @@ finish:
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
}
-static uint64_t
-wi_get_counter(struct ifnet *ifp, ift_counter cnt)
-{
- struct wi_softc *sc;
-
- sc = if_getsoftc(ifp);
-
- switch (cnt) {
- case IFCOUNTER_COLLISIONS:
- return (sc->sc_stats.wi_tx_single_retries +
- sc->sc_stats.wi_tx_multi_retries +
- sc->sc_stats.wi_tx_retry_limit);
- default:
- return (if_get_counter_default(ifp, cnt));
- }
-}
-
static int
wi_write_multi(struct wi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- int n;
- struct ifmultiaddr *ifma;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap;
struct wi_mcast mlist;
+ int n;
- if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
+ if (ic->ic_allmulti > 0 || ic->ic_promisc > 0) {
allmulti:
memset(&mlist, 0, sizeof(mlist));
return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
@@ -1607,17 +1511,23 @@ allmulti:
}
n = 0;
- if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- if (n >= 16)
- goto allmulti;
- IEEE80211_ADDR_COPY(&mlist.wi_mcast[n],
- (LLADDR((struct sockaddr_dl *)ifma->ifma_addr)));
- n++;
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ struct ifnet *ifp;
+ struct ifmultiaddr *ifma;
+
+ ifp = vap->iv_ifp;
+ if_maddr_rlock(ifp);
+ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+ if (n >= 16)
+ goto allmulti;
+ IEEE80211_ADDR_COPY(&mlist.wi_mcast[n],
+ (LLADDR((struct sockaddr_dl *)ifma->ifma_addr)));
+ n++;
+ }
+ if_maddr_runlock(ifp);
}
- if_maddr_runlock(ifp);
return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
IEEE80211_ADDR_LEN * n);
}
@@ -1638,7 +1548,7 @@ wi_update_promisc(struct ieee80211com *ic)
/* XXX handle WEP special case handling? */
wi_write_val(sc, WI_RID_PROMISC,
(ic->ic_opmode == IEEE80211_M_MONITOR ||
- (ic->ic_ifp->if_flags & IFF_PROMISC)));
+ (ic->ic_promisc > 0)));
WI_UNLOCK(sc);
}
@@ -1937,7 +1847,7 @@ wi_read_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
}
static int
-wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
+wi_write_bap(struct wi_softc *sc, int id, int off, const void *buf, int buflen)
{
int error, cnt;
@@ -1949,7 +1859,7 @@ wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
return error;
}
cnt = (buflen + 1) / 2;
- CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, (u_int16_t *)buf, cnt);
+ CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, (const uint16_t *)buf, cnt);
sc->sc_bap_off += cnt * 2;
return 0;
@@ -2039,7 +1949,7 @@ wi_read_rid(struct wi_softc *sc, int rid, void *buf, int *buflenp)
}
static int
-wi_write_rid(struct wi_softc *sc, int rid, void *buf, int buflen)
+wi_write_rid(struct wi_softc *sc, int rid, const void *buf, int buflen)
{
int error;
u_int16_t ltbuf[2];
diff --git a/sys/dev/wi/if_wi_pccard.c b/sys/dev/wi/if_wi_pccard.c
index fd70e77..414dc20d 100644
--- a/sys/dev/wi/if_wi_pccard.c
+++ b/sys/dev/wi/if_wi_pccard.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/socket.h>
#include <sys/systm.h>
+#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/bus.h>
diff --git a/sys/dev/wi/if_wi_pci.c b/sys/dev/wi/if_wi_pci.c
index 198c599..b218c24 100644
--- a/sys/dev/wi/if_wi_pci.c
+++ b/sys/dev/wi/if_wi_pci.c
@@ -238,7 +238,9 @@ wi_pci_suspend(device_t dev)
{
struct wi_softc *sc = device_get_softc(dev);
+ WI_LOCK(sc);
wi_stop(sc, 1);
+ WI_UNLOCK(sc);
return (0);
}
@@ -247,16 +249,15 @@ static int
wi_pci_resume(device_t dev)
{
struct wi_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
- if (sc->wi_bus_type != WI_BUS_PCI_NATIVE)
+ WI_LOCK(sc);
+ if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) {
return (0);
-
- if (ifp->if_flags & IFF_UP) {
- ifp->if_init(ifp->if_softc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ifp->if_start(ifp);
+ WI_UNLOCK(sc);
}
-
+ if (ic->ic_nrunning > 0)
+ wi_init(sc);
+ WI_UNLOCK(sc);
return (0);
}
diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h
index f163744..9b668cc 100644
--- a/sys/dev/wi/if_wivar.h
+++ b/sys/dev/wi/if_wivar.h
@@ -68,7 +68,8 @@ struct wi_vap {
#define WI_VAP(vap) ((struct wi_vap *)(vap))
struct wi_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct mtx sc_mtx;
struct callout sc_watchdog;
@@ -107,7 +108,6 @@ struct wi_softc {
int wi_cmd_count;
int sc_flags;
- int sc_if_flags;
int sc_bap_id;
int sc_bap_off;
@@ -152,6 +152,8 @@ struct wi_softc {
#define WI_FLAGS_HAS_ROAMING 0x0020
#define WI_FLAGS_HAS_FRAGTHR 0x0200
#define WI_FLAGS_HAS_DBMADJUST 0x0400
+#define WI_FLAGS_RUNNING 0x0800
+#define WI_FLAGS_PROMISC 0x1000
struct wi_card_ident {
u_int16_t card_id;
@@ -180,7 +182,7 @@ int wi_shutdown(device_t);
int wi_alloc(device_t, int);
void wi_free(device_t);
extern devclass_t wi_devclass;
-void wi_init(void *);
void wi_intr(void *);
int wi_mgmt_xmit(struct wi_softc *, caddr_t, int);
void wi_stop(struct wi_softc *, int);
+void wi_init(struct wi_softc *);
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index 3440605..01ce3e4 100644
--- a/sys/dev/wpi/if_wpi.c
+++ b/sys/dev/wpi/if_wpi.c
@@ -205,12 +205,12 @@ static int wpi_tx_data_raw(struct wpi_softc *, struct mbuf *,
const struct ieee80211_bpf_params *);
static int wpi_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void wpi_start(struct ifnet *);
-static void wpi_start_task(void *, int);
+static int wpi_transmit(struct ieee80211com *, struct mbuf *);
+static void wpi_start(void *, int);
static void wpi_watchdog_rfkill(void *);
static void wpi_scan_timeout(void *);
static void wpi_tx_timeout(void *);
-static int wpi_ioctl(struct ifnet *, u_long, caddr_t);
+static void wpi_parent(struct ieee80211com *);
static int wpi_cmd(struct wpi_softc *, int, const void *, size_t, int);
static int wpi_mrr_setup(struct wpi_softc *);
static int wpi_add_node(struct wpi_softc *, struct ieee80211_node *);
@@ -272,7 +272,7 @@ static int wpi_hw_init(struct wpi_softc *);
static void wpi_hw_stop(struct wpi_softc *);
static void wpi_radio_on(void *, int);
static void wpi_radio_off(void *, int);
-static void wpi_init(void *);
+static int wpi_init(struct wpi_softc *);
static void wpi_stop_locked(struct wpi_softc *);
static void wpi_stop(struct wpi_softc *);
static void wpi_scan_start(struct ieee80211com *);
@@ -329,13 +329,11 @@ wpi_attach(device_t dev)
{
struct wpi_softc *sc = (struct wpi_softc *)device_get_softc(dev);
struct ieee80211com *ic;
- struct ifnet *ifp;
int i, error, rid;
#ifdef WPI_DEBUG
int supportsa = 1;
const struct wpi_ident *ident;
#endif
- uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_dev = dev;
@@ -445,14 +443,7 @@ wpi_attach(device_t dev)
/* Clear pending interrupts. */
WPI_WRITE(sc, WPI_INT, 0xffffffff);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(dev, "can not allocate ifnet structure\n");
- goto fail;
- }
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
+ ic = &sc->sc_ic;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -481,7 +472,7 @@ wpi_attach(device_t dev)
* Read in the eeprom and also setup the channels for
* net80211. We don't set the rates as net80211 does this for us
*/
- if ((error = wpi_read_eeprom(sc, macaddr)) != 0) {
+ if ((error = wpi_read_eeprom(sc, ic->ic_macaddr)) != 0) {
device_printf(dev, "could not read EEPROM, error %d\n",
error);
goto fail;
@@ -503,20 +494,12 @@ wpi_attach(device_t dev)
}
#endif
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_softc = sc;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = wpi_init;
- ifp->if_ioctl = wpi_ioctl;
- ifp->if_start = wpi_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ieee80211_ifattach(ic, macaddr);
+ ieee80211_ifattach(ic);
ic->ic_vap_create = wpi_vap_create;
ic->ic_vap_delete = wpi_vap_delete;
+ ic->ic_parent = wpi_parent;
ic->ic_raw_xmit = wpi_raw_xmit;
+ ic->ic_transmit = wpi_transmit;
ic->ic_node_alloc = wpi_node_alloc;
sc->sc_node_free = ic->ic_node_free;
ic->ic_node_free = wpi_node_free;
@@ -543,7 +526,7 @@ wpi_attach(device_t dev)
TASK_INIT(&sc->sc_reinittask, 0, wpi_hw_reset, sc);
TASK_INIT(&sc->sc_radiooff_task, 0, wpi_radio_off, sc);
TASK_INIT(&sc->sc_radioon_task, 0, wpi_radio_on, sc);
- TASK_INIT(&sc->sc_start_task, 0, wpi_start_task, sc);
+ TASK_INIT(&sc->sc_start_task, 0, wpi_start, sc);
sc->sc_tq = taskqueue_create("wpi_taskq", M_WAITOK,
taskqueue_thread_enqueue, &sc->sc_tq);
@@ -588,14 +571,13 @@ fail: wpi_detach(dev);
static void
wpi_radiotap_attach(struct wpi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct wpi_rx_radiotap_header *rxtap = &sc->sc_rxtap;
+ struct wpi_tx_radiotap_header *txtap = &sc->sc_txtap;
+
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
- ieee80211_radiotap_attach(ic,
- &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
- WPI_TX_RADIOTAP_PRESENT,
- &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
- WPI_RX_RADIOTAP_PRESENT);
+ ieee80211_radiotap_attach(&sc->sc_ic,
+ &txtap->wt_ihdr, sizeof(*txtap), WPI_TX_RADIOTAP_PRESENT,
+ &rxtap->wr_ihdr, sizeof(*rxtap), WPI_RX_RADIOTAP_PRESENT);
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__);
}
@@ -646,12 +628,9 @@ wpi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return NULL;
- wvp = (struct wpi_vap *) malloc(sizeof(struct wpi_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (wvp == NULL)
- return NULL;
+ wvp = malloc(sizeof(struct wpi_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &wvp->wv_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
if (opmode == IEEE80211_M_IBSS || opmode == IEEE80211_M_HOSTAP) {
WPI_VAP_LOCK_INIT(wvp);
@@ -671,7 +650,7 @@ wpi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_init(vap);
/* Complete setup. */
ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -700,22 +679,21 @@ static int
wpi_detach(device_t dev)
{
struct wpi_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
int qid;
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
- if (ifp != NULL) {
- ic = ifp->if_l2com;
-
+ if (ic->ic_vap_create == wpi_vap_create) {
ieee80211_draintask(ic, &sc->sc_radioon_task);
ieee80211_draintask(ic, &sc->sc_start_task);
wpi_stop(sc);
- taskqueue_drain_all(sc->sc_tq);
- taskqueue_free(sc->sc_tq);
+ if (sc->sc_tq != NULL) {
+ taskqueue_drain_all(sc->sc_tq);
+ taskqueue_free(sc->sc_tq);
+ }
callout_drain(&sc->watchdog_rfkill);
callout_drain(&sc->tx_timeout);
@@ -748,9 +726,6 @@ wpi_detach(device_t dev)
bus_release_resource(dev, SYS_RES_MEMORY,
rman_get_rid(sc->mem), sc->mem);
- if (ifp != NULL)
- if_free(ifp);
-
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__);
WPI_TXQ_STATE_LOCK_DESTROY(sc);
WPI_TXQ_LOCK_DESTROY(sc);
@@ -774,7 +749,7 @@ static int
wpi_suspend(device_t dev)
{
struct wpi_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
ieee80211_suspend_all(ic);
return 0;
@@ -784,7 +759,7 @@ static int
wpi_resume(device_t dev)
{
struct wpi_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
/* Clear device-specific "PCI retry timeout" register (41h). */
pci_write_config(dev, 0x41, 0, 1);
@@ -1191,6 +1166,7 @@ wpi_alloc_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring, int qid)
ring->queued = 0;
ring->cur = 0;
ring->update = 0;
+ mbufq_init(&ring->snd, ifqmaxlen);
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
@@ -1318,6 +1294,7 @@ wpi_reset_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring)
memset(ring->desc, 0, ring->desc_dma.size);
bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
BUS_DMASYNC_PREWRITE);
+ mbufq_drain(&ring->snd);
sc->qfullmsk &= ~(1 << ring->qid);
ring->queued = 0;
ring->cur = 0;
@@ -1448,8 +1425,7 @@ wpi_eeprom_channel_flags(struct wpi_eeprom_chan *channel)
static void
wpi_read_eeprom_band(struct wpi_softc *sc, int n)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct wpi_eeprom_chan *channels = sc->eeprom_channels[n];
const struct wpi_chan_band *band = &wpi_bands[n];
struct ieee80211_channel *c;
@@ -1506,8 +1482,7 @@ wpi_read_eeprom_band(struct wpi_softc *sc, int n)
static int
wpi_read_eeprom_channels(struct wpi_softc *sc, int n)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
const struct wpi_chan_band *band = &wpi_bands[n];
int error;
@@ -1549,8 +1524,7 @@ static int
wpi_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
int nchan, struct ieee80211_channel chans[])
{
- struct ifnet *ifp = ic->ic_ifp;
- struct wpi_softc *sc = ifp->if_softc;
+ struct wpi_softc *sc = ic->ic_softc;
int i;
for (i = 0; i < nchan; i++) {
@@ -1559,8 +1533,7 @@ wpi_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
channel = wpi_find_eeprom_channel(sc, c);
if (channel == NULL) {
- if_printf(ic->ic_ifp,
- "%s: invalid channel %u freq %u/0x%x\n",
+ ic_printf(ic, "%s: invalid channel %u freq %u/0x%x\n",
__func__, c->ic_ieee, c->ic_freq, c->ic_flags);
return EINVAL;
}
@@ -1672,8 +1645,7 @@ wpi_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
static void
wpi_node_free(struct ieee80211_node *ni)
{
- struct ieee80211com *ic = ni->ni_ic;
- struct wpi_softc *sc = ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = ni->ni_ic->ic_softc;
struct wpi_node *wn = WPI_NODE(ni);
if (wn->id != WPI_ID_UNDEFINED) {
@@ -1700,7 +1672,7 @@ wpi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype,
int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct wpi_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = vap->iv_ic->ic_softc;
struct wpi_vap *wvp = WPI_VAP(vap);
uint64_t ni_tstamp, rx_tstamp;
@@ -1744,7 +1716,7 @@ wpi_restore_node(void *arg, struct ieee80211_node *ni)
static void
wpi_restore_node_table(struct wpi_softc *sc, struct wpi_vap *wvp)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
/* Set group keys once. */
WPI_NT_LOCK(sc);
@@ -1763,12 +1735,20 @@ wpi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct wpi_vap *wvp = WPI_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct wpi_softc *sc = ifp->if_softc;
+ struct wpi_softc *sc = ic->ic_softc;
int error = 0;
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
+ WPI_TXQ_LOCK(sc);
+ if (nstate > IEEE80211_S_INIT && sc->sc_running == 0) {
+ DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, __func__);
+ WPI_TXQ_UNLOCK(sc);
+
+ return ENXIO;
+ }
+ WPI_TXQ_UNLOCK(sc);
+
DPRINTF(sc, WPI_DEBUG_STATE, "%s: %s -> %s\n", __func__,
ieee80211_state_name[vap->iv_state],
ieee80211_state_name[nstate]);
@@ -1937,8 +1917,7 @@ static void
wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc,
struct wpi_rx_data *data)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct wpi_rx_ring *ring = &sc->rxq;
struct wpi_rx_stat *stat;
struct wpi_rx_head *head;
@@ -2019,7 +1998,6 @@ wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc,
BUS_DMASYNC_PREWRITE);
/* Finalize mbuf. */
- m->m_pkthdr.rcvif = ifp;
m->m_data = (caddr_t)(head + 1);
m->m_pkthdr.len = m->m_len = len;
@@ -2073,7 +2051,7 @@ wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc,
fail2: m_freem(m);
-fail1: if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+fail1: counter_u64_add(ic->ic_ierrors, 1);
}
static void
@@ -2086,7 +2064,6 @@ wpi_rx_statistics(struct wpi_softc *sc, struct wpi_rx_desc *desc,
static void
wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
{
- struct ifnet *ifp = sc->sc_ifp;
struct wpi_tx_ring *ring = &sc->txq[desc->qid & 0x3];
struct wpi_tx_data *data = &ring->data[desc->idx];
struct wpi_tx_stat *stat = (struct wpi_tx_stat *)(desc + 1);
@@ -2119,14 +2096,11 @@ wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
* Update rate control statistics for the node.
*/
if (status & WPI_TX_STATUS_FAIL) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL);
- } else {
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ } else
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL);
- }
ieee80211_tx_complete(ni, m, (status & WPI_TX_STATUS_FAIL) != 0);
@@ -2135,17 +2109,10 @@ wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
if (ring->queued > 0) {
callout_reset(&sc->tx_timeout, 5*hz, wpi_tx_timeout, sc);
- if (sc->qfullmsk != 0 &&
- ring->queued < WPI_TX_RING_LOMARK) {
+ if ((sc->qfullmsk & (1 << ring->qid)) != 0 &&
+ ring->queued < WPI_TX_RING_LOMARK) {
sc->qfullmsk &= ~(1 << ring->qid);
- IF_LOCK(&ifp->if_snd);
- if (sc->qfullmsk == 0 &&
- (ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- IF_UNLOCK(&ifp->if_snd);
- ieee80211_runtask(ic, &sc->sc_start_task);
- } else
- IF_UNLOCK(&ifp->if_snd);
+ ieee80211_runtask(ic, &sc->sc_start_task);
}
} else
callout_stop(&sc->tx_timeout);
@@ -2203,8 +2170,7 @@ wpi_cmd_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
static void
wpi_notif_intr(struct wpi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t hw;
@@ -2239,7 +2205,7 @@ wpi_notif_intr(struct wpi_softc *sc)
/* An 802.11 frame has been received. */
wpi_rx_done(sc, desc, data);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ if (sc->sc_running == 0) {
/* wpi_stop() was called. */
return;
}
@@ -2328,6 +2294,7 @@ wpi_notif_intr(struct wpi_softc *sc)
device_printf(sc->sc_dev,
"microcontroller initialization failed\n");
wpi_stop_locked(sc);
+ return;
}
/* Save the address of the error log in SRAM. */
sc->errptr = le32toh(uc->errptr);
@@ -2558,7 +2525,6 @@ static void
wpi_intr(void *arg)
{
struct wpi_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
uint32_t r1, r2;
WPI_LOCK(sc);
@@ -2608,7 +2574,7 @@ wpi_intr(void *arg)
done:
/* Re-enable interrupts. */
- if (ifp->if_flags & IFF_UP)
+ if (sc->sc_running)
WPI_WRITE(sc, WPI_INT_MASK, WPI_INT_MASK_DEF);
end: WPI_UNLOCK(sc);
@@ -2617,7 +2583,6 @@ end: WPI_UNLOCK(sc);
static int
wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf)
{
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211_frame *wh;
struct wpi_tx_cmd *cmd;
struct wpi_tx_data *data;
@@ -2633,7 +2598,7 @@ wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf)
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
- if (sc->txq_active == 0) {
+ if (sc->sc_running == 0) {
/* wpi_stop() was called */
error = ENETDOWN;
goto fail;
@@ -2730,14 +2695,8 @@ wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf)
if (ring->qid < WPI_CMD_QUEUE_NUM) {
/* Mark TX ring as full if we reach a certain threshold. */
WPI_TXQ_STATE_LOCK(sc);
- if (++ring->queued > WPI_TX_RING_HIMARK) {
+ if (++ring->queued > WPI_TX_RING_HIMARK)
sc->qfullmsk |= 1 << ring->qid;
-
- IF_LOCK(&ifp->if_snd);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- IF_UNLOCK(&ifp->if_snd);
- }
-
callout_reset(&sc->tx_timeout, 5*hz, wpi_tx_timeout, sc);
WPI_TXQ_STATE_UNLOCK(sc);
}
@@ -3031,24 +2990,47 @@ wpi_tx_data_raw(struct wpi_softc *sc, struct mbuf *m,
return wpi_cmd2(sc, &tx_data);
}
+static __inline int
+wpi_tx_ring_is_full(struct wpi_softc *sc, int ac)
+{
+ struct wpi_tx_ring *ring = &sc->txq[ac];
+ int retval;
+
+ WPI_TXQ_STATE_LOCK(sc);
+ retval = (ring->queued > WPI_TX_RING_HIMARK);
+ WPI_TXQ_STATE_UNLOCK(sc);
+
+ return retval;
+}
+
+static __inline void
+wpi_handle_tx_failure(struct ieee80211_node *ni)
+{
+ /* NB: m is reclaimed on tx failure */
+ if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
+ ieee80211_free_node(ni);
+}
+
static int
wpi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct wpi_softc *sc = ifp->if_softc;
- int error = 0;
+ struct wpi_softc *sc = ic->ic_softc;
+ int ac, error = 0;
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- ieee80211_free_node(ni);
+ ac = M_WME_GETAC(m);
+
+ WPI_TX_LOCK(sc);
+
+ if (sc->sc_running == 0 || wpi_tx_ring_is_full(sc, ac)) {
m_freem(m);
- return ENETDOWN;
+ error = sc->sc_running ? ENOBUFS : ENETDOWN;
+ goto unlock;
}
- WPI_TX_LOCK(sc);
if (params == NULL) {
/*
* Legacy path; interpret frame contents to decide
@@ -3062,13 +3044,11 @@ wpi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
*/
error = wpi_tx_data_raw(sc, m, ni, params);
}
- WPI_TX_UNLOCK(sc);
- if (error != 0) {
- /* NB: m is reclaimed on tx failure */
- ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+unlock: WPI_TX_UNLOCK(sc);
+ if (error != 0) {
+ wpi_handle_tx_failure(ni);
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, __func__);
return error;
@@ -3079,57 +3059,88 @@ wpi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
}
-/**
- * Process data waiting to be sent on the IFNET output queue
- */
-static void
-wpi_start(struct ifnet *ifp)
+static int
+wpi_transmit(struct ieee80211com *ic, struct mbuf *m)
{
- struct wpi_softc *sc = ifp->if_softc;
+ struct wpi_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
- struct mbuf *m;
+ struct mbufq *sndq;
+ int ac, error;
WPI_TX_LOCK(sc);
DPRINTF(sc, WPI_DEBUG_XMIT, "%s: called\n", __func__);
- for (;;) {
- IF_LOCK(&ifp->if_snd);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
- (ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
- IF_UNLOCK(&ifp->if_snd);
- break;
- }
- IF_UNLOCK(&ifp->if_snd);
+ /* Check if interface is up & running. */
+ if (sc->sc_running == 0) {
+ error = ENXIO;
+ goto unlock;
+ }
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
- if (wpi_tx_data(sc, m, ni) != 0) {
- ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- }
+ /* Check for available space. */
+ ac = M_WME_GETAC(m);
+ sndq = &sc->txq[ac].snd;
+ if (wpi_tx_ring_is_full(sc, ac) || mbufq_len(sndq) != 0) {
+ /* wpi_tx_done() will dequeue it. */
+ error = mbufq_enqueue(sndq, m);
+ goto unlock;
+ }
+
+ error = 0;
+ ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+ if (wpi_tx_data(sc, m, ni) != 0) {
+ wpi_handle_tx_failure(ni);
}
DPRINTF(sc, WPI_DEBUG_XMIT, "%s: done\n", __func__);
- WPI_TX_UNLOCK(sc);
+
+unlock: WPI_TX_UNLOCK(sc);
+
+ return (error);
}
+/**
+ * Process data waiting to be sent on the output queue
+ */
static void
-wpi_start_task(void *arg0, int pending)
+wpi_start(void *arg0, int pending)
{
struct wpi_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211_node *ni;
+ struct mbuf *m;
+ uint8_t i;
+
+ WPI_TX_LOCK(sc);
+ if (sc->sc_running == 0)
+ goto unlock;
- wpi_start(ifp);
+ DPRINTF(sc, WPI_DEBUG_XMIT, "%s: called\n", __func__);
+
+ for (i = 0; i < WPI_CMD_QUEUE_NUM; i++) {
+ struct mbufq *sndq = &sc->txq[i].snd;
+
+ for (;;) {
+ if (wpi_tx_ring_is_full(sc, i))
+ break;
+
+ if ((m = mbufq_dequeue(sndq)) == NULL)
+ break;
+
+ ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+ if (wpi_tx_data(sc, m, ni) != 0) {
+ wpi_handle_tx_failure(ni);
+ }
+ }
+ }
+
+ DPRINTF(sc, WPI_DEBUG_XMIT, "%s: done\n", __func__);
+unlock: WPI_TX_UNLOCK(sc);
}
static void
wpi_watchdog_rfkill(void *arg)
{
struct wpi_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
DPRINTF(sc, WPI_DEBUG_WATCHDOG, "RFkill Watchdog: tick\n");
@@ -3146,9 +3157,9 @@ static void
wpi_scan_timeout(void *arg)
{
struct wpi_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
- if_printf(ifp, "scan timeout\n");
+ ic_printf(ic, "scan timeout\n");
taskqueue_enqueue(sc->sc_tq, &sc->sc_reinittask);
}
@@ -3156,44 +3167,28 @@ static void
wpi_tx_timeout(void *arg)
{
struct wpi_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
- if_printf(ifp, "device timeout\n");
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ ic_printf(ic, "device timeout\n");
taskqueue_enqueue(sc->sc_tq, &sc->sc_reinittask);
}
-static int
-wpi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+wpi_parent(struct ieee80211com *ic)
{
- struct wpi_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct wpi_softc *sc = ic->ic_softc;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0;
- switch (cmd) {
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- wpi_init(sc);
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 &&
- vap != NULL)
- ieee80211_stop(vap);
- } else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
- wpi_stop(sc);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
+ if (ic->ic_nrunning > 0) {
+ if (wpi_init(sc) == 0) {
+ ieee80211_notify_radio(ic, 1);
+ ieee80211_start_all(ic);
+ } else {
+ ieee80211_notify_radio(ic, 0);
+ ieee80211_stop(vap);
+ }
+ } else
+ wpi_stop(sc);
}
/*
@@ -3215,9 +3210,13 @@ wpi_cmd(struct wpi_softc *sc, int code, const void *buf, size_t size,
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
- if (sc->txq_active == 0) {
+ if (sc->sc_running == 0) {
/* wpi_stop() was called */
- error = 0;
+ if (code == WPI_CMD_SCAN)
+ error = ENETDOWN;
+ else
+ error = 0;
+
goto fail;
}
@@ -3283,10 +3282,7 @@ wpi_cmd(struct wpi_softc *sc, int code, const void *buf, size_t size,
WPI_TXQ_UNLOCK(sc);
- if (async)
- return 0;
-
- return mtx_sleep(cmd, &sc->sc_mtx, PCATCH, "wpicmd", hz);
+ return async ? 0 : mtx_sleep(cmd, &sc->sc_mtx, PCATCH, "wpicmd", hz);
fail: DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, __func__);
@@ -3301,8 +3297,7 @@ fail: DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, __func__);
static int
wpi_mrr_setup(struct wpi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct wpi_mrr_setup mrr;
int i, error;
@@ -3399,14 +3394,13 @@ wpi_add_node(struct wpi_softc *sc, struct ieee80211_node *ni)
static int
wpi_add_broadcast_node(struct wpi_softc *sc, int async)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct wpi_node_info node;
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__);
memset(&node, 0, sizeof node);
- IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);
+ IEEE80211_ADDR_COPY(node.macaddr, ieee80211broadcastaddr);
node.id = WPI_ID_BROADCAST;
node.plcp = (ic->ic_curmode == IEEE80211_MODE_11A) ?
wpi_ridx_to_plcp[WPI_RIDX_OFDM6] : wpi_ridx_to_plcp[WPI_RIDX_CCK1];
@@ -3492,7 +3486,7 @@ static int
wpi_updateedca(struct ieee80211com *ic)
{
#define WPI_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */
- struct wpi_softc *sc = ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = ic->ic_softc;
struct wpi_edca_params cmd;
int aci, error;
@@ -3526,8 +3520,7 @@ wpi_updateedca(struct ieee80211com *ic)
static void
wpi_set_promisc(struct wpi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t promisc_filter;
@@ -3535,7 +3528,7 @@ wpi_set_promisc(struct wpi_softc *sc)
if (vap != NULL && vap->iv_opmode != IEEE80211_M_HOSTAP)
promisc_filter |= WPI_FILTER_PROMISC;
- if (ifp->if_flags & IFF_PROMISC)
+ if (ic->ic_promisc > 0)
sc->rxon.filter |= htole32(promisc_filter);
else
sc->rxon.filter &= ~htole32(promisc_filter);
@@ -3900,8 +3893,7 @@ wpi_send_rxon(struct wpi_softc *sc, int assoc, int async)
static int
wpi_config(struct wpi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_channel *c = ic->ic_curchan;
int error;
@@ -4011,7 +4003,7 @@ wpi_get_active_dwell_time(struct wpi_softc *sc,
static uint16_t
wpi_limit_dwell(struct wpi_softc *sc, uint16_t dwell_time)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
int bintval = 0;
@@ -4068,8 +4060,7 @@ wpi_get_scan_pause_time(uint32_t time, uint16_t bintval)
static int
wpi_scan(struct wpi_softc *sc, struct ieee80211_channel *c)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_scan_state *ss = ic->ic_scan;
struct ieee80211vap *vap = ss->ss_vap;
struct wpi_scan_hdr *hdr;
@@ -4171,11 +4162,9 @@ wpi_scan(struct wpi_softc *sc, struct ieee80211_channel *c)
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
IEEE80211_FC0_SUBTYPE_PROBE_REQ;
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
- IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
+ IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr);
IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr);
- IEEE80211_ADDR_COPY(wh->i_addr3, ifp->if_broadcastaddr);
- *(uint16_t *)&wh->i_dur[0] = 0; /* filled by h/w */
- *(uint16_t *)&wh->i_seq[0] = 0; /* filled by h/w */
+ IEEE80211_ADDR_COPY(wh->i_addr3, ieee80211broadcastaddr);
frm = (uint8_t *)(wh + 1);
frm = ieee80211_add_ssid(frm, NULL, 0);
@@ -4206,7 +4195,6 @@ wpi_scan(struct wpi_softc *sc, struct ieee80211_channel *c)
/*
* Calculate the active/passive dwell times.
*/
-
dwell_active = wpi_get_active_dwell_time(sc, c, nssid);
dwell_passive = wpi_get_passive_dwell_time(sc, c);
@@ -4324,7 +4312,7 @@ wpi_config_beacon(struct wpi_vap *wvp)
struct ieee80211com *ic = wvp->wv_vap.iv_ic;
struct ieee80211_beacon_offsets *bo = &wvp->wv_boff;
struct wpi_buf *bcn = &wvp->wv_bcbuf;
- struct wpi_softc *sc = ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = ic->ic_softc;
struct wpi_cmd_beacon *cmd = (struct wpi_cmd_beacon *)&bcn->data;
struct ieee80211_tim_ie *tie;
struct mbuf *m;
@@ -4406,7 +4394,7 @@ wpi_setup_beacon(struct wpi_softc *sc, struct ieee80211_node *ni)
static void
wpi_update_beacon(struct ieee80211vap *vap, int item)
{
- struct wpi_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = vap->iv_ic->ic_softc;
struct wpi_vap *wvp = WPI_VAP(vap);
struct wpi_buf *bcn = &wvp->wv_bcbuf;
struct ieee80211_beacon_offsets *bo = &wvp->wv_boff;
@@ -4448,7 +4436,7 @@ static void
wpi_newassoc(struct ieee80211_node *ni, int isnew)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = ni->ni_ic->ic_softc;
struct wpi_node *wn = WPI_NODE(ni);
int error;
@@ -4575,7 +4563,7 @@ wpi_load_key(struct ieee80211_node *ni, const struct ieee80211_key *k)
{
const struct ieee80211_cipher *cip = k->wk_cipher;
struct ieee80211vap *vap = ni->ni_vap;
- struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = ni->ni_ic->ic_softc;
struct wpi_node *wn = WPI_NODE(ni);
struct wpi_node_info node;
uint16_t kflags;
@@ -4639,7 +4627,7 @@ wpi_load_key_cb(void *arg, struct ieee80211_node *ni)
{
const struct ieee80211_key *k = arg;
struct ieee80211vap *vap = ni->ni_vap;
- struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = ni->ni_ic->ic_softc;
struct wpi_node *wn = WPI_NODE(ni);
int error;
@@ -4674,7 +4662,7 @@ static int
wpi_del_key(struct ieee80211_node *ni, const struct ieee80211_key *k)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = ni->ni_ic->ic_softc;
struct wpi_node *wn = WPI_NODE(ni);
struct wpi_node_info node;
uint16_t kflags;
@@ -4724,7 +4712,7 @@ wpi_del_key_cb(void *arg, struct ieee80211_node *ni)
{
const struct ieee80211_key *k = arg;
struct ieee80211vap *vap = ni->ni_vap;
- struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = ni->ni_ic->ic_softc;
struct wpi_node *wn = WPI_NODE(ni);
int error;
@@ -4746,7 +4734,7 @@ wpi_process_key(struct ieee80211vap *vap, const struct ieee80211_key *k,
int set)
{
struct ieee80211com *ic = vap->iv_ic;
- struct wpi_softc *sc = ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = ic->ic_softc;
struct wpi_vap *wvp = WPI_VAP(vap);
struct ieee80211_node *ni;
int error, ni_ref = 0;
@@ -5396,34 +5384,29 @@ static void
wpi_radio_on(void *arg0, int pending)
{
struct wpi_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
device_printf(sc->sc_dev, "RF switch: radio enabled\n");
- if (vap != NULL) {
- wpi_init(sc);
- ieee80211_init(vap);
- }
+ WPI_LOCK(sc);
+ callout_stop(&sc->watchdog_rfkill);
+ WPI_UNLOCK(sc);
- if (WPI_READ(sc, WPI_GP_CNTRL) & WPI_GP_CNTRL_RFKILL) {
- WPI_LOCK(sc);
- callout_stop(&sc->watchdog_rfkill);
- WPI_UNLOCK(sc);
- }
+ if (vap != NULL)
+ ieee80211_init(vap);
}
static void
wpi_radio_off(void *arg0, int pending)
{
struct wpi_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
device_printf(sc->sc_dev, "RF switch: radio disabled\n");
+ ieee80211_notify_radio(ic, 0);
wpi_stop(sc);
if (vap != NULL)
ieee80211_stop(vap);
@@ -5433,19 +5416,16 @@ wpi_radio_off(void *arg0, int pending)
WPI_UNLOCK(sc);
}
-static void
-wpi_init(void *arg)
+static int
+wpi_init(struct wpi_softc *sc)
{
- struct wpi_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- int error;
+ int error = 0;
WPI_LOCK(sc);
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ if (sc->sc_running != 0)
goto end;
/* Check that the radio is not disabled by hardware switch. */
@@ -5454,6 +5434,7 @@ wpi_init(void *arg)
"RF switch: radio disabled (%s)\n", __func__);
callout_reset(&sc->watchdog_rfkill, hz, wpi_watchdog_rfkill,
sc);
+ error = EINPROGRESS;
goto end;
}
@@ -5462,9 +5443,11 @@ wpi_init(void *arg)
device_printf(sc->sc_dev,
"%s: could not read firmware, error %d\n", __func__,
error);
- goto fail;
+ goto end;
}
+ sc->sc_running = 1;
+
/* Initialize hardware and upload firmware. */
error = wpi_hw_init(sc);
wpi_unload_firmware(sc);
@@ -5476,7 +5459,6 @@ wpi_init(void *arg)
}
/* Configure adapter now that it is ready. */
- sc->txq_active = 1;
if ((error = wpi_config(sc)) != 0) {
device_printf(sc->sc_dev,
"%s: could not configure device, error %d\n", __func__,
@@ -5484,34 +5466,34 @@ wpi_init(void *arg)
goto fail;
}
- IF_LOCK(&ifp->if_snd);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- IF_UNLOCK(&ifp->if_snd);
-
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__);
WPI_UNLOCK(sc);
- ieee80211_start_all(ic);
-
- return;
+ return 0;
fail: wpi_stop_locked(sc);
+
end: DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, __func__);
WPI_UNLOCK(sc);
+
+ return error;
}
static void
wpi_stop_locked(struct wpi_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
WPI_LOCK_ASSERT(sc);
+ if (sc->sc_running == 0)
+ return;
+
+ WPI_TX_LOCK(sc);
WPI_TXQ_LOCK(sc);
- sc->txq_active = 0;
+ sc->sc_running = 0;
WPI_TXQ_UNLOCK(sc);
+ WPI_TX_UNLOCK(sc);
WPI_TXQ_STATE_LOCK(sc);
callout_stop(&sc->tx_timeout);
@@ -5522,10 +5504,6 @@ wpi_stop_locked(struct wpi_softc *sc)
callout_stop(&sc->calib_to);
WPI_RXON_UNLOCK(sc);
- IF_LOCK(&ifp->if_snd);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
- IF_UNLOCK(&ifp->if_snd);
-
/* Power OFF hardware. */
wpi_hw_stop(sc);
}
@@ -5544,7 +5522,7 @@ wpi_stop(struct wpi_softc *sc)
static void
wpi_scan_start(struct ieee80211com *ic)
{
- struct wpi_softc *sc = ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = ic->ic_softc;
wpi_set_led(sc, WPI_LED_LINK, 20, 2);
}
@@ -5555,8 +5533,7 @@ wpi_scan_start(struct ieee80211com *ic)
static void
wpi_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct wpi_softc *sc = ifp->if_softc;
+ struct wpi_softc *sc = ic->ic_softc;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
if (vap->iv_state == IEEE80211_S_RUN)
@@ -5571,8 +5548,7 @@ static void
wpi_set_channel(struct ieee80211com *ic)
{
const struct ieee80211_channel *c = ic->ic_curchan;
- struct ifnet *ifp = ic->ic_ifp;
- struct wpi_softc *sc = ifp->if_softc;
+ struct wpi_softc *sc = ic->ic_softc;
int error;
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__);
@@ -5618,7 +5594,7 @@ wpi_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
{
struct ieee80211vap *vap = ss->ss_vap;
struct ieee80211com *ic = vap->iv_ic;
- struct wpi_softc *sc = ic->ic_ifp->if_softc;
+ struct wpi_softc *sc = ic->ic_softc;
int error;
WPI_RXON_LOCK(sc);
@@ -5644,19 +5620,18 @@ static void
wpi_hw_reset(void *arg, int pending)
{
struct wpi_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__);
+ ieee80211_notify_radio(ic, 0);
if (vap != NULL && (ic->ic_flags & IEEE80211_F_SCAN))
ieee80211_cancel_scan(vap);
wpi_stop(sc);
- if (vap != NULL)
+ if (vap != NULL) {
ieee80211_stop(vap);
- wpi_init(sc);
- if (vap != NULL)
ieee80211_init(vap);
+ }
}
diff --git a/sys/dev/wpi/if_wpivar.h b/sys/dev/wpi/if_wpivar.h
index b783528..4e1baa5 100644
--- a/sys/dev/wpi/if_wpivar.h
+++ b/sys/dev/wpi/if_wpivar.h
@@ -72,6 +72,7 @@ struct wpi_tx_ring {
struct wpi_tx_cmd *cmd;
struct wpi_tx_data data[WPI_TX_RING_COUNT];
bus_dma_tag_t data_dmat;
+ struct mbufq snd;
int qid;
int queued;
int cur;
@@ -164,14 +165,15 @@ struct wpi_fw_info {
struct wpi_softc {
device_t sc_dev;
-
- struct ifnet *sc_ifp;
int sc_debug;
int sc_flags;
#define WPI_PS_PATH (1 << 0)
+ int sc_running;
struct mtx sc_mtx;
+ struct ieee80211com sc_ic;
+
struct mtx tx_mtx;
/* Shared area. */
@@ -181,7 +183,6 @@ struct wpi_softc {
struct wpi_tx_ring txq[WPI_NTXQUEUES];
struct mtx txq_mtx;
struct mtx txq_state_mtx;
- uint32_t txq_active;
struct wpi_rx_ring rxq;
uint64_t rx_tstamp;
diff --git a/sys/dev/wtap/if_wtap.c b/sys/dev/wtap/if_wtap.c
index f6dbe77..526ce54 100644
--- a/sys/dev/wtap/if_wtap.c
+++ b/sys/dev/wtap/if_wtap.c
@@ -261,7 +261,7 @@ static int
wtap_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct ieee80211com *ic = vap->iv_ic;
- struct wtap_softc *sc = ic->ic_ifp->if_softc;
+ struct wtap_softc *sc = ic->ic_softc;
struct wtap_vap *avp = WTAP_VAP(vap);
struct ieee80211_node *ni = NULL;
int error;
@@ -318,7 +318,7 @@ wtap_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct wtap_softc *sc = ic->ic_ifp->if_softc;
+ struct wtap_softc *sc = ic->ic_softc;
struct ieee80211vap *vap;
struct wtap_vap *avp;
int error;
@@ -326,15 +326,13 @@ wtap_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
DWTAP_PRINTF("%s\n", __func__);
- avp = malloc(sizeof(struct wtap_vap), M_80211_VAP, M_NOWAIT | M_ZERO);
- if (avp == NULL)
- return (NULL);
+ avp = malloc(sizeof(struct wtap_vap), M_80211_VAP, M_WAITOK | M_ZERO);
avp->id = sc->id;
avp->av_md = sc->sc_md;
avp->av_bcinterval = msecs_to_ticks(BEACON_INTRERVAL + 100*sc->id);
vap = (struct ieee80211vap *) avp;
error = ieee80211_vap_setup(ic, vap, name, unit, IEEE80211_M_MBSS,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
+ flags | IEEE80211_CLONE_NOBEACONS, bssid);
if (error) {
free(avp, M_80211_VAP);
return (NULL);
@@ -351,9 +349,10 @@ wtap_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
vap->iv_bmiss = wtap_bmiss;
/* complete setup */
- ieee80211_vap_attach(vap, wtap_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, wtap_media_change, ieee80211_media_status,
+ mac);
avp->av_dev = make_dev(&wtap_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
- "%s", (const char *)ic->ic_ifp->if_xname);
+ "%s", (const char *)sc->name);
/* TODO this is a hack to force it to choose the rate we want */
ni = ieee80211_ref_node(vap->iv_bss);
@@ -374,148 +373,16 @@ wtap_vap_delete(struct ieee80211vap *vap)
free((struct wtap_vap*) vap, M_80211_VAP);
}
-/* NB: This function is not used.
- * I had the problem of the queue
- * being empty all the time.
- * Maybe I am setting the queue wrong?
- */
static void
-wtap_start(struct ifnet *ifp)
+wtap_parent(struct ieee80211com *ic)
{
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifnet *icifp = ic->ic_ifp;
- struct wtap_softc *sc = icifp->if_softc;
- struct ieee80211_node *ni;
- struct mbuf *m;
-
- DWTAP_PRINTF("my_start, with id=%u\n", sc->id);
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->up == 0)
- return;
- for (;;) {
- if(IFQ_IS_EMPTY(&ifp->if_snd)){
- printf("queue empty, just trying to see "
- "if the other queue is empty\n");
-#if 0
- printf("queue for id=1, %u\n",
- IFQ_IS_EMPTY(&global_mscs[1]->ifp->if_snd));
- printf("queue for id=0, %u\n",
- IFQ_IS_EMPTY(&global_mscs[0]->ifp->if_snd));
-#endif
- break;
- }
- IFQ_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL) {
- printf("error dequeueing from ifp->snd\n");
- break;
- }
- ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
- /*
- * Check for fragmentation. If this frame
- * has been broken up verify we have enough
- * buffers to send all the fragments so all
- * go out or none...
- */
-#if 0
- STAILQ_INIT(&frags);
-#endif
- if ((m->m_flags & M_FRAG)){
- printf("dont support frags\n");
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- return;
- }
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- if(wtap_raw_xmit(ni, m, NULL) < 0){
- printf("error raw_xmiting\n");
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- return;
- }
- }
-}
-
-static int
-wtap_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
-#if 0
- DWTAP_PRINTF("%s\n", __func__);
- uprintf("%s, command %lu\n", __func__, cmd);
-#endif
-#define IS_RUNNING(ifp) \
- ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
- struct ieee80211com *ic = ifp->if_l2com;
- struct wtap_softc *sc = ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *)data;
- int error = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- //printf("%s: %s\n", __func__, "SIOCSIFFLAGS");
- if (IS_RUNNING(ifp)) {
- DWTAP_PRINTF("running\n");
-#if 0
- /*
- * To avoid rescanning another access point,
- * do not call ath_init() here. Instead,
- * only reflect promisc mode settings.
- */
- //ath_mode_init(sc);
-#endif
- } else if (ifp->if_flags & IFF_UP) {
- DWTAP_PRINTF("up\n");
- sc->up = 1;
-#if 0
- /*
- * Beware of being called during attach/detach
- * to reset promiscuous mode. In that case we
- * will still be marked UP but not RUNNING.
- * However trying to re-init the interface
- * is the wrong thing to do as we've already
- * torn down much of our state. There's
- * probably a better way to deal with this.
- */
- //if (!sc->sc_invalid)
- // ath_init(sc); /* XXX lose error */
-#endif
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ieee80211_start_all(ic);
- } else {
- DWTAP_PRINTF("stoping\n");
-#if 0
- ath_stop_locked(ifp);
-#ifdef notyet
- /* XXX must wakeup in places like ath_vap_delete */
- if (!sc->sc_invalid)
- ath_hal_setpower(sc->sc_ah, HAL_PM_FULL_SLEEP);
-#endif
-#endif
- }
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
-#if 0
- DWTAP_PRINTF("%s: %s\n", __func__, "SIOCGIFMEDIA|SIOCSIFMEDIA");
-#endif
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
-#if 0
- DWTAP_PRINTF("%s: %s\n", __func__, "SIOCGIFADDR");
-#endif
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- DWTAP_PRINTF("%s: %s [%lu]\n", __func__, "EINVAL", cmd);
- error = EINVAL;
- break;
- }
- return error;
-#undef IS_RUNNING
-}
-
-static void
-wtap_init(void *arg){
+ struct wtap_softc *sc = ic->ic_softc;
- DWTAP_PRINTF("%s\n", __func__);
+ if (ic->ic_nrunning > 0) {
+ sc->up = 1;
+ ieee80211_start_all(ic);
+ } else
+ sc->up = 0;
}
static void
@@ -581,8 +448,7 @@ wtap_inject(struct wtap_softc *sc, struct mbuf *m)
void
wtap_rx_deliver(struct wtap_softc *sc, struct mbuf *m)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
int type;
#if 0
@@ -591,11 +457,9 @@ wtap_rx_deliver(struct wtap_softc *sc, struct mbuf *m)
DWTAP_PRINTF("[%d] receiving m=%p\n", sc->id, m);
if (m == NULL) { /* NB: shouldn't happen */
- if_printf(ifp, "%s: no mbuf!\n", __func__);
+ ic_printf(ic, "%s: no mbuf!\n", __func__);
}
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
-
ieee80211_dump_pkt(ic, mtod(m, caddr_t), 0,0,0);
/*
@@ -620,8 +484,7 @@ static void
wtap_rx_proc(void *arg, int npending)
{
struct wtap_softc *sc = (struct wtap_softc *)arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct mbuf *m;
struct ieee80211_node *ni;
int type;
@@ -644,12 +507,10 @@ wtap_rx_proc(void *arg, int npending)
m = bf->m;
DWTAP_PRINTF("[%d] receiving m=%p\n", sc->id, bf->m);
if (m == NULL) { /* NB: shouldn't happen */
- if_printf(ifp, "%s: no mbuf!\n", __func__);
+ ic_printf(ic, "%s: no mbuf!\n", __func__);
free(bf, M_WTAP_RXBUF);
return;
}
-
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
#if 0
ieee80211_dump_pkt(ic, mtod(m, caddr_t), 0,0,0);
#endif
@@ -716,7 +577,7 @@ wtap_update_promisc(struct ieee80211com *ic)
}
static int
-wtap_if_transmit(struct ifnet *ifp, struct mbuf *m)
+wtap_transmit(struct ieee80211com *ic, struct mbuf *m)
{
struct ieee80211_node *ni =
(struct ieee80211_node *) m->m_pkthdr.rcvif;
@@ -753,7 +614,7 @@ static void
wtap_node_free(struct ieee80211_node *ni)
{
struct ieee80211com *ic = ni->ni_ic;
- struct wtap_softc *sc = ic->ic_ifp->if_softc;
+ struct wtap_softc *sc = ic->ic_softc;
DWTAP_PRINTF("%s\n", __func__);
sc->sc_node_free(ni);
@@ -762,41 +623,17 @@ wtap_node_free(struct ieee80211_node *ni)
int32_t
wtap_attach(struct wtap_softc *sc, const uint8_t *macaddr)
{
- struct ifnet *ifp;
- struct ieee80211com *ic;
- char wtap_name[] = {'w','T','a','p',sc->id,
- '_','t','a','s','k','q','\0'};
+ struct ieee80211com *ic = &sc->sc_ic;
DWTAP_PRINTF("%s\n", __func__);
- ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- printf("can not if_alloc()\n");
- return -1;
- }
- ic = ifp->if_l2com;
- if_initname(ifp, "wtap", sc->id);
-
- sc->sc_ifp = ifp;
sc->up = 0;
-
STAILQ_INIT(&sc->sc_rxbuf);
- sc->sc_tq = taskqueue_create(wtap_name, M_NOWAIT | M_ZERO,
+ sc->sc_tq = taskqueue_create("wtap_taskq", M_NOWAIT | M_ZERO,
taskqueue_thread_enqueue, &sc->sc_tq);
- taskqueue_start_threads(&sc->sc_tq, 1, PI_SOFT, "%s taskQ",
- ifp->if_xname);
+ taskqueue_start_threads(&sc->sc_tq, 1, PI_SOFT, "%s taskQ", sc->name);
TASK_INIT(&sc->sc_rxtask, 0, wtap_rx_proc, sc);
- ifp->if_softc = sc;
- ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
- ifp->if_start = wtap_start;
- ifp->if_ioctl = wtap_ioctl;
- ifp->if_init = wtap_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;
ic->ic_softc = sc;
ic->ic_name = sc->name;
ic->ic_phytype = IEEE80211_T_DS;
@@ -815,17 +652,8 @@ wtap_attach(struct wtap_softc *sc, const uint8_t *macaddr)
ic->ic_channels[0].ic_flags = IEEE80211_CHAN_B;
ic->ic_channels[0].ic_freq = 2412;
- ieee80211_ifattach(ic, macaddr);
-
-#if 0
- /* new prototype hook-ups */
- msc->if_input = ifp->if_input;
- ifp->if_input = myath_if_input;
- msc->if_output = ifp->if_output;
- ifp->if_output = myath_if_output;
-#endif
- sc->if_transmit = ifp->if_transmit;
- ifp->if_transmit = wtap_if_transmit;
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, macaddr);
+ ieee80211_ifattach(ic);
/* override default methods */
ic->ic_newassoc = wtap_newassoc;
@@ -835,15 +663,14 @@ wtap_attach(struct wtap_softc *sc, const uint8_t *macaddr)
ic->ic_raw_xmit = wtap_raw_xmit;
ic->ic_update_mcast = wtap_update_mcast;
ic->ic_update_promisc = wtap_update_promisc;
+ ic->ic_transmit = wtap_transmit;
+ ic->ic_parent = wtap_parent;
sc->sc_node_alloc = ic->ic_node_alloc;
ic->ic_node_alloc = wtap_node_alloc;
sc->sc_node_free = ic->ic_node_free;
ic->ic_node_free = wtap_node_free;
-#if 0
- ic->ic_node_getsignal = myath_node_getsignal;
-#endif
ic->ic_scan_start = wtap_scan_start;
ic->ic_scan_end = wtap_scan_end;
ic->ic_set_channel = wtap_set_channel;
@@ -882,13 +709,11 @@ wtap_attach(struct wtap_softc *sc, const uint8_t *macaddr)
int32_t
wtap_detach(struct wtap_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
DWTAP_PRINTF("%s\n", __func__);
ieee80211_ageq_drain(&ic->ic_stageq);
ieee80211_ifdetach(ic);
- if_free(ifp);
return 0;
}
diff --git a/sys/dev/wtap/if_wtapvar.h b/sys/dev/wtap/if_wtapvar.h
index a886be9..04a1818 100644
--- a/sys/dev/wtap/if_wtapvar.h
+++ b/sys/dev/wtap/if_wtapvar.h
@@ -130,18 +130,14 @@ struct wtap_vap {
struct taskqueue;
struct wtap_softc {
+ struct ieee80211com sc_ic;
char name[7]; /* wtapXX\0 */
int32_t id;
int32_t up;
- struct ifnet *sc_ifp; /* interface common */
struct wtap_medium *sc_md; /* interface medium */
struct ieee80211_node* (* sc_node_alloc)
(struct ieee80211vap *, const uint8_t [IEEE80211_ADDR_LEN]);
void (*sc_node_free)(struct ieee80211_node *);
- int (*if_output) /* output routine (enqueue) */
- (struct ifnet *, struct mbuf *, struct sockaddr *, struct route *);
- void (*if_input) (struct ifnet *, struct mbuf *);/* from h/w driver */
- int (*if_transmit)(struct ifnet *, struct mbuf *);/* output routine */
struct mtx sc_mtx; /* master lock (recursive) */
struct taskqueue *sc_tq; /* private task queue */
wtap_bufhead sc_rxbuf; /* receive buffer */
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index 3902227..39e03ea 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
+#include <sys/sbuf.h>
#include <machine/stdarg.h>
@@ -91,8 +92,6 @@ static void ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag);
static int ieee80211_media_setup(struct ieee80211com *ic,
struct ifmedia *media, int caps, int addsta,
ifm_change_cb_t media_change, ifm_stat_cb_t media_stat);
-static void ieee80211com_media_status(struct ifnet *, struct ifmediareq *);
-static int ieee80211com_media_change(struct ifnet *);
static int media_status(enum ieee80211_opmode,
const struct ieee80211_channel *);
static uint64_t ieee80211_get_counter(struct ifnet *, ift_counter);
@@ -121,7 +120,7 @@ static const struct ieee80211_rateset ieee80211_rateset_11g =
* all available channels as active, and pick
* a default channel if not already specified.
*/
-static void
+void
ieee80211_chan_init(struct ieee80211com *ic)
{
#define DEFAULTRATES(m, def) do { \
@@ -238,29 +237,6 @@ null_update_promisc(struct ieee80211com *ic)
ic_printf(ic, "need promiscuous mode update callback\n");
}
-static int
-null_transmit(struct ifnet *ifp, struct mbuf *m)
-{
- m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- return EACCES; /* XXX EIO/EPERM? */
-}
-
-static int
-null_output(struct ifnet *ifp, struct mbuf *m,
- const struct sockaddr *dst, struct route *ro)
-{
- if_printf(ifp, "discard raw packet\n");
- return null_transmit(ifp, m);
-}
-
-static void
-null_input(struct ifnet *ifp, struct mbuf *m)
-{
- if_printf(ifp, "if_input should not be called\n");
- m_freem(m);
-}
-
static void
null_update_chw(struct ieee80211com *ic)
{
@@ -281,19 +257,43 @@ ic_printf(struct ieee80211com *ic, const char * fmt, ...)
return (retval);
}
+static LIST_HEAD(, ieee80211com) ic_head = LIST_HEAD_INITIALIZER(ic_head);
+static struct mtx ic_list_mtx;
+MTX_SYSINIT(ic_list, &ic_list_mtx, "ieee80211com list", MTX_DEF);
+
+static int
+sysctl_ieee80211coms(SYSCTL_HANDLER_ARGS)
+{
+ struct ieee80211com *ic;
+ struct sbuf *sb;
+ char *sp;
+ int error;
+
+ sb = sbuf_new_auto();
+ sp = "";
+ mtx_lock(&ic_list_mtx);
+ LIST_FOREACH(ic, &ic_head, ic_next) {
+ sbuf_printf(sb, "%s%s", sp, ic->ic_name);
+ sp = " ";
+ }
+ mtx_unlock(&ic_list_mtx);
+ sbuf_finish(sb);
+ error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
+ sbuf_delete(sb);
+ return (error);
+}
+
+SYSCTL_PROC(_net_wlan, OID_AUTO, devices,
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
+ sysctl_ieee80211coms, "A", "names of available 802.11 devices");
+
/*
* Attach/setup the common net80211 state. Called by
* the driver on attach to prior to creating any vap's.
*/
void
-ieee80211_ifattach(struct ieee80211com *ic,
- const uint8_t macaddr[IEEE80211_ADDR_LEN])
+ieee80211_ifattach(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct sockaddr_dl *sdl;
- struct ifaddr *ifa;
-
- KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type));
IEEE80211_LOCK_INIT(ic, ic->ic_name);
IEEE80211_TX_LOCK_INIT(ic, ic->ic_name);
@@ -311,7 +311,7 @@ ieee80211_ifattach(struct ieee80211com *ic,
* available channels as active, and pick a default
* channel if not already specified.
*/
- ieee80211_media_init(ic);
+ ieee80211_chan_init(ic);
ic->ic_update_mcast = null_update_mcast;
ic->ic_update_promisc = null_update_promisc;
@@ -336,28 +336,9 @@ ieee80211_ifattach(struct ieee80211com *ic,
ieee80211_sysctl_attach(ic);
- ifp->if_addrlen = IEEE80211_ADDR_LEN;
- ifp->if_hdrlen = 0;
-
- CURVNET_SET(vnet0);
-
- if_attach(ifp);
-
- ifp->if_mtu = IEEE80211_MTU_MAX;
- ifp->if_broadcastaddr = ieee80211broadcastaddr;
- ifp->if_output = null_output;
- ifp->if_input = null_input; /* just in case */
- ifp->if_resolvemulti = NULL; /* NB: callers check */
-
- ifa = ifaddr_byindex(ifp->if_index);
- KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__));
- sdl = (struct sockaddr_dl *)ifa->ifa_addr;
- sdl->sdl_type = IFT_ETHER; /* XXX IFT_IEEE80211? */
- sdl->sdl_alen = IEEE80211_ADDR_LEN;
- IEEE80211_ADDR_COPY(LLADDR(sdl), macaddr);
- ifa_free(ifa);
-
- CURVNET_RESTORE();
+ mtx_lock(&ic_list_mtx);
+ LIST_INSERT_HEAD(&ic_head, ic, ic_next);
+ mtx_unlock(&ic_list_mtx);
}
/*
@@ -369,16 +350,11 @@ ieee80211_ifattach(struct ieee80211com *ic,
void
ieee80211_ifdetach(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211vap *vap;
- /*
- * This detaches the main interface, but not the vaps.
- * Each VAP may be in a separate VIMAGE.
- */
- CURVNET_SET(ifp->if_vnet);
- if_detach(ifp);
- CURVNET_RESTORE();
+ mtx_lock(&ic_list_mtx);
+ LIST_REMOVE(ic, ic_next);
+ mtx_unlock(&ic_list_mtx);
/*
* The VAP is responsible for setting and clearing
@@ -402,8 +378,6 @@ ieee80211_ifdetach(struct ieee80211com *ic)
ieee80211_power_detach(ic);
ieee80211_node_detach(ic);
- /* XXX VNET needed? */
- ifmedia_removeall(&ic->ic_media);
counter_u64_free(ic->ic_ierrors);
counter_u64_free(ic->ic_oerrors);
@@ -412,6 +386,20 @@ ieee80211_ifdetach(struct ieee80211com *ic)
IEEE80211_LOCK_DESTROY(ic);
}
+struct ieee80211com *
+ieee80211_find_com(const char *name)
+{
+ struct ieee80211com *ic;
+
+ mtx_lock(&ic_list_mtx);
+ LIST_FOREACH(ic, &ic_head, ic_next)
+ if (strcmp(ic->ic_name, name) == 0)
+ break;
+ mtx_unlock(&ic_list_mtx);
+
+ return (ic);
+}
+
/*
* Default reset method for use with the ioctl support. This
* method is invoked after any state change in the 802.11
@@ -460,8 +448,7 @@ ieee80211_get_counter(struct ifnet *ifp, ift_counter cnt)
int
ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode,
- int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t macaddr[IEEE80211_ADDR_LEN])
+ int flags, const uint8_t bssid[IEEE80211_ADDR_LEN])
{
struct ifnet *ifp;
@@ -490,6 +477,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
vap->iv_htextcaps = ic->ic_htextcaps;
vap->iv_opmode = opmode;
vap->iv_caps |= ieee80211_opcap[opmode];
+ vap->iv_myaddr = ic->ic_macaddr;
switch (opmode) {
case IEEE80211_M_WDS:
/*
@@ -556,8 +544,6 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
*/
vap->iv_reset = default_reset;
- IEEE80211_ADDR_COPY(vap->iv_myaddr, macaddr);
-
ieee80211_sysctl_vattach(vap);
ieee80211_crypto_vattach(vap);
ieee80211_node_vattach(vap);
@@ -581,8 +567,8 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
* from this call the vap is ready for use.
*/
int
-ieee80211_vap_attach(struct ieee80211vap *vap,
- ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
+ieee80211_vap_attach(struct ieee80211vap *vap, ifm_change_cb_t media_change,
+ ifm_stat_cb_t media_stat, const uint8_t macaddr[IEEE80211_ADDR_LEN])
{
struct ifnet *ifp = vap->iv_ifp;
struct ieee80211com *ic = vap->iv_ic;
@@ -610,7 +596,8 @@ ieee80211_vap_attach(struct ieee80211vap *vap,
if (maxrate)
ifp->if_baudrate = IF_Mbps(maxrate);
- ether_ifattach(ifp, vap->iv_myaddr);
+ ether_ifattach(ifp, macaddr);
+ vap->iv_myaddr = IF_LLADDR(ifp);
/* hook output method setup by ether_ifattach */
vap->iv_output = ifp->if_output;
ifp->if_output = ieee80211_output;
@@ -626,8 +613,6 @@ ieee80211_vap_attach(struct ieee80211vap *vap,
ieee80211_syncflag_locked(ic, IEEE80211_F_BURST);
ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT);
ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
- ieee80211_syncifflag_locked(ic, IFF_PROMISC);
- ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
IEEE80211_UNLOCK(ic);
return 1;
@@ -677,8 +662,10 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
/* NB: this handles the bpfdetach done below */
ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF);
- ieee80211_syncifflag_locked(ic, IFF_PROMISC);
- ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
+ if (vap->iv_ifflags & IFF_PROMISC)
+ ieee80211_promisc(vap, false);
+ if (vap->iv_ifflags & IFF_ALLMULTI)
+ ieee80211_allmulti(vap, false);
IEEE80211_UNLOCK(ic);
ifmedia_removeall(&vap->iv_media);
@@ -703,49 +690,57 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
}
/*
- * Synchronize flag bit state in the parent ifnet structure
- * according to the state of all vap ifnet's. This is used,
- * for example, to handle IFF_PROMISC and IFF_ALLMULTI.
+ * Count number of vaps in promisc, and issue promisc on
+ * parent respectively.
*/
void
-ieee80211_syncifflag_locked(struct ieee80211com *ic, int flag)
+ieee80211_promisc(struct ieee80211vap *vap, bool on)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct ieee80211vap *vap;
- int bit, oflags;
+ struct ieee80211com *ic = vap->iv_ic;
- IEEE80211_LOCK_ASSERT(ic);
+ /*
+ * XXX the bridge sets PROMISC but we don't want to
+ * enable it on the device, discard here so all the
+ * drivers don't need to special-case it
+ */
+ if (!(vap->iv_opmode == IEEE80211_M_MONITOR ||
+ (vap->iv_opmode == IEEE80211_M_AHDEMO &&
+ (vap->iv_caps & IEEE80211_C_TDMA) == 0)))
+ return;
- bit = 0;
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
- if (vap->iv_ifp->if_flags & flag) {
- /*
- * XXX the bridge sets PROMISC but we don't want to
- * enable it on the device, discard here so all the
- * drivers don't need to special-case it
- */
- if (flag == IFF_PROMISC &&
- !(vap->iv_opmode == IEEE80211_M_MONITOR ||
- (vap->iv_opmode == IEEE80211_M_AHDEMO &&
- (vap->iv_caps & IEEE80211_C_TDMA) == 0)))
- continue;
- bit = 1;
- break;
- }
- oflags = ifp->if_flags;
- if (bit)
- ifp->if_flags |= flag;
- else
- ifp->if_flags &= ~flag;
- if ((ifp->if_flags ^ oflags) & flag) {
- /* XXX should we return 1/0 and let caller do this? */
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if (flag == IFF_PROMISC)
- ieee80211_runtask(ic, &ic->ic_promisc_task);
- else if (flag == IFF_ALLMULTI)
- ieee80211_runtask(ic, &ic->ic_mcast_task);
- }
+ IEEE80211_LOCK(ic);
+ if (on) {
+ if (++ic->ic_promisc == 1)
+ ieee80211_runtask(ic, &ic->ic_promisc_task);
+ } else {
+ KASSERT(ic->ic_promisc > 0, ("%s: ic %p not promisc",
+ __func__, ic));
+ if (--ic->ic_promisc == 0)
+ ieee80211_runtask(ic, &ic->ic_promisc_task);
}
+ IEEE80211_UNLOCK(ic);
+}
+
+/*
+ * Count number of vaps in allmulti, and issue allmulti on
+ * parent respectively.
+ */
+void
+ieee80211_allmulti(struct ieee80211vap *vap, bool on)
+{
+ struct ieee80211com *ic = vap->iv_ic;
+
+ IEEE80211_LOCK(ic);
+ if (on) {
+ if (++ic->ic_allmulti == 1)
+ ieee80211_runtask(ic, &ic->ic_mcast_task);
+ } else {
+ KASSERT(ic->ic_allmulti > 0, ("%s: ic %p not allmulti",
+ __func__, ic));
+ if (--ic->ic_allmulti == 0)
+ ieee80211_runtask(ic, &ic->ic_mcast_task);
+ }
+ IEEE80211_UNLOCK(ic);
}
/*
@@ -1234,39 +1229,6 @@ ieee80211_media_setup(struct ieee80211com *ic,
return maxrate;
}
-void
-ieee80211_media_init(struct ieee80211com *ic)
-{
- struct ifnet *ifp = ic->ic_ifp;
- int maxrate;
-
- /* NB: this works because the structure is initialized to zero */
- if (!LIST_EMPTY(&ic->ic_media.ifm_list)) {
- /*
- * We are re-initializing the channel list; clear
- * the existing media state as the media routines
- * don't suppress duplicates.
- */
- ifmedia_removeall(&ic->ic_media);
- }
- ieee80211_chan_init(ic);
-
- /*
- * Recalculate media settings in case new channel list changes
- * the set of available modes.
- */
- maxrate = ieee80211_media_setup(ic, &ic->ic_media, ic->ic_caps, 1,
- ieee80211com_media_change, ieee80211com_media_status);
- /* NB: strip explicit mode; we're actually in autoselect */
- ifmedia_set(&ic->ic_media,
- media_status(ic->ic_opmode, ic->ic_curchan) &~
- (IFM_MMASK | IFM_IEEE80211_TURBO));
- if (maxrate)
- ifp->if_baudrate = IF_Mbps(maxrate);
-
- /* XXX need to propagate new media settings to vap's */
-}
-
/* XXX inline or eliminate? */
const struct ieee80211_rateset *
ieee80211_get_suprates(struct ieee80211com *ic, const struct ieee80211_channel *c)
@@ -1395,15 +1357,6 @@ media2mode(const struct ifmedia_entry *ime, uint32_t flags, uint16_t *mode)
}
/*
- * Handle a media change request on the underlying interface.
- */
-int
-ieee80211com_media_change(struct ifnet *ifp)
-{
- return EINVAL;
-}
-
-/*
* Handle a media change request on the vap interface.
*/
int
@@ -1480,23 +1433,6 @@ media_status(enum ieee80211_opmode opmode, const struct ieee80211_channel *chan)
return status;
}
-static void
-ieee80211com_media_status(struct ifnet *ifp, struct ifmediareq *imr)
-{
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap;
-
- imr->ifm_status = IFM_AVALID;
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
- if (vap->iv_ifp->if_flags & IFF_UP) {
- imr->ifm_status |= IFM_ACTIVE;
- break;
- }
- imr->ifm_active = media_status(ic->ic_opmode, ic->ic_curchan);
- if (imr->ifm_status & IFM_ACTIVE)
- imr->ifm_current = imr->ifm_active;
-}
-
void
ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr)
{
diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c
index e646cf2..ae4910c 100644
--- a/sys/net80211/ieee80211_ddb.c
+++ b/sys/net80211/ieee80211_ddb.c
@@ -520,7 +520,7 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta,
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
db_printf(" %s(%p)", vap->iv_ifp->if_xname, vap);
db_printf("\n");
- db_printf("\tifp %p(%s)", ic->ic_ifp, ic->ic_ifp->if_xname);
+ db_printf("\tsoftc %p", ic->ic_softc);
db_printf("\tname %s", ic->ic_name);
db_printf(" comlock %p", &ic->ic_comlock);
db_printf("\n");
@@ -528,7 +528,6 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta,
db_printf(" phytype %d", ic->ic_phytype);
db_printf(" opmode %s", ieee80211_opmode_name[ic->ic_opmode]);
db_printf("\n");
- db_printf("\tmedia %p", &ic->ic_media);
db_printf(" inact %p", &ic->ic_inact);
db_printf("\n");
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 3af75df..9a8e941 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -69,58 +69,27 @@ static MALLOC_DEFINE(M_80211_COM, "80211com", "802.11 com state");
static const char wlanname[] = "wlan";
static struct if_clone *wlan_cloner;
-/*
- * Allocate/free com structure in conjunction with ifnet;
- * these routines are registered with if_register_com_alloc
- * below and are called automatically by the ifnet code
- * when the ifnet of the parent device is created.
- */
-static void *
-wlan_alloc(u_char type, struct ifnet *ifp)
-{
- struct ieee80211com *ic;
-
- ic = IEEE80211_MALLOC(sizeof(struct ieee80211com), M_80211_COM,
- IEEE80211_M_WAITOK | IEEE80211_M_ZERO);
- ic->ic_ifp = ifp;
-
- return (ic);
-}
-
-static void
-wlan_free(void *ic, u_char type)
-{
- IEEE80211_FREE(ic, M_80211_COM);
-}
-
static int
wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
{
struct ieee80211_clone_params cp;
struct ieee80211vap *vap;
struct ieee80211com *ic;
- struct ifnet *ifp;
int error;
error = copyin(params, &cp, sizeof(cp));
if (error)
return error;
- ifp = ifunit(cp.icp_parent);
- if (ifp == NULL)
+ ic = ieee80211_find_com(cp.icp_parent);
+ if (ic == NULL)
return ENXIO;
- /* XXX move printfs to DIAGNOSTIC before release */
- if (ifp->if_type != IFT_IEEE80211) {
- if_printf(ifp, "%s: reject, not an 802.11 device\n", __func__);
- return ENXIO;
- }
if (cp.icp_opmode >= IEEE80211_OPMODE_MAX) {
- if_printf(ifp, "%s: invalid opmode %d\n",
- __func__, cp.icp_opmode);
+ ic_printf(ic, "%s: invalid opmode %d\n", __func__,
+ cp.icp_opmode);
return EINVAL;
}
- ic = ifp->if_l2com;
if ((ic->ic_caps & ieee80211_opcap[cp.icp_opmode]) == 0) {
- if_printf(ifp, "%s mode not supported\n",
+ ic_printf(ic, "%s mode not supported\n",
ieee80211_opmode_name[cp.icp_opmode]);
return EOPNOTSUPP;
}
@@ -131,13 +100,13 @@ wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
(1)
#endif
) {
- if_printf(ifp, "TDMA not supported\n");
+ ic_printf(ic, "TDMA not supported\n");
return EOPNOTSUPP;
}
vap = ic->ic_vap_create(ic, wlanname, unit,
cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
cp.icp_flags & IEEE80211_CLONE_MACADDR ?
- cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp));
+ cp.icp_macaddr : ic->ic_macaddr);
return (vap == NULL ? EIO : 0);
}
@@ -528,17 +497,19 @@ ieee80211_process_callback(struct ieee80211_node *ni,
* (the callers will first need modifying.)
*/
int
-ieee80211_parent_xmitpkt(struct ieee80211com *ic,
- struct mbuf *m)
+ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
{
- struct ifnet *parent = ic->ic_ifp;
+ int error;
+
/*
* Assert the IC TX lock is held - this enforces the
* processing -> queuing order is maintained
*/
IEEE80211_TX_LOCK_ASSERT(ic);
-
- return (parent->if_transmit(parent, m));
+ error = ic->ic_transmit(ic, m);
+ if (error)
+ m_freem(m);
+ return (error);
}
/*
@@ -836,7 +807,6 @@ ieee80211_load_module(const char *modname)
}
static eventhandler_tag wlan_bpfevent;
-static eventhandler_tag wlan_ifllevent;
static void
bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
@@ -864,33 +834,6 @@ bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
}
}
-static void
-wlan_iflladdr(void *arg __unused, struct ifnet *ifp)
-{
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap, *next;
-
- if (ifp->if_type != IFT_IEEE80211 || ic == NULL)
- return;
-
- IEEE80211_LOCK(ic);
- TAILQ_FOREACH_SAFE(vap, &ic->ic_vaps, iv_next, next) {
- /*
- * If the MAC address has changed on the parent and it was
- * copied to the vap on creation then re-sync.
- */
- if (vap->iv_ic == ic &&
- (vap->iv_flags_ext & IEEE80211_FEXT_UNIQMAC) == 0) {
- IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp));
- IEEE80211_UNLOCK(ic);
- if_setlladdr(vap->iv_ifp, IF_LLADDR(ifp),
- IEEE80211_ADDR_LEN);
- IEEE80211_LOCK(ic);
- }
- }
- IEEE80211_UNLOCK(ic);
-}
-
/*
* Module glue.
*
@@ -905,17 +848,12 @@ wlan_modevent(module_t mod, int type, void *unused)
printf("wlan: <802.11 Link Layer>\n");
wlan_bpfevent = EVENTHANDLER_REGISTER(bpf_track,
bpf_track, 0, EVENTHANDLER_PRI_ANY);
- wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
- wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
wlan_cloner = if_clone_simple(wlanname, wlan_clone_create,
wlan_clone_destroy, 0);
- if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free);
return 0;
case MOD_UNLOAD:
- if_deregister_com_alloc(IFT_IEEE80211);
if_clone_detach(wlan_cloner);
EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
- EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent);
return 0;
}
return EINVAL;
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 54ab390..1c7ddb9 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -1329,13 +1329,12 @@ static int
setmlme_dropsta(struct ieee80211vap *vap,
const uint8_t mac[IEEE80211_ADDR_LEN], struct mlmeop *mlmeop)
{
- struct ieee80211com *ic = vap->iv_ic;
- struct ieee80211_node_table *nt = &ic->ic_sta;
+ struct ieee80211_node_table *nt = &vap->iv_ic->ic_sta;
struct ieee80211_node *ni;
int error = 0;
/* NB: the broadcast address means do 'em all */
- if (!IEEE80211_ADDR_EQ(mac, ic->ic_ifp->if_broadcastaddr)) {
+ if (!IEEE80211_ADDR_EQ(mac, vap->iv_ifp->if_broadcastaddr)) {
IEEE80211_NODE_LOCK(nt);
ni = ieee80211_find_node_locked(nt, mac);
IEEE80211_NODE_UNLOCK(nt);
@@ -2529,14 +2528,9 @@ ieee80211_scanreq(struct ieee80211vap *vap, struct ieee80211_scan_req *sr)
static __noinline int
ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq)
{
- struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_scan_req sr; /* XXX off stack? */
int error;
- /* NB: parent must be running */
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return ENXIO;
-
if (ireq->i_len != sizeof(sr))
return EINVAL;
error = copyin(ireq->i_data, &sr, sizeof(sr));
@@ -3300,41 +3294,6 @@ ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211r
return error;
}
-/*
- * Rebuild the parent's multicast address list after an add/del
- * of a multicast address for a vap. We have no way to tell
- * what happened above to optimize the work so we purge the entire
- * list and rebuild from scratch. This is way expensive.
- * Note also the half-baked workaround for if_addmulti calling
- * back to the parent device; there's no way to insert mcast
- * entries quietly and/or cheaply.
- */
-static void
-ieee80211_ioctl_updatemulti(struct ieee80211com *ic)
-{
- struct ifnet *parent = ic->ic_ifp;
- struct ieee80211vap *vap;
- void *ioctl;
-
- IEEE80211_LOCK(ic);
- if_delallmulti(parent);
- ioctl = parent->if_ioctl; /* XXX WAR if_allmulti */
- parent->if_ioctl = NULL;
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- struct ifnet *ifp = vap->iv_ifp;
- struct ifmultiaddr *ifma;
-
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- (void) if_addmulti(parent, ifma->ifma_addr, NULL);
- }
- }
- parent->if_ioctl = ioctl;
- ieee80211_runtask(ic, &ic->ic_mcast_task);
- IEEE80211_UNLOCK(ic);
-}
-
int
ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
@@ -3347,8 +3306,11 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
switch (cmd) {
case SIOCSIFFLAGS:
IEEE80211_LOCK(ic);
- ieee80211_syncifflag_locked(ic, IFF_PROMISC);
- ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
+ if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_PROMISC)
+ ieee80211_promisc(vap, ifp->if_flags & IFF_PROMISC);
+ if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_ALLMULTI)
+ ieee80211_allmulti(vap, ifp->if_flags & IFF_ALLMULTI);
+ vap->iv_ifflags = ifp->if_flags;
if (ifp->if_flags & IFF_UP) {
/*
* Bring ourself up unless we're already operational.
@@ -3371,7 +3333,7 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
- ieee80211_ioctl_updatemulti(ic);
+ ieee80211_runtask(ic, &ic->ic_mcast_task);
break;
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
@@ -3427,17 +3389,16 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
}
break;
- /* Pass NDIS ioctls up to the driver */
- case SIOCGDRVSPEC:
- case SIOCSDRVSPEC:
- case SIOCGPRIVATE_0: {
- struct ifnet *parent = vap->iv_ic->ic_ifp;
- error = parent->if_ioctl(parent, cmd, data);
- break;
- }
default:
+ /*
+ * Pass unknown ioctls first to the driver, and if it
+ * returns ENOTTY, then to the generic Ethernet handler.
+ */
+ if (ic->ic_ioctl != NULL &&
+ (error = ic->ic_ioctl(ic, cmd, data)) != ENOTTY)
+ break;
error = ether_ioctl(ifp, cmd, data);
break;
}
- return error;
+ return (error);
}
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index d11628d..eb333da1 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -254,10 +254,6 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
/* NB: IFQ_HANDOFF reclaims mbuf */
ieee80211_free_node(ni);
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- } else {
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- if_inc_counter(ifp, IFCOUNTER_OMCASTS, mcast);
- if_inc_counter(ifp, IFCOUNTER_OBYTES, len);
}
ic->ic_lastdata = ticks;
@@ -430,17 +426,6 @@ ieee80211_vap_transmit(struct ifnet *ifp, struct mbuf *m)
{
struct ieee80211vap *vap = ifp->if_softc;
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *parent = ic->ic_ifp;
-
- /* NB: parent must be up and running */
- if (!IFNET_IS_UP_RUNNING(parent)) {
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
- "%s: ignore queue, parent %s not up+running\n",
- __func__, parent->if_xname);
- m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- return (ENETDOWN);
- }
/*
* No data frames go out unless we're running.
@@ -507,6 +492,7 @@ ieee80211_raw_output(struct ieee80211vap *vap, struct ieee80211_node *ni,
struct mbuf *m, const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = vap->iv_ic;
+ int error;
/*
* Set node - the caller has taken a reference, so ensure
@@ -528,7 +514,10 @@ ieee80211_raw_output(struct ieee80211vap *vap, struct ieee80211_node *ni,
if (params)
(void) ieee80211_add_xmit_params(m, params);
- return (ic->ic_raw_xmit(ni, m, params));
+ error = ic->ic_raw_xmit(ni, m, params);
+ if (error)
+ if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, 1);
+ return (error);
}
/*
@@ -3457,6 +3446,15 @@ ieee80211_tx_complete(struct ieee80211_node *ni, struct mbuf *m, int status)
{
if (ni != NULL) {
+ struct ifnet *ifp = ni->ni_vap->iv_ifp;
+
+ if (status == 0) {
+ if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ if (m->m_flags & M_MCAST)
+ if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
+ } else
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
if (m->m_flags & M_TXCB)
ieee80211_process_callback(ni, m, status);
ieee80211_free_node(ni);
diff --git a/sys/net80211/ieee80211_power.c b/sys/net80211/ieee80211_power.c
index 91668cc..2d216c2 100644
--- a/sys/net80211/ieee80211_power.c
+++ b/sys/net80211/ieee80211_power.c
@@ -418,7 +418,6 @@ pwrsave_flushq(struct ieee80211_node *ni)
struct ieee80211com *ic = ni->ni_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_psq_head *qhead;
- struct ifnet *parent, *ifp;
struct mbuf *parent_q = NULL, *ifp_q = NULL;
struct mbuf *m;
@@ -429,59 +428,51 @@ pwrsave_flushq(struct ieee80211_node *ni)
qhead = &psq->psq_head[0]; /* 802.11 frames */
if (qhead->head != NULL) {
/* XXX could dispatch through vap and check M_ENCAP */
- parent = vap->iv_ic->ic_ifp;
/* XXX need different driver interface */
/* XXX bypasses q max and OACTIVE */
parent_q = qhead->head;
qhead->head = qhead->tail = NULL;
qhead->len = 0;
- } else
- parent = NULL;
+ }
qhead = &psq->psq_head[1]; /* 802.3 frames */
if (qhead->head != NULL) {
- ifp = vap->iv_ifp;
/* XXX need different driver interface */
/* XXX bypasses q max and OACTIVE */
ifp_q = qhead->head;
qhead->head = qhead->tail = NULL;
qhead->len = 0;
- } else
- ifp = NULL;
+ }
psq->psq_len = 0;
IEEE80211_PSQ_UNLOCK(psq);
/* NB: do this outside the psq lock */
/* XXX packets might get reordered if parent is OACTIVE */
/* parent frames, should be encapsulated */
- if (parent != NULL) {
- while (parent_q != NULL) {
- m = parent_q;
- parent_q = m->m_nextpkt;
- m->m_nextpkt = NULL;
- /* must be encapsulated */
- KASSERT((m->m_flags & M_ENCAP),
- ("%s: parentq with non-M_ENCAP frame!\n",
- __func__));
- /*
- * For encaped frames, we need to free the node
- * reference upon failure.
- */
- if (ieee80211_parent_xmitpkt(ic, m) != 0)
- ieee80211_free_node(ni);
- }
+ while (parent_q != NULL) {
+ m = parent_q;
+ parent_q = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ /* must be encapsulated */
+ KASSERT((m->m_flags & M_ENCAP),
+ ("%s: parentq with non-M_ENCAP frame!\n",
+ __func__));
+ /*
+ * For encaped frames, we need to free the node
+ * reference upon failure.
+ */
+ if (ieee80211_parent_xmitpkt(ic, m) != 0)
+ ieee80211_free_node(ni);
}
/* VAP frames, aren't encapsulated */
- if (ifp != NULL) {
- while (ifp_q != NULL) {
- m = ifp_q;
- ifp_q = m->m_nextpkt;
- m->m_nextpkt = NULL;
- KASSERT((!(m->m_flags & M_ENCAP)),
- ("%s: vapq with M_ENCAP frame!\n", __func__));
- (void) ieee80211_vap_xmitpkt(vap, m);
- }
+ while (ifp_q != NULL) {
+ m = ifp_q;
+ ifp_q = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ KASSERT((!(m->m_flags & M_ENCAP)),
+ ("%s: vapq with M_ENCAP frame!\n", __func__));
+ (void) ieee80211_vap_xmitpkt(vap, m);
}
}
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 01c60e1..7adf044 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -122,23 +122,23 @@ null_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
void
ieee80211_proto_attach(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
+ uint8_t hdrlen;
/* override the 802.3 setting */
- ifp->if_hdrlen = ic->ic_headroom
+ hdrlen = ic->ic_headroom
+ sizeof(struct ieee80211_qosframe_addr4)
+ IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN
+ IEEE80211_WEP_EXTIVLEN;
/* XXX no way to recalculate on ifdetach */
- if (ALIGN(ifp->if_hdrlen) > max_linkhdr) {
+ if (ALIGN(hdrlen) > max_linkhdr) {
/* XXX sanity check... */
- max_linkhdr = ALIGN(ifp->if_hdrlen);
+ max_linkhdr = ALIGN(hdrlen);
max_hdr = max_linkhdr + max_protohdr;
max_datalen = MHLEN - max_hdr;
}
ic->ic_protmode = IEEE80211_PROT_CTSONLY;
- TASK_INIT(&ic->ic_parent_task, 0, parent_updown, ifp);
+ TASK_INIT(&ic->ic_parent_task, 0, parent_updown, ic);
TASK_INIT(&ic->ic_mcast_task, 0, update_mcast, ic);
TASK_INIT(&ic->ic_promisc_task, 0, update_promisc, ic);
TASK_INIT(&ic->ic_chan_task, 0, update_channel, ic);
@@ -188,7 +188,10 @@ ieee80211_proto_vattach(struct ieee80211vap *vap)
int i;
/* override the 802.3 setting */
- ifp->if_hdrlen = ic->ic_ifp->if_hdrlen;
+ ifp->if_hdrlen = ic->ic_headroom
+ + sizeof(struct ieee80211_qosframe_addr4)
+ + IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN
+ + IEEE80211_WEP_EXTIVLEN;
vap->iv_rtsthreshold = IEEE80211_RTS_DEFAULT;
vap->iv_fragthreshold = IEEE80211_FRAG_DEFAULT;
@@ -1155,9 +1158,9 @@ ieee80211_wme_updateparams(struct ieee80211vap *vap)
static void
parent_updown(void *arg, int npending)
{
- struct ifnet *parent = arg;
+ struct ieee80211com *ic = arg;
- parent->if_ioctl(parent, SIOCSIFFLAGS, NULL);
+ ic->ic_parent(ic);
}
static void
@@ -1224,7 +1227,6 @@ ieee80211_start_locked(struct ieee80211vap *vap)
{
struct ifnet *ifp = vap->iv_ifp;
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *parent = ic->ic_ifp;
IEEE80211_LOCK_ASSERT(ic);
@@ -1246,12 +1248,10 @@ ieee80211_start_locked(struct ieee80211vap *vap)
* We are not running; if this we are the first vap
* to be brought up auto-up the parent if necessary.
*/
- if (ic->ic_nrunning++ == 0 &&
- (parent->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ if (ic->ic_nrunning++ == 0) {
IEEE80211_DPRINTF(vap,
IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
- "%s: up parent %s\n", __func__, parent->if_xname);
- parent->if_flags |= IFF_UP;
+ "%s: up parent %s\n", __func__, ic->ic_name);
ieee80211_runtask(ic, &ic->ic_parent_task);
return;
}
@@ -1260,8 +1260,7 @@ ieee80211_start_locked(struct ieee80211vap *vap)
* If the parent is up and running, then kick the
* 802.11 state machine as appropriate.
*/
- if ((parent->if_drv_flags & IFF_DRV_RUNNING) &&
- vap->iv_roaming != IEEE80211_ROAMING_MANUAL) {
+ if (vap->iv_roaming != IEEE80211_ROAMING_MANUAL) {
if (vap->iv_opmode == IEEE80211_M_STA) {
#if 0
/* XXX bypasses scan too easily; disable for now */
@@ -1344,7 +1343,6 @@ ieee80211_stop_locked(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = vap->iv_ifp;
- struct ifnet *parent = ic->ic_ifp;
IEEE80211_LOCK_ASSERT(ic);
@@ -1354,12 +1352,10 @@ ieee80211_stop_locked(struct ieee80211vap *vap)
ieee80211_new_state_locked(vap, IEEE80211_S_INIT, -1);
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
ifp->if_drv_flags &= ~IFF_DRV_RUNNING; /* mark us stopped */
- if (--ic->ic_nrunning == 0 &&
- (parent->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (--ic->ic_nrunning == 0) {
IEEE80211_DPRINTF(vap,
IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
- "down parent %s\n", parent->if_xname);
- parent->if_flags &= ~IFF_UP;
+ "down parent %s\n", ic->ic_name);
ieee80211_runtask(ic, &ic->ic_parent_task);
}
}
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index a812393..b5918b4 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -56,7 +56,8 @@ void ieee80211_proto_detach(struct ieee80211com *);
void ieee80211_proto_vattach(struct ieee80211vap *);
void ieee80211_proto_vdetach(struct ieee80211vap *);
-void ieee80211_syncifflag_locked(struct ieee80211com *, int flag);
+void ieee80211_promisc(struct ieee80211vap *, bool);
+void ieee80211_allmulti(struct ieee80211vap *, bool);
void ieee80211_syncflag(struct ieee80211vap *, int flag);
void ieee80211_syncflag_ht(struct ieee80211vap *, int flag);
void ieee80211_syncflag_ext(struct ieee80211vap *, int flag);
diff --git a/sys/net80211/ieee80211_regdomain.c b/sys/net80211/ieee80211_regdomain.c
index 9dfef2c..efbe1a8 100644
--- a/sys/net80211/ieee80211_regdomain.c
+++ b/sys/net80211/ieee80211_regdomain.c
@@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
-
#include <sys/socket.h>
#include <net/if.h>
@@ -487,7 +486,7 @@ ieee80211_setregdomain(struct ieee80211vap *vap,
memset(&ic->ic_channels[ic->ic_nchans], 0,
(IEEE80211_CHAN_MAX - ic->ic_nchans) *
sizeof(struct ieee80211_channel));
- ieee80211_media_init(ic);
+ ieee80211_chan_init(ic);
/*
* Invalidate channel-related state.
diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c
index c0cbb7d..709710c 100644
--- a/sys/net80211/ieee80211_scan_sta.c
+++ b/sys/net80211/ieee80211_scan_sta.c
@@ -1706,26 +1706,6 @@ static const struct ieee80211_scanner adhoc_default = {
IEEE80211_SCANNER_ALG(ibss, IEEE80211_M_IBSS, adhoc_default);
IEEE80211_SCANNER_ALG(ahdemo, IEEE80211_M_AHDEMO, adhoc_default);
-static void
-ap_force_promisc(struct ieee80211com *ic)
-{
- struct ifnet *ifp = ic->ic_ifp;
-
- IEEE80211_LOCK(ic);
- /* set interface into promiscuous mode */
- ifp->if_flags |= IFF_PROMISC;
- ieee80211_runtask(ic, &ic->ic_promisc_task);
- IEEE80211_UNLOCK(ic);
-}
-
-static void
-ap_reset_promisc(struct ieee80211com *ic)
-{
- IEEE80211_LOCK(ic);
- ieee80211_syncifflag_locked(ic, IFF_PROMISC);
- IEEE80211_UNLOCK(ic);
-}
-
static int
ap_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
{
@@ -1741,7 +1721,7 @@ ap_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
st->st_scangen++;
st->st_newscan = 1;
- ap_force_promisc(vap->iv_ic);
+ ieee80211_promisc(vap, true);
return 0;
}
@@ -1751,7 +1731,7 @@ ap_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
static int
ap_cancel(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
{
- ap_reset_promisc(vap->iv_ic);
+ ieee80211_promisc(vap, false);
return 0;
}
@@ -1825,7 +1805,7 @@ ap_end(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
return 0;
}
}
- ap_reset_promisc(ic);
+ ieee80211_promisc(vap, false);
if (ss->ss_flags & (IEEE80211_SCAN_NOPICK | IEEE80211_SCAN_NOJOIN)) {
/*
* Manual/background scan, don't select+join the
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 26238b8..a450701 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -116,16 +116,15 @@ struct ieee80211_superg;
struct ieee80211_frame;
struct ieee80211com {
- struct ifnet *ic_ifp; /* associated device */
void *ic_softc; /* driver softc */
const char *ic_name; /* usually device name */
ieee80211_com_lock_t ic_comlock; /* state update lock */
ieee80211_tx_lock_t ic_txlock; /* ic/vap TX lock */
+ LIST_ENTRY(ieee80211com) ic_next; /* on global list */
TAILQ_HEAD(, ieee80211vap) ic_vaps; /* list of vap instances */
int ic_headroom; /* driver tx headroom needs */
enum ieee80211_phytype ic_phytype; /* XXX wrong for multi-mode */
enum ieee80211_opmode ic_opmode; /* operation mode */
- struct ifmedia ic_media; /* interface media config */
struct callout ic_inact; /* inactivity processing */
struct taskqueue *ic_tq; /* deferred state thread */
struct task ic_parent_task; /* deferred parent processing */
@@ -151,6 +150,7 @@ struct ieee80211com {
uint8_t ic_allmulti; /* vap's needing all multicast*/
uint8_t ic_nrunning; /* vap's marked running */
uint8_t ic_curmode; /* current mode */
+ uint8_t ic_macaddr[IEEE80211_ADDR_LEN];
uint16_t ic_bintval; /* beacon interval */
uint16_t ic_lintval; /* listen interval */
uint16_t ic_holdover; /* PM hold over duration */
@@ -241,6 +241,11 @@ struct ieee80211com {
const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN]);
void (*ic_vap_delete)(struct ieee80211vap *);
+ /* device specific ioctls */
+ int (*ic_ioctl)(struct ieee80211com *,
+ u_long, void *);
+ /* start/stop device */
+ void (*ic_parent)(struct ieee80211com *);
/* operating mode attachment */
ieee80211vap_attach ic_vattach[IEEE80211_OPMODE_MAX];
/* return hardware/radio capabilities */
@@ -254,6 +259,9 @@ struct ieee80211com {
int (*ic_set_quiet)(struct ieee80211_node *,
u_int8_t *quiet_elm);
+ /* regular transmit */
+ int (*ic_transmit)(struct ieee80211com *,
+ struct mbuf *);
/* send/recv 802.11 management frame */
int (*ic_send_mgmt)(struct ieee80211_node *,
int, int);
@@ -351,14 +359,15 @@ struct ieee80211vap {
TAILQ_ENTRY(ieee80211vap) iv_next; /* list of vap instances */
struct ieee80211com *iv_ic; /* back ptr to common state */
+ const uint8_t *iv_myaddr; /* MAC address: ifp or ic */
uint32_t iv_debug; /* debug msg flags */
struct ieee80211_stats iv_stats; /* statistics */
- uint8_t iv_myaddr[IEEE80211_ADDR_LEN];
uint32_t iv_flags; /* state flags */
uint32_t iv_flags_ext; /* extended state flags */
uint32_t iv_flags_ht; /* HT state flags */
uint32_t iv_flags_ven; /* vendor state flags */
+ uint32_t iv_ifflags; /* ifnet flags */
uint32_t iv_caps; /* capabilities */
uint32_t iv_htcaps; /* HT capabilities */
uint32_t iv_htextcaps; /* HT extended capabilities */
@@ -681,24 +690,24 @@ MALLOC_DECLARE(M_80211_VAP);
"\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS"
int ic_printf(struct ieee80211com *, const char *, ...) __printflike(2, 3);
-void ieee80211_ifattach(struct ieee80211com *,
- const uint8_t macaddr[IEEE80211_ADDR_LEN]);
+void ieee80211_ifattach(struct ieee80211com *);
void ieee80211_ifdetach(struct ieee80211com *);
int ieee80211_vap_setup(struct ieee80211com *, struct ieee80211vap *,
const char name[IFNAMSIZ], int unit,
enum ieee80211_opmode opmode, int flags,
- const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t macaddr[IEEE80211_ADDR_LEN]);
+ const uint8_t bssid[IEEE80211_ADDR_LEN]);
int ieee80211_vap_attach(struct ieee80211vap *,
- ifm_change_cb_t, ifm_stat_cb_t);
+ ifm_change_cb_t, ifm_stat_cb_t,
+ const uint8_t macaddr[IEEE80211_ADDR_LEN]);
void ieee80211_vap_detach(struct ieee80211vap *);
const struct ieee80211_rateset *ieee80211_get_suprates(struct ieee80211com *ic,
const struct ieee80211_channel *);
void ieee80211_announce(struct ieee80211com *);
void ieee80211_announce_channels(struct ieee80211com *);
void ieee80211_drain(struct ieee80211com *);
-void ieee80211_media_init(struct ieee80211com *);
+void ieee80211_chan_init(struct ieee80211com *);
struct ieee80211com *ieee80211_find_vap(const uint8_t mac[IEEE80211_ADDR_LEN]);
+struct ieee80211com *ieee80211_find_com(const char *name);
int ieee80211_media_change(struct ifnet *);
void ieee80211_media_status(struct ifnet *, struct ifmediareq *);
int ieee80211_ioctl(struct ifnet *, u_long, caddr_t);
diff --git a/tools/tools/iwn/iwnstats/main.c b/tools/tools/iwn/iwnstats/main.c
index 590c178..89582aa 100644
--- a/tools/tools/iwn/iwnstats/main.c
+++ b/tools/tools/iwn/iwnstats/main.c
@@ -50,7 +50,7 @@
#include "iwnstats.h"
#include "iwn_ioctl.h"
-#define IWN_DEFAULT_IF "iwn0"
+#define IWN_DEFAULT_IF "wlan0"
static struct iwnstats *
iwnstats_new(const char *ifname)
@@ -290,19 +290,6 @@ main(int argc, char *argv[])
if (ifname)
free(ifname);
ifname = strdup(optarg);
- if (strncmp(ifname, "wlan", 4) == 0) {
- free(ifname);
- len = 0;
- asprintf(&sysctlname, "net.wlan.%s.%%parent", ifname + 4);
- ret = sysctlbyname(sysctlname, NULL, &len, NULL, 0);
- if (ret != 0)
- err(1, "sysctl failed");
- ifname = calloc(len, 1);
- ret = sysctlbyname(sysctlname, ifname, &len, NULL, 0);
- if (ret != 0)
- err(1, "sysctl failed");
- free(sysctlname);
- }
break;
default:
case '?':
OpenPOWER on IntegriCloud