summaryrefslogtreecommitdiffstats
path: root/sys/dev/mwl/if_mwl.c
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 /sys/dev/mwl/if_mwl.c
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
Diffstat (limited to 'sys/dev/mwl/if_mwl.c')
-rw-r--r--sys/dev/mwl/if_mwl.c509
1 files changed, 199 insertions, 310 deletions
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
}
OpenPOWER on IntegriCloud