Module Name:    src
Committed By:   phil
Date:           Sat Jul 28 00:49:44 UTC 2018

Modified Files:
        src/sys/dev/usb [phil-wifi]: if_urtwn.c
        src/sys/net80211 [phil-wifi]: ieee80211.c ieee80211_adhoc.c
            ieee80211_hostap.c ieee80211_input.c ieee80211_ioctl.c
            ieee80211_mesh.c ieee80211_monitor.c ieee80211_netbsd.c
            ieee80211_netbsd.h ieee80211_proto.c ieee80211_scan.c
            ieee80211_scan_sta.c ieee80211_sta.c ieee80211_tdma.c
            ieee80211_wds.c

Log Message:
End of the week state save:
   Got workqueues doing FreeBSD tasks.  (still questions on how correct it is.)
   Incremental changes in many places.
   Still *lots* of debugging code that needs to go away some day.
   "ifconfig urtwn0 up" now does not crash, still needs scan to work properly.


To generate a diff of this commit:
cvs rdiff -u -r1.59.2.3 -r1.59.2.4 src/sys/dev/usb/if_urtwn.c
cvs rdiff -u -r1.56.18.4 -r1.56.18.5 src/sys/net80211/ieee80211.c
cvs rdiff -u -r1.1.2.2 -r1.1.2.3 src/sys/net80211/ieee80211_adhoc.c \
    src/sys/net80211/ieee80211_hostap.c src/sys/net80211/ieee80211_monitor.c \
    src/sys/net80211/ieee80211_sta.c src/sys/net80211/ieee80211_tdma.c \
    src/sys/net80211/ieee80211_wds.c
cvs rdiff -u -r1.114.2.3 -r1.114.2.4 src/sys/net80211/ieee80211_input.c
cvs rdiff -u -r1.60.18.4 -r1.60.18.5 src/sys/net80211/ieee80211_ioctl.c
cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/sys/net80211/ieee80211_mesh.c
cvs rdiff -u -r1.31.2.4 -r1.31.2.5 src/sys/net80211/ieee80211_netbsd.c
cvs rdiff -u -r1.21.2.5 -r1.21.2.6 src/sys/net80211/ieee80211_netbsd.h
cvs rdiff -u -r1.34.14.4 -r1.34.14.5 src/sys/net80211/ieee80211_proto.c
cvs rdiff -u -r1.1.56.4 -r1.1.56.5 src/sys/net80211/ieee80211_scan.c \
    src/sys/net80211/ieee80211_scan_sta.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/if_urtwn.c
diff -u src/sys/dev/usb/if_urtwn.c:1.59.2.3 src/sys/dev/usb/if_urtwn.c:1.59.2.4
--- src/sys/dev/usb/if_urtwn.c:1.59.2.3	Fri Jul 20 20:33:05 2018
+++ src/sys/dev/usb/if_urtwn.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_urtwn.c,v 1.59.2.3 2018/07/20 20:33:05 phil Exp $	*/
+/*	$NetBSD: if_urtwn.c,v 1.59.2.4 2018/07/28 00:49:43 phil Exp $	*/
 /*	$OpenBSD: if_urtwn.c,v 1.42 2015/02/10 23:25:46 mpi Exp $	*/
 
 /*-
@@ -19,13 +19,30 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+/* Some code taken from FreeBSD dev/usb/wlan/if_urtw.c with copyright */
+/*-
+ * Copyright (c) 2008 Weongyo Jeong <weon...@freebsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 /*-
  * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188EU/RTL8188RU/RTL8192CU
  * RTL8192EU.
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.59.2.3 2018/07/20 20:33:05 phil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.59.2.4 2018/07/28 00:49:43 phil Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -94,7 +111,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v
 #define	DBG_REG		__BIT(6)
 #define	DBG_ALL		0xffffffffU
 /* NNN Reset urtwn_debug to 0 when done debugging. */
-u_int urtwn_debug = DBG_INIT|DBG_FN|DBG_STM;
+u_int urtwn_debug = DBG_ALL & ~DBG_REG;
 #define DPRINTFN(n, s)	\
 	do { if (urtwn_debug & (n)) printf s; } while (/*CONSTCOND*/0)
 #else
@@ -203,6 +220,11 @@ static const struct urtwn_dev {
 #undef URTWN_RTL8188E_DEV
 #undef URTWN_RTL8192EU_DEV
 
+/* urtwn data */
+static const uint8_t urtwn_chan_2ghz[] =
+        { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
+
+
 static int	urtwn_match(device_t, cfdata_t, void *);
 static void	urtwn_attach(device_t, device_t, void *);
 static int	urtwn_detach(device_t, int);
@@ -252,7 +274,7 @@ static void	urtwn_dump_rom(struct urtwn_
 static void	urtwn_read_rom(struct urtwn_softc *);
 static void	urtwn_r88e_read_rom(struct urtwn_softc *);
 static int	urtwn_media_change(struct ifnet *);
-static int	urtwn_ra_init(struct urtwn_softc *);
+static int	urtwn_ra_init(struct ieee80211vap *);
 static int	urtwn_get_nettype(struct urtwn_softc *);
 static void	urtwn_set_nettype0_msr(struct urtwn_softc *, uint8_t);
 static void	urtwn_tsf_sync_enable(struct urtwn_softc *);
@@ -262,7 +284,7 @@ static void	urtwn_calib_to_cb(struct urt
 static void	urtwn_next_scan(void *);
 static int	urtwn_newstate(struct ieee80211vap *, enum ieee80211_state,
 		    int);
-static void	urtwn_newstate_cb(struct urtwn_softc *, void *);
+// static void	urtwn_newstate_cb(struct urtwn_softc *, void *);
 static int	urtwn_wme_update(struct ieee80211com *);
 static void	urtwn_wme_update_cb(struct urtwn_softc *, void *);
 static void	urtwn_update_avgrssi(struct urtwn_softc *, int, int8_t);
@@ -326,7 +348,8 @@ static void	urtwn_set_channel(struct iee
 static int	urtwn_transmit(struct ieee80211com *, struct mbuf *);
 static int	urtwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
 		    const struct ieee80211_bpf_params *);
-
+static void	urtwn_getradiocaps(struct ieee80211com *, int, int *,
+		    struct ieee80211_channel []);
 
 /* Aliases. */
 #define	urtwn_bb_write	urtwn_write_4
@@ -394,8 +417,9 @@ urtwn_attach(device_t parent, device_t s
 	(void) usbd_do_request(sc->sc_udev, &req, 0);
 
 	mutex_init(&sc->sc_task_mtx, MUTEX_DEFAULT, IPL_NET);
-	mutex_init(&sc->sc_tx_mtx, MUTEX_DEFAULT, IPL_NONE);
-	mutex_init(&sc->sc_rx_mtx, MUTEX_DEFAULT, IPL_NONE);
+	printf ("sc_tx_mtx INIT, addr 0x%lx\n", (long) &sc->sc_tx_mtx);
+	mutex_init(&sc->sc_tx_mtx, MUTEX_DEFAULT, IPL_SOFTNET);
+	mutex_init(&sc->sc_rx_mtx, MUTEX_DEFAULT, IPL_SOFTNET);
 	mutex_init(&sc->sc_fwcmd_mtx, MUTEX_DEFAULT, IPL_NONE);
 	mutex_init(&sc->sc_write_mtx, MUTEX_DEFAULT, IPL_NONE);
 
@@ -492,13 +516,9 @@ urtwn_attach(device_t parent, device_t s
 		    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
 	}
 
-	printf ("eurtwn: Calling ieee80211_ifattach()\n");
-
 	ieee80211_ifattach(ic);
 
-	printf ("urtwn: Returned from ieee80211_ifattach().\n");
-
-	/* override default methods NNN Need a lot more here!!! */
+	/* override default methods NNN Need more here? */
 	ic->ic_newassoc = urtwn_newassoc;
 	ic->ic_wme.wme_update = urtwn_wme_update;
 	ic->ic_vap_create = urtwn_vap_create;
@@ -509,6 +529,7 @@ urtwn_attach(device_t parent, device_t s
 	ic->ic_set_channel = urtwn_set_channel;
 	ic->ic_transmit = urtwn_transmit;
 	ic->ic_raw_xmit = urtwn_raw_xmit;
+	ic->ic_getradiocaps = urtwn_getradiocaps;
 	
 
 	/* Shouldn't do it, but call vap_create??? */
@@ -529,6 +550,8 @@ urtwn_attach(device_t parent, device_t s
 	/* Debug all! NNN */
 	vap->iv_debug = IEEE80211_MSG_ANY;
 
+	printf ("Initial vap->iv_flags is 0x%lx\n", (long)vap->iv_flags);
+
 	bpf_attach2(vap->iv_ifp, DLT_IEEE802_11_RADIO,
 	    sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
 	    &sc->sc_drvbpf);
@@ -549,7 +572,6 @@ urtwn_attach(device_t parent, device_t s
 		aprint_error_dev(self, "couldn't establish power handler\n");
 
 	SET(sc->sc_flags, URTWN_FLAG_ATTACHED);
-printf ("urtwn: Finished attach.\n");
 	return;
 
  fail:
@@ -576,6 +598,8 @@ urtwn_detach(device_t self, int flags)
 
 	if (ISSET(sc->sc_flags, URTWN_FLAG_ATTACHED)) {
 		usb_rem_task(sc->sc_udev, &sc->sc_task);
+		// urtwn_stop(...) ??
+		// vap_detach(...) ??
 
 		ieee80211_ifdetach(&sc->sc_ic);
 
@@ -592,6 +616,7 @@ urtwn_detach(device_t self, int flags)
 
 	mutex_destroy(&sc->sc_write_mtx);
 	mutex_destroy(&sc->sc_fwcmd_mtx);
+	printf ("sc_tx_mtx destroy\n");
 	mutex_destroy(&sc->sc_tx_mtx);
 	mutex_destroy(&sc->sc_rx_mtx);
 	mutex_destroy(&sc->sc_task_mtx);
@@ -736,6 +761,7 @@ urtwn_alloc_rx_list(struct urtwn_softc *
 	for (size_t j = 0; j < sc->rx_npipe; j++) {
 		TAILQ_INIT(&sc->rx_free_list[j]);
 		for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
+			printf ("alloc rx_data[%ld][%ld]\n", j, i);
 			data = &sc->rx_data[j][i];
 
 			data->sc = sc;	/* Backpointer for callbacks. */
@@ -785,6 +811,7 @@ urtwn_alloc_tx_list(struct urtwn_softc *
 
 	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
 
+	printf ("enter sc_tx_mtx, adr is 0x%lx\n", (long)&sc->sc_tx_mtx);
 	mutex_enter(&sc->sc_tx_mtx);
 	for (size_t j = 0; j < sc->tx_npipe; j++) {
 		TAILQ_INIT(&sc->tx_free_list[j]);
@@ -810,11 +837,14 @@ urtwn_alloc_tx_list(struct urtwn_softc *
 		}
 	}
 	mutex_exit(&sc->sc_tx_mtx);
+	printf ("exit sc_tx_mtx\n");
 	return 0;
 
  fail:
 	urtwn_free_tx_list(sc);
 	mutex_exit(&sc->sc_tx_mtx);
+	printf ("exit sc_tx_mtx\n");
+	printf ("Out of urtwn_alloc_tx_list with error.\n");
 	return error;
 }
 
@@ -1532,18 +1562,16 @@ urtwn_media_change(struct ifnet *ifp)
  * Initialize rate adaptation in firmware.
  */
 static int
-urtwn_ra_init(struct urtwn_softc *sc)
+urtwn_ra_init(struct ieee80211vap *vap)
 {
 	static const uint8_t map[] = {
 		2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
 	};
-	struct ieee80211com *ic = &sc->sc_ic;
-#ifdef notyet
-	struct ieee80211_node *ni = ic->ic_bss; */
+	struct ieee80211com *ic = vap->iv_ic;
+	struct urtwn_softc *sc = ic->ic_softc;
+	struct ieee80211_node *ni = vap->iv_bss;
 	struct ieee80211_rateset *rs = &ni->ni_rates;
-#else
-	struct ieee80211_rateset *rs = ic->ic_sup_rates;
-#endif
+
 	struct r92c_fw_cmd_macid_cfg cmd;
 	uint32_t rates, basicrates;
 	uint32_t mask, rrsr_mask, rrsr_rate;
@@ -1592,14 +1620,14 @@ urtwn_ra_init(struct urtwn_softc *sc)
 	    device_xname(sc->sc_dev), __func__, mode, rates, basicrates,
 	    maxrate, maxbasicrate));
 
-//NNN	if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) {
+	if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) {
 		maxbasicrate |= R92C_RATE_SHORTGI;
 		maxrate |= R92C_RATE_SHORTGI;
-//NNN	}
+	}
 
 	/* Set rates mask for group addressed frames. */
 	cmd.macid = URTWN_MACID_BC | URTWN_MACID_VALID;
-//NNN	if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)
+	if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)
 		cmd.macid |= URTWN_MACID_SHORTGI;
 
 	mask = (mode << 28) | basicrates;
@@ -1620,7 +1648,7 @@ urtwn_ra_init(struct urtwn_softc *sc)
 
 	/* Set rates mask for unicast frames. */
 	cmd.macid = URTWN_MACID_BSS | URTWN_MACID_VALID;
-//NNN	if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)
+	if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)
 		cmd.macid |= URTWN_MACID_SHORTGI;
 
 	mask = (mode << 28) | rates;
@@ -1697,8 +1725,8 @@ urtwn_set_nettype0_msr(struct urtwn_soft
 static void
 urtwn_tsf_sync_enable(struct urtwn_softc *sc)
 {
-#ifdef notyet
-	struct ieee80211_node *ni = sc->sc_ic.ic_bss;
+	struct ieee80211vap *vap  = TAILQ_FIRST(&sc->sc_ic.ic_vaps);
+	struct ieee80211_node *ni = vap->iv_bss;
 	uint64_t tsf;
 
 	DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
@@ -1723,7 +1751,6 @@ urtwn_tsf_sync_enable(struct urtwn_softc
 
 	urtwn_write_1(sc, R92C_BCN_CTRL,
 	    urtwn_read_1(sc, R92C_BCN_CTRL) | R92C_BCN_CTRL_EN_BCN);
-#endif
 }
 
 static void
@@ -1781,6 +1808,7 @@ urtwn_calib_to(void *arg)
 		return;
 
 	/* Do it in a process context. */
+	printf ("Doing a urtwn_calib_to via do_async...\n");
 	urtwn_do_async(sc, urtwn_calib_to_cb, vap, sizeof(struct ieee80211vap *));
 }
 
@@ -1857,7 +1885,8 @@ urtwn_newassoc(struct ieee80211_node *ni
 	ni->ni_txrate = 0;
 }
 
-static __unused int
+#if OLDSTUFF
+static int
 urtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 {
 	struct urtwn_softc *sc = vap->iv_ic->ic_softc;
@@ -2024,6 +2053,7 @@ urtwn_newstate_cb(struct urtwn_softc *sc
 		/* Start periodic scan. */
 		if (!sc->sc_dying)
 			callout_schedule(&sc->sc_scan_to, hz / 5);
+		printf ("Finished to scan code\n");
 		break;
 
 	case IEEE80211_S_AUTH:
@@ -2054,6 +2084,7 @@ urtwn_newstate_cb(struct urtwn_softc *sc
 		break;
 
 	case IEEE80211_S_RUN:
+		printf ("if_urtwn: going to new state S_RUN\n");
 		ni = vap->iv_bss;
 
 		/* XXX: Set 20MHz mode */
@@ -2156,7 +2187,7 @@ urtwn_newstate_cb(struct urtwn_softc *sc
 		    ISSET(sc->chip, URTWN_CHIP_92EU))
 			ni->ni_txrate = ni->ni_rates.rs_nrates - 1;
 		else
-			urtwn_ra_init(sc);
+			urtwn_ra_init(vap);
 
 		/* Turn link LED on. */
 		urtwn_set_led(sc, URTWN_LED_LINK, 1);
@@ -2179,11 +2210,326 @@ urtwn_newstate_cb(struct urtwn_softc *sc
 		printf ("URTWN UNKNOWN nSTATE: %d\n", nstate);
 		break;
 	}
-
+	/* newstate functions expect the ic to be locked. */
+	IEEE80211_LOCK(ic);
 	(*sc->sc_newstate)(vap, nstate, cmd->arg);
+	IEEE80211_UNLOCK(ic);
+	
+	mutex_exit(&sc->sc_write_mtx);
+	splx(s);
+}
+#endif
+
+static __unused int
+urtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
+{
+	struct urtwn_softc *sc = vap->iv_ic->ic_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ieee80211_node *ni;
+	enum ieee80211_state ostate = vap->iv_state;
+	uint32_t reg;
+	uint8_t sifs_time, msr;
+	int s;
+	int error;
+
+	DPRINTFN(DBG_FN|DBG_STM, ("%s: %s: %s(%d)->%s(%d)\n",
+	    device_xname(sc->sc_dev), __func__,
+	    ieee80211_state_name[ostate], ostate,
+	    ieee80211_state_name[nstate], nstate));
+
+	s = splnet();
+	mutex_enter(&sc->sc_write_mtx);
+
+	callout_stop(&sc->sc_scan_to);
+	callout_stop(&sc->sc_calib_to);
+
+	switch (ostate) {
+	case IEEE80211_S_INIT:
+		break;
+
+	case IEEE80211_S_SCAN:
+		if (nstate != IEEE80211_S_SCAN) {
+			/*
+			 * End of scanning
+			 */
+			/* flush 4-AC Queue after site_survey */
+			urtwn_write_1(sc, R92C_TXPAUSE, 0x0);
+
+			/* Allow Rx from our BSSID only. */
+			urtwn_write_4(sc, R92C_RCR,
+			    urtwn_read_4(sc, R92C_RCR) |
+			      R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN);
+		}
+		break;
+
+	case IEEE80211_S_AUTH:
+	case IEEE80211_S_ASSOC:
+		break;
+
+	case IEEE80211_S_RUN:
+		/* Turn link LED off. */
+		urtwn_set_led(sc, URTWN_LED_LINK, 0);
+
+		/* Set media status to 'No Link'. */
+		urtwn_set_nettype0_msr(sc, R92C_CR_NETTYPE_NOLINK);
+
+		/* Stop Rx of data frames. */
+		urtwn_write_2(sc, R92C_RXFLTMAP2, 0);
+
+		/* Reset TSF. */
+		urtwn_write_1(sc, R92C_DUAL_TSF_RST, 0x03);
+
+		/* Disable TSF synchronization. */
+		urtwn_write_1(sc, R92C_BCN_CTRL,
+		    urtwn_read_1(sc, R92C_BCN_CTRL) |
+		      R92C_BCN_CTRL_DIS_TSF_UDT0);
+
+		/* Back to 20MHz mode */
+		urtwn_set_chan(sc, ic->ic_curchan,
+		    IEEE80211_HTINFO_2NDCHAN_NONE);
+
+		if (ic->ic_opmode == IEEE80211_M_IBSS ||
+		    ic->ic_opmode == IEEE80211_M_HOSTAP) {
+			/* Stop BCN */
+			urtwn_write_1(sc, R92C_BCN_CTRL,
+			    urtwn_read_1(sc, R92C_BCN_CTRL) &
+			    ~(R92C_BCN_CTRL_EN_BCN | R92C_BCN_CTRL_TXBCN_RPT));
+		}
+
+		/* Reset EDCA parameters. */
+		urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002f3217);
+		urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005e4317);
+		urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x00105320);
+		urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a444);
+
+		/* flush all cam entries */
+		urtwn_cam_init(sc);
+		break;
+	case IEEE80211_S_CAC:
+	case IEEE80211_S_CSA:
+	case IEEE80211_S_SLEEP:
+		printf ("URTWN UNKNOWN oSTATE: %d\n", ostate);
+		/* NNN what do we do in these states? XXX */
+		break;
+	}
+
+	switch (nstate) {
+	case IEEE80211_S_INIT:
+		/* Turn link LED off. */
+		urtwn_set_led(sc, URTWN_LED_LINK, 0);
+		break;
+
+	case IEEE80211_S_SCAN:
+		if (ostate != IEEE80211_S_SCAN) {
+			/*
+			 * Begin of scanning
+			 */
+
+			/* Set gain for scanning. */
+			reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0));
+			reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
+			urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);
+
+			if (!ISSET(sc->chip, URTWN_CHIP_88E)) {
+				reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
+				reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
+				urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
+			}
+
+			/* Set media status to 'No Link'. */
+			urtwn_set_nettype0_msr(sc, R92C_CR_NETTYPE_NOLINK);
+
+			/* Allow Rx from any BSSID. */
+			urtwn_write_4(sc, R92C_RCR,
+			    urtwn_read_4(sc, R92C_RCR) &
+			    ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN));
+
+			/* Stop Rx of data frames. */
+			urtwn_write_2(sc, R92C_RXFLTMAP2, 0);
+
+			/* Disable update TSF */
+			urtwn_write_1(sc, R92C_BCN_CTRL,
+			    urtwn_read_1(sc, R92C_BCN_CTRL) |
+			      R92C_BCN_CTRL_DIS_TSF_UDT0);
+		}
+
+		/* Make link LED blink during scan. */
+		urtwn_set_led(sc, URTWN_LED_LINK, !sc->ledlink);
+
+		/* Pause AC Tx queues. */
+		urtwn_write_1(sc, R92C_TXPAUSE,
+		    urtwn_read_1(sc, R92C_TXPAUSE) | 0x0f);
+
+		urtwn_set_chan(sc, ic->ic_curchan,
+		    IEEE80211_HTINFO_2NDCHAN_NONE);
+
+		/* Start periodic scan. */
+		if (!sc->sc_dying)
+			callout_schedule(&sc->sc_scan_to, hz / 5);
+		printf ("Finished to scan code\n");
+		break;
+
+	case IEEE80211_S_AUTH:
+		/* Set initial gain under link. */
+		reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0));
+		reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
+		urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);
+
+		if (!ISSET(sc->chip, URTWN_CHIP_88E)) {
+			reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
+			reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
+			urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
+		}
+
+		/* Set media status to 'No Link'. */
+		urtwn_set_nettype0_msr(sc, R92C_CR_NETTYPE_NOLINK);
+
+		/* Allow Rx from any BSSID. */
+		urtwn_write_4(sc, R92C_RCR,
+		    urtwn_read_4(sc, R92C_RCR) &
+		      ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN));
+
+		urtwn_set_chan(sc, ic->ic_curchan,
+		    IEEE80211_HTINFO_2NDCHAN_NONE);
+		break;
+
+	case IEEE80211_S_ASSOC:
+		break;
+
+	case IEEE80211_S_RUN:
+		printf ("if_urtwn: going to new state S_RUN\n");
+		ni = vap->iv_bss;
+
+		/* XXX: Set 20MHz mode */
+		urtwn_set_chan(sc, ic->ic_curchan,
+		    IEEE80211_HTINFO_2NDCHAN_NONE);
+
+		if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+			/* Back to 20MHz mode */
+			urtwn_set_chan(sc, ic->ic_curchan,
+			    IEEE80211_HTINFO_2NDCHAN_NONE);
+
+			/* Set media status to 'No Link'. */
+			urtwn_set_nettype0_msr(sc, R92C_CR_NETTYPE_NOLINK);
+
+			/* Enable Rx of data frames. */
+			urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
+
+			/* Allow Rx from any BSSID. */
+			urtwn_write_4(sc, R92C_RCR,
+			    urtwn_read_4(sc, R92C_RCR) &
+			    ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN));
+
+			/* Accept Rx data/control/management frames */
+			urtwn_write_4(sc, R92C_RCR,
+			    urtwn_read_4(sc, R92C_RCR) |
+			    R92C_RCR_ADF | R92C_RCR_ACF | R92C_RCR_AMF);
+
+			/* Turn link LED on. */
+			urtwn_set_led(sc, URTWN_LED_LINK, 1);
+			break;
+		}
+
+		/* Set media status to 'Associated'. */
+		urtwn_set_nettype0_msr(sc, urtwn_get_nettype(sc));
+
+		/* Set BSSID. */
+		urtwn_write_4(sc, R92C_BSSID + 0, LE_READ_4(&ni->ni_bssid[0]));
+		urtwn_write_4(sc, R92C_BSSID + 4, LE_READ_2(&ni->ni_bssid[4]));
+
+		if (ic->ic_curmode == IEEE80211_MODE_11B) {
+			urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 0);
+		} else {
+			/* 802.11b/g */
+			urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 3);
+		}
+
+		/* Enable Rx of data frames. */
+		urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
+
+		/* Set beacon interval. */
+		urtwn_write_2(sc, R92C_BCN_INTERVAL, ni->ni_intval);
+
+		msr = urtwn_read_1(sc, R92C_MSR);
+		msr &= R92C_MSR_MASK;
+		switch (ic->ic_opmode) {
+		case IEEE80211_M_STA:
+			/* Allow Rx from our BSSID only. */
+			urtwn_write_4(sc, R92C_RCR,
+			    urtwn_read_4(sc, R92C_RCR) |
+			      R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN);
+
+			/* Enable TSF synchronization. */
+			urtwn_tsf_sync_enable(sc);
+
+			msr |= R92C_MSR_INFRA;
+			break;
+		case IEEE80211_M_HOSTAP:
+			urtwn_write_2(sc, R92C_BCNTCFG, 0x000f);
 
+			/* Allow Rx from any BSSID. */
+			urtwn_write_4(sc, R92C_RCR,
+			    urtwn_read_4(sc, R92C_RCR) &
+			    ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN));
+
+			/* Reset TSF timer to zero. */
+			reg = urtwn_read_4(sc, R92C_TCR);
+			reg &= ~0x01;
+			urtwn_write_4(sc, R92C_TCR, reg);
+			reg |= 0x01;
+			urtwn_write_4(sc, R92C_TCR, reg);
+
+			msr |= R92C_MSR_AP;
+			break;
+		default:
+			msr |= R92C_MSR_ADHOC;
+			break;
+		}
+		urtwn_write_1(sc, R92C_MSR, msr);
+
+		sifs_time = 10;
+		urtwn_write_1(sc, R92C_SIFS_CCK + 1, sifs_time);
+		urtwn_write_1(sc, R92C_SIFS_OFDM + 1, sifs_time);
+		urtwn_write_1(sc, R92C_SPEC_SIFS + 1, sifs_time);
+		urtwn_write_1(sc, R92C_MAC_SPEC_SIFS + 1, sifs_time);
+		urtwn_write_1(sc, R92C_R2T_SIFS + 1, sifs_time);
+		urtwn_write_1(sc, R92C_T2T_SIFS + 1, sifs_time);
+
+		/* Initialize rate adaptation. */
+		if (ISSET(sc->chip, URTWN_CHIP_88E) ||
+		    ISSET(sc->chip, URTWN_CHIP_92EU))
+			ni->ni_txrate = ni->ni_rates.rs_nrates - 1;
+		else
+			urtwn_ra_init(vap);
+
+		/* Turn link LED on. */
+		urtwn_set_led(sc, URTWN_LED_LINK, 1);
+
+		/* Reset average RSSI. */
+		sc->avg_pwdb = -1;
+
+		/* Reset temperature calibration state machine. */
+		sc->thcal_state = 0;
+		sc->thcal_lctemp = 0;
+
+		/* Start periodic calibration. */
+		if (!sc->sc_dying)
+			callout_schedule(&sc->sc_calib_to, hz);
+		break;
+	case IEEE80211_S_CAC:
+	case IEEE80211_S_CSA:
+	case IEEE80211_S_SLEEP:
+		/* NNN what do we do in these states? XXX */
+		printf ("URTWN UNKNOWN nSTATE: %d\n", nstate);
+		break;
+	}
 	mutex_exit(&sc->sc_write_mtx);
+
+	/* newstate functions expect the ic to be locked. */
+	error = (*sc->sc_newstate)(vap, nstate, arg);
+	
 	splx(s);
+	return error;
 }
 
 static int
@@ -2394,6 +2740,7 @@ urtwn_rx_frame(struct urtwn_softc *sc, u
 		ifp->if_ierrors++;
 		return;
 	}
+
 	/*
 	 * XXX: This will drop most control packets.  Do we really
 	 * want this in IEEE80211_M_MONITOR mode?
@@ -2489,11 +2836,28 @@ urtwn_rx_frame(struct urtwn_softc *sc, u
 
 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
 
-	/* push the frame up to the 802.11 stack */
-	ieee80211_input(ni, m, rssi, 0);
+	printf ("urtwn rx_frame, ni is 0x%lx.\n", (long)ni);
+	if (ni != NULL) {
+		printf ("  ... and vap = 0x%lx\n", (long)ni->ni_vap);
+		if (ni->ni_vap != NULL) {
+			printf ("  ... and iv_input = 0x%lx\n", (long)ni->ni_vap->iv_input);
 
-	/* Node is no longer needed. */
-	ieee80211_free_node(ni);
+		} else {
+			printf ("iv_input is null, not continuing.\n");
+			splx(s);
+			return;
+		}
+		/* push the frame up to the 802.11 stack */
+		ieee80211_input(ni, m, rssi, 0);
+
+		/* Node is no longer needed. */
+		ieee80211_free_node(ni);
+
+	} else {
+
+		/* No node found ... process differently. */
+		(void) ieee80211_input_all(ic, m, rssi, 0);
+	}
 
 	splx(s);
 }
@@ -2597,10 +2961,13 @@ urtwn_txeof(struct usbd_xfer *xfer, void
 	DPRINTFN(DBG_FN|DBG_TX, ("%s: %s: status=%d\n",
 	    device_xname(sc->sc_dev), __func__, status));
 
+	printf ("enter sc_tx_mtx, adr is 0x%lx (from txeof)\n", (long)&sc->sc_tx_mtx);
 	mutex_enter(&sc->sc_tx_mtx);
 	/* Put this Tx buffer back to our free list. */
 	TAILQ_INSERT_TAIL(&sc->tx_free_list[pidx], data, next);
 	mutex_exit(&sc->sc_tx_mtx);
+	printf ("exit sc_tx_mtx (from txeof)\n");
+
 
 	s = splnet();
 	sc->tx_timer = 0;
@@ -2837,12 +3204,14 @@ urtwn_get_tx_data(struct urtwn_softc *sc
 {
 	struct urtwn_tx_data *data = NULL;
 
-	mutex_enter(&sc->sc_tx_mtx);
+	printf ("enter sc_tx_mtx, adr is 0x%lx (from tx_data)\n", (long)&sc->sc_tx_mtx);
+	mutex_enter(&sc->sc_tx_mtx); 
 	if (!TAILQ_EMPTY(&sc->tx_free_list[pidx])) {
 		data = TAILQ_FIRST(&sc->tx_free_list[pidx]);
 		TAILQ_REMOVE(&sc->tx_free_list[pidx], data, next);
 	}
 	mutex_exit(&sc->sc_tx_mtx);
+	printf ("exit sc_tx_mtx (from tx_data)\n");
 
 	return data;
 }
@@ -3021,8 +3390,8 @@ urtwn_vap_create(struct ieee80211com *ic
 	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
 
 	/* Override state transition machine. */
-	sc->sc_newstate = vap->iv_newstate;
-	vap->iv_newstate = urtwn_newstate;
+	// sc->sc_newstate = vap->iv_newstate;
+	// vap->iv_newstate = urtwn_newstate;
 
 	/* Finish setup */
 	ieee80211_vap_attach(vap, urtwn_media_change,
@@ -3084,29 +3453,92 @@ urtwn_set_channel(struct ieee80211com *i
 
 	DPRINTFN(DBG_FN, ("%s: %s\n",device_xname(sc->sc_dev), __func__));
 
+	mutex_enter(&sc->sc_write_mtx);
 	urtwn_set_chan(sc, ic->ic_curchan, IEEE80211_HTINFO_2NDCHAN_NONE);
+	mutex_exit(&sc->sc_write_mtx);
 } 
 
 static int
 urtwn_transmit(struct ieee80211com *ic, struct mbuf *m)
 {
 	struct urtwn_softc *sc = ic->ic_softc;
+	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+	int s;
+	int error;
+	size_t pktlen = m->m_pkthdr.len;
+        bool mcast = (m->m_flags & M_MCAST) != 0;
 
 	DPRINTFN(DBG_FN, ("%s: %s\n",device_xname(sc->sc_dev), __func__));
 
-	return EIO;
+	s = splnet();
+
+        IFQ_ENQUEUE(&vap->iv_ifp->if_snd, m, error);
+        if (error != 0) {
+                /* mbuf is already freed */
+                goto out;
+        }
+
+        vap->iv_ifp->if_obytes += pktlen;
+        if (mcast)
+                vap->iv_ifp->if_omcasts++;
+
+        if ((vap->iv_ifp->if_flags & IFF_OACTIVE) == 0)
+                if_start_lock(vap->iv_ifp);
+out:
+        splx(s);
+
+        return error;
 }
 
 static int
 urtwn_raw_xmit(struct ieee80211_node *ni , struct mbuf *m,
     const struct ieee80211_bpf_params *bpfp)
 {
+	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211com *ic = ni->ni_ic;
 	struct urtwn_softc *sc = ic->ic_softc;
+	struct urtwn_tx_data *data;
+	int error;
 
 	DPRINTFN(DBG_FN, ("%s: %s\n",device_xname(sc->sc_dev), __func__));
 
-	return EIO;
+	data = urtwn_get_tx_data(sc, sc->ac2idx[WME_AC_VO]);
+
+	if (data == NULL) {
+		vap->iv_ifp->if_flags |= IFF_OACTIVE;
+		DPRINTFN(DBG_TX, ("%s: empty tx_free_list\n",
+				  device_xname(sc->sc_dev)));
+		return ENOBUFS;
+	}
+	
+        bpf_mtap3(vap->iv_rawbpf, m, BPF_D_OUT);
+
+	error = urtwn_tx(sc, m, ni, data);
+	if (error != 0) {
+			printf("ERROR3\n");
+			vap->iv_ifp->if_oerrors++;
+	}
+	m_freem(m);
+	ieee80211_free_node(ni);
+	return error;
+}
+
+static void
+urtwn_getradiocaps(struct ieee80211com *ic,
+    int maxchans, int *nchans, struct ieee80211_channel chans[])
+{
+	uint8_t bands[IEEE80211_MODE_BYTES];
+
+	/*
+	 * NNN Should be able to do something based on chip if
+	 * a chip has more bands .... eg. N ... but for the future.
+	 */
+
+	memset(bands, 0, sizeof(bands));
+	setbit(bands, IEEE80211_MODE_11B);
+	setbit(bands, IEEE80211_MODE_11G);
+	ieee80211_add_channel_list_2ghz(chans, maxchans, nchans,
+	    urtwn_chan_2ghz, nitems(urtwn_chan_2ghz), bands, 0);
 }
 
 

Index: src/sys/net80211/ieee80211.c
diff -u src/sys/net80211/ieee80211.c:1.56.18.4 src/sys/net80211/ieee80211.c:1.56.18.5
--- src/sys/net80211/ieee80211.c:1.56.18.4	Fri Jul 20 20:33:05 2018
+++ src/sys/net80211/ieee80211.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211.c,v 1.56.18.4 2018/07/20 20:33:05 phil Exp $ */
+/*	$NetBSD: ieee80211.c,v 1.56.18.5 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -398,8 +398,14 @@ ieee80211_ifattach(struct ieee80211com *
 	    ic->ic_name);
 	ic->ic_ierrors = counter_u64_alloc(M_WAITOK);
 	ic->ic_oerrors = counter_u64_alloc(M_WAITOK);
-#elif__NetBSD__
-	/* NNN task/workqueue get it ready.... */
+#elif __NetBSD__
+	/*
+	 * Create a workqueue for all state changes, ieee80211_netbsd.*
+	 * has glue to translate taskqueue functions to workqueue.
+	 */
+	if (workqueue_create(&ic->ic_tq, "net80211_wq",
+	    ieee80211_runwork, ic, PRI_SOFTNET, IPL_NET, WQ_MPSAFE))
+		panic("net80211 workqueue not created");
 	ic->ic_ierrors = 0;
 	ic->ic_oerrors = 0;
 #endif
@@ -455,7 +461,9 @@ ieee80211_ifdetach(struct ieee80211com *
 	LIST_REMOVE(ic, ic_next);
 	mtx_unlock(&ic_list_mtx);
 
+#if __FreeBSD__	
 	taskqueue_drain(taskqueue_thread, &ic->ic_restart_task);
+#endif
 
 	/*
 	 * The VAP is responsible for setting and clearing
@@ -809,8 +817,10 @@ ieee80211_vap_detach(struct ieee80211vap
 	ieee80211_draintask(ic, &vap->iv_wme_task);
 	ieee80211_draintask(ic, &ic->ic_parent_task);
 
+#if __FreeBSD__	
 	/* XXX band-aid until ifnet handles this for us */
 	taskqueue_drain(taskqueue_swi, &ifp->if_linktask);
+#endif
 
 	IEEE80211_LOCK(ic);
 	KASSERT(vap->iv_state == IEEE80211_S_INIT , ("vap still running"));

Index: src/sys/net80211/ieee80211_adhoc.c
diff -u src/sys/net80211/ieee80211_adhoc.c:1.1.2.2 src/sys/net80211/ieee80211_adhoc.c:1.1.2.3
--- src/sys/net80211/ieee80211_adhoc.c:1.1.2.2	Thu Jul 12 16:35:34 2018
+++ src/sys/net80211/ieee80211_adhoc.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_adhoc.c,v 1.1.2.2 2018/07/12 16:35:34 phil Exp $ */
+/*	$NetBSD: ieee80211_adhoc.c,v 1.1.2.3 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -114,6 +114,7 @@ adhoc_vdetach(struct ieee80211vap *vap)
 static void
 adhoc_vattach(struct ieee80211vap *vap)
 {
+	printf ("adhoc_vattach\n");
 	vap->iv_newstate = adhoc_newstate;
 	vap->iv_input = adhoc_input;
 	if (vap->iv_opmode == IEEE80211_M_IBSS)
@@ -152,6 +153,7 @@ adhoc_newstate(struct ieee80211vap *vap,
 	struct ieee80211_node *ni;
 	enum ieee80211_state ostate;
 
+	printf ("running adhoc_newstate for %s\n", vap->iv_ifp->if_xname); // NNN
 	IEEE80211_LOCK_ASSERT(vap->iv_ic);
 
 	ostate = vap->iv_state;
@@ -335,6 +337,8 @@ adhoc_input(struct ieee80211_node *ni, s
 	int is_hw_decrypted = 0;
 	int has_decrypted = 0;
 
+	printf ("adhoc input called for %s\n", ifp->if_xname); // NNN
+	
 	/*
 	 * Some devices do hardware decryption all the way through
 	 * to pretending the frame wasn't encrypted in the first place.
@@ -727,6 +731,7 @@ adhoc_recv_mgmt(struct ieee80211_node *n
 #if 0
 	int ht_state_change = 0;
 #endif
+	printf ("adhoc_recv_mgmt called, for %s\n", vap->iv_ifp->if_xname);
 
 	wh = mtod(m0, struct ieee80211_frame *);
 	frm = (uint8_t *)&wh[1];
Index: src/sys/net80211/ieee80211_hostap.c
diff -u src/sys/net80211/ieee80211_hostap.c:1.1.2.2 src/sys/net80211/ieee80211_hostap.c:1.1.2.3
--- src/sys/net80211/ieee80211_hostap.c:1.1.2.2	Thu Jul 12 16:35:34 2018
+++ src/sys/net80211/ieee80211_hostap.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_hostap.c,v 1.1.2.2 2018/07/12 16:35:34 phil Exp $ */
+/*	$NetBSD: ieee80211_hostap.c,v 1.1.2.3 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -114,6 +114,7 @@ hostap_vdetach(struct ieee80211vap *vap)
 static void
 hostap_vattach(struct ieee80211vap *vap)
 {
+	printf ("hostap_vattach\n");
 	vap->iv_newstate = hostap_newstate;
 	vap->iv_input = hostap_input;
 	vap->iv_recv_mgmt = hostap_recv_mgmt;
Index: src/sys/net80211/ieee80211_monitor.c
diff -u src/sys/net80211/ieee80211_monitor.c:1.1.2.2 src/sys/net80211/ieee80211_monitor.c:1.1.2.3
--- src/sys/net80211/ieee80211_monitor.c:1.1.2.2	Thu Jul 12 16:35:34 2018
+++ src/sys/net80211/ieee80211_monitor.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_monitor.c,v 1.1.2.2 2018/07/12 16:35:34 phil Exp $ */
+/*	$NetBSD: ieee80211_monitor.c,v 1.1.2.3 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -93,6 +93,7 @@ monitor_vdetach(struct ieee80211vap *vap
 static void
 monitor_vattach(struct ieee80211vap *vap)
 {
+	printf ("monitor_vattach\n");
 	vap->iv_newstate = monitor_newstate;
 	vap->iv_input = monitor_input;
 	vap->iv_opdetach = monitor_vdetach;
Index: src/sys/net80211/ieee80211_sta.c
diff -u src/sys/net80211/ieee80211_sta.c:1.1.2.2 src/sys/net80211/ieee80211_sta.c:1.1.2.3
--- src/sys/net80211/ieee80211_sta.c:1.1.2.2	Thu Jul 12 16:35:34 2018
+++ src/sys/net80211/ieee80211_sta.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_sta.c,v 1.1.2.2 2018/07/12 16:35:34 phil Exp $ */
+/*	$NetBSD: ieee80211_sta.c,v 1.1.2.3 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -115,6 +115,7 @@ sta_vdetach(struct ieee80211vap *vap)
 static void
 sta_vattach(struct ieee80211vap *vap)
 {
+	printf ("sta_vattach\n");
 	vap->iv_newstate = sta_newstate;
 	vap->iv_input = sta_input;
 	vap->iv_recv_mgmt = sta_recv_mgmt;
Index: src/sys/net80211/ieee80211_tdma.c
diff -u src/sys/net80211/ieee80211_tdma.c:1.1.2.2 src/sys/net80211/ieee80211_tdma.c:1.1.2.3
--- src/sys/net80211/ieee80211_tdma.c:1.1.2.2	Thu Jul 12 16:35:34 2018
+++ src/sys/net80211/ieee80211_tdma.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_tdma.c,v 1.1.2.2 2018/07/12 16:35:34 phil Exp $ */
+/*	$NetBSD: ieee80211_tdma.c,v 1.1.2.3 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -157,6 +157,7 @@ setackpolicy(struct ieee80211com *ic, in
 void
 ieee80211_tdma_vattach(struct ieee80211vap *vap)
 {
+	printf ("ieee80211_tdma_vattach\n");
 	struct ieee80211_tdma_state *ts;
 
 	KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
Index: src/sys/net80211/ieee80211_wds.c
diff -u src/sys/net80211/ieee80211_wds.c:1.1.2.2 src/sys/net80211/ieee80211_wds.c:1.1.2.3
--- src/sys/net80211/ieee80211_wds.c:1.1.2.2	Thu Jul 12 16:35:34 2018
+++ src/sys/net80211/ieee80211_wds.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_wds.c,v 1.1.2.2 2018/07/12 16:35:34 phil Exp $ */
+/*	$NetBSD: ieee80211_wds.c,v 1.1.2.3 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -110,6 +110,7 @@ wds_vdetach(struct ieee80211vap *vap)
 static void
 wds_vattach(struct ieee80211vap *vap)
 {
+	printf("wds_vattach\n");
 	vap->iv_newstate = wds_newstate;
 	vap->iv_input = wds_input;
 	vap->iv_recv_mgmt = wds_recv_mgmt;

Index: src/sys/net80211/ieee80211_input.c
diff -u src/sys/net80211/ieee80211_input.c:1.114.2.3 src/sys/net80211/ieee80211_input.c:1.114.2.4
--- src/sys/net80211/ieee80211_input.c:1.114.2.3	Mon Jul 16 20:11:11 2018
+++ src/sys/net80211/ieee80211_input.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_input.c,v 1.114.2.3 2018/07/16 20:11:11 phil Exp $ */
+/*	$NetBSD: ieee80211_input.c,v 1.114.2.4 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -152,6 +152,7 @@ ieee80211_input_mimo_all(struct ieee8021
 		/* NB: could check for IFF_UP but this is cheaper */
 		if (vap->iv_state == IEEE80211_S_INIT)
 			continue;
+
 		/*
 		 * WDS vap's only receive directed traffic from the
 		 * station at the ``far end''.  That traffic should
@@ -180,6 +181,7 @@ ieee80211_input_mimo_all(struct ieee8021
 			m = NULL;
 		}
 		ni = ieee80211_ref_node(vap->iv_bss);
+		printf ("ieee80211_input_mimo_all on %s, ni=0x%lx\n", vap->iv_ifp->if_xname, (long)ni);
 		type = ieee80211_input_mimo(ni, mcopy);
 		ieee80211_free_node(ni);
 	}

Index: src/sys/net80211/ieee80211_ioctl.c
diff -u src/sys/net80211/ieee80211_ioctl.c:1.60.18.4 src/sys/net80211/ieee80211_ioctl.c:1.60.18.5
--- src/sys/net80211/ieee80211_ioctl.c:1.60.18.4	Fri Jul 20 20:33:05 2018
+++ src/sys/net80211/ieee80211_ioctl.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_ioctl.c,v 1.60.18.4 2018/07/20 20:33:05 phil Exp $ */
+/*	$NetBSD: ieee80211_ioctl.c,v 1.60.18.5 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -3020,6 +3020,7 @@ ieee80211_ioctl_set80211(struct ieee8021
 	case OLD_IEEE80211_IOC_SCAN_REQ:
 		IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
 			"%s: active scan request\n", __func__);
+		printf ("old scan req\n");
 		/*
 		 * If we are in INIT state then the driver has never
 		 * had a chance to setup hardware state to do a scan;
@@ -3028,8 +3029,11 @@ ieee80211_ioctl_set80211(struct ieee8021
 		 * a one-time scan.
 		 */
 		if (vap->iv_state == IEEE80211_S_INIT)
+{  printf ("calling new_state\n");
 			ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
+}
 		else
+{  printf("calling _start_scan()\n");
 			(void) ieee80211_start_scan(vap,
 				IEEE80211_SCAN_ACTIVE |
 				IEEE80211_SCAN_NOPICK |
@@ -3037,6 +3041,7 @@ ieee80211_ioctl_set80211(struct ieee8021
 				IEEE80211_SCAN_FOREVER, 0, 0,
 				/* XXX use ioctl params */
 				vap->iv_des_nssid, vap->iv_des_ssid);
+}
 		break;
 #endif /* OLD_IEEE80211_IOC_SCAN_REQ */
 	case IEEE80211_IOC_SCAN_REQ:

Index: src/sys/net80211/ieee80211_mesh.c
diff -u src/sys/net80211/ieee80211_mesh.c:1.1.2.3 src/sys/net80211/ieee80211_mesh.c:1.1.2.4
--- src/sys/net80211/ieee80211_mesh.c:1.1.2.3	Mon Jul 16 20:11:11 2018
+++ src/sys/net80211/ieee80211_mesh.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_mesh.c,v 1.1.2.3 2018/07/16 20:11:11 phil Exp $ */
+/*	$NetBSD: ieee80211_mesh.c,v 1.1.2.4 2018/07/28 00:49:43 phil Exp $ */
 
 /*- 
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -673,6 +673,7 @@ mesh_vdetach(struct ieee80211vap *vap)
 static void
 mesh_vattach(struct ieee80211vap *vap)
 {
+	printf ("mesh_vattach\n");
 	struct ieee80211_mesh_state *ms;
 	vap->iv_newstate = mesh_newstate;
 	vap->iv_input = mesh_input;

Index: src/sys/net80211/ieee80211_netbsd.c
diff -u src/sys/net80211/ieee80211_netbsd.c:1.31.2.4 src/sys/net80211/ieee80211_netbsd.c:1.31.2.5
--- src/sys/net80211/ieee80211_netbsd.c:1.31.2.4	Fri Jul 20 20:33:05 2018
+++ src/sys/net80211/ieee80211_netbsd.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_netbsd.c,v 1.31.2.4 2018/07/20 20:33:05 phil Exp $ */
+/*	$NetBSD: ieee80211_netbsd.c,v 1.31.2.5 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -29,7 +29,7 @@
 
 #include <sys/cdefs.h>
 /*  __FBSDID("$FreeBSD$");  */
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_netbsd.c,v 1.31.2.4 2018/07/20 20:33:05 phil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_netbsd.c,v 1.31.2.5 2018/07/28 00:49:43 phil Exp $");
 
 /*
  * IEEE 802.11 support (NetBSD-specific code)
@@ -86,6 +86,43 @@ ieee80211_init0(void)
 	return 0;
 }
 
+/*
+ * "taskqueue" support
+ */
+void ieee80211_runwork(struct work *work2do, void *arg)
+{
+	struct task *work_task = (struct task *) work2do;
+	printf ("runwork called! work2do is 0x%lx, t_work.wk_dummy is 0x%lx\n", 
+		(long) work2do, (long)work_task->t_work.wk_dummy);
+	printf ("  runwork:  t_func is 0x%lx, t_arg is 0x%lx\n",
+		(long)work_task->t_func, (long)work_task->t_arg);
+
+	mutex_enter(&work_task->t_mutex);
+	work_task->t_onqueue = 0;
+	mutex_exit(&work_task->t_mutex);
+	
+	work_task->t_func(work_task->t_arg, 0);
+}
+
+void taskqueue_enqueue(struct workqueue *wq, struct task *task_item)
+{
+	printf ("taskqueue_enqueue called\n");
+	mutex_enter(&task_item->t_mutex);
+	if (!task_item->t_onqueue) {
+		printf ("   taskqueue_enqueue adding item to workqueue\n");
+		workqueue_enqueue(wq, &task_item->t_work, NULL);
+		task_item->t_onqueue = 1;
+	}
+	mutex_exit(&task_item->t_mutex);
+}
+
+void taskqueue_drain(struct workqueue *wq, struct task *task_item)
+{
+	printf ("taskqueue_drain called\n");
+	workqueue_wait(wq, &task_item->t_work);
+}
+
+
 static __unused int
 wlan_clone_create(struct if_clone *ifc, int unit, void * params)
 {
@@ -523,7 +560,7 @@ ieee80211_getmgtframe(uint8_t **frm, int
 		 * frames which all fit in MHLEN.
 		 */
 		if (m != NULL)
-			M_ALIGN(m, len);
+			MH_ALIGN(m, len);
 	} else {
 		m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
 		if (m != NULL)
@@ -737,7 +774,7 @@ int
 ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
 {
 	int error;
-
+	printf ("ieee80211_parent_xmitpkt called\n");
 	/*
 	 * Assert the IC TX lock is held - this enforces the
 	 * processing -> queuing order is maintained

Index: src/sys/net80211/ieee80211_netbsd.h
diff -u src/sys/net80211/ieee80211_netbsd.h:1.21.2.5 src/sys/net80211/ieee80211_netbsd.h:1.21.2.6
--- src/sys/net80211/ieee80211_netbsd.h:1.21.2.5	Fri Jul 20 20:33:05 2018
+++ src/sys/net80211/ieee80211_netbsd.h	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_netbsd.h,v 1.21.2.5 2018/07/20 20:33:05 phil Exp $ */
+/*	$NetBSD: ieee80211_netbsd.h,v 1.21.2.6 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -75,29 +75,38 @@
 /*
  * task stuff needs major work NNN! 
  */
-static __inline int dummy(void);
-static __inline int dummy(void) { return 0; }
-
-struct timeout_task { int needsWork; };
 
 typedef void task_fn_t(void *context, int pending);
 
 struct task {
 	/* some kind of queue entry? */
-	task_fn_t *t_func;
-	void *t_arg;
-	int  t_pri;
+	struct work t_work;
+	task_fn_t  *t_func;
+	void       *t_arg;
+	kmutex_t    t_mutex;
+	int         t_onqueue;
 };
+
+static __inline int dummy(void);
+static __inline int dummy(void) { return 0; }
+
+struct timeout_task { int needsWork; };
+
+void ieee80211_runwork(struct work *, void *);
+void taskqueue_enqueue(struct workqueue *, struct task *);
+void taskqueue_drain(struct workqueue *, struct task *);
+
 #define TASK_INIT(var, pri, func, arg) do { \
 	(var)->t_func = func; \
-	(var)->t_arg = arg; \
-        (var)->t_pri = pri; \
+        (var)->t_arg = arg; \
+	(var)->t_work.wk_dummy = var; \
+	mutex_init(&(var)->t_mutex, MUTEX_DEFAULT, IPL_SOFTNET);\
+	(var)->t_onqueue = 0;\
 } while(0)
 
 #define taskqueue workqueue
-#define taskqueue_enqueue(queue,task) /* workqueue_enqueue(queue, task, NULL) */
-#define taskqueue_drain(queue,task)   /* workqueue_wait(queue, task) */
-#define taskqueue_free(queue)         /* workqueue_destroy(queue)  */
+#define taskqueue_free(queue)         workqueue_destroy(queue)
+
 #define taskqueue_block(queue)        /* */
 #define taskqueue_unblock(queue)      /* */
 #define taskqueue_drain_timeout(queue, x) /* */
@@ -147,8 +156,14 @@ void       if_inc_counter(struct ifnet *
 
 #define IF_LLADDR(ifp)     IFADDR_FIRST(ifp)
 
+/* Scanners ... needed because no module support; */
+extern const struct ieee80211_scanner sta_default;
+extern const struct ieee80211_scanner ap_default;
+extern const struct ieee80211_scanner adhoc_default;
+extern const struct ieee80211_scanner mesh_default;
+
 /*
- *  Sysctl support??? BBB
+ *  Sysctl support??? NNN
  */
 
 #define SYSCTL_INT(a1, a2, a3, a4, a5, a6, a7)  /* notyet */
@@ -179,7 +194,7 @@ typedef struct {
 #define	IEEE80211_LOCK_INIT(_ic, _name) do {				\
 	ieee80211_com_lock_t *cl = &(_ic)->ic_comlock;			\
 	snprintf(cl->name, sizeof(cl->name), "%s_com_lock", _name);	\
-        mutex_init(&cl->mtx, MUTEX_DEFAULT, IPL_NET);                   \
+        mutex_init(&cl->mtx, MUTEX_DEFAULT, IPL_SOFTNET);               \
 } while (0)
 #define	IEEE80211_LOCK_OBJ(_ic)	(&(_ic)->ic_comlock.mtx)
 #define	IEEE80211_LOCK_DESTROY(_ic) mutex_destroy(IEEE80211_LOCK_OBJ(_ic))
@@ -203,7 +218,7 @@ typedef struct {
 #define	IEEE80211_TX_LOCK_INIT(_ic, _name) do {				\
 	ieee80211_tx_lock_t *cl = &(_ic)->ic_txlock;			\
 	snprintf(cl->name, sizeof(cl->name), "%s_tx_lock", _name);	\
-	mutex_init(&cl->mtx, MUTEX_DEFAULT, IPL_NET);			\
+	mutex_init(&cl->mtx, MUTEX_DEFAULT, IPL_SOFTNET);		\
 } while (0)
 #define	IEEE80211_TX_LOCK_OBJ(_ic)	(&(_ic)->ic_txlock.mtx)
 #define	IEEE80211_TX_LOCK_DESTROY(_ic) mutex_destroy(IEEE80211_TX_LOCK_OBJ(_ic))
@@ -224,7 +239,7 @@ typedef struct {
 #define IEEE80211_FF_LOCK_INIT(_ic, _name) do {				\
 	ieee80211_ff_lock_t *fl = &(_ic)->ic_fflock;			\
 	snprintf(fl->name, sizeof(fl->name), "%s_ff_lock", _name);	\
-	mutex_init(&fl->mtx, MUTEX_DEFAULT, IPL_NET);                   \
+	mutex_init(&fl->mtx, MUTEX_DEFAULT, IPL_SOFTNET);               \
 } while (0)
 #define IEEE80211_FF_LOCK_OBJ(_ic)	(&(_ic)->ic_fflock.mtx)
 #define IEEE80211_FF_LOCK_DESTROY(_ic)	mutex_destroy(IEEE80211_FF_LOCK_OBJ(_ic))
@@ -243,7 +258,7 @@ typedef struct {
 #define	IEEE80211_NODE_LOCK_INIT(_nt, _name) do {			\
 	ieee80211_node_lock_t *nl = &(_nt)->nt_nodelock;		\
 	snprintf(nl->name, sizeof(nl->name), "%s_node_lock", _name);	\
-	mutex_init(&nl->mtx, MUTEX_DEFAULT, IPL_NET);                   \
+	mutex_init(&nl->mtx, MUTEX_DEFAULT, IPL_SOFTNET);               \
 } while (0)
 #define	IEEE80211_NODE_LOCK_OBJ(_nt)	(&(_nt)->nt_nodelock.mtx)
 #define	IEEE80211_NODE_LOCK_DESTROY(_nt) \
@@ -262,7 +277,7 @@ typedef struct {
  */
 typedef kmutex_t ieee80211_psq_lock_t;
 #define	IEEE80211_PSQ_INIT(_psq, _name) \
-	mutex_init(&(_psq)->psq_lock, MUTEX_DEFAULT, IPL_NET)
+	mutex_init(&(_psq)->psq_lock, MUTEX_DEFAULT, IPL_SOFTNET)
 #define	IEEE80211_PSQ_DESTROY(_psq)	mutex_destroy(&(_psq)->psq_lock)
 #define	IEEE80211_PSQ_LOCK(_psq)	mutex_enter(&(_psq)->psq_lock)
 #define	IEEE80211_PSQ_UNLOCK(_psq)	mutex_exit(&(_psq)->psq_lock)
@@ -287,7 +302,7 @@ typedef kmutex_t ieee80211_psq_lock_t;
  */
 typedef kmutex_t ieee80211_ageq_lock_t;
 #define	IEEE80211_AGEQ_INIT(_aq, _name) \
-	mutex_init(&(_aq)->aq_lock, MUTEX_DEFAULT, IPL_NET)
+	mutex_init(&(_aq)->aq_lock, MUTEX_DEFAULT, IPL_SOFTNET)
 #define	IEEE80211_AGEQ_DESTROY(_aq)	mutex_destroy(&(_aq)->aq_lock)
 #define	IEEE80211_AGEQ_LOCK(_aq)	mutex_enter(&(_aq)->aq_lock)
 #define	IEEE80211_AGEQ_UNLOCK(_aq)	mutex_exit(&(_aq)->aq_lock)
@@ -297,7 +312,7 @@ typedef kmutex_t ieee80211_ageq_lock_t;
  */
 typedef kmutex_t acl_lock_t;
 #define	ACL_LOCK_INIT(_as, _name) \
-	mutex_init(&(_as)->as_lock, MUTEX_DEFAULT, IPL_NET)
+	mutex_init(&(_as)->as_lock, MUTEX_DEFAULT, IPL_SOFTNET)
 #define	ACL_LOCK_DESTROY(_as)		mutex_destroy(&(_as)->as_lock)
 #define	ACL_LOCK(_as)			mutex_enter(&(_as)->as_lock)
 #define	ACL_UNLOCK(_as)			mutex_exit(&(_as)->as_lock)
@@ -309,14 +324,14 @@ typedef kmutex_t acl_lock_t;
  */
 typedef kmutex_t ieee80211_scan_table_lock_t;
 #define	IEEE80211_SCAN_TABLE_LOCK_INIT(_st, _name) \
-	mutex_init(&(_st)->st_lock, MUTEX_DEFAULT, IPL_NET)
+	mutex_init(&(_st)->st_lock, MUTEX_DEFAULT, IPL_SOFTNET)
 #define	IEEE80211_SCAN_TABLE_LOCK_DESTROY(_st)	mutex_destroy(&(_st)->st_lock)
 #define	IEEE80211_SCAN_TABLE_LOCK(_st)		mutex_enter(&(_st)->st_lock)
 #define	IEEE80211_SCAN_TABLE_UNLOCK(_st)	mutex_exit(&(_st)->st_lock)
 
 typedef kmutex_t ieee80211_scan_iter_lock_t;
 #define	IEEE80211_SCAN_ITER_LOCK_INIT(_st, _name) \
-	mutex_init(&(_st)->st_scanlock, MUTEX_DEFAULT, IPL_NET)
+	mutex_init(&(_st)->st_scanlock, MUTEX_DEFAULT, IPL_SOFTNET)
 #define	IEEE80211_SCAN_ITER_LOCK_DESTROY(_st)	mutex_destroy(&(_st)->st_scanlock)
 #define	IEEE80211_SCAN_ITER_LOCK(_st)		mutex_enter(&(_st)->st_scanlock)
 #define	IEEE80211_SCAN_ITER_UNLOCK(_st)	mutex_exit(&(_st)->st_scanlock)
@@ -326,7 +341,7 @@ typedef kmutex_t ieee80211_scan_iter_loc
  */
 typedef kmutex_t ieee80211_rte_lock_t;
 #define	MESH_RT_ENTRY_LOCK_INIT(_rt, _name) \
-	mutex_init(&(rt)->rt_lock, MUTEX_DEFAULT, IPL_NET)
+	mutex_init(&(rt)->rt_lock, MUTEX_DEFAULT, IPL_SOFTNET)
 #define	MESH_RT_ENTRY_LOCK_DESTROY(_rt) \
 	mutex_destroy(&(_rt)->rt_lock)
 #define	MESH_RT_ENTRY_LOCK(rt)	mutex_enter(&(rt)->rt_lock)
@@ -340,7 +355,7 @@ typedef kmutex_t ieee80211_rt_lock_t;
 	FBSDKASSERT(mutex_owned(&(ms)->ms_rt_lock), ("lock not owned"))
 #define	MESH_RT_UNLOCK(ms)	mutex_exit(&(ms)->ms_rt_lock)
 #define	MESH_RT_LOCK_INIT(ms, name) \
-	mutex_init(&(ms)->ms_rt_lock, MUTEX_DEFAULT, IPL_NET)
+	mutex_init(&(ms)->ms_rt_lock, MUTEX_DEFAULT, IPL_SOFTNET)
 #define	MESH_RT_LOCK_DESTROY(ms) \
 	mutex_destroy(&(ms)->ms_rt_lock)
 

Index: src/sys/net80211/ieee80211_proto.c
diff -u src/sys/net80211/ieee80211_proto.c:1.34.14.4 src/sys/net80211/ieee80211_proto.c:1.34.14.5
--- src/sys/net80211/ieee80211_proto.c:1.34.14.4	Fri Jul 20 20:33:05 2018
+++ src/sys/net80211/ieee80211_proto.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_proto.c,v 1.34.14.4 2018/07/20 20:33:05 phil Exp $ */
+/*	$NetBSD: ieee80211_proto.c,v 1.34.14.5 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -287,6 +287,8 @@ ieee80211_proto_attach(struct ieee80211c
 {
 	uint8_t hdrlen;
 
+	printf ("i33380211_proto_attach called\n");  /* NNN debug */
+
 	/* override the 802.3 setting */
 	hdrlen = ic->ic_headroom
 		+ sizeof(struct ieee80211_qosframe_addr4)
@@ -302,6 +304,10 @@ ieee80211_proto_attach(struct ieee80211c
 	ic->ic_protmode = IEEE80211_PROT_CTSONLY;
 
 	TASK_INIT(&ic->ic_parent_task, 0, parent_updown, ic);
+	printf ("parent task: t_work.wk_dummy 0x%lx, t_func 0x%lx t_arg 0x%lx\n",
+		(long)(ic->ic_parent_task.t_work.wk_dummy),
+		(long)(ic->ic_parent_task.t_func),
+		(long)(ic->ic_parent_task.t_arg));
 	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);
@@ -370,6 +376,7 @@ ieee80211_proto_vattach(struct ieee80211
 	TASK_INIT(&vap->iv_nstate_task, 0, ieee80211_newstate_cb, vap);
 	TASK_INIT(&vap->iv_swbmiss_task, 0, beacon_swmiss, vap);
 	TASK_INIT(&vap->iv_wme_task, 0, vap_update_wme, vap);
+
 	/*
 	 * Install default tx rate handling: no fixed rate, lowest
 	 * supported rate for mgmt and multicast frames.  Default
@@ -1405,7 +1412,8 @@ parent_updown(void *arg, int npending)
 {
 	struct ieee80211com *ic = arg;
 
-	ic->ic_parent(ic);
+	printf ("parent_updown called on %s!\n", ic->ic_name);
+	// ic->ic_parent(ic);
 }
 
 static void
@@ -1793,7 +1801,11 @@ ieee80211_restart_all(struct ieee80211co
 	 * NB: do not use ieee80211_runtask here, we will
 	 * block & drain net80211 taskqueue.
 	 */
+#if __FreeBSD__
 	taskqueue_enqueue(taskqueue_thread, &ic->ic_restart_task);
+#elif __NetBSD__
+	printf ("ieee80211_restart_all called .... should add code.\n");
+#endif
 }
 
 void

Index: src/sys/net80211/ieee80211_scan.c
diff -u src/sys/net80211/ieee80211_scan.c:1.1.56.4 src/sys/net80211/ieee80211_scan.c:1.1.56.5
--- src/sys/net80211/ieee80211_scan.c:1.1.56.4	Mon Jul 16 20:11:11 2018
+++ src/sys/net80211/ieee80211_scan.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_scan.c,v 1.1.56.4 2018/07/16 20:11:11 phil Exp $ */
+/*	$NetBSD: ieee80211_scan.c,v 1.1.56.5 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -174,7 +174,7 @@ ieee80211_scan_vdetach(struct ieee80211v
 	IEEE80211_UNLOCK(ic);
 }
 
-#ifdef notyet
+#if __FreeBSD__
 /*
  * Simple-minded scanner module support.
  */
@@ -187,15 +187,34 @@ static const char *scan_modnames[IEEE802
 	"wlan_scan_monitor",	/* IEEE80211_M_MONITOR */
 	"wlan_scan_sta",	/* IEEE80211_M_MBSS */
 };
-#endif
+
 static const struct ieee80211_scanner *scanners[IEEE80211_OPMODE_MAX];
+#elif __NetBSD__
+/*
+ * No module support means we need to initialize them here.
+ */
+static const struct ieee80211_scanner *scanners[IEEE80211_OPMODE_MAX] = {
+	&adhoc_default,		/* IEEE80211_M_IBSS */ 
+	&sta_default,		/* IEEE80211_M_STA */
+	NULL,			/* IEEE80211_M_WDS */
+	&adhoc_default,		/* IEEE80211_M_AHDEMO */
+	&ap_default,		/* IEEE80211_M_HOSTAP */
+	NULL,			/* IEEE80211_M_MONITOR */
+#ifdef IEEE80211_SUPPORT_MESH	
+	&mesh_default,		/* IEEE80211_M_MBSS */
+#else
+	NULL,
+#endif
+};
+
+#endif
 
 const struct ieee80211_scanner *
 ieee80211_scanner_get(enum ieee80211_opmode mode)
 {
 	if (mode >= IEEE80211_OPMODE_MAX)
 		return NULL;
-#ifdef notyet
+#if __FreeBSD__
 	if (scanners[mode] == NULL)
 		ieee80211_load_module(scan_modnames[mode]);
 #endif
@@ -338,6 +357,7 @@ ieee80211_start_scan(struct ieee80211vap
 	u_int duration, u_int mindwell, u_int maxdwell,
 	u_int nssid, const struct ieee80211_scan_ssid ssids[])
 {
+printf ("ieee80211_start_scan called\n");
 	const struct ieee80211_scanner *scan;
 	struct ieee80211com *ic = vap->iv_ic;
 
@@ -363,6 +383,7 @@ ieee80211_check_scan(struct ieee80211vap
 	u_int duration, u_int mindwell, u_int maxdwell,
 	u_int nssid, const struct ieee80211_scan_ssid ssids[])
 {
+	printf ("ieee80211_check_scan called, opmode is %d\n", vap->iv_opmode);
 	struct ieee80211com *ic = vap->iv_ic;
 	struct ieee80211_scan_state *ss = ic->ic_scan;
 	const struct ieee80211_scanner *scan;
@@ -382,7 +403,8 @@ ieee80211_check_scan(struct ieee80211vap
 	 * XXX want more than the ap we're currently associated with
 	 */
 
-	IEEE80211_LOCK(ic);
+	// IEEE80211_LOCK(ic);  NNN who has this locked?
+	IEEE80211_LOCK_ASSERT(ic);
 	IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
 	    "%s: %s scan, %s%s%s%s%s\n"
 	    , __func__
@@ -407,7 +429,7 @@ ieee80211_check_scan(struct ieee80211vap
 	result = ic->ic_scan_methods->sc_check_scan(scan, vap, flags, duration,
 	    mindwell, maxdwell, nssid, ssids);
 
-	IEEE80211_UNLOCK(ic);
+	// IEEE80211_UNLOCK(ic);
 
 	return (result);
 }
@@ -594,6 +616,7 @@ ieee80211_add_scan(struct ieee80211vap *
 {
 	struct ieee80211com *ic = vap->iv_ic;
 
+	printf ("ieee80211_add_scan ...\n");
 	return (ic->ic_scan_methods->sc_add_scan(vap, curchan, sp, wh, subtype,
 	    rssi, noise));
 }
Index: src/sys/net80211/ieee80211_scan_sta.c
diff -u src/sys/net80211/ieee80211_scan_sta.c:1.1.56.4 src/sys/net80211/ieee80211_scan_sta.c:1.1.56.5
--- src/sys/net80211/ieee80211_scan_sta.c:1.1.56.4	Mon Jul 16 20:11:11 2018
+++ src/sys/net80211/ieee80211_scan_sta.c	Sat Jul 28 00:49:43 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_scan_sta.c,v 1.1.56.4 2018/07/16 20:11:11 phil Exp $ */
+/*	$NetBSD: ieee80211_scan_sta.c,v 1.1.56.5 2018/07/28 00:49:43 phil Exp $ */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -186,6 +186,7 @@ static int
 sta_attach(struct ieee80211_scan_state *ss)
 {
 	struct sta_table *st;
+	printf ("sta_attach ...\n");
 
 	st = (struct sta_table *) IEEE80211_MALLOC(sizeof(struct sta_table),
 		M_80211_SCAN,
@@ -262,6 +263,7 @@ sta_add(struct ieee80211_scan_state *ss,
 	const struct ieee80211_frame *wh,
 	int subtype, int rssi, int noise)
 {
+	printf ("sta_add called\n");
 #define	ISPROBE(_st)	((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
 #define	PICK1ST(_ss) \
 	((ss->ss_flags & (IEEE80211_SCAN_PICK1ST | IEEE80211_SCAN_GOTPICK)) == \
@@ -1502,7 +1504,11 @@ sta_assoc_success(struct ieee80211_scan_
 	}
 }
 
-static const struct ieee80211_scanner sta_default __unused = {
+#if __FreeBSD__
+static const struct ieee80211_scanner sta_default = {
+#elif __NetBSD__
+const struct ieee80211_scanner sta_default = {
+#endif
 	.scan_name		= "default",
 	.scan_attach		= sta_attach,
 	.scan_detach		= sta_detach,
@@ -1734,7 +1740,11 @@ adhoc_age(struct ieee80211_scan_state *s
 	IEEE80211_SCAN_TABLE_UNLOCK(st);
 }
 
-static const struct ieee80211_scanner adhoc_default __unused = {
+#if __FreeBSD__	
+static const struct ieee80211_scanner adhoc_default = {
+#elif __NetBSD__
+const struct ieee80211_scanner adhoc_default = {
+#endif
 	.scan_name		= "default",
 	.scan_attach		= sta_attach,
 	.scan_detach		= sta_detach,
@@ -1866,7 +1876,11 @@ ap_end(struct ieee80211_scan_state *ss, 
 	return 1;
 }
 
-static const struct ieee80211_scanner ap_default __unused = {
+#if __FreeBSD__
+static const struct ieee80211_scanner ap_default = {
+#elif __NetBSD__	
+const struct ieee80211_scanner ap_default = {
+#endif
 	.scan_name		= "default",
 	.scan_attach		= sta_attach,
 	.scan_detach		= sta_detach,
@@ -1973,7 +1987,11 @@ notfound:
 	return 1;				/* terminate scan */
 }
 
-static const struct ieee80211_scanner mesh_default __unused = {
+#if __FreeBSD__
+static const struct ieee80211_scanner mesh_default = {
+#elif __NetBSD__
+const struct ieee80211_scanner mesh_default = {
+#endif
 	.scan_name		= "default",
 	.scan_attach		= sta_attach,
 	.scan_detach		= sta_detach,

Reply via email to